Skip to content

Commit 8e198e7

Browse files
Merge pull request #658 from blocknative/release/1.34.0
Release: 1.34.0 - Master
2 parents e7cc89e + 52e5279 commit 8e198e7

11 files changed

+220
-106
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "bnc-onboard",
3-
"version": "1.33.0",
3+
"version": "1.34.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",
@@ -59,7 +59,7 @@
5959
"@ethereumjs/tx": "^3.0.0",
6060
"@gnosis.pm/safe-apps-provider": "^0.5.0",
6161
"@gnosis.pm/safe-apps-sdk": "^3.0.0",
62-
"@keystonehq/eth-keyring": "0.7.2",
62+
"@keystonehq/eth-keyring": "0.7.7",
6363
"@ledgerhq/hw-app-eth": "^5.49.0",
6464
"@ledgerhq/hw-transport-u2f": "^5.21.0",
6565
"@ledgerhq/hw-transport-webusb": "5.53.0",

src/interfaces.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ export interface CommonWalletOptions {
183183
iconSrc?: string
184184
svg?: string
185185
networkId?: number
186+
display?: { mobile?: boolean; desktop?: boolean }
186187
}
187188

188189
export interface SdkWalletOptions extends CommonWalletOptions {

src/modules/check/network.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { networkName } from '../../utilities'
1+
import { getProviderName, networkName } from '../../utilities'
22
import {
33
WalletCheckModal,
44
StateAndHelpers,
@@ -41,14 +41,18 @@ function network(
4141
})
4242
}
4343
}
44-
try {
45-
await wallet?.provider?.request({
46-
method: 'wallet_switchEthereumChain',
47-
params: [{ chainId: '0x' + appNetworkId?.toString(16) }]
48-
})
49-
} catch (e) {
50-
// Could not switch networks so proceed as normal through the checks
44+
// Adds a check for WalletConnect since it hangs for unsupported rpc methods
45+
if (getProviderName(wallet?.provider) !== 'WalletConnect') {
46+
try {
47+
await wallet?.provider?.request({
48+
method: 'wallet_switchEthereumChain',
49+
params: [{ chainId: '0x' + appNetworkId?.toString(16) }]
50+
})
51+
} catch (e) {
52+
// Could not switch networks so proceed as normal through the checks
53+
}
5154
}
55+
5256
if (stateStore.network.get() != appNetworkId) {
5357
return {
5458
heading: heading || 'You Must Change Networks',

src/modules/select/index.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { getProviderName } from '../../utilities'
1111
const desktopDefaultWalletNames = [
1212
'detectedwallet',
1313
'metamask',
14+
'binance',
1415
'frame',
1516
'torus',
1617
'opera',
@@ -46,23 +47,26 @@ function select(
4647
networkId: number,
4748
isMobile: boolean
4849
) {
49-
const defaultWalletNames = isMobile
50-
? mobileDefaultWalletNames
51-
: desktopDefaultWalletNames
52-
5350
if (wallets) {
51+
const hideWallet = (wallet: WalletInitOptions) =>
52+
wallet?.display &&
53+
wallet?.display[isMobile ? 'mobile' : 'desktop'] === false
54+
5455
// For backwards compatibility if a user is still using 'detectedwallet' in the onboard wallet select array
5556
// it will be filtered out so there are no duplicates
5657
wallets = wallets.filter(
5758
wallet =>
58-
'walletName' in wallet ? wallet.walletName !== 'detectedwallet' : true // It is not a WalletInitOption but rather a WalletModule so let it through
59+
'walletName' in wallet
60+
? wallet.walletName !== 'detectedwallet' && !hideWallet(wallet)
61+
: true // It is not a WalletInitOption but rather a WalletModule so let it through
5962
)
6063

6164
// If we detect an injected wallet then place the detected wallet
62-
// at the beginning of the list e.g. the of the wallet select modal
65+
// at the beginning of the list e.g. the top of the wallet select modal
6366
if (injectedWalletDetected()) {
6467
wallets.unshift({ walletName: 'detectedwallet' })
6568
}
69+
6670
return Promise.all(
6771
wallets.map(wallet => {
6872
// If this is a wallet init object then load the built-in wallet module
@@ -87,6 +91,10 @@ function select(
8791
)
8892
}
8993

94+
const defaultWalletNames = isMobile
95+
? mobileDefaultWalletNames
96+
: desktopDefaultWalletNames
97+
9098
return Promise.all(
9199
defaultWalletNames
92100
// Include the detected wallet only if an injected wallet is detected
@@ -180,6 +188,8 @@ function getModule(name: string): Promise<{
180188
return import('./wallets/bitpie')
181189
case 'gnosis':
182190
return import('./wallets/gnosis')
191+
case 'binance':
192+
return import('./wallets/binance-chain-wallet')
183193
case 'detectedwallet':
184194
return import('./wallets/detectedwallet')
185195
case 'tp':

src/modules/select/wallet-icons/icon-binance-chain-wallet.ts

Lines changed: 11 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { CommonWalletOptions, Helpers, WalletModule } from '../../../interfaces'
2+
import { extensionInstallMessage, mobileWalletInstallMessage } from '../content'
3+
import { binanceChainWalletLogo } from '../wallet-icons/icon-binance-chain-wallet'
4+
5+
function binanceChainWallet(
6+
options: CommonWalletOptions & { isMobile: boolean }
7+
): WalletModule {
8+
const { preferred, label, iconSrc, svg, isMobile } = options
9+
10+
return {
11+
name: label || 'Binance Chain Wallet',
12+
iconSrc: iconSrc || binanceChainWalletLogo,
13+
iconSrcSet: iconSrc || binanceChainWalletLogo,
14+
svg: svg || binanceChainWalletLogo,
15+
wallet: async (helpers: Helpers) => {
16+
const { createModernProviderInterface } = helpers
17+
18+
// Ref: https://binance-wallet.gitbook.io/binance-chain-extension-wallet
19+
const provider = (window as any).BinanceChain
20+
21+
return {
22+
provider,
23+
interface: provider && createModernProviderInterface(provider)
24+
}
25+
},
26+
type: 'injected',
27+
link: 'https://docs.binance.org/smart-chain/wallet/binance.html#download-link',
28+
installMessage: isMobile
29+
? mobileWalletInstallMessage
30+
: extensionInstallMessage,
31+
desktop: true,
32+
mobile: false,
33+
preferred
34+
}
35+
}
36+
37+
export default binanceChainWallet

src/modules/select/wallets/fortmatic.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import { SdkWalletOptions, WalletModule, Helpers } from '../../../interfaces'
44
import fortmaticIcon from '../wallet-icons/icon-fortmatic'
55

66
function fortmatic(
7-
options: SdkWalletOptions & { networkId: number }
7+
options: SdkWalletOptions & { networkId: number; rpcUrl: string }
88
): WalletModule {
9-
const { apiKey, networkId, preferred, label, iconSrc, svg } = options
9+
const { apiKey, rpcUrl, networkId, preferred, label, iconSrc, svg } = options
1010

1111
return {
1212
name: label || 'Fortmatic',
@@ -17,7 +17,11 @@ function fortmatic(
1717

1818
const instance = new Fortmatic(
1919
apiKey,
20-
networkId === 1 ? undefined : networkName(networkId)
20+
rpcUrl
21+
? { chainId: networkId, rpcUrl }
22+
: networkId === 1
23+
? undefined
24+
: networkName(networkId)
2125
)
2226

2327
const provider = instance.getProvider()

src/modules/select/wallets/keystone.ts

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ async function keystoneProvider(options: {
128128
.then((res: string) => callback(null, res))
129129
.catch(err => callback(err, null))
130130
},
131+
signTypedMessage: (messageData: any, callback: any) => {
132+
signTypedMessage(messageData)
133+
.then((res: string) => callback(null, res))
134+
.catch(err => callback(err, null))
135+
},
131136
rpcUrl
132137
})
133138

@@ -147,6 +152,7 @@ async function keystoneProvider(options: {
147152
function disconnect() {
148153
dPath = ''
149154
enabled = false
155+
addressList = []
150156
provider.stop()
151157
}
152158

@@ -173,9 +179,11 @@ async function keystoneProvider(options: {
173179
}
174180

175181
function setPrimaryAccount(address: string) {
176-
return keyring.setCurrentAccount(
177-
addressList.findIndex(addr => addr === address) || 0
178-
)
182+
const index = addressList.findIndex(addr => addr === address) || 0
183+
keyring.setCurrentAccount(index)
184+
const accounts = [...addressList]
185+
accounts.unshift(accounts.splice(index, 1)[0])
186+
addressList = accounts
179187
}
180188

181189
function getPrimaryAddress() {
@@ -192,12 +200,14 @@ async function keystoneProvider(options: {
192200
return []
193201
}
194202

195-
if (keyring.getAccounts().length > 0 && !getMore) {
196-
return keyring.getAccounts()
203+
if (addressList.length > 0 && !getMore) {
204+
return addressList
197205
}
198206

199207
try {
200208
addressList = await keyring.addAccounts(keyring.getAccounts().length + 5)
209+
const currentPrimary = getPrimaryAddress()
210+
setPrimaryAccount(currentPrimary)
201211
} catch (error) {
202212
throw error
203213
}
@@ -279,6 +289,24 @@ async function keystoneProvider(options: {
279289
}
280290
}
281291

292+
async function signTypedMessage({ data }: { data: any }) {
293+
if (addressList.length === 0) {
294+
await enable()
295+
}
296+
297+
try {
298+
if (typeof data === 'string') {
299+
return keyring.signTypedData(getPrimaryAddress(), JSON.parse(data))
300+
}
301+
if (typeof data === 'object') {
302+
return keyring.signTypedData(getPrimaryAddress(), data)
303+
}
304+
throw new Error('invalid typed data')
305+
} catch (err) {
306+
throw err
307+
}
308+
}
309+
282310
return provider
283311
}
284312

src/utilities.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import bowser from 'bowser'
22
import BigNumber from 'bignumber.js'
33
import { get } from 'svelte/store'
4-
import ENS, { getEnsAddress } from '@ensdomains/ensjs'
54

65
import { app } from './stores'
76
import { WalletInterface, Ens } from './interfaces'
@@ -71,6 +70,11 @@ export function getAddress(provider: any): Promise<string | any> {
7170
export async function getEns(provider: any, address: string): Promise<Ens> {
7271
const { networkId } = get(app)
7372
try {
73+
// There is an issue with ens and ts unable to find the
74+
// declaration file for it even though it is present.
75+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
76+
// @ts-ignore - TS7016
77+
const { default: ENS, getEnsAddress } = await import('@ensdomains/ensjs')
7478
const ens = new ENS({ provider, ensAddress: getEnsAddress(networkId) })
7579
const { name } = await ens.getName(address)
7680
const nameInterface = await ens.name(name)
@@ -84,6 +88,7 @@ export async function getEns(provider: any, address: string): Promise<Ens> {
8488
}
8589
} catch (e) {
8690
// Error getting ens
91+
console.error(e)
8792
return {}
8893
}
8994
}

src/validation.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -661,8 +661,15 @@ export function validateWalletInit(
661661
): void | never {
662662
validateType({ name: 'walletInit', value: walletInit, type: 'object' })
663663

664-
const { walletName, preferred, label, iconSrc, svg, ...otherParams } =
665-
walletInit
664+
const {
665+
walletName,
666+
preferred,
667+
label,
668+
iconSrc,
669+
svg,
670+
display,
671+
...otherParams
672+
} = walletInit
666673

667674
invalidParams(
668675
otherParams,
@@ -698,10 +705,17 @@ export function validateWalletInit(
698705
'webUri',
699706
'xsUri',
700707
'blockedPopupRedirect',
701-
'customNetwork'
708+
'customNetwork',
709+
'display'
702710
],
703711
'walletInitObject'
704712
)
713+
validateType({
714+
name: 'walletInit.display',
715+
value: display,
716+
type: 'object',
717+
optional: true
718+
})
705719

706720
validateType({
707721
name: 'walletInit.walletName',

0 commit comments

Comments
 (0)