Skip to content

Commit

Permalink
fix: catch ledger timeout error (#2138)
Browse files Browse the repository at this point in the history
* add try catch to evm address generation

Co-authored-by: Tuditi <[email protected]>

* cleanup invoking ledger api

Co-authored-by: Tuditi <[email protected]>

* close auth popup on timout

Co-authored-by: Tuditi <[email protected]>

* use undefined instead of empty string

---------

Co-authored-by: Tuditi <[email protected]>
  • Loading branch information
MarkNerdi and Tuditi authored Mar 14, 2024
1 parent 86af9b6 commit d68f4e9
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 32 deletions.
6 changes: 3 additions & 3 deletions packages/desktop/lib/electron/utils/ledger.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ export async function signTransactionData(transactionHex: string, bip32Path: str
}
} catch (error) {
return {
r: '',
v: '',
s: '',
r: undefined,
v: undefined,
s: undefined,
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,12 @@ export async function generateAndStoreEvmAddressForAccounts(
})
evmAddress = addresses?.[0]
} else {
evmAddress = await Ledger.generateEvmAddress(accountIndex, coinType)
evmAddress = evmAddress.toLowerCase()
try {
evmAddress = await Ledger.generateEvmAddress(accountIndex, coinType)
evmAddress = evmAddress.toLowerCase()
} catch {
// Do nothing
}
}

const evmAddresses = { [coinType]: evmAddress }
Expand Down
45 changes: 21 additions & 24 deletions packages/shared/src/lib/core/ledger/classes/ledger.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
getAmountFromEvmTransactionValue,
prepareEvmTransaction,
} from '@core/layer-2/utils'
import { Converter, MILLISECONDS_PER_SECOND, sleep } from '@core/utils'
import { Converter, MILLISECONDS_PER_SECOND } from '@core/utils'
import { TypedTxData } from '@ethereumjs/tx'
import type { Bip44 } from '@iota/sdk/out/types'
import {
Expand Down Expand Up @@ -45,6 +45,7 @@ export class Ledger {
'ethereum-app-settings',
{
timeout: 0.5 * MILLISECONDS_PER_SECOND,
shouldClosePopup: false,
}
)
} catch (err) {
Expand Down Expand Up @@ -104,7 +105,6 @@ export class Ledger {
),
'evm-signed-transaction'
)
closeProfileAuthPopup({ forceClose: true })

if (transactionSignature) {
const { r, v, s } = transactionSignature
Expand Down Expand Up @@ -133,7 +133,6 @@ export class Ledger {
() => ledgerApiBridge.makeRequest(LedgerApiMethod.SignMessage, messageHex, bip32Path),
'signed-message'
)
closeProfileAuthPopup({ forceClose: true })

const { r, v, s } = transactionSignature
if (r && v && s) {
Expand Down Expand Up @@ -178,7 +177,6 @@ export class Ledger {
() => ledgerApiBridge.makeRequest(LedgerApiMethod.SignEIP712, hashedDomain, hashedMessage, bip32Path),
'signed-eip712'
)
closeProfileAuthPopup({ forceClose: true })

const { r, v, s } = transactionSignature
if (r && v && s) {
Expand All @@ -194,32 +192,31 @@ export class Ledger {
private static async callLedgerApiAsync<R extends LedgerApiRequestResponse>(
callback: () => void,
responseEvent: keyof IPlatformEventMap,
requestOptions: Partial<ILedgerApiRequestOptions> = {}
requestOptions?: Partial<ILedgerApiRequestOptions>
): Promise<R> {
// TODO: Do we need to stop / start polling here? Get's slightly complicated in that
// the Ethereum app settings polling uses this function.

const { timeout, pollingInterval } = { ...DEFAULT_LEDGER_API_REQUEST_OPTIONS, ...requestOptions }
const iterationCount = timeout / pollingInterval

callback()

let returnValue: R | undefined = undefined
return new Promise((resolve, reject) => {
const options: ILedgerApiRequestOptions = { ...DEFAULT_LEDGER_API_REQUEST_OPTIONS, ...requestOptions }

Platform.onEvent(responseEvent, (value) => {
returnValue = <R>value
})
callback()

for (let count = 0; count < iterationCount; count++) {
if (returnValue) {
const onDestroyListener = (): void => {
if (options.shouldClosePopup) {
closeProfileAuthPopup({ forceClose: true })
}
Platform.removeListenersForEvent(responseEvent)
return returnValue
}
await sleep(pollingInterval)
}

Platform.removeListenersForEvent(responseEvent)
return Promise.reject(localize('error.ledger.timeout'))
const timeoutId = setTimeout(() => {
onDestroyListener()
reject(localize('error.ledger.timeout'))
}, options.timeout)

Platform.onEvent(responseEvent, (value) => {
onDestroyListener()
clearTimeout(timeoutId)
resolve(<R>value)
})
})
}

private static userEnablesBlindSigning(): Promise<void> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { MILLISECONDS_PER_SECOND } from '@core/utils'
import { ILedgerApiRequestOptions } from '../interfaces'

export const DEFAULT_LEDGER_API_REQUEST_OPTIONS: ILedgerApiRequestOptions = {
timeout: 60 * MILLISECONDS_PER_SECOND, // In milliseconds
pollingInterval: 100, // In milliseconds
shouldClosePopup: true,
timeout: 60 * MILLISECONDS_PER_SECOND,
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export interface ILedgerApiRequestOptions {
timeout: number
pollingInterval: number
shouldClosePopup: boolean
}

0 comments on commit d68f4e9

Please sign in to comment.