Skip to content

Commit 1dc7fe1

Browse files
authored
Package React (#842)
* Start workspaces migration * Update yarn * Update yarn lock * Fix yaml * Remove tsc * Add yarn.lock * Test publish new versions * Fix build issues * Update lock file * Bust cache * Test CI * CI Fixes * Fix gnosis type error * Fix gnosis types * Update yarn.lock * Update yarn.lock * Modify dev deps * Fix Chain type * New core version * New versions * Make installation on M1 macs possible * Update install docs * Set CI to proper prod branch * Add missing dev dep * Move Injected specific types * Update licenses * Add root script and dep * Update packages * Fix gitignore file * Remove redundant gitignore files * Start on some react hooks * Fixes WalletLink import * Fixes core docs and new version * Modifies core export types * Fixes hooks, adds return types, adds CI
1 parent 9945944 commit 1dc7fe1

File tree

11 files changed

+342
-4
lines changed

11 files changed

+342
-4
lines changed

.circleci/config.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,12 @@ jobs:
178178
working_directory: ~/web3-onboard-monorepo/packages/walletlink
179179
steps:
180180
- node-build-steps
181+
build-react:
182+
docker:
183+
- image: cimg/node:16.13.1
184+
working_directory: ~/web3-onboard-monorepo/packages/react
185+
steps:
186+
- node-build-steps
181187

182188
workflows:
183189
version: 2
@@ -238,3 +244,7 @@ workflows:
238244
jobs:
239245
- build-walletlink:
240246
<<: *deploy_production_filters
247+
react:
248+
jobs:
249+
- build-react:
250+
<<: *deploy_production_filters

packages/core/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ type InitOptions {
3333
### Options
3434

3535
**`wallets`**
36-
An array of wallet modules that you would like to be presented to the user to select from when connecting a wallet. A wallet module is an abstraction that allows for easy interaction without needing to know the specifics of how that wallet works and are separate packages that can be included. A list of wallet module packages that can be installed can be found [here](packages/).
36+
An array of wallet modules that you would like to be presented to the user to select from when connecting a wallet. A wallet module is an abstraction that allows for easy interaction without needing to know the specifics of how that wallet works and are separate packages that can be included. A list of wallet module packages that can be installed can be found [here](../).
3737

3838
**`chains`**
3939
An array of Chains that your app supports:

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@web3-onboard/core",
3-
"version": "2.0.0-alpha.4",
3+
"version": "2.0.0-alpha.5",
44
"scripts": {
55
"build": "rollup -c",
66
"dev": "rollup -c -w",

packages/core/src/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ const API = {
2020
state
2121
}
2222

23+
export type {
24+
InitOptions,
25+
OnboardAPI,
26+
ConnectOptions,
27+
WalletState,
28+
ConnectedChain
29+
} from './types'
30+
2331
function init(options: InitOptions): OnboardAPI {
2432
if (typeof window === 'undefined') return API
2533

packages/react/README.md

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# @web3-onboard/react
2+
3+
A collection of React hooks for implementing web3-onboard in to a React project
4+
5+
## Install
6+
7+
`npm i @web3-onboard/react`
8+
9+
## Usage
10+
11+
```javascript
12+
import React from 'react'
13+
import {
14+
init,
15+
useConnectWallet,
16+
useSetChain,
17+
useWallets
18+
} from '@web3-onboard/react'
19+
import injectedModule from '@web3-onboard/injected-wallets'
20+
import trezorModule from '@web3-onboard/trezor'
21+
import ledgerModule from '@web3-onboard/ledger'
22+
import walletConnectModule from '@web3-onboard/walletconnect'
23+
import walletLinkModule from '@web3-onboard/walletlink'
24+
import portisModule from '@web3-onboard/portis'
25+
import fortmaticModule from '@web3-onboard/fortmatic'
26+
import torusModule from '@web3-onboard/torus'
27+
import keepkeyModule from '@web3-onboard/keepkey'
28+
29+
const injected = injectedModule()
30+
const walletLink = walletLinkModule()
31+
const walletConnect = walletConnectModule()
32+
33+
const portis = portisModule({
34+
apiKey: 'b2b7586f-2b1e-4c30-a7fb-c2d1533b153b'
35+
})
36+
37+
const fortmatic = fortmaticModule({
38+
apiKey: 'pk_test_886ADCAB855632AA'
39+
})
40+
41+
const torus = torusModule()
42+
const ledger = ledgerModule()
43+
const keepkey = keepkeyModule()
44+
45+
const trezorOptions = {
46+
email: 'test@test.com',
47+
appUrl: 'https://www.blocknative.com'
48+
}
49+
50+
const trezor = trezorModule(trezorOptions)
51+
52+
const web3Onboard = init({
53+
wallets: [
54+
ledger,
55+
trezor,
56+
walletConnect,
57+
keepkey,
58+
walletLink,
59+
injected,
60+
fortmatic,
61+
portis,
62+
torus
63+
],
64+
chains: [
65+
{
66+
id: '0x1',
67+
token: 'ETH',
68+
label: 'Ethereum Mainnet',
69+
rpcUrl: 'https://mainnet.infura.io/v3/ababf9851fd845d0a167825f97eeb12b'
70+
},
71+
{
72+
id: '0x3',
73+
token: 'tROP',
74+
label: 'Ethereum Ropsten Testnet',
75+
rpcUrl: 'https://ropsten.infura.io/v3/ababf9851fd845d0a167825f97eeb12b'
76+
},
77+
{
78+
id: '0x4',
79+
token: 'rETH',
80+
label: 'Ethereum Rinkeby Testnet',
81+
rpcUrl: 'https://rinkeby.infura.io/v3/ababf9851fd845d0a167825f97eeb12b'
82+
},
83+
{
84+
id: '0x89',
85+
token: 'MATIC',
86+
label: 'Matic Mainnet',
87+
rpcUrl: 'https://matic-mainnet.chainstacklabs.com'
88+
}
89+
],
90+
appMetadata: {
91+
name: 'Blocknative',
92+
icon: '<svg><svg/>',
93+
description: 'Demo app for Onboard V2',
94+
recommendedInjectedWallets: [
95+
{ name: 'MetaMask', url: 'https://metamask.io' },
96+
{ name: 'Coinbase', url: 'https://wallet.coinbase.com/' }
97+
]
98+
}
99+
})
100+
101+
function App() {
102+
const [{ wallet, connecting }, connect] = useConnectWallet()
103+
const [{ chains, connectedChain, settingChain }, setChain] = useSetChain()
104+
const connectedWallets = useWallets()
105+
106+
return (
107+
<div>
108+
<button onClick={() => connect()}>
109+
{connecting ? 'connecting' : 'connect'}
110+
</button>
111+
{wallet && (
112+
<div>
113+
<label>Switch Chain</label>
114+
{settingChain ? (
115+
<span>Switching chain...</span>
116+
) : (
117+
<select
118+
onChange={({ target: { value } }) =>
119+
console.log('onChange called') || setChain({ chainId: value })
120+
}
121+
value={connectedChain.id}
122+
>
123+
{chains.map(({ id, label }) => {
124+
return <option value={id}>{label}</option>
125+
})}
126+
</select>
127+
)}
128+
</div>
129+
)}
130+
131+
{connectedWallets.map(({ label, accounts }) => {
132+
return (
133+
<div>
134+
<div>{label}</div>
135+
<div>Accounts: {JSON.stringify(accounts, null, 2)}</div>
136+
</div>
137+
)
138+
})}
139+
</div>
140+
)
141+
}
142+
143+
export default App
144+
```

packages/react/package.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "@web3-onboard/react",
3+
"version": "2.0.0-alpha.1",
4+
"description": "Collection of React Hooks for web3-onboard",
5+
"module": "dist/index.js",
6+
"browser": "dist/index.js",
7+
"main": "dist/index.js",
8+
"type": "module",
9+
"typings": "dist/index.d.ts",
10+
"files": [
11+
"dist"
12+
],
13+
"scripts": {
14+
"build": "tsc",
15+
"dev": "tsc -w",
16+
"test": "ava"
17+
},
18+
"license": "MIT",
19+
"devDependencies": {
20+
"@types/react": "^17.0.39",
21+
"typescript": "^4.5.5"
22+
},
23+
"dependencies": {
24+
"@web3-onboard/common": "^2.0.0-alpha.4",
25+
"@web3-onboard/core": "^2.0.0-alpha.4"
26+
},
27+
"peerDependencies": {
28+
"react": "^17.0.2"
29+
}
30+
}

packages/react/src/index.ts

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import { useEffect, useState, useCallback, useMemo } from 'react'
2+
3+
import Web3Onboard from '@web3-onboard/core'
4+
import type {
5+
InitOptions,
6+
OnboardAPI,
7+
ConnectOptions,
8+
WalletState,
9+
ConnectedChain
10+
} from '@web3-onboard/core'
11+
12+
import { Chain } from '@web3-onboard/common'
13+
14+
export let web3Onboard: OnboardAPI | null = null
15+
16+
export const init = (options: InitOptions): OnboardAPI => {
17+
web3Onboard = Web3Onboard(options)
18+
return web3Onboard
19+
}
20+
21+
export const useConnectWallet = (): [
22+
{ wallet: WalletState | null; connecting: boolean },
23+
(options: ConnectOptions) => Promise<void>
24+
] => {
25+
if (!web3Onboard) throw new Error('Must initialize before using hooks.')
26+
27+
const [wallet, setConnectedWallet] = useState<WalletState | null>(null)
28+
const [connecting, setConnecting] = useState(false)
29+
30+
const connect = useCallback(async (options: ConnectOptions) => {
31+
setConnecting(true)
32+
33+
const [lastConnectedWallet] = await (
34+
web3Onboard as OnboardAPI
35+
).connectWallet(options)
36+
37+
setConnecting(false)
38+
39+
if (lastConnectedWallet) {
40+
setConnectedWallet(lastConnectedWallet)
41+
}
42+
}, [])
43+
44+
return [{ wallet, connecting }, connect]
45+
}
46+
47+
type SetChainOptions = {
48+
chainId: string
49+
chainNamespace?: string
50+
}
51+
52+
export const useSetChain = (
53+
walletLabel?: string
54+
): [
55+
{
56+
chains: Chain[]
57+
connectedChain: ConnectedChain | null
58+
settingChain: boolean
59+
},
60+
(options: SetChainOptions) => Promise<void>
61+
] => {
62+
if (!web3Onboard) throw new Error('Must initialize before using hooks.')
63+
64+
const { state, setChain } = web3Onboard as OnboardAPI
65+
const [settingChain, setInProgress] = useState<boolean>(false)
66+
67+
const [connectedChain, setConnectedChain] = useState<ConnectedChain | null>(
68+
null
69+
)
70+
71+
const chains = useMemo(() => state.get().chains, [])
72+
73+
useEffect(() => {
74+
const { unsubscribe } = state.select('wallets').subscribe(wallets => {
75+
const wallet =
76+
wallets.find(({ label }) => label === walletLabel) || wallets[0]
77+
78+
wallet && setConnectedChain(wallet.chains[0])
79+
})
80+
81+
return unsubscribe
82+
}, [])
83+
84+
const set = useCallback(async (options: SetChainOptions) => {
85+
setInProgress(true)
86+
87+
await setChain({ ...options, wallet: walletLabel })
88+
89+
setInProgress(false)
90+
}, [])
91+
92+
return [{ chains, connectedChain, settingChain }, set]
93+
}
94+
95+
export const useWallets = (): WalletState[] => {
96+
if (!web3Onboard) throw new Error('Must initialize before using hooks.')
97+
98+
const [wallets, setConnectedWallets] = useState<WalletState[]>([])
99+
100+
useEffect(() => {
101+
const wallets$ = (web3Onboard as OnboardAPI).state.select('wallets')
102+
const { unsubscribe } = wallets$.subscribe(setConnectedWallets)
103+
104+
return unsubscribe
105+
}, [])
106+
107+
return wallets
108+
}

packages/react/tsconfig.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"extends": "../../tsconfig.json",
3+
"include": ["src/**/*"],
4+
5+
"compilerOptions": {
6+
"outDir": "dist",
7+
"rootDir": "src",
8+
"declarationDir": "dist",
9+
"paths": {
10+
"*": ["./src/*", "./node_modules/*"]
11+
},
12+
"typeRoots": ["node_modules/@types"]
13+
}
14+
}

packages/walletlink/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@web3-onboard/walletlink",
3-
"version": "2.0.0-alpha.4",
3+
"version": "2.0.0-alpha.5",
44
"description": "WalletLink module for web3-onboard",
55
"module": "dist/index.js",
66
"browser": "dist/index.js",

packages/walletlink/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ function walletLink(options?: { darkMode?: boolean }): WalletInit {
1111
const [chain] = chains
1212
const { name, icon } = appMetadata || {}
1313

14-
const { default: WalletLink } = await import('walletlink')
14+
const { WalletLink } = await import('walletlink')
1515

1616
const base64 = window.btoa(icon || '')
1717
const appLogoUrl = `data:image/svg+xml;base64,${base64}`

0 commit comments

Comments
 (0)