|
2 | 2 |
|
3 | 3 | A collection of React hooks for implementing web3-onboard in to a React project
|
4 | 4 |
|
5 |
| -## Install |
| 5 | +## Quickstart with Injected Wallets and Ethers Provider |
6 | 6 |
|
7 |
| -`npm i @web3-onboard/react` |
| 7 | +### Install Modules |
8 | 8 |
|
9 |
| -## Example Usage |
| 9 | +**NPM** |
| 10 | +`npm i @web3-onboard/react @web3-onboard/injected-wallets ethers` |
| 11 | + |
| 12 | +**Yarn** |
| 13 | +`yarn add @web3-onboard/react @web3-onboard/injected-wallets ethers` |
| 14 | + |
| 15 | +### Add Code |
10 | 16 |
|
11 | 17 | ```javascript
|
12 | 18 | import React from 'react'
|
13 |
| -import { ethers } from 'ethers' |
14 |
| -import { |
15 |
| - init, |
16 |
| - useConnectWallet, |
17 |
| - useSetChain, |
18 |
| - useWallets |
19 |
| -} from '@web3-onboard/react' |
| 19 | +import { init, useConnectWallet } from '@web3-onboard/react' |
20 | 20 | import injectedModule from '@web3-onboard/injected-wallets'
|
21 |
| -import coinbaseModule from '@web3-onboard/coinbase' |
22 |
| -import trezorModule from '@web3-onboard/trezor' |
23 |
| -import ledgerModule from '@web3-onboard/ledger' |
24 |
| -import walletConnectModule from '@web3-onboard/walletconnect' |
25 |
| -import portisModule from '@web3-onboard/portis' |
26 |
| -import fortmaticModule from '@web3-onboard/fortmatic' |
27 |
| -import torusModule from '@web3-onboard/torus' |
28 |
| -import keepkeyModule from '@web3-onboard/keepkey' |
29 |
| -import dcentModule from '@web3-onboard/dcent' |
| 21 | +import { ethers } from 'ethers' |
30 | 22 |
|
31 | 23 | // Sign up to get your free API key at https://explorer.blocknative.com/?signup=true
|
32 | 24 | const dappId = '1730eff0-9d50-4382-a3fe-89f0d34a2070'
|
33 | 25 |
|
34 | 26 | const injected = injectedModule()
|
35 |
| -const coinbase = coinbaseModule() |
36 |
| -const walletConnect = walletConnectModule() |
37 | 27 |
|
38 |
| -const portis = portisModule({ |
39 |
| - apiKey: 'b2b7586f-2b1e-4c30-a7fb-c2d1533b153b' |
40 |
| -}) |
| 28 | +const infuraKey = '<INFURA_KEY>' |
| 29 | +const rpcUrl = `https://mainnet.infura.io/v3/${infuraKey}` |
41 | 30 |
|
42 |
| -const fortmatic = fortmaticModule({ |
43 |
| - apiKey: 'pk_test_886ADCAB855632AA' |
44 |
| -}) |
45 |
| - |
46 |
| -const torus = torusModule() |
47 |
| -const ledger = ledgerModule() |
48 |
| -const keepkey = keepkeyModule() |
49 |
| - |
50 |
| -const trezorOptions = { |
51 |
| - email: 'test@test.com', |
52 |
| - appUrl: 'https://www.blocknative.com' |
53 |
| -} |
54 |
| - |
55 |
| -const trezor = trezorModule(trezorOptions) |
56 |
| - |
57 |
| -const dcent = dcentModule() |
58 |
| - |
59 |
| -const magic = magicModule({ |
60 |
| - // Example api key, may need to be updated when max hits reached |
61 |
| - // Get one to test with for free from https://magic.link/ |
62 |
| - apiKey: 'pk_live_02207D744E81C2BA', |
63 |
| - userEmail: localStorage.getItem('magicUserEmail') |
64 |
| -}) |
65 |
| - |
66 |
| -const web3auth = web3authModule({ |
67 |
| - clientId: |
68 |
| - 'DJuUOKvmNnlzy6ruVgeWYWIMKLRyYtjYa9Y10VCeJzWZcygDlrYLyXsBQjpJ2hxlBO9dnl8t9GmAC2qOP5vnIGo' |
69 |
| -}) |
70 |
| - |
71 |
| -const web3Onboard = init({ |
72 |
| - wallets: [ |
73 |
| - injected, |
74 |
| - coinbase, |
75 |
| - ledger, |
76 |
| - trezor, |
77 |
| - walletConnect, |
78 |
| - keepkey, |
79 |
| - web3auth, |
80 |
| - magic, |
81 |
| - portis, |
82 |
| - torus, |
83 |
| - dcent |
84 |
| - ], |
| 31 | +// initialize Onboard |
| 32 | +init({ |
| 33 | + wallets: [injected], |
85 | 34 | chains: [
|
86 | 35 | {
|
87 | 36 | id: '0x1',
|
88 | 37 | token: 'ETH',
|
89 | 38 | label: 'Ethereum Mainnet',
|
90 |
| - rpcUrl: 'https://mainnet.infura.io/v3/ababf9851fd845d0a167825f97eeb12b' |
91 |
| - }, |
92 |
| - { |
93 |
| - id: '0x3', |
94 |
| - token: 'tROP', |
95 |
| - label: 'Ethereum Ropsten Testnet', |
96 |
| - rpcUrl: 'https://ropsten.infura.io/v3/ababf9851fd845d0a167825f97eeb12b' |
97 |
| - }, |
98 |
| - { |
99 |
| - id: '0x4', |
100 |
| - token: 'rETH', |
101 |
| - label: 'Ethereum Rinkeby Testnet', |
102 |
| - rpcUrl: 'https://rinkeby.infura.io/v3/ababf9851fd845d0a167825f97eeb12b' |
103 |
| - }, |
104 |
| - { |
105 |
| - id: '0x89', |
106 |
| - token: 'MATIC', |
107 |
| - label: 'Matic Mainnet', |
108 |
| - rpcUrl: 'https://matic-mainnet.chainstacklabs.com' |
109 |
| - } |
110 |
| - ], |
111 |
| - appMetadata: { |
112 |
| - name: 'Blocknative', |
113 |
| - icon: '<svg><svg/>', |
114 |
| - description: 'Demo app for Onboard V2', |
115 |
| - recommendedInjectedWallets: [ |
116 |
| - { name: 'MetaMask', url: 'https://metamask.io' }, |
117 |
| - { name: 'Coinbase', url: 'https://wallet.coinbase.com/' } |
118 |
| - ] |
119 |
| - }, |
120 |
| - apiKey: 'xxx387fb-bxx1-4xxc-a0x3-9d37e426xxxx' |
121 |
| - notify: { |
122 |
| - enabled: true, |
123 |
| - transactionHandler: transaction => { |
124 |
| - console.log({ transaction }) |
125 |
| - } |
126 |
| - }, |
127 |
| - accountCenter: { |
128 |
| - desktop: { |
129 |
| - position: 'topRight', |
130 |
| - enabled: true, |
131 |
| - minimal: true |
132 |
| - }, |
133 |
| - mobile: { |
134 |
| - position: 'topRight', |
135 |
| - enabled: true, |
136 |
| - minimal: true |
137 |
| - } |
138 |
| - }, |
139 |
| - apiKey: dappId, |
140 |
| - notify: { |
141 |
| - enabled: true, |
142 |
| - transactionHandler: transaction => { |
143 |
| - console.log({ transaction }) |
144 |
| - if (transaction.eventCode === 'txPool') { |
145 |
| - return { |
146 |
| - // autoDismiss set to `0` will persist the notification until the user excuses it |
147 |
| - autoDismiss: 0, |
148 |
| - // message: `Your transaction is pending, click <a href="https://rinkeby.etherscan.io/tx/${transaction.hash}">here</a> for more info.`, |
149 |
| - // or you could use onClick for when someone clicks on the notification itself |
150 |
| - onClick: () => |
151 |
| - window.open(`https://rinkeby.etherscan.io/tx/${transaction.hash}`) |
152 |
| - } |
153 |
| - } |
| 39 | + rpcUrl |
154 | 40 | }
|
155 |
| - } |
156 |
| - i18n: { |
157 |
| - en: { |
158 |
| - connect: { |
159 |
| - selectingWallet: { |
160 |
| - header: 'custom text header' |
161 |
| - } |
162 |
| - }, |
163 |
| - notify: { |
164 |
| - transaction: { |
165 |
| - txStuck: 'custom text for this notification event' |
166 |
| - } |
167 |
| - } |
168 |
| - }, |
169 |
| - es: { |
170 |
| - transaction: { |
171 |
| - txRequest: 'Su transacción está esperando que confirme' |
172 |
| - } |
173 |
| - } |
174 |
| - } |
| 41 | + ] |
175 | 42 | })
|
176 | 43 |
|
177 | 44 | function App() {
|
178 |
| - const [{ wallet, connecting }, connect, disconnect, updateBalances, setWalletModules] = |
179 |
| - useConnectWallet() |
180 |
| - const [{ chains, connectedChain, settingChain }, setChain] = useSetChain() |
181 |
| - const [notifications, customNotification, updateNotify] = useNotifications() |
182 |
| - const connectedWallets = useWallets() |
183 |
| - const updateAccountCenter = useAccountCenter() |
184 |
| - const updateLocale = useSetLocale() |
185 |
| - |
186 |
| - let provider |
187 |
| - |
188 |
| - useEffect(() => { |
189 |
| - if (!wallet?.provider) { |
190 |
| - provider = null |
191 |
| - } else { |
192 |
| - provider = new ethers.providers.Web3Provider(wallet.provider, 'any') |
193 |
| - } |
194 |
| - }, [wallet] |
| 45 | + const [{ wallet, connecting }, connect, disconnect] = useConnectWallet() |
| 46 | + |
| 47 | + // create an ethers provider |
| 48 | + let ethersProvider |
| 49 | + |
| 50 | + if (wallet) { |
| 51 | + ethersProvider = new ethers.providers.Web3Provider(wallet.provider, 'any') |
| 52 | + } |
195 | 53 |
|
196 | 54 | return (
|
197 | 55 | <div>
|
198 |
| - <button onClick={() => connect()}> |
199 |
| - {connecting ? 'connecting' : 'connect'} |
| 56 | + <button |
| 57 | + disabled={connecting} |
| 58 | + onClick={() => (wallet ? disconnect() : connect())} |
| 59 | + > |
| 60 | + {connecting ? 'connecting' : wallet ? 'disconnect' : 'connect'} |
200 | 61 | </button>
|
201 |
| - {wallet && ( |
202 |
| - <div> |
203 |
| - <label>Switch Chain</label> |
204 |
| - {settingChain ? ( |
205 |
| - <span>Switching chain...</span> |
206 |
| - ) : ( |
207 |
| - <select |
208 |
| - onChange={({ target: { value } }) => |
209 |
| - console.log('onChange called') || setChain({ chainId: value }) |
210 |
| - } |
211 |
| - value={connectedChain.id} |
212 |
| - > |
213 |
| - {chains.map(({ id, label }) => { |
214 |
| - return <option value={id}>{label}</option> |
215 |
| - })} |
216 |
| - </select> |
217 |
| - )} |
218 |
| - <button onClick={() => disconnect(wallet)}>Disconnect Wallet</button> |
219 |
| - </div> |
220 |
| - <button |
221 |
| - className="bn-demo-button" |
222 |
| - onClick={() => { |
223 |
| - // Default position of AccountCenter it top right |
224 |
| - updateAccountCenter({ |
225 |
| - position: 'bottomLeft', |
226 |
| - enabled: true, |
227 |
| - minimal: true |
228 |
| - }) |
229 |
| - }} |
230 |
| - > |
231 |
| - Account Center to Bottom Left |
232 |
| - </button> |
233 |
| - )} |
234 |
| - |
235 |
| - {connectedWallets.map(({ label, accounts }) => { |
236 |
| - return ( |
237 |
| - <div> |
238 |
| - <div>{label}</div> |
239 |
| - <div>Accounts: {JSON.stringify(accounts, null, 2)}</div> |
240 |
| - </div> |
241 |
| - ) |
242 |
| - })} |
243 | 62 | </div>
|
244 | 63 | )
|
245 | 64 | }
|
246 |
| - |
247 |
| -export default App |
248 | 65 | ```
|
249 | 66 |
|
250 | 67 | ## `init`
|
|
0 commit comments