Skip to content

Commit 83875fa

Browse files
authored
Merge pull request #425 from blocknative/develop
Release 1.12.0
2 parents 8a9f127 + e0d079e commit 83875fa

File tree

13 files changed

+229
-30
lines changed

13 files changed

+229
-30
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ node_modules
33
dist/
44
package-lock.json
55
.rpt2_cache
6-
.vscode
6+
.vscode
7+
*.patch

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "bnc-onboard",
3-
"version": "1.11.1",
3+
"version": "1.12.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",
@@ -47,6 +47,7 @@
4747
"dependencies": {
4848
"@ledgerhq/hw-app-eth": "^5.21.0",
4949
"@ledgerhq/hw-transport-u2f": "^5.21.0",
50+
"@ledgerhq/hw-transport-webusb": "^5.22.0",
5051
"@portis/web3": "^2.0.0-beta.57",
5152
"@toruslabs/torus-embed": "^1.8.2",
5253
"@unilogin/provider": "^0.6.1",

rollup.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export default {
7272
'ethereumjs-util',
7373
'hdkey',
7474
'@ledgerhq/hw-transport-u2f',
75+
'@ledgerhq/hw-transport-webusb',
7576
'@ledgerhq/hw-app-eth',
7677
'util',
7778
'assert',

src/@types/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ declare module 'ethereumjs-util'
1212
declare module 'hdkey'
1313
declare module '@ledgerhq/hw-app-eth'
1414
declare module '@ledgerhq/hw-transport-u2f'
15+
declare module '@ledgerhq/hw-transport-webusb'
1516

1617
declare module '*.png'
1718
declare module '*.svg'

src/interfaces.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ export interface Helpers {
135135
disconnected: boolean
136136
walletName: string
137137
}) => void
138+
browser: Browser
139+
os: OS
138140
}
139141

140142
export interface WalletInterface {
@@ -429,12 +431,24 @@ export interface BalanceStore {
429431
get: () => any
430432
}
431433

434+
export type Browser = {
435+
name: string
436+
version: string
437+
}
438+
439+
export type OS = {
440+
name: string
441+
version: string
442+
versionName: string
443+
}
444+
432445
export interface AppState {
433446
dappId: string
434447
networkId: number
435448
version: string
436449
mobileDevice: boolean
437-
os: string
450+
os: OS
451+
browser: Browser
438452
darkMode: boolean
439453
autoSelectWallet: string
440454
walletSelectInProgress: boolean

src/modules/select/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ function getModule(name: string): Promise<any> | undefined {
9494
return import('./wallets/unilogin')
9595
case 'mykey':
9696
return import('./wallets/mykey')
97+
case 'huobiwallet':
98+
return import('./wallets/huobiwallet')
9799
default:
98100
return
99101
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const huobiwalletIcon = `
2+
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 1024 1024">
3+
<defs>
4+
<style>.cls-1{fill:#2d65f8;}.cls-1,.cls-2{fill-rule:evenodd;}.cls-2{fill:#173fff;}.cls-3{fill:#fcfcff;}.cls-4{fill:#fff;}</style>
5+
</defs>
6+
<title>huobi wallet icon</title>
7+
<path class="cls-1" d="M292.28,0H552Q742.79,27,858.24,122.88T1024,392V731.72c0,101.63-10.58,138.48-30.45,175.64a207.13,207.13,0,0,1-86.19,86.19c-37.16,19.87-74,30.45-175.64,30.45H292.28c-101.63,0-138.48-10.58-175.64-30.45a207.13,207.13,0,0,1-86.19-86.19C10.58,870.2,0,833.35,0,731.72V292.28C0,190.65,10.58,153.8,30.45,116.64a207.13,207.13,0,0,1,86.19-86.19C153.8,10.58,190.65,0,292.28,0Z"/>
8+
<path class="cls-2" d="M993.55,116.64a207.13,207.13,0,0,0-86.19-86.19C870.21,10.58,833.35,0,731.72,0H552Q742.79,27,858.24,122.88T1024,392V292.28C1024,190.65,1013.42,153.8,993.55,116.64Z"/>
9+
<path class="cls-3" d="M591.8,382.71c0-97.43-48-181.13-84.48-208.41,0,0-2.78-1.53-2.59,2.3-3,188-100.19,239-153.65,307.63-123.27,158.45-8.6,332.23,108.14,364.18,65.35,18-15.06-31.95-25.4-136.86C421.21,584.73,591.8,487.81,591.8,382.71Z"/>
10+
<path class="cls-4" d="M643.64,445.69c-.78-.51-1.81-.9-2.53.32-2.07,23.74-26.56,74.42-57.67,121C478.07,725,538.08,801.1,571.91,842.18c19.44,23.74,0,0,49-24.25,60.52-36.26,99.8-98.95,105.62-168.62A242.5,242.5,0,0,0,643.64,445.69Z"/>
11+
</svg>`
12+
13+
export default huobiwalletIcon
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { mobileWalletInstallMessage } from '../content'
2+
import {
3+
WalletModule,
4+
Helpers,
5+
InjectedWithBalanceOptions
6+
} from '../../../interfaces'
7+
8+
import huobiwalletIcon from '../wallet-icons/icon-huobiwallet'
9+
10+
function huobiwallet(options: InjectedWithBalanceOptions): WalletModule {
11+
const { preferred, label, svg, rpcUrl } = options
12+
13+
return {
14+
name: label || 'Huobi Wallet',
15+
svg: svg || huobiwalletIcon,
16+
wallet: async (helpers: Helpers) => {
17+
const { getProviderName, getAddress, getNetwork, getBalance } = helpers
18+
const huobiwalletProvider =
19+
(window as any).ethereum ||
20+
((window as any).web3 && (window as any).web3.currentProvider)
21+
22+
const isHuobiWallet =
23+
getProviderName(huobiwalletProvider) === 'huobiwallet'
24+
let createProvider
25+
26+
if (isHuobiWallet && rpcUrl) {
27+
createProvider = (await import('./providerEngine')).default
28+
}
29+
30+
const provider = createProvider ? createProvider({ rpcUrl }) : null
31+
32+
let warned = false
33+
34+
return {
35+
provider: huobiwalletProvider,
36+
interface: isHuobiWallet
37+
? {
38+
address: {
39+
get: () => getAddress(huobiwalletProvider)
40+
},
41+
network: {
42+
get: () => getNetwork(huobiwalletProvider)
43+
},
44+
balance: {
45+
get: async () => {
46+
if (!provider) {
47+
if (!warned) {
48+
console.warn(
49+
'The Huobi Wallet provider does not allow rpc calls preventing Onboard.js from getting the balance. You can pass in a "rpcUrl" to the Huobi Wallet initialization object to get the balance.'
50+
)
51+
warned = true
52+
}
53+
54+
return null
55+
}
56+
57+
const address = await getAddress(huobiwalletProvider)
58+
59+
return getBalance(provider, address)
60+
}
61+
},
62+
name: getProviderName(huobiwalletProvider)
63+
}
64+
: null
65+
}
66+
},
67+
type: 'injected',
68+
link: 'https://www.huobiwallet.com',
69+
installMessage: mobileWalletInstallMessage,
70+
mobile: true,
71+
preferred
72+
}
73+
}
74+
75+
export default huobiwallet

src/modules/select/wallets/ledger.ts

Lines changed: 61 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { LedgerOptions, WalletModule, Helpers } from '../../../interfaces'
1+
import {
2+
LedgerOptions,
3+
WalletModule,
4+
Helpers,
5+
Browser,
6+
OS
7+
} from '../../../interfaces'
28

39
import ledgerIcon from '../wallet-icons/icon-ledger'
410

@@ -21,15 +27,17 @@ function ledger(options: LedgerOptions & { networkId: number }): WalletModule {
2127
svg: svg || ledgerIcon,
2228
iconSrc,
2329
wallet: async (helpers: Helpers) => {
24-
const { BigNumber, networkName, resetWalletState } = helpers
30+
const { BigNumber, networkName, resetWalletState, browser, os } = helpers
2531

2632
const provider = await ledgerProvider({
2733
rpcUrl,
2834
networkId,
29-
LedgerTransport,
35+
CustomLedgerTransport: LedgerTransport,
3036
BigNumber,
3137
networkName,
32-
resetWalletState
38+
resetWalletState,
39+
browser,
40+
os
3341
})
3442

3543
return {
@@ -64,17 +72,18 @@ function ledger(options: LedgerOptions & { networkId: number }): WalletModule {
6472
async function ledgerProvider(options: {
6573
networkId: number
6674
rpcUrl: string
67-
LedgerTransport: any
75+
CustomLedgerTransport: any
6876
BigNumber: any
6977
networkName: (id: number) => string
7078
resetWalletState: (options?: {
7179
disconnected: boolean
7280
walletName: string
7381
}) => void
82+
browser: Browser
83+
os: OS
7484
}) {
7585
const { default: createProvider } = await import('./providerEngine')
7686
const { generateAddresses, isValidPath } = await import('./hd-wallet')
77-
const { default: TransportU2F } = await import('@ledgerhq/hw-transport-u2f')
7887
const { default: Eth } = await import('@ledgerhq/hw-app-eth')
7988

8089
const EthereumTx = await import('ethereumjs-tx')
@@ -84,10 +93,12 @@ async function ledgerProvider(options: {
8493
const {
8594
networkId,
8695
rpcUrl,
87-
LedgerTransport,
96+
CustomLedgerTransport,
8897
BigNumber,
8998
networkName,
90-
resetWalletState
99+
resetWalletState,
100+
browser,
101+
os
91102
} = options
92103

93104
let dPath = ''
@@ -147,10 +158,14 @@ async function ledgerProvider(options: {
147158
provider.isCustomPath = isCustomPath
148159

149160
let transport: any
161+
let transportSubscription: any
150162
let eth: any
151163

152164
function disconnect() {
153165
transport && transport.close()
166+
transportSubscription &&
167+
transportSubscription.unsubscribe &&
168+
transportSubscription.unsubscribe()
154169
provider.stop()
155170
resetWalletState({ disconnected: true, walletName: 'Ledger' })
156171
}
@@ -185,27 +200,54 @@ async function ledgerProvider(options: {
185200

186201
async function createTransport() {
187202
try {
188-
transport = LedgerTransport
189-
? await LedgerTransport.create()
190-
: await TransportU2F.create()
191-
192-
eth = new Eth(transport)
193-
194203
const observer = {
195204
next: (event: any) => {
196205
if (event.type === 'remove') {
197206
disconnect()
198207
}
199208
},
200-
error: () => {},
209+
error: (error: any) => {
210+
throw new Error(error)
211+
},
201212
complete: () => {}
202213
}
203214

204-
LedgerTransport
205-
? LedgerTransport.listen(observer)
206-
: TransportU2F.listen(observer)
215+
if (CustomLedgerTransport) {
216+
transport = await CustomLedgerTransport.create()
217+
transportSubscription = CustomLedgerTransport.listen(observer)
218+
} else {
219+
if (
220+
os.name === 'Windows' &&
221+
parseInt(os.versionName) >= 11 &&
222+
(browser.name === 'Internet Explorer' || browser.name === 'Firefox')
223+
) {
224+
throw new Error(
225+
`OS: ${os.name} ${os.versionName} and Browser: ${browser.name} are not compatible with Ledger wallets, please switch to Chrome browser to continue.`
226+
)
227+
} else if (
228+
(os.name === 'macOS' || os.name === 'Linux') &&
229+
(browser.name === 'Firefox' || browser.name === 'Safari')
230+
) {
231+
const { default: TransportU2F } = await import(
232+
'@ledgerhq/hw-transport-u2f'
233+
)
234+
235+
transport = await TransportU2F.create()
236+
} else {
237+
const { default: TransportWebUsb } = await import(
238+
'@ledgerhq/hw-transport-webusb'
239+
)
240+
241+
transport = await TransportWebUsb.create()
242+
transportSubscription = TransportWebUsb.listen(observer)
243+
}
244+
}
245+
246+
eth = new Eth(transport)
207247
} catch (error) {
208-
throw new Error('Error connecting to Ledger wallet')
248+
throw new Error(
249+
'An error occurred when trying to connect to your Ledger wallet'
250+
)
209251
}
210252
}
211253

src/onboard.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ function init(initialization: Initialization): API {
5252
hideBranding
5353
} = initialization
5454

55-
const { os, isMobile } = getDeviceInfo()
55+
const { os, browser, isMobile } = getDeviceInfo()
5656

5757
const initializedModules = initializeModules(
5858
networkId,
@@ -83,6 +83,7 @@ function init(initialization: Initialization): API {
8383
version,
8484
mobileDevice: isMobile,
8585
os,
86+
browser,
8687
darkMode,
8788
displayBranding,
8889
checkModules: initializedModules.walletCheck

src/utilities.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -215,19 +215,26 @@ export function getProviderName(provider: any): string | undefined {
215215
return 'MYKEY'
216216
}
217217

218+
if (provider.isHbWallet) {
219+
return 'huobiwallet'
220+
}
221+
222+
218223
if (provider.host && provider.host.indexOf('localhost') !== -1) {
219224
return 'localhost'
220225
}
221226
}
222227

223228
export function getDeviceInfo() {
224-
const browser = bowser.getParser(window.navigator.userAgent)
225-
const { name } = browser.getOS()
226-
const { type } = browser.getPlatform()
229+
const parsed = bowser.getParser(window.navigator.userAgent)
230+
const os = parsed.getOS()
231+
const browser = parsed.getBrowser()
232+
const { type } = parsed.getPlatform()
227233

228234
return {
229235
isMobile: type ? type !== 'desktop' : window.innerWidth < 600,
230-
os: name
236+
os,
237+
browser
231238
}
232239
}
233240

0 commit comments

Comments
 (0)