Skip to content

Commit ee6fa4f

Browse files
mholtzmantaylorjdawsonlnbc1QWFyb24
authored
1.28.0-0.2.0: Generic web3 wallet for injected wallet providers (#583)
* allow user to select injected provider * add icon, pretty it up * Removes extra metamask * Update logic and add auto name feature * Version bump * Move filter, adjust metmask matcher * Add small fix for metamask name * Formatting * Add logo * Remove unused method Co-authored-by: Taylor Dawson <taylorjdawson@gmail.com> Co-authored-by: Aaron Barnard <abarnard@protonmail.com>
1 parent b3767a0 commit ee6fa4f

File tree

7 files changed

+110
-17
lines changed

7 files changed

+110
-17
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "bnc-onboard",
3-
"version": "1.28.0-0.1.1",
3+
"version": "1.28.0-0.2.0",
44
"description": "Onboard users to web3 by allowing them to select a wallet, get that wallet ready to transact and have access to synced wallet state.",
55
"keywords": [
66
"ethereum",

src/modules/select/index.ts

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,21 @@ import {
44
AllWalletInitOptions
55
} from '../../interfaces'
66
import { isWalletInit } from '../../validation'
7+
import { getProviderName } from '../../utilities'
78

89
// wallets that qualify for default wallets need to have no
910
// init parameters that are required for full functionality
10-
const desktopDefaultWalletNames = ['metamask', 'torus', 'opera', 'liquality']
11+
const desktopDefaultWalletNames = [
12+
'detectedwallet',
13+
'metamask',
14+
'frame',
15+
'torus',
16+
'opera',
17+
'liquality'
18+
]
1119

1220
const mobileDefaultWalletNames = [
21+
'detectedwallet',
1322
'metamask',
1423
'coinbase',
1524
'trust',
@@ -28,6 +37,9 @@ const mobileDefaultWalletNames = [
2837
'authereum'
2938
]
3039

40+
const injectedWalletDetected = () =>
41+
window.ethereum && getProviderName(window.ethereum) === undefined
42+
3143
function select(
3244
wallets: Array<WalletInitOptions | WalletModule> | undefined,
3345
networkId: number,
@@ -39,10 +51,15 @@ function select(
3951

4052
if (wallets) {
4153
return Promise.all(
42-
wallets.map(wallet => {
43-
if (isWalletInit(wallet)) {
44-
const { walletName, ...initParams } = wallet
45-
54+
wallets
55+
// only include a detected wallet if it's not already one of the provided options
56+
.filter(
57+
wallet =>
58+
isWalletInit(wallet) &&
59+
(wallet.walletName !== 'detectedwallet' || injectedWalletDetected())
60+
)
61+
.map(wallet => {
62+
const { walletName, ...initParams } = wallet as WalletInitOptions
4663
try {
4764
return getModule(walletName).then((m: any) =>
4865
m.default({ ...initParams, networkId, isMobile })
@@ -54,17 +71,22 @@ function select(
5471
throw error
5572
}
5673
}
57-
}
5874

59-
return Promise.resolve(wallet)
60-
})
75+
return Promise.resolve(wallet)
76+
})
6177
)
6278
}
6379

6480
return Promise.all(
65-
defaultWalletNames.map(walletName =>
66-
getModule(walletName).then((m: any) => m.default({ networkId }))
67-
)
81+
defaultWalletNames
82+
// only include a detected wallet if it's not already one of the provided options
83+
.filter(
84+
walletName =>
85+
walletName !== 'detectedwallet' || injectedWalletDetected()
86+
)
87+
.map(walletName =>
88+
getModule(walletName).then((m: any) => m.default({ networkId }))
89+
)
6890
)
6991
}
7092

@@ -146,6 +168,8 @@ function getModule(name: string): Promise<{
146168
return import('./wallets/bitpie')
147169
case 'gnosis':
148170
return import('./wallets/gnosis')
171+
case 'detectedwallet':
172+
return import('./wallets/detectedwallet')
149173
default:
150174
throw new Error(`${name} is not a valid walletName.`)
151175
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2+
<path d="M21 18V19C21 20.1 20.1 21 19 21H5C3.89 21 3 20.1 3 19V5C3 3.9 3.89 3 5 3H19C20.1 3 21 3.9 21 5V6H12C10.89 6 10 6.9 10 8V16C10 17.1 10.89 18 12 18H21ZM12 16H22V8H12V16ZM16 13.5C15.17 13.5 14.5 12.83 14.5 12C14.5 11.17 15.17 10.5 16 10.5C16.83 10.5 17.5 11.17 17.5 12C17.5 12.83 16.83 13.5 16 13.5Z" fill="black"/>
3+
</svg>`
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const injectedIcon = `
2+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
3+
<path fill-rule="evenodd" d="M16.168 2.924L4.51 13.061a.25.25 0 00.164.439h5.45a.75.75 0 01.692 1.041l-2.559 6.066 11.215-9.668a.25.25 0 00-.164-.439H14a.75.75 0 01-.687-1.05l2.855-6.526zm-.452-1.595a1.341 1.341 0 012.109 1.55L15.147 9h4.161c1.623 0 2.372 2.016 1.143 3.075L8.102 22.721a1.149 1.149 0 01-1.81-1.317L8.996 15H4.674c-1.619 0-2.37-2.008-1.148-3.07l12.19-10.6z">
4+
</path>
5+
</svg>
6+
`
7+
8+
export default injectedIcon
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { extensionInstallMessage } from '../content'
2+
import { WalletModule, Helpers, CommonWalletOptions } from '../../../interfaces'
3+
import injectedIcon from '../wallet-icons/icon-detected-wallet'
4+
5+
function injected(options: CommonWalletOptions): WalletModule {
6+
const { preferred, label, svg } = options
7+
8+
const provider =
9+
(window as any).ethereum ||
10+
((window as any).web3 && (window as any).web3.currentProvider)
11+
12+
const name =
13+
label ||
14+
Object.keys(provider)
15+
.find(key => key.startsWith('is') && !key.includes('MetaMask'))
16+
?.split('is')[1] ||
17+
'Detected Wallet'
18+
19+
return {
20+
name,
21+
svg: svg || injectedIcon,
22+
wallet: async (helpers: Helpers) => {
23+
const {
24+
getProviderName,
25+
createModernProviderInterface,
26+
createLegacyProviderInterface
27+
} = helpers
28+
29+
return {
30+
provider,
31+
interface:
32+
provider && getProviderName(provider) === undefined
33+
? typeof provider.enable === 'function'
34+
? createModernProviderInterface(provider)
35+
: createLegacyProviderInterface(provider)
36+
: null
37+
}
38+
},
39+
type: 'injected',
40+
installMessage: extensionInstallMessage,
41+
desktop: true,
42+
mobile: true,
43+
preferred
44+
}
45+
}
46+
47+
export default injected

src/modules/select/wallets/frame.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@ import { WalletModule, Helpers, CommonWalletOptions } from '../../../interfaces'
44
import frameIcon from '../wallet-icons/icon-frame.png'
55
import frameIcon2x from '../wallet-icons/icon-frame@2x.png'
66

7+
async function getProvider() {
8+
const injected = window.ethereum
9+
10+
if (injected && (injected as any).isFrame) {
11+
return injected
12+
}
13+
14+
const { default: ethProvider } = await import('eth-provider')
15+
return ethProvider('frame')
16+
}
17+
718
function frame(options: CommonWalletOptions): WalletModule {
819
const { preferred, label, iconSrc, svg } = options
920

@@ -15,8 +26,7 @@ function frame(options: CommonWalletOptions): WalletModule {
1526
wallet: async (helpers: Helpers) => {
1627
const { createModernProviderInterface } = helpers
1728

18-
const { default: ethProvider } = await import('eth-provider')
19-
const provider = ethProvider('frame')
29+
const provider = await getProvider()
2030

2131
return {
2232
provider,

src/utilities.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,8 @@ export function getProviderName(provider: any): string | undefined {
253253
return 'XDEFI'
254254
}
255255

256-
if (provider.isMetaMask) {
257-
return 'MetaMask'
256+
if (provider.isFrame) {
257+
return 'Frame'
258258
}
259259

260260
if (provider.isMYKEY) {
@@ -288,7 +288,8 @@ export function getProviderName(provider: any): string | undefined {
288288
// =====================================
289289
// When adding new wallet place above this metamask check as some providers
290290
// have an isMetaMask property in addition to the wallet's own `is[WalletName]`
291-
if (provider.isMetaMask) {
291+
292+
if (provider.isMetaMask && provider._metamask) {
292293
return 'MetaMask'
293294
}
294295

0 commit comments

Comments
 (0)