Skip to content

Commit 42624cf

Browse files
Feature: Display Unavailable Injected Wallets (#1458)
* Working display all wallets * Variable name changes * Filter out undefined wallet modules * Add examples of how to use new config options * Refactor filter and map to be a combined reduce * Add documentation * Increment versions * Fix import * Make it a minor change rather than a bugfix Co-authored-by: Adam Carpenter <[email protected]> * Update core version in react and vue packages * Bump package versions * Increment package versions * Add documentation to new features to docs site Co-authored-by: Adam Carpenter <[email protected]>
1 parent 528a5d7 commit 42624cf

File tree

13 files changed

+450
-127
lines changed

13 files changed

+450
-127
lines changed

docs/src/routes/docs/[...4]wallets/injected.md

Lines changed: 141 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -162,44 +162,148 @@ const onboard = Onboard({
162162
})
163163
```
164164

165+
## Display Unavailable Wallets
166+
167+
You may want to display injected wallets that are not currently available to the user and you can use the `displayUnavailable` option to do that:
168+
169+
```javascript
170+
const injected = injectedModule({
171+
displayUnavailable: true
172+
})
173+
```
174+
175+
This will render every injected wallet as regardless of whether it has been detected in the window, happy days.
176+
Then the issue of the order of wallets displayed becomes apparent when you have 21 injected wallets at the top of the wallets list. To solve this, all injected wallets are sorted alphabetically by default and there is an additional `sort` parameter which receives the final list of wallets and then returns the list to be rendered. This allows for example setting MetaMask and Coinbase first and then just the rest alphabetically:
177+
178+
```javascript
179+
const injected = injectedModule({
180+
// display all wallets even if they are unavailable
181+
displayUnavailable: true,
182+
// do a manual sort of injected wallets so that MetaMask and Coinbase are ordered first
183+
sort: (wallets) => {
184+
const metaMask = wallets.find(({ label }) => label === ProviderLabel.MetaMask)
185+
const coinbase = wallets.find(({ label }) => label === ProviderLabel.Coinbase)
186+
187+
return (
188+
[
189+
metaMask,
190+
coinbase,
191+
...wallets.filter(
192+
({ label }) => label !== ProviderLabel.MetaMask && label !== ProviderLabel.Coinbase
193+
)
194+
]
195+
// remove undefined values
196+
.filter((wallet) => wallet)
197+
)
198+
}
199+
})
200+
```
201+
202+
You may want to display all wallets, but filter out specific wallets based on their availability. For example I may want to display all unavailable wallets except when Binance and Bitski wallet is unavailable, then don't show them, but if they are available, then do show them. To do this, the filters value has been extended to have a new value: `'unavailable'`, as in; remove this wallet if it is unavailable, even though `displayUnavailable` wallets is set:
203+
204+
```javascript
205+
const injected = injectedModule({
206+
// display all wallets even if they are unavailable
207+
displayUnavailable: true,
208+
// but only show Binance and Bitski wallet if they are available
209+
filter: {
210+
[ProviderLabel.Binance]: 'unavailable',
211+
[ProviderLabel.Bitski]: 'unavailable'
212+
},
213+
// do a manual sort of injected wallets so that MetaMask and Coinbase are ordered first
214+
sort: (wallets) => {
215+
const metaMask = wallets.find(({ label }) => label === ProviderLabel.MetaMask)
216+
const coinbase = wallets.find(({ label }) => label === ProviderLabel.Coinbase)
217+
218+
return (
219+
[
220+
metaMask,
221+
coinbase,
222+
...wallets.filter(
223+
({ label }) => label !== ProviderLabel.MetaMask && label !== ProviderLabel.Coinbase
224+
)
225+
]
226+
// remove undefined values
227+
.filter((wallet) => wallet)
228+
)
229+
}
230+
})
231+
```
232+
233+
If a wallet is selected, but is not available the default error message is: `Please install or enable ${walletName} to continue`. You may want to customise that message, so there is the `walletUnavailableMessage` parameter which is a function that takes the wallet object that is unavailable and returns a string which is the message to display:
234+
235+
```javascript
236+
const injected = injectedModule({
237+
custom: [
238+
// include custom (not natively supported) injected wallet modules here
239+
],
240+
// display all wallets even if they are unavailable
241+
displayUnavailable: true,
242+
// but only show Binance and Bitski wallet if they are available
243+
filter: {
244+
[ProviderLabel.Binance]: 'unavailable',
245+
[ProviderLabel.Bitski]: 'unavailable'
246+
},
247+
// do a manual sort of injected wallets so that MetaMask and Coinbase are ordered first
248+
sort: (wallets) => {
249+
const metaMask = wallets.find(({ label }) => label === ProviderLabel.MetaMask)
250+
const coinbase = wallets.find(({ label }) => label === ProviderLabel.Coinbase)
251+
252+
return (
253+
[
254+
metaMask,
255+
coinbase,
256+
...wallets.filter(
257+
({ label }) => label !== ProviderLabel.MetaMask && label !== ProviderLabel.Coinbase
258+
)
259+
]
260+
// remove undefined values
261+
.filter((wallet) => wallet)
262+
)
263+
},
264+
walletUnavailableMessage: (wallet) => `Oops ${wallet.label} is unavailable!`
265+
})
266+
```
267+
165268
### Injected Wallets Supported Natively
166269

167-
- Metamask - *Desktop & Mobile* (Mobile relies on Wallet Connect and is detected inside MetaMask app browser)
168-
- Binance - *Desktop*
169-
- Coinbase - *Desktop & Mobile*
170-
- Tally - *Desktop*
171-
- Exodus - *Desktop & Mobile*
172-
- Trust - *Mobile*
173-
- Opera - *Desktop & Mobile*
174-
- Status - *Mobile*
175-
- Alphawallet - *Mobile*
176-
- Atoken - *Mobile*
177-
- Bitpie - *Mobile*
178-
- Blockwallet - *Desktop*
179-
- Brave - *Desktop & Mobile*
180-
- D'Cent - *Mobile*
181-
- Frame - *Desktop*
182-
- Huobiwallet - *Mobile*
183-
- Hyperpay - *Mobile*
184-
- IMtoken - *Mobile*
185-
- Liquality - *Desktop*
186-
- Meetone - *Mobile*
187-
- Mykey - *Mobile*
188-
- Ownbit - *Mobile*
189-
- Tokenpocket - *Desktop & Mobile*
190-
- TP - *Mobile*
191-
- xDefi - *Desktop & Mobile*
192-
- 1inch - *Mobile*
193-
- Tokenary - *Mobile*
194-
- GameStop - *Desktop*
195-
- Rabby - *Desktop*
196-
- MathWallet - *Desktop & Mobile*
197-
- Gamestop - *Desktop*
198-
- Bitkeep - *Desktop & Mobile*
199-
- Sequence - *Desktop & Mobile*
200-
- Core - *Desktop*
201-
- Bitski - *Desktop & Mobile*
202-
- Enkrypt - *Desktop & Mobile*
270+
- Metamask - _Desktop & Mobile_ (Mobile relies on Wallet Connect and is detected inside MetaMask app browser)
271+
- Binance - _Desktop_
272+
- Coinbase - _Desktop & Mobile_
273+
- Tally - _Desktop_
274+
- Exodus - _Desktop & Mobile_
275+
- Trust - _Mobile_
276+
- Opera - _Desktop & Mobile_
277+
- Status - _Mobile_
278+
- Alphawallet - _Mobile_
279+
- Atoken - _Mobile_
280+
- Bitpie - _Mobile_
281+
- Blockwallet - _Desktop_
282+
- Brave - _Desktop & Mobile_
283+
- D'Cent - _Mobile_
284+
- Frame - _Desktop_
285+
- Huobiwallet - _Mobile_
286+
- Hyperpay - _Mobile_
287+
- IMtoken - _Mobile_
288+
- Liquality - _Desktop_
289+
- Meetone - _Mobile_
290+
- Mykey - _Mobile_
291+
- Ownbit - _Mobile_
292+
- Tokenpocket - _Desktop & Mobile_
293+
- TP - _Mobile_
294+
- xDefi - _Desktop & Mobile_
295+
- 1inch - _Mobile_
296+
- Tokenary - _Mobile_
297+
- GameStop - _Desktop_
298+
- Rabby - _Desktop_
299+
- MathWallet - _Desktop & Mobile_
300+
- Gamestop - _Desktop_
301+
- Bitkeep - _Desktop & Mobile_
302+
- Sequence - _Desktop & Mobile_
303+
- Core - _Desktop_
304+
- Bitski - _Desktop & Mobile_
305+
- Enkrypt - _Desktop & Mobile_
203306

204307
## Build Environments
205-
For build env configurations and setups please see the Build Env section [here](/docs/modules/core#build-environments)
308+
309+
For build env configurations and setups please see the Build Env section [here](/docs/modules/core#build-environments)

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.13.1-alpha.1",
3+
"version": "2.13.1-alpha.2",
44
"description": "Web3-Onboard makes it simple to connect Ethereum hardware and software wallets to your dapp. Features standardized spec compliant web3 providers for all supported wallets, framework agnostic modern javascript UI with code splitting, CSS customization, multi-chain and multi-account support, reactive wallet state subscriptions and real-time transaction state change notifications.",
55
"keywords": [
66
"Ethereum",

packages/core/src/store/actions.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,8 +393,10 @@ export function uniqueWalletsByLabel(
393393
): WalletModule[] {
394394
return walletModuleList.filter(
395395
(wallet, i) =>
396+
wallet &&
396397
walletModuleList.findIndex(
397-
(innerWallet: WalletModule) => innerWallet.label === wallet.label
398+
(innerWallet: WalletModule) =>
399+
innerWallet && innerWallet.label === wallet.label
398400
) === i
399401
)
400402
}

packages/core/src/views/connect/Index.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@
170170
} catch (error) {
171171
const { message } = error as { message: string }
172172
connectingErrorMessage = message
173+
connectingWalletLabel = ''
173174
scrollToTop()
174175
}
175176
}

packages/demo/src/App.svelte

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import Onboard from '@web3-onboard/core'
33
import fortmaticModule from '@web3-onboard/fortmatic'
44
import gnosisModule from '@web3-onboard/gnosis'
5-
import injectedModule from '@web3-onboard/injected-wallets'
5+
import injectedModule, { ProviderLabel } from '@web3-onboard/injected-wallets'
66
import keepkeyModule from '@web3-onboard/keepkey'
77
import keystoneModule from '@web3-onboard/keystone'
88
import ledgerModule from '@web3-onboard/ledger'
@@ -66,11 +66,39 @@
6666
6767
const injected = injectedModule({
6868
custom: [
69-
// include custom injected wallet modules here
70-
],
71-
filter: {
72-
// mapping of wallet label to filter here
73-
}
69+
// include custom (not natively supported) injected wallet modules here
70+
]
71+
// display all wallets even if they are unavailable
72+
// displayUnavailable: true
73+
// but only show Binance and Bitski wallet if they are available
74+
// filter: {
75+
// [ProviderLabel.Binance]: 'unavailable',
76+
// [ProviderLabel.Bitski]: 'unavailable'
77+
// }
78+
// do a manual sort of injected wallets so that MetaMask and Coinbase are ordered first
79+
// sort: wallets => {
80+
// const metaMask = wallets.find(
81+
// ({ label }) => label === ProviderLabel.MetaMask
82+
// )
83+
// const coinbase = wallets.find(
84+
// ({ label }) => label === ProviderLabel.Coinbase
85+
// )
86+
87+
// return (
88+
// [
89+
// metaMask,
90+
// coinbase,
91+
// ...wallets.filter(
92+
// ({ label }) =>
93+
// label !== ProviderLabel.MetaMask &&
94+
// label !== ProviderLabel.Coinbase
95+
// )
96+
// ]
97+
// // remove undefined values
98+
// .filter(wallet => wallet)
99+
// )
100+
// }
101+
// walletUnavailableMessage: wallet => `Oops ${wallet.label} is unavailable!`
74102
})
75103
76104
const coinbaseWallet = coinbaseModule()
@@ -262,7 +290,7 @@
262290
},
263291
position: 'topRight'
264292
}
265-
},
293+
}
266294
// containerElements: {
267295
// // El must be present at time of JS script execution
268296
// // See ../public/index.html for element example
@@ -298,8 +326,6 @@
298326
299327
let toAddress
300328
const sendTransaction = async provider => {
301-
await onboard.setChain({ chainId: '0x5' })
302-
303329
const ethersProvider = new ethers.providers.Web3Provider(provider, 'any')
304330
305331
const signer = ethersProvider.getSigner()

0 commit comments

Comments
 (0)