Browse Source

feat: copy button, formatting, link previews

fix/enable-imgix
Thomas Osmonson 4 years ago
parent
commit
0153faa900
  1. 2
      lib/mdx-frontmatter-loader.js
  2. 70
      lib/mdx-loader.js
  3. 16
      package.json
  4. BIN
      public/images/todo-list-app.png
  5. 4
      src/common/navigation.yaml
  6. 75
      src/components/custom-blocks/page-reference.tsx
  7. 6
      src/components/feedback.tsx
  8. 11
      src/components/icons/clipboard-check.tsx
  9. 10
      src/components/icons/clipboard.tsx
  10. 10
      src/components/icons/copy.tsx
  11. 13
      src/components/icons/sitemap.tsx
  12. 99
      src/components/layouts/markdown-wrapper.tsx
  13. 140
      src/components/mdx/components/code.tsx
  14. 131
      src/components/mdx/components/link.tsx
  15. 34
      src/components/mdx/markdown-wrapper.tsx
  16. 12
      src/components/mdx/md-contents.tsx
  17. 5
      src/components/mdx/mdx-components.tsx
  18. 21
      src/components/mdx/overrides.tsx
  19. 51
      src/components/page-meta.tsx
  20. 44
      src/components/page-top.tsx
  21. 8
      src/components/search.tsx
  22. 4
      src/components/tooltip.tsx
  23. 38
      src/pages/authentication/building-todo-app.md
  24. 3
      src/pages/authentication/connect.md
  25. 5
      src/pages/authentication/overview.md
  26. 8
      src/pages/authentication/profiles.md
  27. 2
      src/pages/build-an-app.md
  28. 2
      src/pages/data-indexing/collaborate.md
  29. 2
      src/pages/data-indexing/integrate.md
  30. 2
      src/pages/data-indexing/models.md
  31. 2
      src/pages/data-indexing/overview.md
  32. 4
      src/pages/data-indexing/server-extras.md
  33. 2
      src/pages/data-storage/authentication.md
  34. 2
      src/pages/data-storage/collection-type.md
  35. 13
      src/pages/data-storage/collections.md
  36. 2
      src/pages/data-storage/overview.md
  37. 2
      src/pages/data-storage/storage-guide.md
  38. 2
      src/pages/data-storage/storage-write-read.md
  39. 5
      src/pages/ecosystem/address-confirmation.md
  40. 2
      src/pages/ecosystem/contributing.md
  41. 16
      src/pages/ecosystem/faq.md
  42. 1
      src/pages/ecosystem/overview.md
  43. 25
      src/pages/ecosystem/stacks-token-holders.md
  44. 1
      src/pages/ecosystem/stacks-token.md
  45. 2
      src/pages/index.md
  46. 2
      src/pages/mining.md
  47. 2
      src/pages/naming-services/architecture.md
  48. 6
      src/pages/naming-services/build-profile-search-index.md
  49. 4
      src/pages/naming-services/choose-name.md
  50. 2
      src/pages/naming-services/comparison.md
  51. 2
      src/pages/naming-services/create-namespace.md
  52. 2
      src/pages/naming-services/did.md
  53. 2
      src/pages/naming-services/forks.md
  54. 4
      src/pages/naming-services/manage-names.md
  55. 2
      src/pages/naming-services/namespaces.md
  56. 2
      src/pages/naming-services/overview.md
  57. 5
      src/pages/naming-services/register-name.md
  58. 5
      src/pages/naming-services/resolve-name.md
  59. 9
      src/pages/naming-services/subdomains-tutorial.md
  60. 13
      src/pages/naming-services/subdomains.md
  61. 5
      src/pages/references/blockstack-cli.md
  62. 4
      src/pages/references/clarity-language.md
  63. 9
      src/pages/references/deploy-tips.md
  64. 54
      src/pages/references/faqs.md
  65. 3
      src/pages/references/glossary.md
  66. 4
      src/pages/references/stacks-blockchain.md
  67. 2
      src/pages/references/stacks-rpc-api.md
  68. 8
      src/pages/smart-contracts/cli-wallet-quickstart.md
  69. 3
      src/pages/smart-contracts/counter-tutorial.md
  70. 13
      src/pages/smart-contracts/hello-world-tutorial.md
  71. 3
      src/pages/smart-contracts/install-source.md
  72. 38
      src/pages/smart-contracts/overview.md
  73. 3
      src/pages/smart-contracts/principals.md
  74. 6
      src/pages/smart-contracts/running-a-testnet-node.md
  75. 5
      src/pages/smart-contracts/signing-transactions.md
  76. 6
      src/pages/smart-contracts/testing-contracts.md
  77. 2
      src/pages/stacks-blockchain/atlas/how-atlas-works.md
  78. 2
      src/pages/stacks-blockchain/atlas/overview.md
  79. 2
      src/pages/stacks-blockchain/atlas/usage.md
  80. 3
      src/pages/stacks-blockchain/best-practices.md
  81. 12
      src/pages/stacks-blockchain/install-api.md
  82. 5
      src/pages/stacks-blockchain/installing-memcached.md
  83. 2
      src/pages/stacks-blockchain/overview.md
  84. 7
      src/pages/stacks-blockchain/wire-format.md
  85. 5
      src/pages/stacks-wallet/install.md
  86. 5
      src/pages/stacks-wallet/overview.md
  87. 7
      src/pages/stacks-wallet/security.md
  88. 65
      src/pages/stacks-wallet/troubleshooting.md
  89. 12
      src/pages/stacks-wallet/usage.md
  90. 17
      src/pages/storage-hubs/amazon-s3-deploy.md
  91. 3
      src/pages/storage-hubs/config-schema.md
  92. 3
      src/pages/storage-hubs/digital-ocean-deploy.md
  93. 2
      src/pages/storage-hubs/gaia-admin.md
  94. 3
      src/pages/storage-hubs/hello-hub-choice.md
  95. 4
      src/pages/storage-hubs/overview.md
  96. 322
      yarn.lock

2
lib/mdx-frontmatter-loader.js

@ -34,7 +34,7 @@ async function mdxFrontmatterLoader(src) {
const headings = getHeadings(content);
const duration = getReadingTime(content).text;
const code =
`import { MDWrapper } from '@components/layouts/markdown-wrapper';
`import { MDWrapper } from '@components/mdx/markdown-wrapper';
export default function Layout({ children, ...props }){
return (
<MDWrapper frontmatter={${JSON.stringify({

70
lib/mdx-loader.js

@ -1,70 +0,0 @@
const { getOptions } = require('loader-utils');
const mdx = require('@mdx-js/mdx');
const fm = require('gray-matter');
const remark = require('remark');
const strip = require('strip-markdown');
const readingTime = require('reading-time');
const DEFAULT_RENDERER = `
import React from 'react'
import { mdx } from '@mdx-js/react'
`;
const getReadingTime = mdxContent => readingTime(mdxContent);
const getHeadings = mdxContent => {
const regex = /\n(#+)(.*)/gm;
const found = mdxContent.match(regex);
const getLevel = string => string.split('#');
const headings =
found && found.length
? found.map(f => {
const md = f.split('# ')[1];
let content = md;
remark()
.use(strip)
.process(md, (err, file) => {
if (err) throw err;
content = file.contents.toString().trim();
});
const level = getLevel(f).length;
return { content, level };
})
: [];
return headings;
};
const layoutPropsString = `const layoutProps = {`;
const newLayoutPropsString = frontmatter => `const layoutProps = {
frontmatter: ${frontmatter},\n`;
const withFrontmatter = (code, frontmatter) =>
code.replace(layoutPropsString, newLayoutPropsString(frontmatter));
const loader = async function (src) {
const callback = this.async();
const options = Object.assign({}, getOptions(this), {
filepath: this.resourcePath,
});
const { content, data } = fm(src);
const headings = getHeadings(content);
const duration = getReadingTime(content).text;
const frontmatter = JSON.stringify({ duration, ...data, headings });
let result;
try {
result = await mdx(content, options);
} catch (err) {
return callback(err);
}
const { renderer = DEFAULT_RENDERER } = options;
const code = withFrontmatter(`${renderer}\n${result}`, frontmatter);
return callback(null, code);
};
module.exports = loader;

16
package.json

@ -2,10 +2,10 @@
"name": "@blockstack/docs",
"version": "1.0.0",
"dependencies": {
"@blockstack/ui": "2.12.2-beta.0",
"@docsearch/react": "^1.0.0-alpha.26",
"@blockstack/ui": "file:.yalc/@blockstack/ui",
"@docsearch/react": "^1.0.0-alpha.27",
"@hashicorp/remark-plugins": "^3.0.0",
"@mdx-js/loader": "1.6.15",
"@mdx-js/loader": "1.6.16",
"@mdx-js/mdx": "^1.6.16",
"@mdx-js/react": "^1.6.16",
"@next/mdx": "^9.4.4",
@ -16,7 +16,7 @@
"@types/node": "^14.0.27",
"@types/nprogress": "^0.2.0",
"@types/reach__tooltip": "^0.2.0",
"algoliasearch": "^4.3.1",
"algoliasearch": "^4.4.0",
"babel-plugin-macros": "^2.8.0",
"cache-manager": "^3.3.0",
"cache-manager-fs-hash": "^0.0.9",
@ -34,15 +34,15 @@
"lodash.debounce": "^4.0.8",
"mdi-react": "7.3.0",
"micro-memoize": "^4.0.9",
"next": "^9.5.2-canary.7",
"next": "^9.5.2-canary.9",
"next-fonts": "^1.4.0",
"next-google-fonts": "^1.1.0",
"next-mdx-remote": "^0.6.0",
"nprogress": "^0.2.0",
"p-all": "^3.0.0",
"preact": "^10.4.4",
"preact": "^10.4.7",
"preact-render-to-string": "^5.1.4",
"preact-ssr-prepass": "^1.1.0",
"preact-ssr-prepass": "^1.1.1",
"prettier": "^2.0.5",
"preval.macro": "^5.0.0",
"react-gesture-responder": "^2.1.0",
@ -63,7 +63,7 @@
"remark-unwrap-images": "2.0.0",
"remark-vscode": "^1.0.0-beta.2",
"strip-markdown": "^3.1.2",
"swr": "^0.2.3",
"swr": "^0.3.0",
"turndown": "^6.0.0",
"typescript": "^3.9.7",
"unified-vscode": "^1.0.0-beta.1",

BIN
public/images/todo-list-app.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

4
src/common/navigation.yaml

@ -22,11 +22,12 @@ sections:
pages:
- path: /overview
- path: /profiles
- path: /connect
sections:
- title: Tutorials
usePageTitles: true
pages:
- path: /building-todo-app
- path: /connect
- path: /data-storage
pages:
- path: /overview
@ -63,7 +64,6 @@ sections:
- path: /install
- path: /usage
- path: /security
- path: /troubleshooting
- path: /naming-services
pages:
- path: /overview

75
src/components/custom-blocks/page-reference.tsx

@ -1,8 +1,11 @@
import React from 'react';
import { Box, Flex, BoxProps, color, Grid, space } from '@blockstack/ui';
import { BlockstackLogo } from '@components/icons/blockstack-logo';
import { StackIcon } from '@components/icons/stack';
import { SitemapIcon } from '@components/icons/sitemap';
import { border, onlyText, transition } from '@common/utils';
import { useTouchable } from '@common/hooks/use-touchable';
import { Caption, Text } from '@components/typography';
import { Text } from '@components/typography';
import Link from 'next/link';
import { useAppState } from '@common/hooks/use-app-state';
import { Img } from '@components/mdx/image';
@ -84,7 +87,7 @@ const InlineCard = ({ page }) => {
<Box flexShrink={0} size="64px" overflow="hidden" borderRadius={'12px'}>
<Image
transition={transition('0.45s')}
transform={(hover || active) && 'scale(1.12)'}
transform={(hover || active) && 'scale(1.18)'}
style={{ willChange: 'transform' }}
size="64px"
src={page.images.sm}
@ -165,7 +168,7 @@ const GridCardImage: React.FC<BoxProps & { isHovered?: boolean; page: any }> = R
)
);
const GridCardDetails: React.FC<BoxProps & { isHovered?: boolean; page: any }> = React.memo(
const GridItemDetails: React.FC<BoxProps & { isHovered?: boolean; page: any }> = React.memo(
({ isHovered, page, ...props }) => (
<>
<Flex alignItems="flex-start" justifyContent="flex-start" flexDirection="column">
@ -192,11 +195,63 @@ const GridCard: React.FC<BoxProps & { page?: any }> = React.memo(({ page, ...res
{...bind}
>
<GridCardImage page={page} isHovered={hover || active} />
<GridCardDetails page={page} />
<GridItemDetails page={page} />
</Box>
);
});
const getIcon = (icon: string) => {
switch (icon) {
case 'BlockstackIcon':
return (p: BoxProps) => <BlockstackLogo size="32px" color="#9985FF" {...p} />;
case 'StacksIcon':
return (p: BoxProps) => (
<Grid borderRadius="6px" style={{ placeItems: 'center' }} bg="#9985FF" size="32px" {...p}>
<StackIcon size="24px" color={color('bg')} />
</Grid>
);
case 'TestnetIcon':
return (p: BoxProps) => (
<Grid borderRadius="6px" style={{ placeItems: 'center' }} bg="#9985FF" size="32px" {...p}>
<SitemapIcon size="24px" color={color('bg')} />
</Grid>
);
default:
return (p: BoxProps) => <BlockstackLogo size="32px" color={color('accent')} {...p} />;
}
};
const GridSmallItem: React.FC<BoxProps & { page?: any }> = ({ page, ...rest }) => {
const { hover, active, bind } = useTouchable({
behavior: 'link',
});
const Icon = getIcon(page.icon);
return (
<Box
position="relative"
color={color('text-title')}
_hover={{ color: color('accent') }}
{...rest}
{...bind}
>
{page.icon ? <Icon mb={space('base')} /> : null}
<GridItemDetails page={page} />
</Box>
);
};
const getComponent = (type: 'default' | 'inline' | 'grid' | 'grid-small') => {
switch (type) {
case 'inline':
return InlineCard;
case 'grid':
return GridCard;
case 'grid-small':
return GridSmallItem;
default:
return GridCard;
}
};
export const PageReference: React.FC<BoxProps> = React.memo(({ children }) => {
const content = onlyText(children).trim();
const [variant, _paths] = content.includes('\n') ? content.split('\n') : ['default', content];
@ -206,6 +261,8 @@ export const PageReference: React.FC<BoxProps> = React.memo(({ children }) => {
if (!routes) return null;
const pages = paths.map(path => routes?.find(route => route.path === path)).filter(page => page);
const Comp = getComponent(variant as any);
return (
<Grid
width="100%"
@ -219,13 +276,9 @@ export const PageReference: React.FC<BoxProps> = React.memo(({ children }) => {
`repeat(${pages.length === 1 ? 1 : 3}, 1fr)`,
]}
>
{pages.map((page, key) =>
variant === 'inline' ? (
<InlineCard key={key} page={page} />
) : (
<GridCard key={key} page={page} />
)
)}
{pages.map((page, key) => (
<Comp key={key} page={page} />
))}
</Grid>
);
});

6
src/components/feedback.tsx

@ -19,10 +19,12 @@ import { useRouter } from 'next/router';
import { getHeadingStyles } from '@components/mdx/typography';
import { css } from '@styled-system/css';
import { StatusCheck } from '@components/status-check';
import { useColorMode } from '@common/hooks/use-color-mode';
const Icon: React.FC<BoxProps & { icon: React.FC<any> }> = ({ icon: IconComponent, ...props }) => {
const { bind, hover, active } = useTouchable();
const isHovered = hover || active;
const [mode] = useColorMode();
return (
<Box
color={color('text-caption')}
@ -31,7 +33,9 @@ const Icon: React.FC<BoxProps & { icon: React.FC<any> }> = ({ icon: IconComponen
{...props}
{...bind}
>
<IconComponent bg={isHovered ? color('accent') : color('bg-alt')} />
<IconComponent
bg={isHovered ? '#9985FF' : mode === 'light' ? color('bg-alt') : color('bg-light')}
/>
</Box>
);
};

11
src/components/icons/clipboard-check.tsx

@ -0,0 +1,11 @@
import React from 'react';
import { BaseSvg, SvgProps } from '@components/icons/_base';
export const ClipboardCheckIcon: SvgProps = props => (
<BaseSvg {...props}>
<path stroke="none" d="M0 0h24v24H0z" />
<path d="M9 5H7a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2V7a2 2 0 0 0 -2 -2h-2" />
<rect x="9" y="3" width="6" height="4" rx="2" />
<path d="M9 14l2 2l4 -4" />
</BaseSvg>
);

10
src/components/icons/clipboard.tsx

@ -0,0 +1,10 @@
import React from 'react';
import { BaseSvg, SvgProps } from '@components/icons/_base';
export const ClipboardIcon: SvgProps = props => (
<BaseSvg {...props}>
<path stroke="none" d="M0 0h24v24H0z" />
<path d="M9 5H7a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2V7a2 2 0 0 0 -2 -2h-2" />
<rect x="9" y="3" width="6" height="4" rx="2" />
</BaseSvg>
);

10
src/components/icons/copy.tsx

@ -0,0 +1,10 @@
import React from 'react';
import { BaseSvg, SvgProps } from '@components/icons/_base';
export const CopyIcon: SvgProps = props => (
<BaseSvg {...props}>
<path stroke="none" d="M0 0h24v24H0z" />
<rect x="8" y="8" width="12" height="12" rx="2" />
<path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2" />
</BaseSvg>
);

13
src/components/icons/sitemap.tsx

@ -0,0 +1,13 @@
import React from 'react';
import { BaseSvg, SvgProps } from '@components/icons/_base';
export const SitemapIcon: SvgProps = props => (
<BaseSvg {...props}>
<path stroke="none" d="M0 0h24v24H0z" />
<rect x="3" y="15" width="6" height="6" rx="2" />
<rect x="15" y="15" width="6" height="6" rx="2" />
<rect x="9" y="3" width="6" height="6" rx="2" />
<path d="M6 15v-1a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v1" />
<line x1="12" y1="9" x2="12" y2="12" />
</BaseSvg>
);

99
src/components/layouts/markdown-wrapper.tsx

@ -1,99 +0,0 @@
import React from 'react';
import { Box, Flex, Stack, space, BoxProps, color } from '@blockstack/ui';
import { MDContents } from '@components/mdx/md-contents';
import { H1 } from '@components/mdx';
import Head from 'next/head';
import { Text } from '@components/typography';
import { useRouter } from 'next/router';
import dynamic from 'next/dynamic';
import { getTitle } from '@common/utils';
import { css } from '@styled-system/css';
import { getHeadingStyles } from '@components/mdx/typography';
import { ToolsIcon } from '@components/icons/tools';
import { ClockIcon } from '@components/icons/clock';
const Search = dynamic(() => import('@components/search'));
const Experience: React.FC<BoxProps & { level?: 'beginner' | 'intermediate' | 'advanced' }> = ({
level,
...rest
}) => (
<Flex align="center" {...rest}>
<Box mr={space('extra-tight')} color={color('text-caption')}>
<ToolsIcon size="20px" />
</Box>
<Text textTransform="capitalize">{level}</Text>
</Flex>
);
const Duration: React.FC<BoxProps & { value?: string }> = ({ value, ...rest }) => (
<Flex align="center" {...rest}>
<Box mr={space('extra-tight')} color={color('text-caption')}>
<ClockIcon size="20px" />
</Box>
<Text>{value}</Text>
</Flex>
);
const PageTop: React.FC<any> = props => {
const router = useRouter();
const isHome = router?.pathname === '/';
return (
<Box
mb={['extra-loose', 'extra-loose', '64px']}
px={space(['extra-loose', 'extra-loose', 'none', 'none'])}
>
<Flex>
<H1 mb="0 !important">{getTitle(props)}</H1>
{isHome ? (
<Box width="100%" maxWidth="208px">
<Search />
</Box>
) : null}
</Flex>
{props.description ? (
<Box mt="40px !important">
<Text
css={css({
...getHeadingStyles('h4'),
})}
>
{props.description}
</Text>{' '}
</Box>
) : null}
<Stack isInline spacing={space('base')} mt={space('extra-loose')}>
{props.experience ? <Experience level={props.experience} /> : null}
{!isHome && props.duration ? <Duration value={props.duration} /> : null}
</Stack>
</Box>
);
};
const defaultFrontmatter = {
headings: [],
description:
'Blockstack is an open-source and developer-friendly network for building decentralized apps and smart contracts.',
};
export const MDWrapper: React.FC<any> = React.memo(
({ frontmatter = defaultFrontmatter, dynamicHeadings = [], ...props }) => {
const { headings, description } = frontmatter;
return (
<>
<Head>
<title>{getTitle(frontmatter)} | Blockstack</title>
<meta name="description" content={description} />
</Head>
<MDContents
pageTop={() => <PageTop {...frontmatter} />}
headings={[...headings, ...dynamicHeadings]}
>
{props.children}
</MDContents>
</>
);
}
);
export default MDWrapper;

140
src/components/mdx/components/code.tsx

@ -1,9 +1,13 @@
import React from 'react';
import React, { Children } from 'react';
import { Box, BoxProps, color, space, themeColor } from '@blockstack/ui';
import { border } from '@common/utils';
import { Box, Flex, BoxProps, color, space, useClipboard, themeColor } from '@blockstack/ui';
import { ClipboardCheckIcon } from '@components/icons/clipboard-check';
import { border, onlyText } from '@common/utils';
import { css } from '@styled-system/css';
import { Text } from '@components/typography';
import { useHover } from 'use-events';
import { IconButton } from '@components/icon-button';
import { CopyIcon as BaseCopyIcon } from '@components/icons/copy';
const LINE_MINIMUM = 4;
@ -39,55 +43,95 @@ export const Code: React.FC<
BoxProps & { highlight?: string; lang?: string; lines: number }
> = React.memo(
React.forwardRef(({ children, highlight, lang, lines, ...rest }, ref) => {
const [hover, bind] = useHover();
const numbers = getHighlightLineNumbers(highlight);
const convertSingleChildToString = child => onlyText(child).replace(/\n/g, '');
const tokenLines = Children.toArray(children).map(convertSingleChildToString);
const codeString = tokenLines.join('\n');
const { hasCopied, onCopy } = useClipboard(codeString);
const CopyIcon = hasCopied ? ClipboardCheckIcon : BaseCopyIcon;
return (
<Box className={lines <= 3 ? 'no-line-numbers' : ''} ref={ref as any} overflowX="auto">
<Box
as="code"
css={css({
width: '100%',
display: 'flex',
flexDirection: 'column',
minWidth: 'fit-content',
'.token-line': {
display: 'inline-block',
...generateCssStylesForHighlightedLines(numbers),
},
counterReset: 'line',
'& .token-line': {
'.comment': {
color: 'rgba(255,255,255,0.5) !important',
},
<Box position="relative" {...bind}>
<Box className={lines <= 3 ? 'no-line-numbers' : ''} ref={ref as any} overflowX="auto">
<Box
as="code"
css={css({
width: '100%',
display: 'flex',
fontSize: '14px',
'&::before':
lines > LINE_MINIMUM && lang !== 'bash'
? {
counterIncrement: 'line',
content: 'counter(line, decimal-leading-zero)',
display: 'grid',
placeItems: 'center',
color: themeColor('ink.400'),
mr: '16px',
width: '42px',
fontSize: '12px',
borderRight: '1px solid rgb(39,41,46)',
}
: {},
},
pr: space(['base-loose', 'base-loose', 'extra-loose', 'extra-loose']),
pl:
lines <= LINE_MINIMUM || lang === 'bash'
? space(['extra-loose', 'extra-loose', 'base-loose', 'base-loose'])
: 'unset',
})}
{...rest}
>
<Box height="16px" width="100%" />
{children}
<Box height="16px" width="100%" />
flexDirection: 'column',
minWidth: 'fit-content',
'.token-line': {
display: 'inline-block',
...generateCssStylesForHighlightedLines(numbers),
},
counterReset: 'line',
'& .token-line': {
'.comment': {
color: 'rgba(255,255,255,0.5) !important',
},
display: 'flex',
fontSize: '14px',
'&::before':
lines > LINE_MINIMUM && lang !== 'bash'
? {
counterIncrement: 'line',
content: 'counter(line, decimal-leading-zero)',
display: 'grid',
placeItems: 'center',
color: themeColor('ink.400'),
mr: '16px',
width: '42px',
fontSize: '12px',
borderRight: '1px solid rgb(39,41,46)',
}
: {},
},
pr: space(['base-loose', 'base-loose', 'extra-loose', 'extra-loose']),
pl:
lines <= LINE_MINIMUM || lang === 'bash'
? space(['extra-loose', 'extra-loose', 'base-loose', 'base-loose'])
: 'unset',
})}
{...rest}
>
<Box height="16px" width="100%" />
{children}
<Box height="16px" width="100%" />
</Box>
</Box>
{hover ? (
<Flex
size="80%"
justifyContent="flex-end"
alignItems="flex-start"
position="absolute"
right="0"
top="0"
zIndex={999999}
px={space('base')}
py={lines === 1 ? '10px' : space('base')}
display={['none', 'none', 'flex']}
>
<IconButton
title="Copy to clipboard"
bg="transparent"
_hover={{
color: 'white',
// @ts-ignore
bg: themeColor('ink.900'),
}}
color={themeColor('ink.400')}
onClick={onCopy}
>
<CopyIcon size="20px" />
</IconButton>
</Flex>
) : null}
</Box>
);
})

131
src/components/mdx/components/link.tsx

@ -1,6 +1,26 @@
import { Box, BoxProps } from '@blockstack/ui';
import { Box, BoxProps, color, space, Fade } from '@blockstack/ui';
import NextLink from 'next/link';
import React, { forwardRef, Ref } from 'react';
import { useAppState } from '@common/hooks/use-app-state';
import { border, transition } from '@common/utils';
import { Text } from '@components/typography';
import { useTouchable } from '@common/hooks/use-touchable';
import { css } from '@styled-system/css';
import { getHeadingStyles } from '@components/mdx/typography';
import { PageMeta } from '@components/page-meta';
export const MarkdownLink = ({ href, ...rest }: { href: string }) => {
const isExternal = !href || href?.includes('http') || href?.includes('mailto');
const link = <LinkWithHover href={href || undefined} {...rest} />;
return isExternal ? (
link
) : (
<NextLink href={href} passHref>
{link}
</NextLink>
);
};
export const SmartLink = ({ href, ...rest }: { href: string }) => {
const isExternal = !href || href?.includes('http') || href?.includes('mailto');
@ -15,21 +35,104 @@ export const SmartLink = ({ href, ...rest }: { href: string }) => {
);
};
const Card = ({ route, styles, ...rest }) => {
const { description } = route;
return (
<Box
style={{ userSelect: 'none', pointerEvents: 'none', ...styles }}
transition={transition()}
pt={space('tight')}
{...rest}
>
<Box
bg={color('bg')}
minWidth="280px"
border={border()}
borderRadius="12px"
overflow="hidden"
boxShadow="0px 2px 4px rgba(0, 0, 0, 0.02), 0px 24px 40px rgba(0, 0, 0, 0.08)"
>
<Box bg={color('bg-light')} p={space('base')}>
<Text
css={css({
...getHeadingStyles('h5'),
display: 'block',
})}
>
{description}
</Text>
<PageMeta small {...route} />
</Box>
</Box>
</Box>
);
};
export const LinkWithHover = forwardRef(
(
props: { href?: string; target?: string; rel?: string } & BoxProps,
ref: Ref<HTMLDivElement>
) => {
const { bind, hover } = useTouchable();
const { routes } = useAppState();
const isExternal =
props.href && (props.href?.includes('http') || props.href?.includes('mailto'));
const previewData =
!isExternal && props.href && props.href.startsWith('/')
? routes.find(r => r.path.endsWith(props.href))
: undefined;
return (
<Box display="inline" position="relative" {...bind}>
<Box
as={props.href ? 'a' : 'span'}
ref={ref}
color="var(--colors-accent)"
cursor="pointer"
textDecoration="underline"
_hover={{ textDecoration: 'none' }}
_focus={{ boxShadow: 'outline' }}
rel="nofollow noopener noreferrer"
{...props}
/>
{previewData ? (
<Fade in={hover}>
{styles => (
<Card
route={previewData}
position="absolute"
left={0}
top="100%"
styles={styles}
zIndex={999}
/>
)}
</Fade>
) : null}
</Box>
);
}
);
export const Link = forwardRef(
(
props: { href?: string; target?: string; rel?: string } & BoxProps,
ref: Ref<HTMLDivElement>
) => (
<Box
as={props.href ? 'a' : 'span'}
ref={ref}
color="var(--colors-accent)"
cursor="pointer"
textDecoration="underline"
_hover={{ textDecoration: 'none' }}
_focus={{ boxShadow: 'outline' }}
rel="nofollow noopener noreferrer"
{...props}
/>
)
) => {
return (
<Box
as={props.href ? 'a' : 'span'}
ref={ref}
color="var(--colors-accent)"
cursor="pointer"
textDecoration="underline"
_hover={{ textDecoration: 'none' }}
_focus={{ boxShadow: 'outline' }}
rel="nofollow noopener noreferrer"
{...props}
/>
);
}
);

34
src/components/mdx/markdown-wrapper.tsx

@ -0,0 +1,34 @@
import React from 'react';
import { MDContents } from '@components/mdx/md-contents';
import Head from 'next/head';
import { getTitle } from '@common/utils';
import { PageTop } from '@components/page-top';
const defaultFrontmatter = {
headings: [],
description:
'Blockstack is an open-source and developer-friendly network for building decentralized apps and smart contracts.',
};
export const MDWrapper: React.FC<any> = React.memo(
({ frontmatter = defaultFrontmatter, dynamicHeadings = [], ...props }) => {
const { headings, description } = frontmatter;
return (
<>
<Head>
<title>{getTitle(frontmatter)} | Blockstack</title>
<meta name="description" content={description} />
</Head>
<MDContents
pageTop={() => <PageTop {...frontmatter} />}
headings={[...headings, ...dynamicHeadings]}
>
{props.children}
</MDContents>
</>
);
}
);
export default MDWrapper;

12
src/components/mdx/md-contents.tsx

@ -11,10 +11,14 @@ import { border } from '@common/utils';
import { getCapsizeStyles } from '@components/mdx/typography';
export const styleOverwrites = {
section: {
'&:first-child > h2:first-child': {
mt: 0,
'& > section': {
'&:nth-child(2)': {
'& > *:first-child': {
mt: 0,
},
},
},
section: {
'& > *:not(pre):not(ul):not(ol):not(img):not([data-reach-accordion]):not(section):not(hr)': {
px: space(['extra-loose', 'extra-loose', 'none', 'none']),
},
@ -48,7 +52,7 @@ export const styleOverwrites = {
borderRadius: [0, 0, '12px'],
bg: themeColor('ink'),
},
'& > div > code': {
'& > div > div > code': {
whiteSpace: 'pre',
overflowX: 'auto',
maxWidth: '100%',

5
src/components/mdx/mdx-components.tsx

@ -2,7 +2,7 @@ import React from 'react';
import {
Pre,
THead,
SmartLink,
MarkdownLink,
TData,
Table,
InlineCode,
@ -24,7 +24,6 @@ import {
import { Img } from '@components/mdx/image';
import { Code } from '@components/mdx/components';
import { PageReference } from '@components/custom-blocks/page-reference';
import { MDWrapper } from '@components/layouts/markdown-wrapper';
export const Components = {
h1: () => null,
@ -41,7 +40,7 @@ export const Components = {
table: Table,
th: THead,
td: TData,
a: SmartLink,
a: MarkdownLink,
p: P,
ul: Ul,
ol: Ol,

21
src/components/mdx/overrides.tsx

@ -16,27 +16,6 @@ img{
image-rendering: crisp-edges;
will-change: transform;
}
.headroom {
top: 0;
left: 0;
right: 0;
zIndex: 1;
}
.headroom--unfixed {
position: relative;
transform: translateY(0);
}
.headroom--scrolled {
transition: transform 200ms ease-in-out;
}
.headroom--unpinned {
position: fixed;
transform: translateY(-100%);
}
.headroom--pinned {
position: fixed;
transform: translateY(0%);
}
:root{
--docsearch-modal-background: ${color('bg')};
--docsearch-text-color: ${color('text-title')};

51
src/components/page-meta.tsx

@ -0,0 +1,51 @@
import React from 'react';
import { Box, Flex, space, Stack, BoxProps, color, StackProps } from '@blockstack/ui';
import { Text } from '@components/typography';
import { ToolsIcon } from '@components/icons/tools';
import { ClockIcon } from '@components/icons/clock';
import { css } from '@styled-system/css';
import { getCapsizeStyles } from '@components/mdx/typography';
const Experience: React.FC<
BoxProps & { level?: 'beginner' | 'intermediate' | 'advanced'; small?: boolean }
> = ({ level, small, ...rest }) => (
<Flex align="center" {...rest}>
<Box mr={space('extra-tight')} color={color('text-caption')}>
<ToolsIcon size={small ? '16px' : '20px'} />
</Box>
<Text
textTransform="capitalize"
css={css({
...getCapsizeStyles(small ? 14 : 16, 16),
})}
>
{level}
</Text>
</Flex>
);
const Duration: React.FC<BoxProps & { value?: string; small?: boolean }> = ({
value,
small,
...rest
}) => (
<Flex align="center" {...rest}>
<Box mr={space('extra-tight')} color={color('text-caption')}>
<ClockIcon size={small ? '16px' : '20px'} />
</Box>
<Text
css={css({
...getCapsizeStyles(small ? 14 : 16, 16),
})}
>
{value}
</Text>
</Flex>
);
export const PageMeta: React.FC<StackProps & any> = ({ experience, duration, isHome, small }) => (
<Stack isInline spacing={space('base')} mt={space('extra-loose')}>
{experience ? <Experience small={small} level={experience} /> : null}
{!isHome && duration ? <Duration small={small} value={duration} /> : null}
</Stack>
);

44
src/components/page-top.tsx

@ -0,0 +1,44 @@
import React from 'react';
import { Box, Flex, Stack, space, BoxProps } from '@blockstack/ui';
import { H1 } from '@components/mdx/index';
import { Text } from '@components/typography';
import { useRouter } from 'next/router';
import dynamic from 'next/dynamic';
import { getTitle } from '@common/utils';
import { css } from '@styled-system/css';
import { getHeadingStyles } from '@components/mdx/typography';
const Search = dynamic(() => import('@components/search'));
import { PageMeta } from '@components/page-meta';
export const PageTop: React.FC<BoxProps> = props => {
const router = useRouter();
const isHome = router?.pathname === '/';
return (
<Box
as="section"
mb={['extra-loose', 'extra-loose', '64px']}
px={space(['extra-loose', 'extra-loose', 'none', 'none'])}
>
<Flex>
<H1 mb="0 !important">{getTitle(props)}</H1>
{isHome ? (
<Box width="100%" maxWidth="208px">
<Search />
</Box>
) : null}
</Flex>
{props.description ? (
<Box mt="40px !important">
<Text
css={css({
...getHeadingStyles('h4'),
})}
>
{props.description}
</Text>{' '}
</Box>
) : null}
<PageMeta duration={props.duration} experience={props.experience} isHome={isHome} />
</Box>
);
};

8
src/components/search.tsx

@ -52,16 +52,14 @@ const Key: React.FC<BoxProps> = React.memo(({ children, ...rest }) => (
placeItems: 'center',
}}
size="18px"
bg={color('bg')}
border={border()}
bg={'rgba(0,0,0,0.11)'}
borderRadius="3px"
boxShadow="low"
opacity={0.75}
opacity={0.65}
{...rest}
>
<Text
css={css({
color: color('text-caption'),
color: color('text-body'),
display: 'block',
transform: 'translateY(1px)',
...getCapsizeStyles(12, 12),

4
src/components/tooltip.tsx

@ -13,7 +13,7 @@ const centered = (triggerRect: any, tooltipRect: any) => {
};
};
export const Tooltip = ({ children, label, 'aria-label': ariaLabel }: any) => {
export const Tooltip = ({ children, label, 'aria-label': ariaLabel, style = {}, ...rest }: any) => {
const [trigger, tooltip] = useTooltip();
const { onMouseDown, ...triggerProps } = trigger;
@ -33,8 +33,10 @@ export const Tooltip = ({ children, label, 'aria-label': ariaLabel }: any) => {
borderRadius: '3px',
padding: '0.5em 1em',
fontSize: '12px',
...style,
}}
position={centered}
{...rest}
/>
</>
);

38
src/pages/authentication/building-todo-app.md

@ -1,6 +1,8 @@
---
title: Building a Todo app
description: Learn how to integrate authentication and data storage.
experience: beginners
duration: 30 minutes
tags:
- tutorial
images:
@ -13,6 +15,10 @@ redirect_from:
# Building a Todo app
![What you'll be creating in this tutorial](/images/todo-list-app.png)
## Introduction
In this tutorial, you will learn about Blockstack authentication and storage by installing,
running and reviewing the code for a "Todos" web app built with Blockstack and [React](https://reactjs.org/).
@ -49,21 +55,21 @@ $ npm run start
You should see output similar to the following:
```bash
Compiled successfully!
Compiled successfully!
You can now view bs-todo in the browser.
You can now view bs-todo in the browser.
http://localhost:3000/
Note that the development build is not optimized.
To create a production build, use npm run build.
Note that the development build is not optimized.
To create a production build, use npm run build.
```
### Step 3: Open your local browser to [`http://localhost:3000`](http://localhost:3000) if it doesn't open automatically.
You should see the app's landing page:
![](/images/todos-home.png)
![The homepage of the todos app](/images/todos-home.png)
## Onboard into your first Blockstack app
@ -73,7 +79,7 @@ The app displays a standardized introductory modal using
[Blockstack Connect](https://github.com/blockstack/ux/tree/master/packages/connect), a JavaScript
library that makes it easy to integrate Blockstack into the UI of any web app.
![](/images/todos-intro.png)
![The Blockstack Connect Modal](/images/todos-intro.png)
Below, you can see the relevant parts of the [React component](https://reactjs.org/docs/react-component.html)
that triggers this modal in [`src/components/Signin.jsx`](https://github.com/blockstack/blockstack-todos/blob/master/src/components/Signin.jsx):
@ -179,7 +185,7 @@ componentDidMount() {
The app triggers a popup window in which [the Blockstack App](https://github.com/blockstack/ux/tree/master/packages/app)
is loaded from [`app.blockstack.org`](http://app.blockstack.org/) and begins generating a new _Secret Key_.
![](/images/todos-generation.svg)
![What the UI looks like when a new ID is generated](/images/todos-generation.svg)
### Step 3: Choose **Copy Secret Key** to copy your _Secret Key_ to the clipboard.
@ -190,11 +196,11 @@ all of the private data they create and manage with Blockstack apps.
_Secret Keys_ are like strong passwords. However, they can never be recovered if lost or reset if stolen.
As such, it's paramount that users handle them with great care.
![](/images/todos-copy-secret-key.svg)
![An example of a secret key](/images/todos-copy-secret-key.svg)
### Step 4: Choose **I've saved it** to confirm you've secured your _Secret Key_ in a suitable place.
![](/images/todos-ive-saved-it.svg)
![An example of the I've saved it screen](/images/todos-ive-saved-it.svg)
### Step 5: Enter a username value and choose **Continue**
@ -203,7 +209,7 @@ The username will be used by the app to generate a URL for sharing your todos, s
It is registered on the Stacks blockchain with the [Blockstack Naming System (BNS)](/core/naming/introduction)
and associated with your _Secret Key_.
![](/images/todos-username.svg)
![Choosing a user name example](/images/todos-username.svg)
### Done: You've now completed onboarding into the app!
@ -212,13 +218,13 @@ and associated with your _Secret Key_.
Once you've authenticated the app, you can can start adding todos by entering values into the "Write your to do"
field and hitting "Enter".
![](/images/todos-home-authenticated.svg)
![The authenticated view of the todos app](/images/todos-home-authenticated.svg)
The data for all todos are saved as JSON to the Gaia hub linked to your Secret Key using the
[`putFile`](http://blockstack.github.io/blockstack.js/globals.html#putfile) method of the `userSession` object in the
[`src/assets/data-store.js`](https://github.com/blockstack/blockstack-todos/blob/master/src/assets/data-store.js#L26) module:
```js
```jsx
export const saveTasks = async (userSession, tasks, isPublic) => {
await userSession.putFile(TASKS_FILENAME, JSON.stringify({ tasks, isPublic }), {
encrypt: !isPublic,
@ -229,7 +235,7 @@ export const saveTasks = async (userSession, tasks, isPublic) => {
These todos are subsequently loaded using the [`getFile`](http://blockstack.github.io/blockstack.js/globals.html#getfile)
method of the same object in the same module:
```js
```jsx
export const fetchTasks = async (userSession, username) => {
const tasksJSON = await userSession.getFile(TASKS_FILENAME, {
decrypt: false,
@ -248,7 +254,7 @@ When deleting a todo, the same `putFile` method is used to save a new JSON array
Select "Make public" to make your todos accessible to the public for sharing via URL.
![](/images/todos-public.svg)
![Public todos view](/images/todos-public.svg)
This will call `saveTasks` with the `isPublic` parameter set to `true`, which is used to disable encryption when using `putFile`.
@ -280,14 +286,14 @@ Once signed out, select "Sign in" to sign back in with your _Secret Key_.
If you've previously deauthenticated the Blockstack app, you'll see a prompt to enter your _Secret Key_:
![](/images/todos-sign-in.svg)
![An example of a sign in screen](/images/todos-sign-in.svg)
The above screen will be ommitted if you have an active session with the Blockstack app already.
Then you'll be presented with the option to select an existing username associated with your _Secret Key_ or
create a new one if you wish to authenticate the app with a different identity and data set:
![](/images/todos-choose-account.svg)
![An example of the choose an account screen](/images/todos-choose-account.svg)
You'll now see your todos as an authenticated user for the username you've chosen.

3
src/pages/authentication/connect.md

@ -2,10 +2,9 @@
title: Blockstack Connect
description: Learn what Connect is and how to integrate it into an app.
experience: beginners
duration: 15 minutes
---
# Guide to Blockstack Connect
## Introduction
Blockstack Connect is a JavaScript library for integrating Blockstack authentication and smart contracts into your app.

5
src/pages/authentication/overview.md

@ -6,11 +6,6 @@ images:
sm: /images/pages/authentication-sm.svg
---
# Authentication protocol
Blockstack Auth provides single sign on and authentication without third parties or remote servers.
On this page, you'll get an overview of authentication from a developer perspective.
## Authentication flow
For an application developer, the application flow is similar to the typical client-server flow used by centralized sign in services (e.g., OAuth). However, with Blockstack, the authentication flow happens entirely client-side.

8
src/pages/authentication/profiles.md

@ -1,12 +1,8 @@
---
title: Guide to Blockstack Profiles
title: Guide to Profiles
description: Learn about profiles on the Blockstack network
---
# Guide to Blockstack Profiles
You can use `blockstack.js` to create and register a Blockstack username on the Stacks blockchain.
This section describes the `Profile` object and contains the following topics:
## About profiles
Profile data is stored using Gaia on the user's selected storage provider. An example of a `profile.json` file URL using

2
src/pages/build-an-app.md

@ -6,7 +6,7 @@ images:
sm: /images/pages/build-an-app-sm.svg
---
# Building decentralized apps
## Introduction
Prefer to jump right in? Get started with this tutorial where you’ll create a decentralized to-do list app.

2
src/pages/data-indexing/collaborate.md

@ -3,7 +3,7 @@ title: Collaborate with groups
description: A key feature of Radiks is support for private collaboration between multiple users.
---
# Collaborate with groups
## Introduction
A key feature of Radiks is support for private collaboration between multiple users. Supporting collaboration with
client-side encryption and user-owned storage can be complicated, but the patterns to implement it are generally the

2
src/pages/data-indexing/integrate.md

@ -3,7 +3,7 @@ title: Integrate Radiks
description: Learn how to setup Radiks with your application.
---
# Integrate Radiks
## Introduction
Using Radiks with your application requires a Radiks server and a client application constructed to use the server.
In this article, you learn how to install, setup, and run a pre-packaged Radiks server that connects to MongoDB.

2
src/pages/data-indexing/models.md

@ -3,7 +3,7 @@ title: Create and use models
description: Model and query application data with Radiks.
---
# Create and use models
## Introduction
Radiks allows you to model your client data. You can then query this data and display it for a
user in multi-player applications. A social application where users want to see the comments of

2
src/pages/data-indexing/overview.md

@ -6,7 +6,7 @@ images:
sm: /images/pages/radiks-sm.svg
---
# Radiks the data indexer
## Introduction
The Blockstack Radiks feature enables Blockstack decentralized applications (DApps) to index and store across data
belonging to multiple users. Radiks works with Blockstack's Gaia Storage System. Using Radiks, you can build

4
src/pages/data-indexing/server-extras.md

@ -3,10 +3,6 @@ title: Radiks server tips and tricks
description: Some tips and tricks for working with a Radiks server.
---
# Radiks server tips and tricks
In this section, you'll find some tips and tricks you can use to work with a Radiks server.
## Access the MongoDB collection
Radiks-server keeps all models inside of a collection. You can use the `getDB` function to access this collection from inside your application.

2
src/pages/data-storage/authentication.md

@ -2,7 +2,7 @@
description: 'Storing user data with Blockstack'
---
# Authentication and Gaia
## Introduction
Blockstack authentication is a bearer token-based authentication system. From an app user's perspective,
login similar to third-party authentication techniques that they're familiar with. For an app developer,

2
src/pages/data-storage/collection-type.md

@ -2,7 +2,7 @@
title: Create a Collection type
---
# How to create a Collection type
## Introduction
Collections support data portability between applications. Blockstack supplies a `Contact` collection for use by Blockstack applications. Developers can create additional collection types, use them in their own applications, and publish them so other developers can make use of them too.

13
src/pages/data-storage/collections.md

@ -1,8 +1,9 @@
---
title: Collections (Preview)
description: Learn about the beta release of Collections and how you can start using it.
---
# Work with Collections (Preview)
## Introduction
Collections is the feature designed to make data portable among Blockstack applications. Sharing is accomplished by
storing a user's data in a standardized format at a known, Gaia storage location. Collections associate user data with
@ -11,13 +12,9 @@ a user's decentralized ID. When users move among apps, the same data is availabl
On this page, you learn what collections are and how to use them. You'll learn about the `Contact` collection in
particular. The following topics are covered:
> #### Preview release
>
> This is a preview release of the `Contact` collections. This release allows developers to try out the new collections
> functionality and we are interested in collecting feedback. Please feel free to report issues or request enhancements
> with collections or `Contacts` themselves on the [blockstack-collections repository](https://github.com/blockstack/blockstack-collections/issues/new).
>
> If you encounter problems with `blockstack.js` you can [file issues or request enhancements on its repo](https://github.com/blockstack/blockstack.js/issues/new).
-> This is a preview release of the `Contact` collections. This release allows developers to try out the new collections functionality and we are interested in collecting feedback. Please feel free to report issues or request enhancements with collections or `Contacts` themselves on the [blockstack-collections repository](https://github.com/blockstack/blockstack-collections/issues/new).
~> If you encounter problems with `blockstack.js` you can [file issues or request enhancements on its repo](https://github.com/blockstack/blockstack.js/issues/new).
## Understand how collections work

2
src/pages/data-storage/overview.md

@ -6,7 +6,7 @@ images:
sm: /images/pages/data-storage-sm.svg
---
# A decentralized storage architecture
## Introduction
The Blockstack Network stores application data using a storage system called
Gaia. Transactional metadata is stored on the Blockstack blockchain and user

2
src/pages/data-storage/storage-guide.md

@ -2,7 +2,7 @@
title: Guide to Blockstack Storage
---
# Guide to Blockstack Storage
## Introduction
The Blockstack Platform stores application data in the Gaia Storage System. Transactional metadata is stored on the
Blockstack blockchain and user application data is stored in Gaia storage. Storing data off of the blockchain ensures

2
src/pages/data-storage/storage-write-read.md

@ -2,7 +2,7 @@
description: 'Storing user data with Blockstack'
---
# Storage write and read
## Introduction
Once a user authenticates and a DApp obtains authentication, the application interacts with Gaia through the
blockstack.js library. There are two simple methods for working with data in Gaia hub: the `putFile()` and `getFile()`

5
src/pages/ecosystem/address-confirmation.md

@ -1,8 +1,9 @@
---
description: 'Blockstack Network documentation'
title: Confirm your address
description: Learn how to confirm a Stacks address
---
# Check your address
## Introduction
We recommend that you confirm your address is correct by going through the following steps in the Stacks Wallet:

2
src/pages/ecosystem/contributing.md

@ -3,7 +3,7 @@ title: How to contribute
description: Learn how this site is built, and how you could contribute to it.
---
# How to contribute
## Introduction
Welcome! Thank you for your interest in contributing and helping make these docs as good as they can be! This page will
outline how this site is built, its general structure, getting it running locally, and some helpful tips for using all of its features.

16
src/pages/ecosystem/faq.md

@ -1,16 +0,0 @@
---
description: 'Blockstack Network documentation'
---
export { convertFaqAnswersToMDX as getStaticProps } from '@common/data/faq'
import { FAQs } from '@components/faq'
# FAQs about Stacks tokens and wallet
## Stacks tokens
<FAQs category="tokens" data={props.mdx} />
## Stacks Wallet
<FAQs category="wallet" data={props.mdx} />

1
src/pages/ecosystem/overview.md

@ -1,5 +1,6 @@
---
description: Learn about Blockstack and decentralization
icon: BlockstackIcon
---
# Overview of Blockstack

25
src/pages/ecosystem/stacks-token-holders.md

@ -1,8 +1,9 @@
---
title: Stacks token holders
description: 'Blockstack token holder documentation'
---
# Information for current token holders
## Introduction
The information on this page is intended for **current Stacks (STX) token holders** during Blockstack’s token sale through early 2018.
@ -18,28 +19,6 @@ address directly to Blockstack, you can either use the **Restore from Seed
Phrase** feature on the Stacks Wallet or contact us at <hello@stackstoken.com> for
help.
<!-- Use the following form to check your Stacks allocation: -->
<!-- TODO: make work with react -->
<!-- <div class="uk-background-secondary uk-padding uk-panel"> -->
<!-- <script> -->
<!-- function process() -->
<!-- { -->
<!-- var url="https://explorer.blockstack.org/address/stacks/" + document.getElementById("url").value; -->
<!-- location.href=url; -->
<!-- return false; -->
<!-- } -->
<!-- </script> -->
<!-- <form class="uk-form-horizontal" onSubmit="return process();" autocomplete="off"> -->
<!-- <div> -->
<!-- <input style="background: #fff !important;" class="uk-input" type="text" name="url" id="url" placeholder="Enter public Stacks Wallet address"> -->
<!-- <input class="uk-button uk-button-default uk-form-width-medium uk-align-center" type="submit" value="Check allocation"> -->
<!-- </div> -->
<!-- </form> -->
<!-- </div> -->
You should see a report detailing the tokens allocated to your address and when they unlock:
![](/images/unlocking-address.png)

1
src/pages/ecosystem/stacks-token.md

@ -1,6 +1,7 @@
---
title: Stacks token
description: Learn about the native token of Blockstack
icon: StacksIcon
---
# Learn more about the Stacks token

2
src/pages/index.md

@ -18,4 +18,4 @@ description: All you need to build decentralized apps and smart contracts.
## Explore
[@page-reference | grid-small]
| /ecosystem/overview, /ecosystem/stacks-token
| /ecosystem/overview, /ecosystem/stacks-token, /smart-contracts/running-a-testnet-node

2
src/pages/mining.md

@ -6,4 +6,4 @@ images:
sm: /images/pages/mining-sm.svg
---
# Mine Stacks Token
## Introduction

2
src/pages/naming-services/architecture.md

@ -3,7 +3,7 @@ title: Blockstack naming service (BNS)
description: The BNS node is the heart of the system. It is responsible for building up and replicating global name state.
---
# Understand the Architecture
## Understand the Architecture
The BNS node is the heart of the system. It is responsible for building up
and replicating global name state.

6
src/pages/naming-services/build-profile-search-index.md

@ -2,7 +2,7 @@
description: Blockstack naming service (BNS)
---
# How to build a Profile Search Index
## Introduction
The search subsystem for Stacks Blockchain creates an index for data associated
with registered names in namespaces and makes that data searchable.
@ -26,7 +26,7 @@ http://localhost:5000/search?query=<SEARCH_PATTERN>
This document describes how to setup the search subsystem to respond at that endpoint.
# Installation
## Installation
- **Step 1:** First, make sure you have [virtualenv installed](http://docs.python-guide.org/en/latest/dev/virtualenvs/).
Then, setup the API and search subsystem:
@ -67,7 +67,7 @@ python -m search.basic_index --refresh
$ sed -i 's/SEARCH_API_ENDPOINT_ENABLED \= False/SEARCH_API_ENDPOINT_ENABLED \= True/' config.py
```
# Usage
## Usage
You can quickly test the search index from the command line:

4
src/pages/naming-services/choose-name.md

@ -3,10 +3,6 @@ title: Choose a name
description: This section explains how to choose and create a namespace.
---
# Choose a name
This section explains how to choose and create a namespace.
## Intended uses for a namespace
The intention is that each application can create its own BNS

2
src/pages/naming-services/comparison.md

@ -3,7 +3,7 @@ title: Feature comparison
description: This page describes some other naming systems in comparison to Blockstack.
---
# Naming system feature comparison
## Introduction
BNS is not the only naming system in wide-spread use, nor is it the only
decentralized naming system that implements human-readable, globally-unique, and

2
src/pages/naming-services/create-namespace.md

@ -3,7 +3,7 @@ title: Creating a Namespace
description: Learn how to create a namespace in the Blockstack Naming Service.
---
# Creating a Namespace
## Introduction
Making a namespace is very expensive. Given the large amount of cryptocurrency at stake in name creation, developers
wanting to create their own namespaces should read [Understand Namespaces](/core/naming/namespaces) first. You should

2
src/pages/naming-services/did.md

@ -3,7 +3,7 @@ title: Decentralized Identifiers (DIDs)
description: BNS nodes are compliant with the emerging Decentralized Identity Foundation protocol specification for decentralized identifiers.
---
# Decentralized Identifiers (DIDs)
## Introduction
BNS nodes are compliant with the emerging
[Decentralized Identity Foundation](http://identity.foundation) protocol

2
src/pages/naming-services/forks.md

@ -3,7 +3,7 @@ title: BNS forks
description: Learn about forks within the context of the BNS.
---
# BNS Forks
## Introduction
BNS effectively uses a public blockchain to store a database log. A BNS peer
bootstraps itself by downloading and replaying the database log from the

4
src/pages/naming-services/manage-names.md

@ -3,10 +3,6 @@ title: Manage BNS Names
description: This section teaches you how to manage your namespace.
---
# Manage BNS Names
This section teaches you how to manage your namespace.
## Overview of management
Once you register a BNS name, you have the power to change its zone file hash,

2
src/pages/naming-services/namespaces.md

@ -3,7 +3,7 @@ title: Understand Namespaces
description: Namespaces are the top-level naming objects in BNS.
---
# Understand Namespaces
## Introduction
Namespaces are the top-level naming objects in BNS.

2
src/pages/naming-services/overview.md

@ -97,7 +97,7 @@ can do the following and more:
- Build public-key infrastructure where it's easy for users to discover and
remember each other's keys.
# Organization of BNS
## Organization of BNS
BNS names are organized into a global name hierarchy. There are three different
layers in this hierarchy related to naming:

5
src/pages/naming-services/register-name.md

@ -3,11 +3,6 @@ title: Register a name
description: This section explains registering BNS names and provides instructions for methods you can use to understand the cost of namespace registration.
---
# Register a name
This section explains registering BNS names and provides instructions for methods
you can use to understand the cost of namespace registration.
## Understand registration
Registering a BNS name costs cryptocurrency. This cost comes from two sources:

5
src/pages/naming-services/resolve-name.md

@ -3,11 +3,6 @@ title: Resolve a name
description: This section explains resolving BNS names and provides instructions for methods you can use to accomplish namespace resolution.
---
## Resolve a name
This section explains resolving BNS names and provides instructions for methods
you can use to accomplish namespace resolution.
## Understand resolution
BNS names are bound to both public keys and to about 40Kb of off-chain state.

9
src/pages/naming-services/subdomains-tutorial.md

@ -1,12 +1,11 @@
---
description: 'Blockstack naming service (BNS)'
title: Subdomain registrar
description: Learn how to create, register, and run a subdomain registrar.
---
# Subdomain Design and Implementation
## Introduction
Subdomains allow us to provide names to end users cheaply (and quickly). This
tutorial explains you how to create, register, and run a subdomain register, it
contains the following sections:
Subdomains allow us to provide names to end users cheaply (and quickly).
## Strong subdomain ownership

13
src/pages/naming-services/subdomains.md

@ -1,13 +1,9 @@
---
description: 'Blockstack naming service (BNS)'
title: Subdomains
description: This section explains BNS subdomains and provides instructions for methods you can use to work with them.
---
# BNS Subdomains
This section explains BNS subdomains and provides instructions for methods
you can use to work with them. The following topics are included:
# Overview of subdomains
## Overview of subdomains
BNS names are strongly-owned because the owner of its private key can generate
valid transactions that update its zone file hash and owner. However, this comes at the
@ -236,8 +232,7 @@ subdomain registrars on behalf of their applications. For example,
the name `personal.id` is used to register Blockstack application users without
requiring them to spend any Bitcoin.
We supply a reference
implementation of a [BNS Subdomain Registrar](https://github.com/blockstack/subdomain-registrar)
We supply a reference implementation of a [BNS Subdomain Registrar](https://github.com/blockstack/subdomain-registrar)
to help developers broadcast subdomain operations. Users would still own their
subdomain names; the registrar simply gives developers a convenient way for them
to register and manage them in the context of a particular application.

5
src/pages/references/blockstack-cli.md

@ -5,7 +5,7 @@ title: Blockstack CLI
export { convertBlockstackCLIUsageToMdx as getStaticProps } from '@common/data/cli-ref'
import { CLIReferenceTable } from '@components/cli-reference'
# Blockstack CLI reference
## Introduction
The command line is intended for developers only. Developers can use the command
line to test and debug Blockstack applications in ways that the Blockstack
@ -17,8 +17,7 @@ Browser does not yet support. Using the command line, developers can:
- Query Stacks Nodes
- Implement a minimum viable authentication flow
!> Many of the commands operate on unencrypted private keys. For this reason,
DO NOT use this tool for day-to-day tasks as you risk the security of your keys.
!> Many of the commands operate on unencrypted private keys. For this reason, **DO NOT** use this tool for day-to-day tasks as you risk the security of your keys.
You must install the command line before you can use the commands.

4
src/pages/references/clarity-language.md

@ -6,10 +6,6 @@ description: See a detailed list of all keywords and functions for the Clarity l
export { convertClarityRefToMdx as getStaticProps } from '@common/data/clarity-ref'
import { ClarityKeywordReference, ClarityFunctionReference } from '@components/clarity-ref'
# Clarity Language Reference
This file contains the reference for the Clarity language.
## Clarity Type System
The Clarity language uses a strong static type system. Function arguments

9
src/pages/references/deploy-tips.md

@ -1,10 +1,13 @@
---
description: Blockstack dApp documentation
title: Deploy tips
description: Learn some common methods for deploying your application.
---
# Deployment
## Introduction
Blockstack applications are web applications that authenticate users with Blockstack Auth and store data with Gaia. Both of these technologies can be accessed on the client side. As such, Blockstack apps tend to be simple in design and operation, since in many cases, they don’t have to host anything besides the application’s assets.
Blockstack applications are web applications that authenticate users with Blockstack Auth and store data with Gaia.
Both of these technologies can be accessed on the client side. As such, Blockstack apps tend to be simple in design and
operation, since in many cases, they don’t have to host anything besides the application’s assets.
## Where to deploy your application

54
src/pages/references/faqs.md

@ -1,54 +0,0 @@
---
title: FAQs
description: This is a comprehensive list of all the Blockstack FAQs.
redirect_from: /org/voucherholder
---
export { convertFaqAnswersToMDX as getStaticProps } from '@common/data/faq'
import { FAQs } from '@components/faq'
# Blockstack FAQs
This is a comprehensive list of all the Blockstack FAQs.
## General questions
<FAQs category="general" data={props.mdx} />
## Application user questions
<FAQs category="appusers" data={props.mdx} />
## Stacks Token questions
<FAQs category="tokens" data={props.mdx} />
## Stacks Wallet questions
<FAQs category="wallet" data={props.mdx} />
## DApp developers questions
<FAQs category="appdevs" data={props.mdx} />
## Core developer questions
<FAQs category="coredevs" data={props.mdx} />
## Open source developer questions
<FAQs category="opensource" data={props.mdx} />
## Miscellaneous questions
<FAQs category="miscquest" data={props.mdx} />
## Important disclaimer
_The Securities and Exchange Commission (SEC) has qualified the offering statement that we have filed with the SEC under Regulation A for our offering of certain of our Stacks Tokens. The information in that offering statement is more complete than the information we are providing now, and could differ in important ways. You must read the documents filed with the SEC before investing. The offering is being made only by means of its offering statement. This document shall not constitute an offer to sell or the solicitation of an offer to buy, nor shall there be any sale of these securities in any state or jurisdiction in which such offer, solicitation or sale would be unlawful prior to registration or qualification under the securities laws of any such state or jurisdiction._
_An indication of interest involves no obligation or commitment of any kind. Any person interested in investing in any offering of Stacks Tokens should review our disclosures and the publicly filed offering statement and the f<a href='https://stackstoken.com/circular'>final offering circular</a> that is part of that offering statement. Blockstack is not registered, licensed or supervised as a broker dealer or investment adviser by the SEC, the Financial Industry Regulatory Authority (FINRA) or any other financial regulatory authority or licensed to provide any financial advice or services._
## Forward-looking statements
_This communication contains forward-looking statements that are based on our beliefs and assumptions and on information currently available to us. In some cases, you can identify forward-looking statements by the following words: “will,” “expect,” “would,” “intend,” “believe,” or other comparable terminology. Forward-looking statements in this document include, but are not limited to, statements about our plans for developing the platform and future utility for the Stacks Token, our Clarity smart contracting language, and potential mining operations. These statements involve risks, uncertainties, assumptions and other factors that may cause actual results or performance to be materially different. More information on the factors, risks and uncertainties that could cause or contribute to such differences is included in our filings with the SEC, including in the “Risk Factors” and “Management’s Discussion & Analysis” sections of our offering statement on Form 1-A. We cannot assure you that the forward-looking statements will prove to be accurate. These forward-looking statements speak only as of the date hereof. We disclaim any obligation to update these forward-looking statements._

3
src/pages/references/glossary.md

@ -1,10 +1,9 @@
---
title: Glossary
description: A comprehensive list of terms used within the ecosystem.
---
export { convertGlossaryToJson as getStaticProps } from '@common/data/glossary'
import { Glossary } from '@components/glossary'
# Glossary
<Glossary data={props.glossary} />

4
src/pages/references/stacks-blockchain.md

@ -3,7 +3,7 @@ title: Stacks Blockchain APIs
description: Interacting with the Stacks 2.0 Blockchain
---
# Stacks Blockchain APIs
## Introduction
With the launch of Stacks 2.0, a new version of the Blockstack blockchain was released. There are two ways of interacting with the blockchain, either using the Stacks Blockchain API or by making RPC calls to a Stacks Core directly.
@ -15,6 +15,6 @@ The Stacks 2.0 blockchain's Rust implementation exposes RPC endpoints (in JSON f
The Stacks Blockchain API was built to maintain pageable materialized views of the Stacks 2.0 Blockchain. It is a server that exposes a RESTful JSON API, hosted by PBC. It introduces aidditonal functionality (e.g. get all transactions), as well as proxies calls directly to Stacks Node. [You can find the OpenAPI specification and documentation here](https://blockstack.github.io/stacks-blockchain-sidecar/).
_Note: Using this API requires you to trust the server, but provides a faster onboarding experience. It also addresses performance issues for which querying a node itself would be too slow or difficult._
~> Note: Using this API requires you to trust the server, but provides a faster onboarding experience. It also addresses performance issues for which querying a node itself would be too slow or difficult
-> If you are looking for the Stacks 1.0 RPC endpoint references, please follow [this link](https://core.blockstack.org/).

2
src/pages/references/stacks-rpc-api.md

@ -3,7 +3,7 @@ title: Stacks Node RPC API
description: Every running Stacks node exposes an RPC API, which allows you to interact with the underlying blockchain.
---
# RPC API Reference
## Introduction
Every running Stacks node exposes an RPC API, which allows you to interact with the underlying blockchain.

8
src/pages/smart-contracts/cli-wallet-quickstart.md

@ -1,10 +1,12 @@
---
description: 'Blockstack CLI Wallet Quickstart'
title: CLI Wallet quickstart
description: Learn how to set up a wallet via the CLI and send/receive STX on the Testnet.
---
# Send/Receive Stacks on Testnet
## Introduction
This quickstart guide will show you how to setup a Stacks wallet using the Blockstack JavaScript CLI and use it to send/receive Stacks tokens on Testnet. This wallet is intended for developer experimentation with Testnet only, do not use this wallet to store your tokens.
This quickstart guide will show you how to setup a Stacks wallet using the Blockstack JavaScript CLI and use it to
send/receive Stacks tokens on Testnet. This wallet is intended for developer experimentation with Testnet only, do not use this wallet to store your tokens.
## Prerequisites

3
src/pages/smart-contracts/counter-tutorial.md

@ -1,4 +1,5 @@
---
title: Counter tutorial
description: Learn how to write a simple smart contract in the Clarity language.
experience: intermediate
duration: 30 minutes
@ -9,7 +10,7 @@ images:
sm: /images/pages/counter-tutorial-sm.svg
---
# Counter smart contract
## Introduction
In this tutorial, you learn how to implement a smart contract that stores and manipulates an integer value on the Stacks 2.0 blockchain. By the end of this tutorial, you will ...

13
src/pages/smart-contracts/hello-world-tutorial.md

@ -1,6 +1,6 @@
---
title: Hello, World!
description: Get Started Writing Smart Contracts with Clarity
description: Learn the basics of Clarity and write a simple Hello World smart contract.
duration: 18 minutes
experience: beginners
images:
@ -8,9 +8,7 @@ images:
sm: /images/pages/hello-world-sm.svg
---
# Hello, World!
## Overview
## Introduction
In the world of smart contracts, everything is a blockchain transaction. You use tokens in your wallet to deploy a smart contract in a transaction, and each call to that contract after it's published is a transaction, too. That means that at each step, tokens are being exchanged as transaction fees. This tutorial introduces you to this mode of programming, which transforms blockchains into powerful state machines capable of executing complex logic.
@ -149,8 +147,6 @@ Locate the `(echo-number)` method, provide any integer for the `val` argument an
**Congratulations! You just deployed your smart contract and called a public function on the Testnet.**
---
With the completion of this tutorial, you now:
- Have a working Clarity starter project and local dev environment
@ -207,8 +203,3 @@ blockstack call_contract_func <stx_address> hello-world echo-number 2000 1 <stx_
```
To learn more about the Blockstack CLI commands, you can run `blockstack-cli help all`.
## Where to go next
- <a href="tutorial-counter.html">Next tutorial: Writing a counter smart contract</a>
- <a href="tutorial-test.html">Tutorial: Testing contracts with JavaScript and Mocha</a>

3
src/pages/smart-contracts/install-source.md

@ -1,8 +1,9 @@
---
title: Install Clarity from source
description: 'Blockstack smart contracting language'
---
# Install Clarity from Source
## Installation
Build using `rust` and `cargo`:

38
src/pages/smart-contracts/overview.md

@ -6,21 +6,28 @@ images:
sm: /images/pages/smart-contracts-sm.svg
---
# Write smart contracts
## Introduction
Clarity is a programming language for writing smart contracts on the Stacks 2.0 blockchain. It supports programmatic control over digital assets.
Clarity is a programming language for writing smart contracts on the Stacks 2.0 blockchain. It supports programmatic
control over digital assets.
## Smart contracts
Smart contracts encode and enforce rules for modifying a particular set of data that is shared among people and entities who don't necessarily trust each other. For example, a smart contract can hold funds in escrow until multiple parties agree to release them, create its own ledger and keep track of its own novel tokens (fungible or non-fungible), and even help make supply chains more transparent.
Smart contracts encode and enforce rules for modifying a particular set of data that is shared among people and entities
who don't necessarily trust each other. For example, a smart contract can hold funds in escrow until multiple parties
agree to release them, create its own ledger and keep track of its own novel tokens (fungible or non-fungible), and
even help make supply chains more transparent.
Because smart contracts are programs that exist in a blockchain, anyone can query them, and anyone can submit transactions to execute them. A smart contract execution can result in new transactions being written to the blockchain.
Because smart contracts are programs that exist in a blockchain, anyone can query them, and anyone can submit transactions
to execute them. A smart contract execution can result in new transactions being written to the blockchain.
Apps can take advantage of smart contracts to manage a global state that is visible to the public. Anyone can audit the blockchain in order to independently verify that an app's global shared state has been managed correctly according to the smart contract's rules.
Apps can take advantage of smart contracts to manage a global state that is visible to the public. Anyone can audit the
blockchain in order to independently verify that an app's global shared state has been managed correctly according to the smart contract's rules.
## Use cases
Not every decentralized application requires smart contracts, but Clarity unlocks interesting capabilities for decentralized applications. Examples of use cases include, but are not limited to:
Not every decentralized application requires smart contracts, but Clarity unlocks interesting capabilities for
decentralized applications. Examples of use cases include, but are not limited to:
- Access control (e.g. pay to access)
- Non-fungible (e.g. collectibles) and fungible tokens (e.g. stablecoins)
@ -35,20 +42,29 @@ Clarity differs from most other smart contract languages in two essential ways:
- The language is interpreted and broadcast on the blockchain as is (not compiled)
- The language is decidable (not Turing complete)
Using an interpreted language ensures that the executed code is human-readable and auditable. A decidable language like Clarity makes it possible to determine precisely which code is going to be executed, for any function.
Using an interpreted language ensures that the executed code is human-readable and auditable. A decidable language
like Clarity makes it possible to determine precisely which code is going to be executed, for any function.
A Clarity smart contract is composed of two parts &mdash; a data space and a set of functions. Only the associated smart contract may modify its corresponding data space on the blockchain. Functions may be private and thus callable only from within the smart contract, or public and thus callable from other contracts. Users call smart contracts' public functions by broadcasting a transaction on the blockchain which invokes the public function. Contracts can also call public functions from other smart contracts.
A Clarity smart contract is composed of two parts &mdash; a data space and a set of functions. Only the associated
smart contract may modify its corresponding data space on the blockchain. Functions may be private and thus callable
only from within the smart contract, or public and thus callable from other contracts. Users call smart contracts'
public functions by broadcasting a transaction on the blockchain which invokes the public function. Contracts
can also call public functions from other smart contracts.
Note some of the key Clarity language rules and limitations.
- The only primitive types are booleans, integers, buffers, and principals
- Recursion is illegal and there are no anonymous functions.
- Looping may only be performed via `map`, `filter`, or `fold`
- There is support for lists, however, the only variable length lists in the language appear as function inputs; There is no support for list operations like append or join.
- There is support for lists, however, the only variable length lists in the language appear as function inputs;
There is no support for list operations like append or join.
- Variables are immutable.
## Learning Clarity
The tutorials are ordered from "beginner" to "advanced." Start with the [Hello World tutorial](tutorial), then learn how to construct [a counter](tutorial-counter), and finally, learn how to [test your smart contracts](tutorial-test) using Mocha.
The tutorials are ordered from "beginner" to "advanced." Start with the [Hello World tutorial](/smart-contracts/hello-world-tutorial),
then learn how to construct [a counter](/smart-contracts/counter-tutorial), and finally, learn how to
[test your smart contracts](/smart-contracts/testing-contracts) using Mocha.
Once you've got the hang of the general workflow, environment, and language syntax, you should be ready to start writing contracts, referring to the [Clarity language reference](clarityRef) as you go.
Once you've got the hang of the general workflow, environment, and language syntax, you should be ready to start writing
contracts, referring to the [Clarity language reference](/references/clarity-language) as you go.

3
src/pages/smart-contracts/principals.md

@ -1,8 +1,9 @@
---
title: Principals
description: 'Clarity: Understanding Principals'
---
# Understanding Principals
## Introduction
_Principals_ are a Clarity native type that represents an entity that can have a token balance. This section discusses principals and how they are used in the Clarity.

6
src/pages/smart-contracts/running-a-testnet-node.md

@ -1,3 +1,9 @@
---
title: Testnet
description: Run the latest builds of a Stacks Testnet node
icon: TestnetIcon
---
# Running a Testnet Node
The Stacks 2.0 testnet is currently in development. As part of the testnet, you can run a node and connect it to a public network. This guide will walk you through downloading and running your own node in the testnet network.

5
src/pages/smart-contracts/signing-transactions.md

@ -1,8 +1,11 @@
---
title: Signing transactions
description: Learn how to sign transactions using Blockstack Connect.
experience: advanced
duration: 30 minutes
---
# Signing transactions
## Introduction
With Connect, you can interact with the Stacks 2.0 blockchain. You can allow your users to send transactions
and interact with smart contracts.

6
src/pages/smart-contracts/testing-contracts.md

@ -1,13 +1,11 @@
---
title: Testing Clarity code
description: Learn to Test Clarity Contract Code with JavaScript and Mocha
description: Learn to Test Clarity Contract Code with JavaScript and Mocha.
experience: advanced
duration: 15 minutes
---
# Testing Clarity code
## Overview
## Introduction
Clarity, Blockstack's smart contracting language, is based on [LISP](<https://en.wikipedia.org/wiki/Lisp_(programming_language)>). Clarity is an interpreted language, and [decidable](https://en.wikipedia.org/wiki/Recursive_language). In this tutorial, you will learn how to test Clarity and how use [Mocha](https://mochajs.org/) to test Clarity contracts while you develop them.

2
src/pages/stacks-blockchain/atlas/how-atlas-works.md

@ -3,7 +3,7 @@ title: How Atlas works
description: Atlas was designed to overcome the structural weaknesses inherent to all distributed hash tables.
---
# How Atlas Works
## Introduction
Atlas was designed to overcome the structural weaknesses inherent to all
distributed hash tables. In particular, it uses an unstructured peer network to

2
src/pages/stacks-blockchain/atlas/overview.md

@ -3,7 +3,7 @@ title: Overview of the Atlas network
description: This document describes the Atlas network, a peer-to-peer content-addressed storage system whose chunks' hashes are announced on a public blockchain.
---
# Overview of the Atlas network
## Introduction
This document describes the Atlas network, a peer-to-peer content-addressed
storage system whose chunks' hashes are announced on a public blockchain. Atlas

2
src/pages/stacks-blockchain/atlas/usage.md

@ -3,8 +3,6 @@ title: How to use the Atlas network
description: This section teaches you how to use the Atlas network.
---
# How to Use the Atlas Network
## The API
While the Blockstack software stack expects that Atlas-hosted data is made up of

3
src/pages/stacks-blockchain/best-practices.md

@ -1,9 +1,8 @@
---
title: Best practices
descriptions: Helpful tips for getting a core node up and running.
---
# Best practices
## Hardware and OS requirements
- A 64-bit CPU running at at least 1 GHz is _highly_ recommended (but not strictly required)

12
src/pages/stacks-blockchain/install-api.md

@ -1,6 +1,12 @@
# Blockstack API
---
title: Blockstack API
description: Step-by-step instructions for deploying a Blockstack API node on Debian or Ubuntu are below.
duration: 30 minutes
tags:
- tutorial
---
Step-by-step instructions for deploying a Blockstack API node on Debian or Ubuntu are below.
## Introduction
- **Step 1:** Make sure you have a Stacks Node running locally (see [instructions](https://github.com/blockstack/blockstack-core/blob/master/README.md#quick-start)).
@ -82,5 +88,5 @@ sudo systemctl restart blockstack_api
sudo systemctl restart nginx
```
If you run into any issues, please [submit a Github issue](https://github.com/blockstack/blockstack-core/issues) and we'll update these
If you run into any issues, please [submit a Github issue](https://github.com/blockstack/stacks-blockchain/issues) and we'll update these
instructions.

5
src/pages/stacks-blockchain/installing-memcached.md

@ -1,4 +1,7 @@
# Installing Memcached
---
title: Installing Memcached
description: Learn how to install Memcached to improve performance of a local Blockstack API instance.
---
The Blockstack API optionally uses memcached and pylibmc for scaling read-only
calls. If you want to enable this functionality then you should have memcached

2
src/pages/stacks-blockchain/overview.md

@ -2,4 +2,4 @@
title: Overview
---
# Overview
## Introduction

7
src/pages/stacks-blockchain/wire-format.md

@ -1,4 +1,9 @@
# Bitcoin wire format
---
title: Bitcoin wire format
description: Learn about the format of transactions used for name operations in the Blockstack network.
---
## Introduction
This page is for organizations who want to be able to create and send name operation transactions to the blockchain(s) Blockstack supports.
It describes the transaction formats for the Bitcoin blockchain.

5
src/pages/stacks-wallet/install.md

@ -1,8 +1,9 @@
---
description: 'How to use the Blockstack Software'
title: Install the Stacks wallet
description: Learn how to install the Stacks wallet
---
# Install the Stacks Wallet software
## Introduction
You use the Stacks Wallet software client alone or with a hardware wallet to send and receive
Stacks (STX) tokens. On this page, you learn how to install the Stacks Wallet software.

5
src/pages/stacks-wallet/overview.md

@ -1,8 +1,9 @@
---
description: 'How to use the Blockstack Software'
title: Stacks wallet overview
description: Learn about cryptocurrency wallets, STX, and the Stacks wallet.
---
# Understand cryptocurrency wallets
## Introduction
If you are, or plan to be a Stacks token holder, you need to think about how you
can manage your Stacks (STX) tokens. How can you review your token balance? How can send or

7
src/pages/stacks-wallet/security.md

@ -1,8 +1,9 @@
---
description: 'Blockstack Network documentation'
title: Wallet security
description: Best practices for keeping your wallet(s) secure.
---
# Wallet and identity security
## Introduction
It is important that you understand how to keep good security for your Stacks Wallet software and your Blockstack identity.
@ -12,7 +13,7 @@ Both your wallet seed phrase and your Secret Recovery Code are cryptographic key
Stacks Wallet software. A **Secret Recovery Code** gives you access to your Blockstack identity. You need to use the
strictest security available to you for both of these keys.
The CrtypoCurrency Security Standard publishes [guidelines for key storage](https://cryptoconsortium.github.io/CCSS/Details/#1.03).
The Cryptocurrency Security Standard publishes [guidelines for key storage](https://cryptoconsortium.github.io/CCSS/Details/#1.03).
These guidelines are presented from least (Level I) to most secure (Level III). We recommend you store your keys with at least
Level II security. This level states that you should:

65
src/pages/stacks-wallet/troubleshooting.md

@ -1,65 +0,0 @@
---
description: 'How to use the Blockstack Software'
---
export { convertFaqAnswersToMDX as getStaticProps } from '@common/data/faq'
import { FAQs } from '@components/faq'
<!-- TODO: very out of date, update content -->
# Wallet FAQs and Troubleshooting
This page contains frequently asked questions and troubleshooting related to the wallet.
## Frequently asked questions
<FAQs category="wallet" data={props.mdx} />
## Change from a software-only wallet to a hardware wallet
To change from a software-only wallet to a hardware wallet, do the following:
1. Purchase and set up your hardware wallet according to the manufacturer's instructions.
2. **Reset** the Blockstack Software wallet <a href="wallet-use.html#reset-the-wallet" target="_blank">according to the instructions</a>.
3. Choose the <a href="wallet-use.html#use-with-a-hardware-wallet" target="_blank">hardware wallet option</a> to setup the Blockstack Software wallet.
4. Use the <a href="wallet-use.html#receive-stacks" target="_blank">**Receive** button to display the Stacks address</a>.
5. Login into your Coinlist account.
6. Change your Stacks wallet address.
## View or change your Stacks wallet address on Coinlist
If you purchased Stacks via Coinlist during in the token sale, your Stacks address is located at this URL:
```
https://sale.stackstoken.com/stacks-token-sale/YOUR_COINLIST_USERNAME/wallet_address
```
For example, if your Coinlist user name is `Eleven`, the URL you would use is:
```
https://sale.stackstoken.com/stacks-token-sale/Eleven/wallet_address
```
To view or change your Stacks address on Coinlist, do the following:
1. Log into your Coinlist account.
2. Enter a URL in this format:
```
https://sale.stackstoken.com/stacks-token-sale/YOUR_COINLIST_USERNAME/wallet_address
```
3. Change your address if necessary.
## I tried to login to CoinList with my AngelList account. Now, I can’t sign in. How do I access my account?
If you previously set up your CoinList account by logging in with your AngelList credentials and you are having issues signing into your account, you must create a separate password for Coinlist. To do this:
1. Go to <a href="https://stackstoken.net/login" target="_blank">stackstoken.net</a>.
2. Select **Forgot your Password?**.
3. Enter the email associated with your AngelList account.
4. Select **Send recovery email**.
5. Locate the recovery email in your email software.
6. Use the instructions in the recovery email to create a unique password for your CoinList account.
Going forward, you can access your CoinList account by logging in with your email and new password.

12
src/pages/stacks-wallet/usage.md

@ -1,10 +1,11 @@
---
description: 'Blockstack Network documentation'
title: Using the Stacks wallet
description: Learn how to use the Stacks wallet
---
# Use the Stacks Wallet software
## Introduction
This page describes how to use the Stacks Wallet software to manager your Stacks (STX) tokens. This page contains the following topics:
This page describes how to use the Stacks Wallet software to manager your Stacks (STX) tokens.
The Stacks Wallet software is installed on your computer, it is not a web application. You should have already [downloaded, verified, and installed the wallet software](wallet-install).
@ -270,8 +271,7 @@ They are maintained.
Once you reset the wallet, you have to start over from the _Terms of Use_. If
you do not restart the wallet, you can simple close it.
1. Click the <span class="uk-margin-small-center" uk-icon="cog"></span>
(settings icon) in the upper right corner of the wallet.
1. Click the settings icon in the upper right corner of the wallet.
The system opens the **Settings** dialog.
@ -280,7 +280,7 @@ you do not restart the wallet, you can simple close it.
2. Select **Reset Wallet**.
System asks for confirmation. If, for some reason, you want to stop the reset
you would press <span class="uk-margin-small-center" uk-icon="close"></span> (right corner) or **Close**.
you would press close icon in the right corner or **Close**.
3. Select **Are you sure?** to complete the reset.

17
src/pages/storage-hubs/amazon-s3-deploy.md

@ -1,20 +1,19 @@
---
description: 'Storing user data with Blockstack'
title: Configure a hub on Amazon EC2
description: Learn how to run a Gaia hub on Amazon EC2.
---
# Configure a hub on Amazon EC2
## Introduction
This teaches you how to run a Gaia hub on Amazon EC2. Amazon EC2 is an affordable and convenient cloud computing provider.
This example uses Amazon EC2 instance together with an [EBS](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AmazonEBS.html)
disk for file storage.
> #### Is this tutorial for you?
>
> This documentation is appropriate for advanced power users who are familiar with command line tools, `ssh`, and
> basic editing configuration files.
>
> If you are planning on running an _open-membership hub_ or an _application-specific hub_, see
> [the section on Hub Operation](hub-operation).
#### Is this tutorial for you?
-> This documentation is appropriate for advanced power users who are familiar with command line tools, `ssh`, and basic editing configuration files.
-> If you are planning on running an _open-membership hub_ or an _application-specific hub_, see [the section on Hub Operation](hub-operation).
## Prerequisites you need

3
src/pages/storage-hubs/config-schema.md

@ -1,8 +1,9 @@
---
title: Hub configuration
description: 'Storing user data with Blockstack'
---
# Hub configuration parameters
## Schema
The following JSON schema details the possible parameters for a hub configuration:

3
src/pages/storage-hubs/digital-ocean-deploy.md

@ -1,8 +1,9 @@
---
title: Configure a hub on DigitalOcean
description: 'Storing user data with Blockstack'
---
# Configure a hub on DigitalOcean
## Introduction
This teaches you how to run a Gaia storage hub on DigitalOcean (DO). DigitalOcean is an affordable and convenient cloud computing provider. This example uses DigitalOcean Spaces for file storage. A space is equivalent to AWS's S3 file storage solution.

2
src/pages/storage-hubs/gaia-admin.md

@ -3,7 +3,7 @@ title: Gaia admin
description: 'Storing user data with Blockstack'
---
# Use the admin service
## Introduction
A Gaia service can run a simple administrative service co-located with your Gaia hub. This service allows you to administer the Gaia hub with the help of an API key. Gaia hubs installed using the Gaia Amazon Machine Image (AMI) have this service integrated automatically.

3
src/pages/storage-hubs/hello-hub-choice.md

@ -1,8 +1,9 @@
---
title: Hello world hub choice
description: 'Storing user data with Blockstack'
---
# Hello hub choice tutorial
## Introduction
-> The functionality described in this tutorial has been deprecated with the Blockstack Browser. It will continue working only for apps that have not yet upgraded to Blockstack Connect.

4
src/pages/storage-hubs/overview.md

@ -4,10 +4,6 @@ redirect_from:
- /storage/hello-hub-choice.html
---
# Understand hub operation
This page describes the considerations hub operators must take into account when creating and operating a Gaia storage hub.
## Configuration files
You should store a JSON configuration file either in the top-level directory of

322
yarn.lock

@ -9,11 +9,23 @@
dependencies:
"@algolia/cache-common" "4.3.1"
"@algolia/cache-browser-local-storage@4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.4.0.tgz#f58055bdf798d7b31b6d5f86e465cb0fc7dd6694"
integrity sha512-2AiKgN7DpFypkRCRkpqH7waXXyFdcnsPWzmN8sLHrB/FfXqgmsQb3pGft+9YHZIDQ0vAnfgMxSGgMhMGW+0Qnw==
dependencies:
"@algolia/cache-common" "4.4.0"
"@algolia/cache-common@4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@algolia/cache-common/-/cache-common-4.3.1.tgz#2470fd0a358ae5a66119851d77cdf12969b53591"
integrity sha512-BgZVQKfQ3rYSKHDbEuYeIHgQ7cIqbDVUe8gPib/YI6hB2FWdt3hQyDqKslulBt65MxZ5CLSrWg8mq/qL077Bog==
"@algolia/cache-common@4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@algolia/cache-common/-/cache-common-4.4.0.tgz#bfe84790230f5d2de495238b29e9397c5ed2b26e"
integrity sha512-PrIgoMnXaDWUfwOekahro543pgcJfgRu/nd/ZQS5ffem3+Ow725eZY6HDpPaQ1k3cvLii9JH6V2sNJConjqUKA==
"@algolia/cache-in-memory@4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@algolia/cache-in-memory/-/cache-in-memory-4.3.1.tgz#905a27ab5f1303b1e0fea719bc808784e9415169"
@ -21,6 +33,13 @@
dependencies:
"@algolia/cache-common" "4.3.1"
"@algolia/cache-in-memory@4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@algolia/cache-in-memory/-/cache-in-memory-4.4.0.tgz#54a089094c2afa5b9cacab4b60a5f1ba29013a7c"
integrity sha512-9+XlUB0baDU/Dp9URRHPp6Q37YmTO0QmgPWt9+n+wqZrRL0jR3Jezr4jCT7RemqGMxBiR+YpnqaUv0orpb0ptw==
dependencies:
"@algolia/cache-common" "4.4.0"
"@algolia/client-account@4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@algolia/client-account/-/client-account-4.3.1.tgz#e84f93e2c3375a9defc690e4c24b2e2d9a28824f"
@ -30,6 +49,15 @@
"@algolia/client-search" "4.3.1"
"@algolia/transporter" "4.3.1"
"@algolia/client-account@4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@algolia/client-account/-/client-account-4.4.0.tgz#7dbeff83e1c85d853b3ad224674a924e02b94d1b"
integrity sha512-Kynu3cMEs0clTLf674rtrCF+FWR/JwlQxKlIWsPzvLBRmNXdvYej9YBcNaOr4OTQFCCZn9JVE8ib91Z7J4IL1Q==
dependencies:
"@algolia/client-common" "4.4.0"
"@algolia/client-search" "4.4.0"
"@algolia/transporter" "4.4.0"
"@algolia/client-analytics@4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-4.3.1.tgz#391227f0e2cc1a7fefedbab06f4b2b78f59579a5"
@ -40,6 +68,16 @@
"@algolia/requester-common" "4.3.1"
"@algolia/transporter" "4.3.1"
"@algolia/client-analytics@4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-4.4.0.tgz#50dde68b067c615fc91434c98db9b5ca429be33d"
integrity sha512-GQyjQimKAc9sZbafxln9Wk7j4pEYiORv28MZkZ+0Bjt7WNXIeO7OgOOECVpQHm9buyV6hCKpNtJcbb5/syRzdQ==
dependencies:
"@algolia/client-common" "4.4.0"
"@algolia/client-search" "4.4.0"
"@algolia/requester-common" "4.4.0"
"@algolia/transporter" "4.4.0"
"@algolia/client-common@4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-4.3.1.tgz#053580c0c2ed982eb2f65c7d728238f3da67db4e"
@ -48,6 +86,14 @@
"@algolia/requester-common" "4.3.1"
"@algolia/transporter" "4.3.1"
"@algolia/client-common@4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-4.4.0.tgz#b9fa987bc7a148f9756da59ada51fe2494a4aa9a"
integrity sha512-a3yr6UhzjWPHDG/8iGp9UvrDOm1aeHVWJIf0Nj/cIvqX5tNCEIo4IMe59ovApkDgLOIpt/cLsyhn9/FiPXRhJA==
dependencies:
"@algolia/requester-common" "4.4.0"
"@algolia/transporter" "4.4.0"
"@algolia/client-recommendation@4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@algolia/client-recommendation/-/client-recommendation-4.3.1.tgz#e693b16cdf6ec7fa532f9ab39143c8dabed5cc76"
@ -57,6 +103,15 @@
"@algolia/requester-common" "4.3.1"
"@algolia/transporter" "4.3.1"
"@algolia/client-recommendation@4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@algolia/client-recommendation/-/client-recommendation-4.4.0.tgz#82410f7a346ed8518b8dcd28bc47571e850ab74f"
integrity sha512-sBszbQH46rko6w2fdEG77ma8+fAg0SDkLZGxWhv4trgcnYGUBFl2dcpEPt/6koto9b4XYlf+eh+qi6iGvYqRPg==
dependencies:
"@algolia/client-common" "4.4.0"
"@algolia/requester-common" "4.4.0"
"@algolia/transporter" "4.4.0"
"@algolia/client-search@4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.3.1.tgz#e0a3d9b757855901a185d3d918b27af28d520a5b"
@ -66,11 +121,25 @@
"@algolia/requester-common" "4.3.1"
"@algolia/transporter" "4.3.1"
"@algolia/client-search@4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.4.0.tgz#c1e107206f3ae719cd3a9877889eea5e5cbcdc62"
integrity sha512-jqWcxCUyPPHnHreoMb2PnN9iHTP+V/nL62R84XuTRDE3VgTnhm4ZnqyuRdzZQqaz+gNy5znav64TmQ9FN9WW5g==
dependencies:
"@algolia/client-common" "4.4.0"
"@algolia/requester-common" "4.4.0"
"@algolia/transporter" "4.4.0"
"@algolia/logger-common@4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@algolia/logger-common/-/logger-common-4.3.1.tgz#31d2ff5f81a3e2424cfb4b205e64cfd7b1acfba5"
integrity sha512-HOY89EkxFFR0LjeqE+fqaF3EeQUAYFdVdrAXsnrWhm/OsAlXiy+vsoHL4EaJLXvTQlJRBbgNyyQv8ZPAN9JLCw==
"@algolia/logger-common@4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@algolia/logger-common/-/logger-common-4.4.0.tgz#8115d95d5f6227f0127d33130a9c4622cde64f6f"
integrity sha512-2vjmSENLaKNuF+ytRDysfWxxgFG95WXCHwHbueThdPMCK3hskkwqJ0Y/pugKfzl+54mZxegb4BYfgcCeuaHVUw==
"@algolia/logger-console@4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@algolia/logger-console/-/logger-console-4.3.1.tgz#f61f2e0ed67ae92556d7e1b1cb4f08e270b2734b"
@ -78,6 +147,13 @@
dependencies:
"@algolia/logger-common" "4.3.1"
"@algolia/logger-console@4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@algolia/logger-console/-/logger-console-4.4.0.tgz#1e0eaaf0879f152f9a1fa333c4cd8cb55e071552"
integrity sha512-st/GUWyKvr6YM72OOfF+RmpdVGda3BPXbQ+chpntUq1WyVkyZXGjSmH1IcBVlua27GzxabwOUYON39cF3x10/g==
dependencies:
"@algolia/logger-common" "4.4.0"
"@algolia/requester-browser-xhr@4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.3.1.tgz#c664be05dbdddbd63cb66c4e32b598b563ab83d1"
@ -85,11 +161,23 @@
dependencies:
"@algolia/requester-common" "4.3.1"
"@algolia/requester-browser-xhr@4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.4.0.tgz#f5877397ed92d2d64d08846ea969aeb559a5efb6"
integrity sha512-V3a4hXlNch355GnWaT1f5QfXhROpsjT6sd0Znq29gAhwLqfBExhLW6Khdkv5pENC0Qy7ClVhdXFrBL9QCQer1g==
dependencies:
"@algolia/requester-common" "4.4.0"
"@algolia/requester-common@4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.3.1.tgz#215084aa1ea025b1f2f73eb03b437de89c7c6c39"
integrity sha512-2lu0gOB2Rt4mn9gKDxjB8rY2IvU4usDA8bZVGl5tf/E81kRovtDZcgZjuKQ5zMyJ/xuIYXjx+ECXAxjUnNhieA==
"@algolia/requester-common@4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.4.0.tgz#0e977939aae32ff81a6d27480a71771a65db6051"
integrity sha512-jPinHlFJEFokxQ5b3JWyjQKKn+FMy0hH99PApzOgQAYOSiFRXiPEZp6LeIexDeLLu7Y3eRt/3nHvjPKa6PmRRw==
"@algolia/requester-node-http@4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-4.3.1.tgz#8ffaeef57c1410e32d59565fbd2db6705bffaa92"
@ -97,6 +185,13 @@
dependencies:
"@algolia/requester-common" "4.3.1"
"@algolia/requester-node-http@4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-4.4.0.tgz#6ffba93d54eeadf64cb1be67fae5c4e3f7c8f390"
integrity sha512-b7HC9C/GHxiV4+0GpCRTtjscvwarPr3dGm4CAhb6AkNjgjRcFUNr1NfsF75w3WVmzmt79/7QZihddztDdVMGjw==
dependencies:
"@algolia/requester-common" "4.4.0"
"@algolia/transporter@4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@algolia/transporter/-/transporter-4.3.1.tgz#8320b29cabf54a1486435bea51d1c562952337ce"
@ -106,6 +201,15 @@
"@algolia/logger-common" "4.3.1"
"@algolia/requester-common" "4.3.1"
"@algolia/transporter@4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@algolia/transporter/-/transporter-4.4.0.tgz#6ec79aac43bc515c8e4f6d6e27dc8d8cd7112f7e"
integrity sha512-Xxzq91DEEeKIzT3DU46n4LEyTGAKZNtSHc2H9wvIY5MYwhZwEribmXXZ6k8W1FvBvzggv3juu0SP+xwGoR7F0w==
dependencies:
"@algolia/cache-common" "4.4.0"
"@algolia/logger-common" "4.4.0"
"@algolia/requester-common" "4.4.0"
"@ampproject/toolbox-core@^2.5.4":
version "2.5.4"
resolved "https://registry.yarnpkg.com/@ampproject/toolbox-core/-/toolbox-core-2.5.4.tgz#8554c5398b6d65d240085a6b0abb94f9a3276dce"
@ -1375,19 +1479,48 @@
use-events "^1.4.1"
use-onclickoutside "^0.3.1"
"@docsearch/css@^1.0.0-alpha.26":
version "1.0.0-alpha.26"
resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-1.0.0-alpha.26.tgz#a2f9b61168d527600b0e3f31c0f04998002f3aa2"
integrity sha512-YAa7R6O2MMdRtxTaMB3TTfeelhpf01J1xtnGZEQa7LNA64QO8BErceQIMQq5/ZMXnGViK/eUjqSVyCu7uzYE5w==
"@blockstack/ui@file:.yalc/@blockstack/ui":
version "2.12.4"
dependencies:
"@popperjs/core" "^2.4.0"
"@reach/alert" "^0.10.2"
"@reach/auto-id" "^0.10.0"
"@reach/rect" "^0.10.2"
"@styled-system/css" "5.1.5"
"@styled-system/should-forward-prop" "^5.1.5"
"@styled-system/theme-get" "^5.1.2"
"@types/react-transition-group" "^4.2.4"
"@types/styled-components" "^5.1.0"
"@types/styled-system" "^5.1.6"
"@types/styled-system__css" "^5.0.8"
"@types/styled-system__should-forward-prop" "^5.1.1"
"@types/styled-system__theme-get" "^5.0.0"
color "3.1.2"
flushable "^1.0.0"
prettier "^2.0.5"
prism-react-renderer "^1.0.2"
prismjs "^1.20.0"
prop-types "^15.7.2"
react-spring "8.0.27"
react-transition-group "^4.4.1"
styled-system "5.1.5"
type-fest "^0.15.1"
use-events "^1.4.1"
use-onclickoutside "^0.3.1"
"@docsearch/css@^1.0.0-alpha.27":
version "1.0.0-alpha.27"
resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-1.0.0-alpha.27.tgz#7f50985869ebab10ffb901b94ed7545269a3393c"
integrity sha512-Kw6R/gAHMZW2tKZO2a0gd3I8Yf6bJgTk3Dp+L0ZFrvEHEh8v3yQKvoxVify3ML9YVyvCxxAPQQuF9u3JNUwvXw==
"@docsearch/react@^1.0.0-alpha.26":
version "1.0.0-alpha.26"
resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-1.0.0-alpha.26.tgz#98b736d7de951bfa55cf3d0eb3639f93c9dd1db2"
integrity sha512-2eKIcUXuWbGgz6/xF+p7kYyd1IVGcnB8r+oIkTD6Tqtq0VGzZmf9ZPCOX37G38pVIJXAAxmtAb7oPO311xGWNQ==
"@docsearch/react@^1.0.0-alpha.27":
version "1.0.0-alpha.27"
resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-1.0.0-alpha.27.tgz#eae61d648ddc3667c5dee82c4cd9d47bf35a3c85"
integrity sha512-jcgUHZsrNNRsaVsplqKhXWheh4VzRTCdhsPuVhJMRvfsFUqXEPo/7kVt5xIybtOj9u+/FVdeSO+APJEE2rakYA==
dependencies:
"@docsearch/css" "^1.0.0-alpha.26"
"@francoischalifour/autocomplete-core" "^1.0.0-alpha.26"
"@francoischalifour/autocomplete-preset-algolia" "^1.0.0-alpha.26"
"@docsearch/css" "^1.0.0-alpha.27"
"@francoischalifour/autocomplete-core" "^1.0.0-alpha.27"
"@francoischalifour/autocomplete-preset-algolia" "^1.0.0-alpha.27"
algoliasearch "^4.0.0"
"@emotion/is-prop-valid@^0.8.1", "@emotion/is-prop-valid@^0.8.8":
@ -1412,15 +1545,15 @@
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed"
integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==
"@francoischalifour/autocomplete-core@^1.0.0-alpha.26":
version "1.0.0-alpha.26"
resolved "https://registry.yarnpkg.com/@francoischalifour/autocomplete-core/-/autocomplete-core-1.0.0-alpha.26.tgz#fc9ec90a62f0665c7092d19a649c751fe3794de3"
integrity sha512-XUXAGVx0My9isShokR1QB/oPFQiaPYDCouoTZTN+DISQw5AK6kGZUCFFXJSRNHTxBq1/0e70DYEiQa8E+rT/Og==
"@francoischalifour/autocomplete-core@^1.0.0-alpha.27":
version "1.0.0-alpha.27"
resolved "https://registry.yarnpkg.com/@francoischalifour/autocomplete-core/-/autocomplete-core-1.0.0-alpha.27.tgz#bd85058bf0ef02e9f9a57c7973c705edc2a25c41"
integrity sha512-kpKbtrjMt9l1HIFFmmH0u88633/1oBD+mEjKg1EIRJ1zQCeOBxlQvIXZ3X6GEoud79QjLVoc8HD4HN1OMRt+OA==
"@francoischalifour/autocomplete-preset-algolia@^1.0.0-alpha.26":
version "1.0.0-alpha.26"
resolved "https://registry.yarnpkg.com/@francoischalifour/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.0.0-alpha.26.tgz#3e20315d43dfef6c676cab4267974de70c2f6ec2"
integrity sha512-RrayxZgvTzpwq+RqEIpVn2UOEFLwa+HADCr2I3UI05o/OGU7Wc6LltpQy54scR+FlAIk6qTJwp5Nw/ecJn6xXg==
"@francoischalifour/autocomplete-preset-algolia@^1.0.0-alpha.27":
version "1.0.0-alpha.27"
resolved "https://registry.yarnpkg.com/@francoischalifour/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.0.0-alpha.27.tgz#29de9939274887363f6e3f41078b2ee3e9c56493"
integrity sha512-Mp4lhlLd8vuLOCXtuw8UTUaJXGRrXYL7AN/ZmhaMwqyL9e9XSqLlcv82EWP0NAMcoz/I1E1C709h4jnbnN4llw==
"@hashicorp/remark-plugins@^3.0.0":
version "3.0.0"
@ -1435,41 +1568,16 @@
unist-util-map "^2.0.1"
unist-util-visit "^2.0.2"
"@mdx-js/loader@1.6.15":
version "1.6.15"
resolved "https://registry.yarnpkg.com/@mdx-js/loader/-/loader-1.6.15.tgz#11d5ed30c7c0d3e5a5dbfa946f5e097ad547db03"
integrity sha512-ssDjQByfiZdBKaP8Hyti1KzFW3t4DsFMcGRbU+0CQjVQ0xjcnymswFSAL+7Q8Yh2kK1HkeUHsHpFP+8l/fSoUQ==
"@mdx-js/loader@1.6.16":
version "1.6.16"
resolved "https://registry.yarnpkg.com/@mdx-js/loader/-/loader-1.6.16.tgz#5a9c3b0ab41885cd2df85bcf360644ca63e44e88"
integrity sha512-jYIAav17lXmEvweO6bzbsqY9mRTm49UeXXSZPAB81uCX8j91Pgi50Z0NnEN777yQEgGm2Z5PMtnJdxGFQIAjJQ==
dependencies:
"@mdx-js/mdx" "1.6.15"
"@mdx-js/react" "1.6.15"
"@mdx-js/mdx" "1.6.16"
"@mdx-js/react" "1.6.16"
loader-utils "2.0.0"
"@mdx-js/mdx@1.6.15":
version "1.6.15"
resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.6.15.tgz#96e3db4e442008501ba7c4457382c02ff938f13a"
integrity sha512-jDp29ATBPliN8FlMpB11287x+MbpM/xj8uT5E7i1+2SoMgDNc/B1EqNd5eZLFYT0lyDk9IyKkcE0w0A0o616RA==
dependencies:
"@babel/core" "7.10.5"
"@babel/plugin-syntax-jsx" "7.10.4"
"@babel/plugin-syntax-object-rest-spread" "7.8.3"
"@mdx-js/util" "1.6.15"
babel-plugin-apply-mdx-type-prop "1.6.15"
babel-plugin-extract-import-names "1.6.15"
camelcase-css "2.0.1"
detab "2.0.3"
hast-util-raw "6.0.0"
lodash.uniq "4.5.0"
mdast-util-to-hast "9.1.0"
remark-footnotes "1.0.0"
remark-mdx "1.6.15"
remark-parse "8.0.3"
remark-squeeze-paragraphs "4.0.0"
style-to-object "0.3.0"
unified "9.1.0"
unist-builder "2.0.3"
unist-util-visit "2.0.3"
"@mdx-js/mdx@^1.6.16", "@mdx-js/mdx@^1.6.8":
"@mdx-js/mdx@1.6.16", "@mdx-js/mdx@^1.6.16", "@mdx-js/mdx@^1.6.8":
version "1.6.16"
resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.6.16.tgz#f01af0140539c1ce043d246259d8becd2153b2bb"
integrity sha512-jnYyJ0aCafCIehn3GjYcibIapaLBgs3YkoenNQBPcPFyyuUty7B3B07OE+pMllhJ6YkWeP/R5Ax19x0nqTzgJw==
@ -1494,21 +1602,11 @@
unist-builder "2.0.3"
unist-util-visit "2.0.3"
"@mdx-js/react@1.6.15":
version "1.6.15"
resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-1.6.15.tgz#99a6061d0f74f2d01b95ad0314efba9ad6f19e81"
integrity sha512-C8yhsYZyFwL2kTa4Yw1zFIUxHcl225NrP75F6qgNbBum1APcsnl0WQ7N5V/l515gxnJmXSRQ6uL7pAFPZvdmzA==
"@mdx-js/react@^1.6.16", "@mdx-js/react@^1.6.8":
"@mdx-js/react@1.6.16", "@mdx-js/react@^1.6.16", "@mdx-js/react@^1.6.8":
version "1.6.16"
resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-1.6.16.tgz#538eb14473194d0b3c54020cb230e426174315cd"
integrity sha512-+FhuSVOPo7+4fZaRwWuCSRUcZkJOkZu0rfAbBKvoCg1LWb1Td8Vzi0DTLORdSvgWNbU6+EL40HIgwTOs00x2Jw==
"@mdx-js/util@1.6.15":
version "1.6.15"
resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.6.15.tgz#0e555fac778dfb1bd99ffedc00a22a26a26564f1"
integrity sha512-0JTd7as6t6sYiMfoOgGodNqD3hf/WlHPhZBNdZdyMWJDoqSq2uv12iNsBQP4jytvsREvEZyKjA944EAImxLz/w==
"@mdx-js/util@1.6.16":
version "1.6.16"
resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.6.16.tgz#07a7342f6b61ea1ecbfb31e6e23bf7a8c79b9b57"
@ -1526,10 +1624,10 @@
resolved "https://registry.yarnpkg.com/@next/mdx/-/mdx-9.5.1.tgz#c7e2fd457810b34e8ce598f57075b799ca48751b"
integrity sha512-jmNKqEMWkCPQWWeoq6CiOShngGv99Cs+rQSLlU7BZMVCZzbcTVEkAsUqR4WfLA97K2ihjtNidY5jwbKFu4h83Q==
"@next/react-dev-overlay@9.5.2-canary.7":
version "9.5.2-canary.7"
resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-9.5.2-canary.7.tgz#41f1f4a2513a897b548620f6e45df030602c495d"
integrity sha512-lDFIorQQE55Z62XvouJ7XcRw5EzU6LiZjoeilpnfpCXMyhPvxXR/XZ2P5WwM/6/+8o5DjvXlsEhyY2T2C9RJLQ==
"@next/react-dev-overlay@9.5.2-canary.9":
version "9.5.2-canary.9"
resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-9.5.2-canary.9.tgz#c14c4490b72236886990b380ab1f563527ed7760"
integrity sha512-CG3vcw9ASxmGNETs6svNhIII0PE9DkFyceB1gglKMcyJGa5bsqOaKXNRa3gDur8DrotOk5fbiecfXg3AM0VglQ==
dependencies:
"@babel/code-frame" "7.8.3"
ally.js "1.4.1"
@ -1542,10 +1640,10 @@
stacktrace-parser "0.1.10"
strip-ansi "6.0.0"
"@next/react-refresh-utils@9.5.2-canary.7":
version "9.5.2-canary.7"
resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-9.5.2-canary.7.tgz#db801584c088a1a961c771eb5fbbbf91b5764e32"
integrity sha512-6Lk9eEhwaK+KYCaaIqbCBTexw9J3BCJn4xJq589aW0IghWYXTFuJB/w3W4ZHxUFC4jJWvw6Y/eOpNvDQh05Xww==
"@next/react-refresh-utils@9.5.2-canary.9":
version "9.5.2-canary.9"
resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-9.5.2-canary.9.tgz#6b922e1998e3d04c1a643347ff35632c417a43cc"
integrity sha512-VfC6dlsXQk3Ub2Sm8mL305Zb2uRpu2flEil+WGt2aDuJwQInII+/jQ9Yvz/wwoEV/QnmqZ4xuBY2FTL2Bfpq9w==
"@popperjs/core@^2.4.0":
version "2.4.4"
@ -2243,7 +2341,7 @@ algoliasearch@^3.24.5:
semver "^5.1.0"
tunnel-agent "^0.6.0"
algoliasearch@^4.0.0, algoliasearch@^4.3.1:
algoliasearch@^4.0.0:
version "4.3.1"
resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.3.1.tgz#dea6ad87705e0439855cf3e5a4406b74e794b874"
integrity sha512-q8aIYgdZZWOMzmvlIwxcbktVa8+M5cyI8hIrgd/NcSz/XKHfVTKdNYbnsmPqmYrssAmepx8C8vHnJrPuumUnYA==
@ -2263,6 +2361,26 @@ algoliasearch@^4.0.0, algoliasearch@^4.3.1:
"@algolia/requester-node-http" "4.3.1"
"@algolia/transporter" "4.3.1"
algoliasearch@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.4.0.tgz#25c356d8bdcf7e3f941633f61e1ac111ddcba404"
integrity sha512-Ag3wxe/nSodNl/1KbHibtkh7TNLptKE300/wnGVtszRjXivaWD6333nUpCumrYObHym/fHMHyLcmQYezXbAIWQ==
dependencies:
"@algolia/cache-browser-local-storage" "4.4.0"
"@algolia/cache-common" "4.4.0"
"@algolia/cache-in-memory" "4.4.0"
"@algolia/client-account" "4.4.0"
"@algolia/client-analytics" "4.4.0"
"@algolia/client-common" "4.4.0"
"@algolia/client-recommendation" "4.4.0"
"@algolia/client-search" "4.4.0"
"@algolia/logger-common" "4.4.0"
"@algolia/logger-console" "4.4.0"
"@algolia/requester-browser-xhr" "4.4.0"
"@algolia/requester-common" "4.4.0"
"@algolia/requester-node-http" "4.4.0"
"@algolia/transporter" "4.4.0"
ally.js@1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/ally.js/-/ally.js-1.4.1.tgz#9fb7e6ba58efac4ee9131cb29aa9ee3b540bcf1e"
@ -2489,14 +2607,6 @@ aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2"
integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==
babel-plugin-apply-mdx-type-prop@1.6.15:
version "1.6.15"
resolved "https://registry.yarnpkg.com/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.15.tgz#d970e46033e47259d330c5cb64bbcde74098ac92"
integrity sha512-viGIiG66GOJoID7kJZRrAh15e7y/Calfi5vDgkF6soxT6OO57rWH+rqrC2Uo0e26Cs/uhyOo4M5UKRKutbEPgg==
dependencies:
"@babel/helper-plugin-utils" "7.10.4"
"@mdx-js/util" "1.6.15"
babel-plugin-apply-mdx-type-prop@1.6.16:
version "1.6.16"
resolved "https://registry.yarnpkg.com/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.16.tgz#4becd65b3aa108f15c524a0b125ca7c81f3443d8"
@ -2512,13 +2622,6 @@ babel-plugin-dynamic-import-node@^2.3.3:
dependencies:
object.assign "^4.1.0"
babel-plugin-extract-import-names@1.6.15:
version "1.6.15"
resolved "https://registry.yarnpkg.com/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.15.tgz#03f98dc11f40ad261dbd9ad89d5ca0ebc83aeea0"
integrity sha512-t7EdzuBXMKKwRZbxe0EiFNRZGo4vhnSDKGCllBEgYnUs/PqDfGCPweg6ztPDEFWRJRZ0TCfNhlthslfyUPTOjA==
dependencies:
"@babel/helper-plugin-utils" "7.10.4"
babel-plugin-extract-import-names@1.6.16:
version "1.6.16"
resolved "https://registry.yarnpkg.com/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.16.tgz#b964004e794bdd62534c525db67d9e890d5cc079"
@ -6357,10 +6460,10 @@ next-transpile-modules@^4.0.2:
micromatch "^4.0.2"
slash "^3.0.0"
next@^9.5.2-canary.7:
version "9.5.2-canary.7"
resolved "https://registry.yarnpkg.com/next/-/next-9.5.2-canary.7.tgz#4f753ba974e58c5f07a4d00eb484b3f4d38fc2cb"
integrity sha512-Alo6nQf5VMr3X9kZYXPLjQDlKUMapRuRqRpf9VqgFjE2mxXPGEpfSz6EHz4KuQpcCYflE2RxrHaWKeL8+DgaIw==
next@^9.5.2-canary.9:
version "9.5.2-canary.9"
resolved "https://registry.yarnpkg.com/next/-/next-9.5.2-canary.9.tgz#e8d3bdbcb8e72dbbb862b764b0e79632b3a09bdb"
integrity sha512-IcYGrJkmsdETJwwOSl+Hq8H1XktItBMxFqUNnfPh1QHroKMZ3MuPfpb+dhnmV1s9+PZWhq/FkJSuM4jx01xo6A==
dependencies:
"@ampproject/toolbox-optimizer" "2.5.14"
"@babel/code-frame" "7.8.3"
@ -6381,8 +6484,8 @@ next@^9.5.2-canary.7:
"@babel/preset-typescript" "7.9.0"
"@babel/runtime" "7.9.6"
"@babel/types" "7.9.6"
"@next/react-dev-overlay" "9.5.2-canary.7"
"@next/react-refresh-utils" "9.5.2-canary.7"
"@next/react-dev-overlay" "9.5.2-canary.9"
"@next/react-refresh-utils" "9.5.2-canary.9"
ast-types "0.13.2"
babel-plugin-syntax-jsx "6.18.0"
babel-plugin-transform-define "2.0.0"
@ -7323,16 +7426,21 @@ preact-render-to-string@^5.1.4:
dependencies:
pretty-format "^3.8.0"
preact-ssr-prepass@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/preact-ssr-prepass/-/preact-ssr-prepass-1.1.0.tgz#62390309cfac3f7c1d3fe3708b63b828ab2ee9f9"
integrity sha512-NZMBkRDZKmflEhA5YRMeaBgcvYmqorbWjpoSQ3s1bG/5FN5tgnMCw8slLHndUEeFOEHX2OquhxFotmF1tkgGHg==
preact-ssr-prepass@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/preact-ssr-prepass/-/preact-ssr-prepass-1.1.1.tgz#1031e50c3b80cbdd8e155e520d0e97b9bc425faa"
integrity sha512-AszER25gPq8GMcUP+PruRCRg6FEgeoVfR8tlquz7QCPbRLSqkmHkTNwRiwx0zeRl0wd0CtFN4D9r6zCPeVo8Hg==
preact@^10.4.4:
version "10.4.6"
resolved "https://registry.yarnpkg.com/preact/-/preact-10.4.6.tgz#86cc43396e4bdd755726a2b4b1f0529e78067cd3"
integrity sha512-80WJfXH53yyINig5Wza/8MD9n4lMg9G6aN00ws0ptsAaY/Fu/M7xW4zICf7OLfocVltxS30wvNQ8oIbUyZS1tw==
preact@^10.4.7:
version "10.4.7"
resolved "https://registry.yarnpkg.com/preact/-/preact-10.4.7.tgz#5a530d34b4ba45f38234be8b1b3fe910098a165f"
integrity sha512-DtnnPbOm7oxW7Sxf5Co+KSIOxo7bGm0vLfJN/wGey7G2sAGKnGP5+bFyE2YIgutMISQl6xFVTsOd6l/Au88VVw==
prelude-ls@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
@ -7821,20 +7929,6 @@ remark-images@2.0.0:
unist-util-is "^4.0.0"
unist-util-visit-parents "^3.0.0"
remark-mdx@1.6.15:
version "1.6.15"
resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-1.6.15.tgz#8762b8ebda06d8d775908aed342852fa641df414"
integrity sha512-YrEB0Qm8/rkL9rverXuHq5kGgobFQnSKwiQy9SH8S9AXu592O+UnoMaw+TRLiycBIbLUM3wf9dxtg/2sRjc68Q==
dependencies:
"@babel/core" "7.10.5"
"@babel/helper-plugin-utils" "7.10.4"
"@babel/plugin-proposal-object-rest-spread" "7.10.4"
"@babel/plugin-syntax-jsx" "7.10.4"
"@mdx-js/util" "1.6.15"
is-alphabetical "1.0.4"
remark-parse "8.0.3"
unified "9.1.0"
remark-mdx@1.6.16:
version "1.6.16"
resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-1.6.16.tgz#13ee40ad0614a1cc179aca3604d7f1b79e498a2f"
@ -8895,10 +8989,10 @@ svgo@^1.0.0:
unquote "~1.1.1"
util.promisify "~1.0.0"
swr@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/swr/-/swr-0.2.3.tgz#e0fb260d27f12fafa2388312083368f45127480d"
integrity sha512-JhuuD5ojqgjAQpZAhoPBd8Di0Mr1+ykByVKuRJdtKaxkUX/y8kMACWKkLgLQc8pcDOKEAnbIreNjU7HfqI9nHQ==
swr@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/swr/-/swr-0.3.0.tgz#69602953dd50ab07fe60c920fd63199256645675"
integrity sha512-3p0p5TWH0qiaKAph5wBkMwqe2WjNseITfjmdVoNzjqRZGn/gnpRi6whMDjhMVb/vp/yyDtKWPlyjid8QZH+UhA==
dependencies:
fast-deep-equal "2.0.1"

Loading…
Cancel
Save