Skip to content

Commit 052be53

Browse files
authored
Merge pull request #2201 from oasisprotocol/lw/dedupe-usb-transport
Deduplicate logic in TransportWebUSB.create and requestDevice
2 parents 08bf1cc + f8142fd commit 052be53

File tree

7 files changed

+19
-44
lines changed

7 files changed

+19
-44
lines changed

.changelog/2201.trivial.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Deduplicate logic in TransportWebUSB.create and requestDevice

extension/src/ExtLedgerAccessPopup/ExtLedgerAccessPopup.tsx

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { Header } from 'app/components/Header'
1010
import { ErrorFormatter } from 'app/components/ErrorFormatter'
1111
import { AlertBox } from 'app/components/AlertBox'
1212
import { WalletErrors } from 'types/errors'
13-
import { requestDevice } from 'app/lib/ledger'
1413
import logotype from '../../../public/Icon Blue 192.png'
1514
import { CountdownButton } from 'app/components/CountdownButton'
1615
import TransportWebUSB from '@ledgerhq/hw-transport-webusb'
@@ -49,14 +48,11 @@ export function ExtLedgerAccessPopup() {
4948
const handleConnect = async () => {
5049
setConnection('connecting')
5150
try {
52-
const device = await requestDevice()
53-
const transport = await TransportWebUSB.create()
54-
if (device && transport) {
55-
setConnection('connected')
56-
// Used to redirect after reopening wallet
57-
window.localStorage.setItem('oasis_wallet_granted_usb_ledger_timestamp', Date.now().toString())
58-
setTimeout(() => window.close(), 5_000)
59-
}
51+
await (await TransportWebUSB.create()).close() // Get access permissions
52+
setConnection('connected')
53+
// Used to redirect after reopening wallet
54+
window.localStorage.setItem('oasis_wallet_granted_usb_ledger_timestamp', Date.now().toString())
55+
setTimeout(() => window.close(), 5_000)
6056
} catch {
6157
setConnection('error')
6258
}

extension/src/ExtLedgerAccessPopup/__tests__/index.test.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import React from 'react'
22
import { render, screen } from '@testing-library/react'
33
import userEvent from '@testing-library/user-event'
4-
import { requestDevice } from 'app/lib/ledger'
54
import { ExtLedgerAccessPopup } from '../ExtLedgerAccessPopup'
65
import TransportWebUSB from '@ledgerhq/hw-transport-webusb'
76

8-
jest.mock('app/lib/ledger')
9-
jest.mock('@ledgerhq/hw-transport')
7+
jest.mock('@ledgerhq/hw-transport-webusb')
108

119
describe('<ExtLedgerAccessPopup />', () => {
1210
it('should render component', () => {
@@ -16,8 +14,8 @@ describe('<ExtLedgerAccessPopup />', () => {
1614
})
1715

1816
it('should render success state', async () => {
19-
jest.mocked(requestDevice).mockResolvedValue({} as USBDevice)
20-
jest.mocked(TransportWebUSB.create).mockResolvedValue({} as TransportWebUSB)
17+
jest.mocked(TransportWebUSB.isSupported).mockResolvedValue(true)
18+
jest.mocked(TransportWebUSB.create).mockResolvedValue({ close: () => {} } as TransportWebUSB)
2119

2220
render(<ExtLedgerAccessPopup />)
2321

@@ -28,12 +26,12 @@ describe('<ExtLedgerAccessPopup />', () => {
2826
})
2927

3028
it('should render error state', async () => {
31-
jest.mocked(requestDevice).mockRejectedValue(new Error('error'))
32-
jest.mocked(TransportWebUSB.create).mockRejectedValue(new Error('error'))
29+
jest.mocked(TransportWebUSB.isSupported).mockResolvedValue(true)
30+
jest.mocked(TransportWebUSB.create).mockRejectedValue(new Error('Dummy error'))
3331

3432
render(<ExtLedgerAccessPopup />)
3533

36-
userEvent.click(screen.getByRole('button'))
34+
await userEvent.click(screen.getByRole('button'))
3735

3836
expect(await screen.findByText('ledger.extension.failed')).toBeInTheDocument()
3937
expect(screen.getByLabelText('Status is critical')).toBeInTheDocument()

jest.config.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ const config = {
2424
},
2525
],
2626
},
27-
transformIgnorePatterns: [
28-
'/node_modules/(?!(@ledgerhq/hw-transport-webusb|cborg|grommet/es6|grommet-icons/es6)/)',
29-
],
27+
transformIgnorePatterns: ['/node_modules/(?!(cborg|grommet/es6|grommet-icons/es6)/)'],
3028
testMatch: [
3129
'<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}',
3230
'<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}',

src/app/lib/__tests__/ledger.test.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
import { canAccessBle, Ledger, LedgerSigner, requestDevice } from '../ledger'
1+
import { canAccessBle, Ledger, LedgerSigner } from '../ledger'
22
import OasisApp from '@oasisprotocol/ledger'
33
import { WalletError, WalletErrors } from 'types/errors'
44
import { Wallet, WalletType } from 'app/state/wallet/types'
5-
import { isSupported, requestLedgerDevice } from '@ledgerhq/hw-transport-webusb/lib-es/webusb'
65
import BleTransport from '@oasisprotocol/ionic-ledger-hw-transport-ble/lib'
76

8-
jest.mock('@ledgerhq/hw-transport-webusb/lib-es/webusb')
97
jest.mock('@oasisprotocol/ionic-ledger-hw-transport-ble/lib', () => {
108
return {
119
isEnabled: jest.fn(),
@@ -22,16 +20,6 @@ function mockAppIsOpen(appName: string) {
2220
appInfo.mockResolvedValueOnce({ appName: appName, return_code: 0x9000, error_message: '' })
2321
}
2422

25-
describe('Extension access', () => {
26-
it('should return a ledger device when web usb is supported', async () => {
27-
const device = {} as USBDevice
28-
jest.mocked(isSupported).mockResolvedValue(true)
29-
jest.mocked(requestLedgerDevice).mockResolvedValue(device)
30-
const result = await requestDevice()
31-
expect(result).toBe(device)
32-
})
33-
})
34-
3523
describe('Ledger Library', () => {
3624
afterEach(() => {
3725
jest.resetAllMocks()

src/app/lib/ledger.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { LedgerWalletType, Wallet, WalletType } from 'app/state/wallet/types'
55
import { WalletError, WalletErrors } from 'types/errors'
66
import { hex2uint, publicKeyToAddress } from './helpers'
77
import type Transport from '@ledgerhq/hw-transport'
8-
import { isSupported, requestLedgerDevice } from '@ledgerhq/hw-transport-webusb/lib-es/webusb'
8+
import TransportWebUSB from '@ledgerhq/hw-transport-webusb'
99
import BleTransport from '@oasisprotocol/ionic-ledger-hw-transport-ble/lib'
1010
import { runtimeIs } from 'app/lib/runtimeIs'
1111

@@ -16,7 +16,7 @@ interface LedgerAccount {
1616
}
1717

1818
export async function canAccessNavigatorUsb(): Promise<boolean> {
19-
return await isSupported()
19+
return await TransportWebUSB.isSupported()
2020
}
2121

2222
export async function canAccessBle(): Promise<boolean> {
@@ -26,12 +26,6 @@ export async function canAccessBle(): Promise<boolean> {
2626
return hasBLE && hasLEScan
2727
}
2828

29-
export async function requestDevice(): Promise<USBDevice | undefined> {
30-
if (await isSupported()) {
31-
return await requestLedgerDevice()
32-
}
33-
}
34-
3529
function successOrThrowWalletError<T>(response: Response<T>, message: string) {
3630
try {
3731
return successOrThrow(response)

src/app/pages/OpenWalletPage/Features/FromLedger/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ export function FromLedger({ openLedgerAccessPopup }: SelectOpenMethodProps) {
3535
useEffect(() => {
3636
if (openLedgerAccessPopup) {
3737
// In default ext popup this gets auto-accepted / auto-rejected. In a tab or persistent popup it would
38-
// prompt user to select a ledger device. TransportWebUSB.create seems to match requestDevice called in
39-
// openLedgerAccessPopup.
40-
// If TransportWebUSB.create() is rejected then call openLedgerAccessPopup and requestDevice. When user
38+
// prompt user to select a ledger device.
39+
// If TransportWebUSB.create() is rejected then call openLedgerAccessPopup. When user
4140
// confirms the prompt tell them to come back here. TransportWebUSB.create() will resolve.
4241
TransportWebUSB.create()
42+
.then(t => t.close())
4343
.then(() => setHasUsbLedgerAccess(true))
4444
.catch(() => setHasUsbLedgerAccess(false))
4545
} else {

0 commit comments

Comments
 (0)