Skip to content

Commit

Permalink
feat: add docstrings (#17)
Browse files Browse the repository at this point in the history
* feat: add docstrings

* feat: add examples

* chore: remove unused package

* fix: type error

* chore: docs prerender safe

* chore: protect ssr
  • Loading branch information
tmm authored Jan 2, 2022
1 parent 9557353 commit 571648b
Show file tree
Hide file tree
Showing 43 changed files with 994 additions and 175 deletions.
7 changes: 7 additions & 0 deletions .changeset/shaggy-radios-cover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'wagmi-private': patch
'wagmi': patch
'wagmi-testing': patch
---

standardize connector provider
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

🚀   Hooks for connecting wallets, signing messages, sending transactions, etc.

💼   Built-in wallet connectors: MetaMask, WalletConnect, Coinbase Wallet
💼   Built-in wallet connectors for MetaMask, WalletConnect, and Coinbase Wallet

🌀   Auto-refresh data on wallet and network changes

Expand Down
3 changes: 0 additions & 3 deletions docs/.babelrc

This file was deleted.

51 changes: 51 additions & 0 deletions docs/components/Account.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import * as React from 'react'
import { Avatar, Box, Button, Stack } from 'degen'
import { useAccount } from 'wagmi'

export const Account = () => {
const [{ data: accountData }, disconnect] = useAccount({
fetchEns: true,
})

if (!accountData) return null

const formattedAddress = `${accountData.address.slice(
0,
6,
)}${accountData.address.slice(38, 42)}`
return (
<Stack
align="center"
direction={{ xs: 'vertical', sm: 'horizontal' }}
justify="space-between"
>
<Stack align="center" direction={{ xs: 'vertical', sm: 'horizontal' }}>
<Avatar
src={accountData.ens?.avatar as any}
label="ENS Avatar"
placeholder={!accountData.ens?.avatar}
/>
<Stack space="0">
<Box fontSize="large" textAlign={{ xs: 'center', sm: 'left' }}>
{accountData.ens?.name
? `${accountData.ens?.name} (${formattedAddress})`
: formattedAddress}
</Box>
{accountData.connector?.name && (
<Box
fontSize="small"
color="textSecondary"
textAlign={{ xs: 'center', sm: 'left' }}
>
Connected to {accountData.connector.name}
</Box>
)}
</Stack>
</Stack>

<Button variant="secondary" onClick={disconnect}>
Disconnect
</Button>
</Stack>
)
}
23 changes: 23 additions & 0 deletions docs/components/ConnectWallet.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as React from 'react'
import { useAccount } from 'wagmi'

import { PreviewWrapper } from './PreviewWrapper'
import { Account } from './Account'
import { WalletSelector } from './WalletSelector'

export const ConnectWallet = () => {
const [{ data }] = useAccount()

if (data)
return (
<PreviewWrapper>
<Account />
</PreviewWrapper>
)

return (
<PreviewWrapper>
<WalletSelector />
</PreviewWrapper>
)
}
31 changes: 31 additions & 0 deletions docs/components/PreviewWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as React from 'react'
import { useTheme as useNextThemes } from 'next-themes'
import { Box, useTheme } from 'degen'

type Props = {
children: React.ReactNode
}

export const PreviewWrapper = ({ children }: Props) => {
const { theme } = useNextThemes()
const { setMode } = useTheme()

React.useEffect(() => {
if (!theme) return
setMode(theme as any)
}, [theme, setMode])

return (
<Box
borderColor="foregroundSecondary"
borderRadius="2xLarge"
borderWidth="0.5"
marginY="8"
overflow="hidden"
padding="6"
width="full"
>
{children}
</Box>
)
}
69 changes: 69 additions & 0 deletions docs/components/SignMessage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import * as React from 'react'
import { Box, Button, Text, Textarea } from 'degen'
import { verifyMessage } from 'ethers/lib/utils'
import { useAccount, useSignMessage } from 'wagmi'

import { PreviewWrapper } from './PreviewWrapper'
import { Account } from './Account'
import { WalletSelector } from './WalletSelector'

export const SignMessage = () => {
const previousMessage = React.useRef<string>()
const [{ data: accountData }] = useAccount()
const [message, setMessage] = React.useState('')
const [{ data, error, loading }, signMessage] = useSignMessage()

const recoveredAddress = React.useMemo(() => {
if (!data || !previousMessage.current) return undefined
return verifyMessage(previousMessage.current, data)
}, [data, previousMessage])

if (accountData)
return (
<PreviewWrapper>
<Account />
<Box
as="form"
display="flex"
flexDirection="column"
gap="4"
marginTop="8"
onSubmit={(event) => {
event.preventDefault()
previousMessage.current = message
signMessage({ message })
}}
>
<Textarea
label="Enter a message to sign"
placeholder="The quick brown fox…"
onChange={(event) => setMessage(event.target.value)}
/>
<Button
width="full"
center
disabled={loading || !message.length}
loading={loading}
>
{loading ? 'Check Wallet' : 'Sign Message'}
</Button>

{data && (
<Box>
<Box>Recovered Address: {recoveredAddress}</Box>
<Box style={{ wordBreak: 'break-all' }}>Signature: {data}</Box>
</Box>
)}
{error && (
<Text color="red">{error?.message ?? 'Error signing message'}</Text>
)}
</Box>
</PreviewWrapper>
)

return (
<PreviewWrapper>
<WalletSelector />
</PreviewWrapper>
)
}
40 changes: 40 additions & 0 deletions docs/components/WalletSelector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as React from 'react'
import { Button, Stack, Text } from 'degen'
import { useConnect } from 'wagmi'

import { useIsMounted } from '../hooks'

export const WalletSelector = () => {
const isMounted = useIsMounted()
const [
{
data: { connector, connectors },
error,
loading,
},
connect,
] = useConnect()

return (
<Stack space="4">
{connectors.map((x) => (
<Button
width="full"
variant="tertiary"
center
loading={loading && x.name === connector?.name}
disabled={isMounted ? !x.ready : false}
key={x.id}
onClick={() => connect(x)}
>
{isMounted ? x.name : x.id === 'injected' ? x.id : x.name}
{isMounted ? !x.ready && ' (unsupported)' : ''}
</Button>
))}

{error && (
<Text color="red">{error?.message ?? 'Failed to connect'}</Text>
)}
</Stack>
)
}
4 changes: 4 additions & 0 deletions docs/components/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export { Account } from './Account'
export { ConnectWallet } from './ConnectWallet'
export { PreviewWrapper } from './PreviewWrapper'
export { SignMessage } from './SignMessage'
1 change: 1 addition & 0 deletions docs/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { useIsMounted } from './useIsMounted'
9 changes: 9 additions & 0 deletions docs/hooks/useIsMounted.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as React from 'react'

export const useIsMounted = () => {
const [mounted, setMounted] = React.useState(false)

React.useEffect(() => setMounted(true), [])

return mounted
}
10 changes: 7 additions & 3 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,24 @@
},
"dependencies": {
"@reach/skip-nav": "^0.16.0",
"degen": "^0.0.49",
"ethers": "^5.5.1",
"next": "12.0.7",
"next-themes": "0.0.8",
"nextra": "v2.0.0-beta.5",
"nextra-theme-docs": "2.0.0-beta.5",
"react": "17.0.2",
"react-dom": "17.0.2"
"react-dom": "17.0.2",
"wagmi": "0.0.10"
},
"devDependencies": {
"@types/node": "17.0.5",
"@types/react": "17.0.38",
"autoprefixer": "^10.4.0",
"eslint": "8.5.0",
"eslint-config-next": "12.0.7",
"postcss": "^8.4.5",
"tailwindcss": "^3.0.7",
"postcss": "8.2.1",
"tailwindcss": "2.2.4",
"typescript": "4.5.4"
}
}
81 changes: 79 additions & 2 deletions docs/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,87 @@
import type { AppProps } from 'next/app'
import 'nextra-theme-docs/style.css'
import { ThemeProvider } from 'degen'
import { providers } from 'ethers'
import Head from 'next/head'
import {
InjectedConnector,
Provider,
WalletConnectConnector,
WalletLinkConnector,
chain,
defaultChains,
defaultL2Chains,
} from 'wagmi'

import 'nextra-theme-docs/style.css'
import '../styles/globals.css'

/* eslint-disable import/no-unresolved */
// https://github.com/import-js/eslint-plugin-import/issues/1868
import 'degen/styles'
/* eslint-enable import/no-unresolved */

const infuraId = process.env.NEXT_PUBLIC_INFURA_ID as string

const chains = [...defaultChains, ...defaultL2Chains]

type Config = { chainId?: number }
const connectors = ({ chainId }: Config) => {
const rpcUrl =
chains.find((x) => x.id === chainId)?.rpcUrls?.[0] ??
chain.mainnet.rpcUrls[0]
return [
new InjectedConnector({ chains }),
new WalletConnectConnector({
options: {
infuraId,
qrcode: true,
},
}),
new WalletLinkConnector({
options: {
appName: 'wagmi',
jsonRpcUrl: `${rpcUrl}/${infuraId}`,
},
}),
]
}
const provider = ({ chainId }: Config) =>
new providers.InfuraProvider(chainId, infuraId)
const webSocketProvider = ({ chainId }: Config) =>
new providers.InfuraWebSocketProvider(chainId, infuraId)

const App = ({ Component, pageProps }: AppProps) => {
return <Component {...pageProps} />
return (
<>
<Provider
autoConnect
connectorStorageKey="wagmi.wallet"
connectors={connectors}
provider={provider}
webSocketProvider={webSocketProvider}
>
<ThemeProvider
defaultMode={
typeof window !== 'undefined'
? (localStorage.getItem('theme') as any)
: undefined
}
>
<Component {...pageProps} />
</ThemeProvider>
</Provider>

<Head>
{/* Set theme directly to prevent flash */}
<script
dangerouslySetInnerHTML={{
__html: `!function(){try{var d=document.documentElement;var e=localStorage.getItem('theme');if(e){d.setAttribute('data-theme',e.trim())}else{d.setAttribute('data-theme','light');}}catch(t){}}();`,
}}
key="theme-script"
/>
</Head>
</>
)
}

export default App
2 changes: 1 addition & 1 deletion docs/pages/comparison.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ There are a few different options of React libraries for Ethereum that help mana
### Pros

- Hooks for connecting wallets, signing messages, sending transactions, etc.
- Built-in wallet connectors: MetaMask, WalletConnect, Coinbase Wallet
- Built-in wallet connectors for MetaMask, WalletConnect, and Coinbase Wallet
- Auto-refresh data on wallet and network changes
- TypeScript ready
- Zero-dependencies (besides ethers.js peer dependency)
Expand Down
3 changes: 1 addition & 2 deletions docs/pages/docs/hooks/useTransaction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ const App = () => {

### request (optional)

Message to sign with wallet.
Object to create request with. See [**TransactionRequest**](https://docs.ethers.io/v5/api/providers/types/#providers-TransactionRequest) for more info.
Object to use when creating transaction. See [**TransactionRequest**](https://docs.ethers.io/v5/api/providers/types/#providers-TransactionRequest) for more info.

```tsx highlight='5'
import { useTransaction } from 'wagmi'
Expand Down
Loading

0 comments on commit 571648b

Please sign in to comment.