From ce1ee516db3962cb502c7f7d4c4392a47df9031f Mon Sep 17 00:00:00 2001 From: kevin <35275952+kaladinlight@users.noreply.github.com> Date: Mon, 9 Sep 2024 16:51:20 -0600 Subject: [PATCH] feat: ledger app gate event emitter (#7697) --- .../cosmossdk/cosmos/CosmosChainAdapter.ts | 8 +- .../thorchain/ThorchainChainAdapter.ts | 8 +- .../chain-adapters/src/evm/EvmBaseAdapter.ts | 25 +++- packages/chain-adapters/src/utils/index.ts | 1 + .../chain-adapters/src/utils/ledgerAppGate.ts | 121 ++++++++++++++++ .../src/utxo/UtxoBaseAdapter.ts | 9 +- src/assets/translations/en/main.json | 2 +- .../ManageAccountsDrawer.tsx | 14 +- .../LedgerOpenApp/LedgerOpenAppModal.tsx | 28 ++-- .../hooks/useLedgerAppDetails.tsx | 58 -------- .../Send/hooks/useFormSend/useFormSend.tsx | 11 +- src/components/Modals/Send/utils.ts | 3 - .../components/ApprovalStep.tsx | 7 +- .../components/HopTransactionStep.tsx | 18 +-- .../VerifyAddresses/VerifyAddresses.tsx | 25 +--- src/components/Sweep.tsx | 14 +- src/context/AppProvider/AppContext.tsx | 33 ++++- .../fox-farming/hooks/useFoxFarming.ts | 33 +---- .../Deposit/components/Approve.tsx | 5 - .../Deposit/components/Confirm.tsx | 5 - .../Withdraw/components/Approve.tsx | 5 - .../Withdraw/components/Confirm.tsx | 5 - .../Deposit/components/Approve.tsx | 5 - .../univ2/hooks/useUniV2LiquidityPool.ts | 15 +- .../useLedgerOpenApp/useLedgerOpenApp.tsx | 132 ------------------ src/lib/account/utxo.ts | 26 +--- .../utils/thorchain/hooks/useSendThorTx.tsx | 11 +- .../Pool/components/Borrow/BorrowConfirm.tsx | 6 +- .../ChangeAddress/ChangeAddressConfirm.tsx | 12 +- .../RFOX/components/Claim/ClaimConfirm.tsx | 12 +- .../components/Stake/Bridge/BridgeConfirm.tsx | 19 +-- .../components/Stake/Bridge/BridgeStatus.tsx | 14 +- .../RFOX/components/Stake/StakeConfirm.tsx | 27 +--- .../components/Unstake/UnstakeConfirm.tsx | 12 +- .../AddLiquidity/AddLiquidityInput.tsx | 7 - .../useStakingAction/useStakingAction.tsx | 3 - src/setupVitest.ts | 5 +- 37 files changed, 260 insertions(+), 484 deletions(-) create mode 100644 packages/chain-adapters/src/utils/ledgerAppGate.ts delete mode 100644 src/components/Modals/LedgerOpenApp/hooks/useLedgerAppDetails.tsx delete mode 100644 src/hooks/useLedgerOpenApp/useLedgerOpenApp.tsx diff --git a/packages/chain-adapters/src/cosmossdk/cosmos/CosmosChainAdapter.ts b/packages/chain-adapters/src/cosmossdk/cosmos/CosmosChainAdapter.ts index daf5cafd436..0992f2c06a4 100644 --- a/packages/chain-adapters/src/cosmossdk/cosmos/CosmosChainAdapter.ts +++ b/packages/chain-adapters/src/cosmossdk/cosmos/CosmosChainAdapter.ts @@ -21,7 +21,7 @@ import type { SignTxInput, } from '../../types' import { ChainAdapterDisplayName, CONTRACT_INTERACTION } from '../../types' -import { bnOrZero, toAddressNList } from '../../utils' +import { bnOrZero, toAddressNList, verifyLedgerAppOpen } from '../../utils' import { assertAddressNotSanctioned } from '../../utils/validateAddress' import type { ChainAdapterArgs as BaseChainAdapterArgs } from '../CosmosSdkBaseAdapter' import { assertIsValidatorAddress, CosmosSdkBaseAdapter, Denoms } from '../CosmosSdkBaseAdapter' @@ -95,14 +95,18 @@ export class ChainAdapter extends CosmosSdkBaseAdapter implements IChainAdap throw new Error(`wallet does not support ${this.getDisplayName()}`) } - await this.assertSwitchChain(input.wallet) - const from = await this.getAddress(input) const txToSign = await this.buildSendApiTransaction({ ...input, from }) @@ -407,8 +410,11 @@ export abstract class EvmBaseAdapter implements IChainAdap try { const { txToSign, wallet } = signTxInput - if (!this.supportsChain(wallet, txToSign.chainId)) + if (!this.supportsChain(wallet, txToSign.chainId)) { throw new Error(`wallet does not support chain reference: ${txToSign.chainId}`) + } + + await verifyLedgerAppOpen(this.chainId, wallet) const signedTx = await wallet.ethSignTx(txToSign) @@ -468,6 +474,7 @@ export abstract class EvmBaseAdapter implements IChainAdap throw new Error(`wallet does not support ${this.getDisplayName()}`) await this.assertSwitchChain(wallet) + await verifyLedgerAppOpen(this.chainId, wallet) const signedMessage = await wallet.ethSignMessage(messageToSign) @@ -492,6 +499,7 @@ export abstract class EvmBaseAdapter implements IChainAdap } await this.assertSwitchChain(wallet) + await verifyLedgerAppOpen(this.chainId, wallet) const result = await wallet.ethSignTypedData(typedDataToSign) @@ -511,6 +519,13 @@ export abstract class EvmBaseAdapter implements IChainAdap return input.pubKey } + if (!this.supportsChain(wallet)) { + throw new Error(`wallet does not support ${this.getDisplayName()}`) + } + + await this.assertSwitchChain(wallet) + await verifyLedgerAppOpen(this.chainId, wallet) + const address = await (wallet as ETHWallet).ethGetAddress({ addressNList: toAddressNList(bip44Params), showDisplay: showOnDevice, @@ -602,8 +617,6 @@ export abstract class EvmBaseAdapter implements IChainAdap throw new Error(`wallet does not support ${this.getDisplayName()}`) } - await this.assertSwitchChain(wallet) - const from = await this.getAddress({ accountNumber, wallet }) const txToSign = await this.buildCustomApiTx({ ...input, from }) diff --git a/packages/chain-adapters/src/utils/index.ts b/packages/chain-adapters/src/utils/index.ts index 3b32e75c39f..cacfec3cd12 100644 --- a/packages/chain-adapters/src/utils/index.ts +++ b/packages/chain-adapters/src/utils/index.ts @@ -5,6 +5,7 @@ export * from './bignumber' export * from './bip44' export * from './fees' export * from './utxoUtils' +export * from './ledgerAppGate' export const getAssetNamespace = (type: string): AssetNamespace => { if (type === 'ERC20') return 'erc20' diff --git a/packages/chain-adapters/src/utils/ledgerAppGate.ts b/packages/chain-adapters/src/utils/ledgerAppGate.ts new file mode 100644 index 00000000000..4729834041b --- /dev/null +++ b/packages/chain-adapters/src/utils/ledgerAppGate.ts @@ -0,0 +1,121 @@ +import type { ChainId } from '@shapeshiftoss/caip' +import type { HDWallet } from '@shapeshiftoss/hdwallet-core' +import { isLedger } from '@shapeshiftoss/hdwallet-ledger' +import { KnownChainIds } from '@shapeshiftoss/types' +import EventEmitter from 'events' + +export const emitter = new EventEmitter() + +export type LedgerOpenAppEventArgs = { + chainId: ChainId + reject: (reason?: any) => void +} + +export const getLedgerAppName = (chainId: ChainId | KnownChainIds | undefined) => { + switch (chainId as KnownChainIds) { + case KnownChainIds.ArbitrumMainnet: + case KnownChainIds.AvalancheMainnet: + case KnownChainIds.ArbitrumNovaMainnet: + case KnownChainIds.BaseMainnet: + case KnownChainIds.BnbSmartChainMainnet: + case KnownChainIds.EthereumMainnet: + case KnownChainIds.GnosisMainnet: + case KnownChainIds.OptimismMainnet: + case KnownChainIds.PolygonMainnet: + return 'Ethereum' + case KnownChainIds.BitcoinCashMainnet: + return 'Bitcoin Cash' + case KnownChainIds.BitcoinMainnet: + return 'Bitcoin' + case KnownChainIds.CosmosMainnet: + return 'Cosmos' + case KnownChainIds.DogecoinMainnet: + return 'Dogecoin' + case KnownChainIds.LitecoinMainnet: + return 'Litecoin' + case KnownChainIds.ThorchainMainnet: + return 'THORChain' + default: + throw Error(`Unsupported chainId: ${chainId}`) + } +} + +const getCoin = (chainId: ChainId | KnownChainIds) => { + switch (chainId as KnownChainIds) { + case KnownChainIds.BitcoinMainnet: + return 'Bitcoin' + case KnownChainIds.DogecoinMainnet: + return 'Dogecoin' + case KnownChainIds.BitcoinCashMainnet: + return 'BitcoinCash' + case KnownChainIds.LitecoinMainnet: + return 'Litecoin' + case KnownChainIds.EthereumMainnet: + return 'Ethereum' + case KnownChainIds.AvalancheMainnet: + return 'Avalanche' + case KnownChainIds.OptimismMainnet: + return 'Optimism' + case KnownChainIds.BnbSmartChainMainnet: + return 'BnbSmartChain' + case KnownChainIds.PolygonMainnet: + return 'Polygon' + case KnownChainIds.GnosisMainnet: + return 'Gnosis' + case KnownChainIds.ArbitrumMainnet: + return 'Arbitrum' + case KnownChainIds.ArbitrumNovaMainnet: + return 'ArbitrumNova' + case KnownChainIds.BaseMainnet: + return 'Base' + case KnownChainIds.ThorchainMainnet: + return 'Rune' + case KnownChainIds.CosmosMainnet: + return 'Atom' + default: + throw Error(`Unsupported chainId: ${chainId}`) + } +} + +export const verifyLedgerAppOpen = async (chainId: ChainId | KnownChainIds, wallet: HDWallet) => { + const coin = getCoin(chainId) + const appName = getLedgerAppName(chainId) + + if (!isLedger(wallet)) return + + const isAppOpen = async () => { + try { + await wallet.validateCurrentApp(coin) + return true + } catch { + return false + } + } + + if (await isAppOpen()) return + + let intervalId: NodeJS.Timer | undefined + + try { + await new Promise((resolve, reject) => { + // emit event to trigger modal open + const args: LedgerOpenAppEventArgs = { chainId, reject } + emitter.emit('LedgerOpenApp', args) + + // prompt user to open app on device + wallet.openApp(appName) + + intervalId = setInterval(async () => { + if (!(await isAppOpen())) return + + // emit event to trigger modal close + emitter.emit('LedgerAppOpened') + clearInterval(intervalId) + resolve() + }, 1000) + }) + } catch { + clearInterval(intervalId) + throw new Error('Ledger app open cancelled') + } +} diff --git a/packages/chain-adapters/src/utxo/UtxoBaseAdapter.ts b/packages/chain-adapters/src/utxo/UtxoBaseAdapter.ts index 61c00baee13..c19c4f1d1e7 100644 --- a/packages/chain-adapters/src/utxo/UtxoBaseAdapter.ts +++ b/packages/chain-adapters/src/utxo/UtxoBaseAdapter.ts @@ -46,6 +46,7 @@ import { convertXpubVersion, toAddressNList, toRootDerivationPath, + verifyLedgerAppOpen, } from '../utils' import { bn, bnOrZero } from '../utils/bignumber' import { assertAddressNotSanctioned } from '../utils/validateAddress' @@ -240,9 +241,11 @@ export abstract class UtxoBaseAdapter implements IChainAd const targetIndex = bip44Params.index ?? nextIndex ?? 0 - const address = await (() => { + const address = await (async () => { if (pubKey) return account?.chainSpecific.addresses?.[targetIndex]?.pubkey + await verifyLedgerAppOpen(this.chainId, wallet) + return wallet.btcGetAddress({ addressNList: toAddressNList({ ...bip44Params, index: targetIndex }), coin: this.coinName, @@ -435,6 +438,8 @@ export abstract class UtxoBaseAdapter implements IChainAd throw new Error(`UtxoBaseAdapter: wallet does not support ${this.coinName}`) } + await verifyLedgerAppOpen(this.chainId, wallet) + const signedTx = await wallet.btcSignTx(txToSign) if (!signedTx?.serializedTx) throw new Error('UtxoBaseAdapter: error signing tx') @@ -549,6 +554,8 @@ export abstract class UtxoBaseAdapter implements IChainAd ): Promise { this.assertIsAccountTypeSupported(accountType) + await verifyLedgerAppOpen(this.chainId, wallet) + const bip44Params = this.getBIP44Params({ accountNumber, accountType }) const path = toRootDerivationPath(bip44Params) const publicKeys = await wallet.getPublicKeys([ diff --git a/src/assets/translations/en/main.json b/src/assets/translations/en/main.json index 9943026755a..f521ac04001 100644 --- a/src/assets/translations/en/main.json +++ b/src/assets/translations/en/main.json @@ -1889,7 +1889,7 @@ "ledgerOpenApp": { "title": "Open the %{appName} App", "description": "To continue, you will need to open the %{appName} app on your Ledger device.", - "signingDescription": "Signing prompt will automatically pop-up in your device after opening the app" + "devicePrompt": "Your device will prompt you with any necessary steps required to complete your current action." }, "loremIpsum": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut sed lectus efficitur, iaculis sapien eu, luctus tellus. Maecenas eget sapien dignissim, finibus mauris nec, mollis ipsum. Donec sodales sit amet felis sagittis vestibulum. Ut in consectetur lacus. Suspendisse potenti. Aenean at massa consequat lectus semper pretium. Cras sed bibendum enim. Mauris euismod sit amet dolor in placerat.", "transactionHistory": { diff --git a/src/components/ManageAccountsDrawer/ManageAccountsDrawer.tsx b/src/components/ManageAccountsDrawer/ManageAccountsDrawer.tsx index 51c0bff7e77..c5227935ab1 100644 --- a/src/components/ManageAccountsDrawer/ManageAccountsDrawer.tsx +++ b/src/components/ManageAccountsDrawer/ManageAccountsDrawer.tsx @@ -1,6 +1,5 @@ import type { ChainId } from '@shapeshiftoss/caip' import { useCallback, useEffect, useMemo, useState } from 'react' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { useWallet } from 'hooks/useWallet/useWallet' import { assertUnreachable } from 'lib/utils' @@ -25,8 +24,6 @@ export const ManageAccountsDrawer = ({ const [step, setStep] = useState('selectChain') const [selectedChainId, setSelectedChainId] = useState(null) - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: false }) - const handleClose = useCallback(() => { setStep('selectChain') onClose() @@ -66,16 +63,11 @@ export const ManageAccountsDrawer = ({ }, [parentSelectedChainId]) const handleSelectChainId = useCallback( - async (chainId: ChainId) => { + (chainId: ChainId) => { setSelectedChainId(chainId) - - // Only proceed to next step if the promise is resolved, i.e the user has opened the Ledger - // app without cancelling - await checkLedgerAppOpenIfLedgerConnected(chainId) - .then(() => handleNext()) - .catch(console.error) + handleNext() }, - [checkLedgerAppOpenIfLedgerConnected, handleNext], + [handleNext], ) const drawerContent = useMemo(() => { diff --git a/src/components/Modals/LedgerOpenApp/LedgerOpenAppModal.tsx b/src/components/Modals/LedgerOpenApp/LedgerOpenAppModal.tsx index a95a9300cc8..3d71880f3c3 100644 --- a/src/components/Modals/LedgerOpenApp/LedgerOpenAppModal.tsx +++ b/src/components/Modals/LedgerOpenApp/LedgerOpenAppModal.tsx @@ -10,26 +10,36 @@ import { Spinner, VStack, } from '@chakra-ui/react' -import type { ChainId } from '@shapeshiftoss/caip' -import { useCallback } from 'react' +import { type ChainId, ethAssetId } from '@shapeshiftoss/caip' +import { getLedgerAppName, isEvmChainId } from '@shapeshiftoss/chain-adapters' +import { useCallback, useMemo } from 'react' import { useTranslate } from 'react-polyglot' import { RawText } from 'components/Text' import { useModal } from 'hooks/useModal/useModal' +import { selectAssetById, selectFeeAssetByChainId } from 'state/slices/selectors' +import { useAppSelector } from 'state/store' import { AssetOnLedger } from './components/AssetOnLedger' -import { useLedgerAppDetails } from './hooks/useLedgerAppDetails' export type LedgerOpenAppModalProps = { chainId: ChainId onCancel: () => void - isSigning: boolean } -export const LedgerOpenAppModal = ({ chainId, onCancel, isSigning }: LedgerOpenAppModalProps) => { - const { close: closeModal, isOpen } = useModal('ledgerOpenApp') +export const LedgerOpenAppModal = ({ chainId, onCancel }: LedgerOpenAppModalProps) => { const translate = useTranslate() + const feeAsset = useAppSelector(state => selectFeeAssetByChainId(state, chainId)) + const ethAsset = useAppSelector(state => selectAssetById(state, ethAssetId)) + const { close: closeModal, isOpen } = useModal('ledgerOpenApp') + + const appName = useMemo(() => { + return getLedgerAppName(chainId) + }, [chainId]) - const { appName, appAsset } = useLedgerAppDetails(chainId) + const appAsset = useMemo(() => { + if (isEvmChainId(chainId)) return ethAsset + return feeAsset + }, [feeAsset, chainId, ethAsset]) const handleClose = useCallback(() => { closeModal() @@ -57,9 +67,7 @@ export const LedgerOpenAppModal = ({ chainId, onCancel, isSigning }: LedgerOpenA appName, })} - {isSigning ? ( - {translate('ledgerOpenApp.signingDescription')} - ) : null} + {translate('ledgerOpenApp.devicePrompt')} diff --git a/src/components/Modals/LedgerOpenApp/hooks/useLedgerAppDetails.tsx b/src/components/Modals/LedgerOpenApp/hooks/useLedgerAppDetails.tsx deleted file mode 100644 index bd257a1e217..00000000000 --- a/src/components/Modals/LedgerOpenApp/hooks/useLedgerAppDetails.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import type { ChainId } from '@shapeshiftoss/caip' -import { ethAssetId } from '@shapeshiftoss/caip' -import { isEvmChainId } from '@shapeshiftoss/chain-adapters' -import { KnownChainIds } from '@shapeshiftoss/types' -import { assertUnreachable } from '@shapeshiftoss/utils' -import { useMemo } from 'react' -import { selectAssetById, selectFeeAssetByChainId } from 'state/slices/selectors' -import { useAppSelector } from 'state/store' - -// Note these are hardcoded to the ledger app names that are currently supported by the Ledger SDK. -// The name is used by the SDK to prompt the user to open the correct app on their device. A -// mismatch will cause the this feature to break. Be careful when modifying these, as it could break -// Ledger device support. -export const getLedgerAppName = (_chainId: ChainId) => { - const chainId = _chainId as KnownChainIds - switch (chainId) { - case KnownChainIds.ArbitrumMainnet: - case KnownChainIds.AvalancheMainnet: - case KnownChainIds.ArbitrumNovaMainnet: - case KnownChainIds.BaseMainnet: - case KnownChainIds.BnbSmartChainMainnet: - case KnownChainIds.EthereumMainnet: - case KnownChainIds.GnosisMainnet: - case KnownChainIds.OptimismMainnet: - case KnownChainIds.PolygonMainnet: - return 'Ethereum' - case KnownChainIds.BitcoinCashMainnet: - return 'Bitcoin Cash' - case KnownChainIds.BitcoinMainnet: - return 'Bitcoin' - case KnownChainIds.CosmosMainnet: - return 'Cosmos' - case KnownChainIds.DogecoinMainnet: - return 'Dogecoin' - case KnownChainIds.LitecoinMainnet: - return 'Litecoin' - case KnownChainIds.ThorchainMainnet: - return 'THORChain' - default: - assertUnreachable(chainId) - } - - throw Error(`Unsupported chainId: ${chainId}`) -} - -export const useLedgerAppDetails = (chainId: ChainId) => { - const feeAsset = useAppSelector(state => selectFeeAssetByChainId(state, chainId)) - const ethAsset = useAppSelector(state => selectAssetById(state, ethAssetId)) - const appName = useMemo(() => { - return getLedgerAppName(chainId) - }, [chainId]) - const appAsset = useMemo(() => { - if (isEvmChainId(chainId)) return ethAsset - return feeAsset - }, [feeAsset, chainId, ethAsset]) - - return { appName, appAsset } -} diff --git a/src/components/Modals/Send/hooks/useFormSend/useFormSend.tsx b/src/components/Modals/Send/hooks/useFormSend/useFormSend.tsx index 9cc4c35cbda..138e220a58f 100644 --- a/src/components/Modals/Send/hooks/useFormSend/useFormSend.tsx +++ b/src/components/Modals/Send/hooks/useFormSend/useFormSend.tsx @@ -2,7 +2,6 @@ import { ExternalLinkIcon } from '@chakra-ui/icons' import { Link, Text, useToast } from '@chakra-ui/react' import { useCallback } from 'react' import { useTranslate } from 'react-polyglot' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { useModal } from 'hooks/useModal/useModal' import { useWallet } from 'hooks/useWallet/useWallet' import { selectAssetById } from 'state/slices/selectors' @@ -20,8 +19,6 @@ export const useFormSend = () => { state: { wallet }, } = useWallet() - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) - const handleFormSend = useCallback( async (sendInput: SendInput) => { try { @@ -29,11 +26,7 @@ export const useFormSend = () => { if (!asset) throw new Error(`No asset found for assetId ${sendInput.assetId}`) if (!wallet) throw new Error('No wallet connected') - const broadcastTXID = await handleSend({ - wallet, - sendInput, - checkLedgerAppOpenIfLedgerConnected, - }) + const broadcastTXID = await handleSend({ wallet, sendInput }) setTimeout(() => { toast({ @@ -79,7 +72,7 @@ export const useFormSend = () => { send.close() } }, - [checkLedgerAppOpenIfLedgerConnected, qrCode, send, toast, translate, wallet], + [qrCode, send, toast, translate, wallet], ) return { diff --git a/src/components/Modals/Send/utils.ts b/src/components/Modals/Send/utils.ts index 99acc88ca4a..cd0c812d2f6 100644 --- a/src/components/Modals/Send/utils.ts +++ b/src/components/Modals/Send/utils.ts @@ -91,18 +91,15 @@ export const estimateFees = ({ export const handleSend = async ({ sendInput, wallet, - checkLedgerAppOpenIfLedgerConnected, }: { sendInput: SendInput wallet: HDWallet - checkLedgerAppOpenIfLedgerConnected: (chainId: ChainId) => Promise }): Promise => { const state = store.getState() const asset = selectAssetById(state, sendInput.assetId ?? '') if (!asset) return '' const chainId = asset.chainId - await checkLedgerAppOpenIfLedgerConnected(chainId) const supportedEvmChainIds = getSupportedEvmChainIds() const acccountMetadataFilter = { accountId: sendInput.accountId } diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/ApprovalStep.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/ApprovalStep.tsx index af0f774afbf..63d4c77ed60 100644 --- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/ApprovalStep.tsx +++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/ApprovalStep.tsx @@ -19,7 +19,6 @@ import { MiddleEllipsis } from 'components/MiddleEllipsis/MiddleEllipsis' import { Row } from 'components/Row/Row' import { Text } from 'components/Text' import { AllowanceType } from 'hooks/queries/useApprovalFees' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { useLocaleFormatter } from 'hooks/useLocaleFormatter/useLocaleFormatter' import { useToggle } from 'hooks/useToggle/useToggle' import { fromBaseUnit } from 'lib/math' @@ -123,7 +122,6 @@ const ApprovalStepPending = ({ // Default to exact allowance for LiFi due to contract vulnerabilities const [isExactAllowance, toggleIsExactAllowance] = useToggle(isLifiStep ? true : false) - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) const hopExecutionMetadataFilter = useMemo(() => { return { tradeId: activeTradeId, @@ -160,10 +158,7 @@ const ApprovalStepPending = ({ }, [isAllowanceResetStep, state]) const handleSignAllowanceApproval = useCallback(async () => { - // Only proceed to execute the approval if the promise is resolved, i.e the user has opened the - // Ledger app without cancelling try { - await checkLedgerAppOpenIfLedgerConnected(tradeQuoteStep.sellAsset.chainId) setFeeQueryEnabled(false) await approveMutation.mutateAsync() } catch (error) { @@ -171,7 +166,7 @@ const ApprovalStepPending = ({ } finally { setFeeQueryEnabled(true) } - }, [approveMutation, checkLedgerAppOpenIfLedgerConnected, tradeQuoteStep.sellAsset.chainId]) + }, [approveMutation]) const feeAsset = useAppSelector(state => selectFeeAssetById(state, tradeQuoteStep.sellAsset.assetId), diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/HopTransactionStep.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/HopTransactionStep.tsx index 3beff8a2c26..07aad36d175 100644 --- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/HopTransactionStep.tsx +++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/HopTransactionStep.tsx @@ -16,7 +16,6 @@ import { MiddleEllipsis } from 'components/MiddleEllipsis/MiddleEllipsis' import { RawText, Text } from 'components/Text' import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton' import { useSafeTxQuery } from 'hooks/queries/useSafeTx' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { useLocaleFormatter } from 'hooks/useLocaleFormatter/useLocaleFormatter' import { getTxLink } from 'lib/getTxLink' import { fromBaseUnit } from 'lib/math' @@ -56,8 +55,6 @@ export const HopTransactionStep = ({ } = useLocaleFormatter() const translate = useTranslate() - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) - const hopExecutionMetadataFilter = useMemo(() => { return { tradeId: activeTradeId, @@ -73,23 +70,14 @@ export const HopTransactionStep = ({ const executeTrade = useTradeExecution(hopIndex, activeTradeId) - const handleSignTx = useCallback(async () => { + const handleSignTx = useCallback(() => { if (swapTxState !== TransactionExecutionState.AwaitingConfirmation) { console.error('attempted to execute in-progress swap') return } - // Only proceed to execute the trade if the promise is resolved, i.e the user has opened the - // Ledger app without cancelling - await checkLedgerAppOpenIfLedgerConnected(tradeQuoteStep.sellAsset.chainId) - .then(() => executeTrade()) - .catch(console.error) - }, [ - checkLedgerAppOpenIfLedgerConnected, - executeTrade, - swapTxState, - tradeQuoteStep.sellAsset.chainId, - ]) + executeTrade() + }, [executeTrade, swapTxState]) const isBridge = useMemo( () => tradeQuoteStep.buyAsset.chainId !== tradeQuoteStep.sellAsset.chainId, diff --git a/src/components/MultiHopTrade/components/VerifyAddresses/VerifyAddresses.tsx b/src/components/MultiHopTrade/components/VerifyAddresses/VerifyAddresses.tsx index cda7afda58e..ec8d6ae81d3 100644 --- a/src/components/MultiHopTrade/components/VerifyAddresses/VerifyAddresses.tsx +++ b/src/components/MultiHopTrade/components/VerifyAddresses/VerifyAddresses.tsx @@ -26,7 +26,6 @@ import { SlideTransition } from 'components/SlideTransition' import { RawText, Text } from 'components/Text' import type { TextPropTypes } from 'components/Text/Text' import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { useWallet } from 'hooks/useWallet/useWallet' import { walletSupportsChain } from 'hooks/useWalletSupportsChain/useWalletSupportsChain' import { @@ -287,23 +286,13 @@ export const VerifyAddresses = () => { ], ) - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) - - const handleBuyVerify = useCallback(async () => { - // Only proceed to verify the buy address if the promise is resolved, i.e the user has opened - // the Ledger app without cancelling - await checkLedgerAppOpenIfLedgerConnected(buyAsset.chainId) - .then(() => handleVerify(AddressVerificationType.Buy)) - .catch(console.error) - }, [checkLedgerAppOpenIfLedgerConnected, handleVerify, buyAsset.chainId]) - - const handleSellVerify = useCallback(async () => { - // Only proceed to verify the sell address if the promise is resolved, i.e the user has opened - // the Ledger app without cancelling - await checkLedgerAppOpenIfLedgerConnected(sellAsset.chainId) - .then(() => handleVerify(AddressVerificationType.Sell)) - .catch(console.error) - }, [checkLedgerAppOpenIfLedgerConnected, handleVerify, sellAsset.chainId]) + const handleBuyVerify = useCallback(() => { + handleVerify(AddressVerificationType.Buy) + }, [handleVerify]) + + const handleSellVerify = useCallback(() => { + handleVerify(AddressVerificationType.Sell) + }, [handleVerify]) const verifyBuyAssetTranslation: TextPropTypes['translation'] = useMemo( () => ['trade.verifyAsset', { asset: buyAsset.symbol }], diff --git a/src/components/Sweep.tsx b/src/components/Sweep.tsx index cd4c32d56a8..2fae6ae2e8d 100644 --- a/src/components/Sweep.tsx +++ b/src/components/Sweep.tsx @@ -4,7 +4,6 @@ import { FeeDataKey } from '@shapeshiftoss/chain-adapters' import { useCallback, useEffect, useState } from 'react' import { useTranslate } from 'react-polyglot' import { Row } from 'components/Row/Row' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { useWallet } from 'hooks/useWallet/useWallet' import { fromBaseUnit } from 'lib/math' import { sleep } from 'lib/poll/poll' @@ -37,8 +36,6 @@ export const Sweep = ({ const [isSweepPending, setIsSweepPending] = useState(false) const [txId, setTxId] = useState(null) - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) - const { state: { wallet }, } = useWallet() @@ -86,19 +83,12 @@ export const Sweep = ({ fiatSymbol: '', } - const txId = await handleSend({ wallet, sendInput, checkLedgerAppOpenIfLedgerConnected }) + const txId = await handleSend({ wallet, sendInput }) setTxId(txId) } catch (e) { console.error(e) } - }, [ - accountId, - assetId, - checkLedgerAppOpenIfLedgerConnected, - estimatedFeesData, - fromAddress, - wallet, - ]) + }, [accountId, assetId, estimatedFeesData, fromAddress, wallet]) const adapter = assertGetUtxoChainAdapter(fromAssetId(assetId).chainId) diff --git a/src/context/AppProvider/AppContext.tsx b/src/context/AppProvider/AppContext.tsx index 9204be35065..e031742ecc5 100644 --- a/src/context/AppProvider/AppContext.tsx +++ b/src/context/AppProvider/AppContext.tsx @@ -1,5 +1,8 @@ import { usePrevious, useToast } from '@chakra-ui/react' import { fromAccountId } from '@shapeshiftoss/caip' +import type { LedgerOpenAppEventArgs } from '@shapeshiftoss/chain-adapters' +import { emitter } from '@shapeshiftoss/chain-adapters' +import { isLedger } from '@shapeshiftoss/hdwallet-ledger' import { MetaMaskShapeShiftMultiChainHDWallet } from '@shapeshiftoss/hdwallet-shapeshift-multichain' import type { AccountMetadataById } from '@shapeshiftoss/types' import { useQueries } from '@tanstack/react-query' @@ -12,6 +15,7 @@ import { useNfts } from 'components/Nfts/hooks/useNfts' import { usePlugins } from 'context/PluginProvider/PluginProvider' import { useIsSnapInstalled } from 'hooks/useIsSnapInstalled/useIsSnapInstalled' import { useMixpanelPortfolioTracking } from 'hooks/useMixpanelPortfolioTracking/useMixpanelPortfolioTracking' +import { useModal } from 'hooks/useModal/useModal' import { useRouteAssetId } from 'hooks/useRouteAssetId/useRouteAssetId' import { useWallet } from 'hooks/useWallet/useWallet' import { walletSupportsChain } from 'hooks/useWalletSupportsChain/useWalletSupportsChain' @@ -61,6 +65,31 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => { const routeAssetId = useRouteAssetId() const isSnapInstalled = Boolean(useIsSnapInstalled()) const previousIsSnapInstalled = usePrevious(isSnapInstalled) + const { close: closeModal, open: openModal } = useModal('ledgerOpenApp') + + useEffect(() => { + const handleLedgerOpenApp = ({ chainId, reject }: LedgerOpenAppEventArgs) => { + const onCancel = () => { + closeModal() + reject() + } + + openModal({ chainId, onCancel }) + } + + const handleLedgerAppOpened = () => { + closeModal() + } + + emitter.on('LedgerOpenApp', handleLedgerOpenApp) + emitter.on('LedgerAppOpened', handleLedgerAppOpened) + + return () => { + emitter.off('LedgerOpenApp', handleLedgerOpenApp) + emitter.off('LedgerAppOpened', handleLedgerAppOpened) + } + }) + useNfts() // track anonymous portfolio @@ -126,9 +155,7 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => { return } - if (!wallet) { - return - } + if (!wallet || isLedger(wallet)) return let chainIds = supportedChains.filter(chainId => { return walletSupportsChain({ diff --git a/src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts b/src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts index 55b49f0331a..2ab2f77e333 100644 --- a/src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts +++ b/src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts @@ -9,7 +9,6 @@ import { supportsETH } from '@shapeshiftoss/hdwallet-core' import { useCallback, useMemo } from 'react' import { encodeFunctionData, getAddress, maxUint256 } from 'viem' import { useFoxEth } from 'context/FoxEthProvider/FoxEthProvider' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { useWallet } from 'hooks/useWallet/useWallet' import { toBaseUnit } from 'lib/math' import { isValidAccountNumber } from 'lib/utils/accounts' @@ -38,8 +37,6 @@ export const useFoxFarming = ( contractAddress: FoxEthStakingContractAddress, { skip }: UseFoxFarmingOptions = {}, ) => { - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) - const { farmingAccountId } = useFoxEth() const ethAsset = useAppSelector(state => selectAssetById(state, ethAssetId)) const lpAsset = useAppSelector(state => selectAssetById(state, foxEthLpAssetId)) @@ -86,8 +83,6 @@ export const useFoxFarming = ( wallet, }) - await checkLedgerAppOpenIfLedgerConnected(ethChainId) - const txid = await buildAndBroadcast({ adapter, buildCustomTxInput, @@ -108,7 +103,6 @@ export const useFoxFarming = ( lpAsset.precision, adapter, contractAddress, - checkLedgerAppOpenIfLedgerConnected, ], ) @@ -133,8 +127,6 @@ export const useFoxFarming = ( wallet, }) - await checkLedgerAppOpenIfLedgerConnected(ethChainId) - const txid = await buildAndBroadcast({ adapter, buildCustomTxInput, @@ -155,7 +147,6 @@ export const useFoxFarming = ( lpAsset.precision, adapter, contractAddress, - checkLedgerAppOpenIfLedgerConnected, ], ) @@ -281,8 +272,6 @@ export const useFoxFarming = ( const fees = await getApproveFees() if (!fees) return - await checkLedgerAppOpenIfLedgerConnected(ethChainId) - const txid = await buildAndBroadcast({ adapter, receiverAddress: CONTRACT_INTERACTION, // no receiver for this contract call @@ -297,14 +286,7 @@ export const useFoxFarming = ( }) return txid - }, [ - accountNumber, - adapter, - checkLedgerAppOpenIfLedgerConnected, - contractAddress, - getApproveFees, - wallet, - ]) + }, [accountNumber, adapter, contractAddress, getApproveFees, wallet]) const claimRewards = useCallback(async () => { if (skip || !isValidAccountNumber(accountNumber) || !wallet || !userAddress) return @@ -324,8 +306,6 @@ export const useFoxFarming = ( wallet, }) - await checkLedgerAppOpenIfLedgerConnected(ethChainId) - const txid = await buildAndBroadcast({ adapter, buildCustomTxInput, @@ -333,16 +313,7 @@ export const useFoxFarming = ( }) return txid - }, [ - accountNumber, - adapter, - checkLedgerAppOpenIfLedgerConnected, - contractAddress, - foxFarmingContract.abi, - skip, - userAddress, - wallet, - ]) + }, [accountNumber, adapter, contractAddress, foxFarmingContract.abi, skip, userAddress, wallet]) return { allowance, diff --git a/src/features/defi/providers/foxy/components/FoxyManager/Deposit/components/Approve.tsx b/src/features/defi/providers/foxy/components/FoxyManager/Deposit/components/Approve.tsx index 064d6aaca55..b0bf5606ac9 100644 --- a/src/features/defi/providers/foxy/components/FoxyManager/Deposit/components/Approve.tsx +++ b/src/features/defi/providers/foxy/components/FoxyManager/Deposit/components/Approve.tsx @@ -12,7 +12,6 @@ import { useCallback, useContext, useMemo } from 'react' import { useTranslate } from 'react-polyglot' import { useHistory } from 'react-router-dom' import type { StepComponentProps } from 'components/DeFi/components/Steps' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { usePoll } from 'hooks/usePoll/usePoll' import { useWallet } from 'hooks/useWallet/useWallet' import { bn, bnOrZero } from 'lib/bignumber/bignumber' @@ -28,7 +27,6 @@ import { DepositContext } from '../DepositContext' type ApproveProps = StepComponentProps & { accountId: AccountId | undefined } export const Approve: React.FC = ({ accountId, onNext }) => { - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) const { poll } = usePoll() const foxyApi = getFoxyApi() const { state, dispatch } = useContext(DepositContext) @@ -112,8 +110,6 @@ export const Approve: React.FC = ({ accountId, onNext }) => { if (!supportsETH(walletState.wallet)) throw new Error(`handleApprove: wallet does not support ethereum`) - await checkLedgerAppOpenIfLedgerConnected(feeAsset.chainId) - await foxyApi.approve({ tokenContractAddress: assetReference, contractAddress, @@ -169,7 +165,6 @@ export const Approve: React.FC = ({ accountId, onNext }) => { bip44Params, state, feeAsset, - checkLedgerAppOpenIfLedgerConnected, contractAddress, asset.precision, poll, diff --git a/src/features/defi/providers/foxy/components/FoxyManager/Deposit/components/Confirm.tsx b/src/features/defi/providers/foxy/components/FoxyManager/Deposit/components/Confirm.tsx index 98cc8a5d1f7..d91eed5329a 100644 --- a/src/features/defi/providers/foxy/components/FoxyManager/Deposit/components/Confirm.tsx +++ b/src/features/defi/providers/foxy/components/FoxyManager/Deposit/components/Confirm.tsx @@ -16,7 +16,6 @@ import type { StepComponentProps } from 'components/DeFi/components/Steps' import { Row } from 'components/Row/Row' import { RawText, Text } from 'components/Text' import type { TextPropTypes } from 'components/Text/Text' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { usePoll } from 'hooks/usePoll/usePoll' import { useWallet } from 'hooks/useWallet/useWallet' import { bn, bnOrZero } from 'lib/bignumber/bignumber' @@ -33,7 +32,6 @@ import { DepositContext } from '../DepositContext' type ConfirmProps = StepComponentProps & { accountId: AccountId | undefined } export const Confirm: React.FC = ({ onNext, accountId }) => { - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) const { poll } = usePoll() const foxyApi = getFoxyApi() const { state, dispatch } = useContext(DepositContext) @@ -86,8 +84,6 @@ export const Confirm: React.FC = ({ onNext, accountId }) => { if (!supportsETH(walletState.wallet)) throw new Error(`handleDeposit: wallet does not support ethereum`) - await checkLedgerAppOpenIfLedgerConnected(feeAsset.chainId) - const txid = await foxyApi.deposit({ amountDesired: bnOrZero(state?.deposit.cryptoAmount) .times(bn(10).pow(asset.precision)) @@ -137,7 +133,6 @@ export const Confirm: React.FC = ({ onNext, accountId }) => { bip44Params, dispatch, feeAsset, - checkLedgerAppOpenIfLedgerConnected, state?.deposit.cryptoAmount, asset.precision, contractAddress, diff --git a/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/components/Approve.tsx b/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/components/Approve.tsx index b5d0401fb4b..6db3968468c 100644 --- a/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/components/Approve.tsx +++ b/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/components/Approve.tsx @@ -11,7 +11,6 @@ import { useFoxyQuery } from 'features/defi/providers/foxy/components/FoxyManage import { useCallback, useContext, useMemo } from 'react' import { useTranslate } from 'react-polyglot' import type { StepComponentProps } from 'components/DeFi/components/Steps' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { usePoll } from 'hooks/usePoll/usePoll' import { useWallet } from 'hooks/useWallet/useWallet' import { bn, bnOrZero } from 'lib/bignumber/bignumber' @@ -27,7 +26,6 @@ import { WithdrawContext } from '../WithdrawContext' type ApproveProps = StepComponentProps & { accountId: AccountId | undefined } export const Approve: React.FC = ({ accountId, onNext }) => { - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) const { poll } = usePoll() const foxyApi = getFoxyApi() const { state, dispatch } = useContext(WithdrawContext) @@ -128,8 +126,6 @@ export const Approve: React.FC = ({ accountId, onNext }) => { throw new Error(`handleApprove: wallet does not support ethereum`) dispatch({ type: FoxyWithdrawActionType.SET_LOADING, payload: true }) - await checkLedgerAppOpenIfLedgerConnected(feeAsset.chainId) - await foxyApi.approve({ tokenContractAddress: rewardId, contractAddress, @@ -173,7 +169,6 @@ export const Approve: React.FC = ({ accountId, onNext }) => { }, [ asset.precision, bip44Params, - checkLedgerAppOpenIfLedgerConnected, contractAddress, dispatch, estimatedGasCryptoBaseUnit, diff --git a/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/components/Confirm.tsx b/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/components/Confirm.tsx index d4c16e28da5..c88776b6423 100644 --- a/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/components/Confirm.tsx +++ b/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/components/Confirm.tsx @@ -17,7 +17,6 @@ import type { StepComponentProps } from 'components/DeFi/components/Steps' import { Row } from 'components/Row/Row' import { RawText, Text } from 'components/Text' import type { TextPropTypes } from 'components/Text/Text' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { usePoll } from 'hooks/usePoll/usePoll' import { useWallet } from 'hooks/useWallet/useWallet' import { bn, bnOrZero } from 'lib/bignumber/bignumber' @@ -35,7 +34,6 @@ export const Confirm: React.FC { - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) const { poll } = usePoll() const foxyApi = getFoxyApi() const { state, dispatch } = useContext(WithdrawContext) @@ -90,8 +88,6 @@ export const Confirm: React.FC = ({ accountId, onNext, isReset }) => { - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) const { poll } = usePoll() const { state, dispatch } = useContext(DepositContext) const estimatedGasCryptoPrecision = state?.approve.estimatedGasCryptoPrecision @@ -159,8 +157,6 @@ export const Approve: React.FC = ({ accountId, onNext, isReset }) const adapter = assertGetEvmChainAdapter(chainId) - await checkLedgerAppOpenIfLedgerConnected(asset.chainId) - const buildCustomTxInput = await createBuildCustomTxInput({ accountNumber, from: fromAccountId(accountId).account, @@ -217,7 +213,6 @@ export const Approve: React.FC = ({ accountId, onNext, isReset }) assetId, assets, chainId, - checkLedgerAppOpenIfLedgerConnected, dispatch, inboundAddress, isReset, diff --git a/src/features/defi/providers/univ2/hooks/useUniV2LiquidityPool.ts b/src/features/defi/providers/univ2/hooks/useUniV2LiquidityPool.ts index 92c53c3ddc4..eb0db66a92b 100644 --- a/src/features/defi/providers/univ2/hooks/useUniV2LiquidityPool.ts +++ b/src/features/defi/providers/univ2/hooks/useUniV2LiquidityPool.ts @@ -13,7 +13,6 @@ import isNumber from 'lodash/isNumber' import { useCallback, useMemo } from 'react' import type { Address } from 'viem' import { encodeFunctionData, getAddress, maxUint256 } from 'viem' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { useWallet } from 'hooks/useWallet/useWallet' import { bn, bnOrZero } from 'lib/bignumber/bignumber' import { fromBaseUnit, toBaseUnit } from 'lib/math' @@ -55,8 +54,6 @@ export const useUniV2LiquidityPool = ({ assetId1: AssetId lpAssetId: AssetId } & UseUniV2LiquidityPoolOptions) => { - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) - const assetId0OrWeth = assetId0 === ethAssetId ? wethAssetId : assetId0 const assetId1OrWeth = assetId1 === ethAssetId ? wethAssetId : assetId1 @@ -203,8 +200,6 @@ export const useUniV2LiquidityPool = ({ try { if (skip || !isNumber(accountNumber) || !uniswapRouterContract || !wallet) return - await checkLedgerAppOpenIfLedgerConnected(fromAssetId(assetId0OrWeth).chainId) - const maybeEthAmount = (() => { if (assetId0OrWeth === wethAssetId) return token0Amount if (assetId1OrWeth === wethAssetId) return token1Amount @@ -238,7 +233,6 @@ export const useUniV2LiquidityPool = ({ adapter, assetId0OrWeth, assetId1OrWeth, - checkLedgerAppOpenIfLedgerConnected, makeAddLiquidityData, skip, uniswapRouterContract, @@ -329,8 +323,6 @@ export const useUniV2LiquidityPool = ({ try { if (skip || !isNumber(accountNumber) || !uniswapRouterContract || !wallet) return - await checkLedgerAppOpenIfLedgerConnected(fromAssetId(assetId0OrWeth).chainId) - const data = makeRemoveLiquidityData({ asset0ContractAddress, asset1ContractAddress, @@ -365,8 +357,6 @@ export const useUniV2LiquidityPool = ({ accountNumber, uniswapRouterContract, wallet, - checkLedgerAppOpenIfLedgerConnected, - assetId0OrWeth, makeRemoveLiquidityData, asset0ContractAddress, asset1ContractAddress, @@ -605,9 +595,6 @@ export const useUniV2LiquidityPool = ({ async (contractAddress: Address) => { if (skip || !wallet || !isNumber(accountNumber)) return - // UNI-V2 is hardcoded to Ethereum Mainnet - await checkLedgerAppOpenIfLedgerConnected(ethChainId) - const contract = getOrCreateContractByType({ address: contractAddress, type: ContractType.ERC20, @@ -641,7 +628,7 @@ export const useUniV2LiquidityPool = ({ return txid }, - [accountNumber, adapter, checkLedgerAppOpenIfLedgerConnected, getApproveFees, skip, wallet], + [accountNumber, adapter, getApproveFees, skip, wallet], ) return { diff --git a/src/hooks/useLedgerOpenApp/useLedgerOpenApp.tsx b/src/hooks/useLedgerOpenApp/useLedgerOpenApp.tsx deleted file mode 100644 index deabc4de475..00000000000 --- a/src/hooks/useLedgerOpenApp/useLedgerOpenApp.tsx +++ /dev/null @@ -1,132 +0,0 @@ -import type { ChainId } from '@shapeshiftoss/caip' -import type { slip44Table } from '@shapeshiftoss/hdwallet-core' -import { isLedger } from '@shapeshiftoss/hdwallet-ledger' -import { KnownChainIds } from '@shapeshiftoss/types' -import { assertUnreachable } from '@shapeshiftoss/utils' -import { useCallback } from 'react' -import { getLedgerAppName } from 'components/Modals/LedgerOpenApp/hooks/useLedgerAppDetails' -import { useModal } from 'hooks/useModal/useModal' -import { useWallet } from 'hooks/useWallet/useWallet' - -type Slip44Key = keyof typeof slip44Table - -export const getSlip44KeyFromChainId = (chainId: ChainId): Slip44Key | undefined => { - const knownChainId = chainId as KnownChainIds - switch (knownChainId) { - // UTXO chains - case KnownChainIds.BitcoinMainnet: - return 'Bitcoin' - case KnownChainIds.DogecoinMainnet: - return 'Dogecoin' - case KnownChainIds.BitcoinCashMainnet: - return 'BitcoinCash' - case KnownChainIds.LitecoinMainnet: - return 'Litecoin' - // EVM chains - case KnownChainIds.EthereumMainnet: - return 'Ethereum' - case KnownChainIds.AvalancheMainnet: - return 'Avalanche' - case KnownChainIds.OptimismMainnet: - return 'Optimism' - case KnownChainIds.BnbSmartChainMainnet: - return 'BnbSmartChain' - case KnownChainIds.PolygonMainnet: - return 'Polygon' - case KnownChainIds.GnosisMainnet: - return 'Gnosis' - case KnownChainIds.ArbitrumMainnet: - return 'Arbitrum' - case KnownChainIds.ArbitrumNovaMainnet: - return 'ArbitrumNova' - case KnownChainIds.BaseMainnet: - return 'Base' - // Cosmos chains - case KnownChainIds.ThorchainMainnet: - return 'Rune' - case KnownChainIds.CosmosMainnet: - return 'Atom' - default: - assertUnreachable(knownChainId) - } -} - -type UseLedgerOpenAppProps = { - isSigning: boolean -} - -/** - * This hook provides a function that can be used to check if the Ledger app is open for the given chainId. - * - * If the app is not open, it will display a modal to prompt the user to open the app. - * - * The function will resolve when the app is open, or reject if the user cancels the request. - */ -export const useLedgerOpenApp = ({ isSigning }: UseLedgerOpenAppProps) => { - const { close: closeModal, open: openModal } = useModal('ledgerOpenApp') - - const wallet = useWallet().state.wallet - - const checkIsCorrectAppOpen = useCallback( - async (chainId: ChainId) => { - const slip44Key = getSlip44KeyFromChainId(chainId) - - const ledgerWallet = wallet && isLedger(wallet) ? wallet : undefined - if (!ledgerWallet || !slip44Key) return false - try { - await ledgerWallet.validateCurrentApp(slip44Key) - return true - } catch (error) { - console.error(error) - return false - } - }, - [wallet], - ) - - const checkLedgerApp = useCallback( - (chainId: ChainId) => { - return new Promise(async (resolve, reject) => { - // If the user is not using a Ledger, resolve the promise immediately - if (wallet && !isLedger(wallet)) { - resolve() - return - } - - // If the ledger app is already open, resolve the promise immediately - const isValidApp = await checkIsCorrectAppOpen(chainId) - if (isValidApp) { - resolve() - return - } - - // Prompt the "open app" notification on the device so users can open the correct app with 1 click - const ledgerWallet = wallet && isLedger(wallet) ? wallet : undefined - ledgerWallet?.openApp(getLedgerAppName(chainId)) - - // Poll the Ledger every second to see if the correct app is open - const intervalId = setInterval(async () => { - const isValidApp = await checkIsCorrectAppOpen(chainId) - if (isValidApp) { - closeModal() - clearInterval(intervalId) - resolve() - } - }, 1000) - - // Set a callback to reject the promise when the user cancels the request - const onCancel = () => { - closeModal() - clearInterval(intervalId) - reject() - } - - // Display the request to open the Ledger app - openModal({ chainId, onCancel, isSigning }) - }) - }, - [checkIsCorrectAppOpen, closeModal, openModal, wallet, isSigning], - ) - - return checkLedgerApp -} diff --git a/src/lib/account/utxo.ts b/src/lib/account/utxo.ts index 5e780f519b9..3e51ac17725 100644 --- a/src/lib/account/utxo.ts +++ b/src/lib/account/utxo.ts @@ -1,11 +1,6 @@ import { toAccountId } from '@shapeshiftoss/caip' -import { - convertXpubVersion, - toRootDerivationPath, - utxoAccountParams, - utxoChainIds, -} from '@shapeshiftoss/chain-adapters' -import { bip32ToAddressNList, supportsBTC } from '@shapeshiftoss/hdwallet-core' +import { utxoAccountParams, utxoChainIds } from '@shapeshiftoss/chain-adapters' +import { supportsBTC } from '@shapeshiftoss/hdwallet-core' import { MetaMaskShapeShiftMultiChainHDWallet } from '@shapeshiftoss/hdwallet-shapeshift-multichain' import type { AccountMetadataById, UtxoChainId } from '@shapeshiftoss/types' import { UtxoAccountType } from '@shapeshiftoss/types' @@ -29,24 +24,13 @@ export const deriveUtxoAccountIdsAndMetadata: DeriveAccountIdsAndMetadata = asyn supportedAccountTypes = [UtxoAccountType.P2pkh] } for (const accountType of supportedAccountTypes) { - const { bip44Params, scriptType } = utxoAccountParams(chainId, accountType, accountNumber) - const addressNList = bip32ToAddressNList(toRootDerivationPath(bip44Params)) - const pubkeys = await wallet.getPublicKeys([ - { - coin: adapter.getCoinName(), - addressNList, - curve: 'secp256k1', - scriptType, - }, - ]) + const { xpub: pubkey } = await adapter.getPublicKey(wallet, accountNumber, accountType) - // We do not want to throw for all ChainIds and script types, if one fails - if (!pubkeys?.[0]?.xpub || typeof pubkeys?.[0]?.xpub !== 'string') continue - - const pubkey = convertXpubVersion(pubkeys[0].xpub, accountType) if (!pubkey) continue + const { bip44Params } = utxoAccountParams(chainId, accountType, accountNumber) const accountId = toAccountId({ chainId, account: pubkey }) + acc[accountId] = { accountType, bip44Params } } } diff --git a/src/lib/utils/thorchain/hooks/useSendThorTx.tsx b/src/lib/utils/thorchain/hooks/useSendThorTx.tsx index df8dae09fee..1e3943f8e3d 100644 --- a/src/lib/utils/thorchain/hooks/useSendThorTx.tsx +++ b/src/lib/utils/thorchain/hooks/useSendThorTx.tsx @@ -15,7 +15,6 @@ import { selectInboundAddressData } from 'react-queries/selectors' import { getAddress, zeroAddress } from 'viem' import type { SendInput } from 'components/Modals/Send/Form' import { estimateFees, handleSend } from 'components/Modals/Send/utils' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { useWallet } from 'hooks/useWallet/useWallet' import { bn, bnOrZero } from 'lib/bignumber/bignumber' import { getTxLink } from 'lib/getTxLink' @@ -76,7 +75,6 @@ export const useSendThorTx = ({ const [txId, setTxId] = useState(null) const [serializedTxIndex, setSerializedTxIndex] = useState(null) - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) const wallet = useWallet().state.wallet const toast = useToast() const translate = useTranslate() @@ -273,8 +271,6 @@ export const useSendThorTx = ({ if (accountNumber === undefined) return if (isToken(asset.assetId) && !inboundAddressData) return - await checkLedgerAppOpenIfLedgerConnected(asset.chainId) - if ( action !== 'withdrawRunepool' && !shouldUseDustAmount && @@ -371,11 +367,7 @@ export const useSendThorTx = ({ input: '', } - const _txId = await handleSend({ - sendInput, - wallet, - checkLedgerAppOpenIfLedgerConnected, - }) + const _txId = await handleSend({ sendInput, wallet }) return { _txId, @@ -427,7 +419,6 @@ export const useSendThorTx = ({ toast, translate, depositWithExpiryInputData, - checkLedgerAppOpenIfLedgerConnected, fromAddress, selectedCurrency, ]) diff --git a/src/pages/Lending/Pool/components/Borrow/BorrowConfirm.tsx b/src/pages/Lending/Pool/components/Borrow/BorrowConfirm.tsx index ae2bf9f9ac4..2efac321488 100644 --- a/src/pages/Lending/Pool/components/Borrow/BorrowConfirm.tsx +++ b/src/pages/Lending/Pool/components/Borrow/BorrowConfirm.tsx @@ -39,7 +39,6 @@ import { RawText, Text } from 'components/Text' import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton' import { queryClient } from 'context/QueryClientProvider/queryClient' import { useInterval } from 'hooks/useInterval/useInterval' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { useWallet } from 'hooks/useWallet/useWallet' import { bn, bnOrZero } from 'lib/bignumber/bignumber' import { getMaybeCompositeAssetSymbol } from 'lib/mixpanel/helpers' @@ -92,8 +91,6 @@ export const BorrowConfirm = ({ state: { wallet }, } = useWallet() - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) - const borrowAssetId = borrowAsset?.assetId ?? '' const history = useHistory() const translate = useTranslate() @@ -315,7 +312,7 @@ export const BorrowConfirm = ({ if (!sendInput) throw new Error('Error building send input') - return handleSend({ sendInput, wallet, checkLedgerAppOpenIfLedgerConnected }) + return handleSend({ sendInput, wallet }) })() if (!maybeTxId) { @@ -348,7 +345,6 @@ export const BorrowConfirm = ({ setDepositAmount, history, selectedCurrency, - checkLedgerAppOpenIfLedgerConnected, ]) // Quote expiration interval diff --git a/src/pages/RFOX/components/ChangeAddress/ChangeAddressConfirm.tsx b/src/pages/RFOX/components/ChangeAddress/ChangeAddressConfirm.tsx index 409121429e5..798e948edb4 100644 --- a/src/pages/RFOX/components/ChangeAddress/ChangeAddressConfirm.tsx +++ b/src/pages/RFOX/components/ChangeAddress/ChangeAddressConfirm.tsx @@ -24,7 +24,6 @@ import { Row } from 'components/Row/Row' import { SlideTransition } from 'components/SlideTransition' import { RawText } from 'components/Text' import { useEvmFees } from 'hooks/queries/useEvmFees' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { useWallet } from 'hooks/useWallet/useWallet' import { middleEllipsis } from 'lib/utils' import { @@ -69,7 +68,6 @@ export const ChangeAddressConfirm: React.FC< () => (feeAsset ? assertGetEvmChainAdapter(fromAssetId(feeAsset.assetId).chainId) : undefined), [feeAsset], ) - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) const stakingAssetAccountAddress = useMemo( () => fromAccountId(confirmedQuote.stakingAssetAccountId).account, @@ -177,13 +175,9 @@ export const ChangeAddressConfirm: React.FC< const handleSubmit = useCallback(async () => { if (!stakingAsset) return - await checkLedgerAppOpenIfLedgerConnected(stakingAsset.chainId) - .then(async () => { - await handleChangeAddress() - history.push(ChangeAddressRoutePaths.Status) - }) - .catch(console.error) - }, [history, handleChangeAddress, stakingAsset, checkLedgerAppOpenIfLedgerConnected]) + await handleChangeAddress() + history.push(ChangeAddressRoutePaths.Status) + }, [history, handleChangeAddress, stakingAsset]) const changeAddressTx = useAppSelector(gs => selectTxById(gs, serializedChangeAddressTxIndex)) const isChangeAddressTxPending = useMemo( diff --git a/src/pages/RFOX/components/Claim/ClaimConfirm.tsx b/src/pages/RFOX/components/Claim/ClaimConfirm.tsx index 8e5d43edd67..e3fbd468747 100644 --- a/src/pages/RFOX/components/Claim/ClaimConfirm.tsx +++ b/src/pages/RFOX/components/Claim/ClaimConfirm.tsx @@ -24,7 +24,6 @@ import { Row, type RowProps } from 'components/Row/Row' import { SlideTransition } from 'components/SlideTransition' import { Timeline, TimelineItem } from 'components/Timeline/Timeline' import { useEvmFees } from 'hooks/queries/useEvmFees' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { useWallet } from 'hooks/useWallet/useWallet' import { bnOrZero } from 'lib/bignumber/bignumber' import { fromBaseUnit } from 'lib/math' @@ -63,7 +62,6 @@ export const ClaimConfirm: FC & ClaimCo const history = useHistory() const translate = useTranslate() const wallet = useWallet().state.wallet - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) const handleGoBack = useCallback(() => { history.push(ClaimRoutePaths.Select) @@ -209,13 +207,9 @@ export const ClaimConfirm: FC & ClaimCo const handleSubmit = useCallback(async () => { if (!stakingAsset) return - await checkLedgerAppOpenIfLedgerConnected(stakingAsset.chainId) - .then(async () => { - await handleClaim() - history.push(ClaimRoutePaths.Status) - }) - .catch(console.error) - }, [handleClaim, history, checkLedgerAppOpenIfLedgerConnected, stakingAsset]) + await handleClaim() + history.push(ClaimRoutePaths.Status) + }, [handleClaim, history, stakingAsset]) const claimTx = useAppSelector(gs => selectTxById(gs, serializedClaimTxIndex)) const isClaimTxPending = useMemo( diff --git a/src/pages/RFOX/components/Stake/Bridge/BridgeConfirm.tsx b/src/pages/RFOX/components/Stake/Bridge/BridgeConfirm.tsx index 7ceac17893c..e9600b962ab 100644 --- a/src/pages/RFOX/components/Stake/Bridge/BridgeConfirm.tsx +++ b/src/pages/RFOX/components/Stake/Bridge/BridgeConfirm.tsx @@ -21,7 +21,6 @@ import { getChainShortName } from 'components/MultiHopTrade/components/MultiHopT import { Row, type RowProps } from 'components/Row/Row' import { SlideTransition } from 'components/SlideTransition' import { Timeline, TimelineItem } from 'components/Timeline/Timeline' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { bnOrZero } from 'lib/bignumber/bignumber' import { toBaseUnit } from 'lib/math' import { selectPortfolioCryptoPrecisionBalanceByFilter } from 'state/slices/selectors' @@ -44,7 +43,6 @@ const CustomRow: React.FC = props => = ({ }) => { const translate = useTranslate() const history = useHistory() - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) const { sellAsset, @@ -40,16 +38,10 @@ export const BridgeStatus: React.FC = ({ }, [confirmedQuote, history]) const handleSignAndBroadcast = useCallback(async () => { - if (!sellAsset) return undefined + if (!sellAsset) return - try { - await checkLedgerAppOpenIfLedgerConnected(sellAsset.chainId) - - return handleBridge() - } catch (e) { - console.error(e) - } - }, [handleBridge, checkLedgerAppOpenIfLedgerConnected, sellAsset]) + return await handleBridge() + }, [handleBridge, sellAsset]) const steps: MultiStepStatusStep[] = useMemo(() => { if (!(sellAsset && buyAsset)) return [] diff --git a/src/pages/RFOX/components/Stake/StakeConfirm.tsx b/src/pages/RFOX/components/Stake/StakeConfirm.tsx index f9274978499..3b01c0aaf32 100644 --- a/src/pages/RFOX/components/Stake/StakeConfirm.tsx +++ b/src/pages/RFOX/components/Stake/StakeConfirm.tsx @@ -26,7 +26,6 @@ import type { RowProps } from 'components/Row/Row' import { Row } from 'components/Row/Row' import { SlideTransition } from 'components/SlideTransition' import { Timeline, TimelineItem } from 'components/Timeline/Timeline' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { bnOrZero } from 'lib/bignumber/bignumber' import { fromBaseUnit, toBaseUnit } from 'lib/math' import { middleEllipsis } from 'lib/utils' @@ -64,7 +63,6 @@ export const StakeConfirm: React.FC = ({ const queryClient = useQueryClient() const history = useHistory() const translate = useTranslate() - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) const stakingAsset = useAppSelector(state => selectAssetById(state, confirmedQuote.stakingAssetId), @@ -264,28 +262,11 @@ export const StakeConfirm: React.FC = ({ const handleSubmit = useCallback(async () => { if (!stakingAsset) return - if (isApprovalRequired) { - return checkLedgerAppOpenIfLedgerConnected(stakingAsset.chainId) - .then(() => { - handleApprove() - }) - .catch(console.error) - } + if (isApprovalRequired) return handleApprove() - await checkLedgerAppOpenIfLedgerConnected(stakingAsset.chainId) - .then(async () => { - await handleStake() - history.push(StakeRoutePaths.Status) - }) - .catch(console.error) - }, [ - handleStake, - history, - isApprovalRequired, - handleApprove, - stakingAsset, - checkLedgerAppOpenIfLedgerConnected, - ]) + await handleStake() + history.push(StakeRoutePaths.Status) + }, [handleStake, history, isApprovalRequired, handleApprove, stakingAsset]) const stakeCards = useMemo(() => { if (!stakingAsset) return null diff --git a/src/pages/RFOX/components/Unstake/UnstakeConfirm.tsx b/src/pages/RFOX/components/Unstake/UnstakeConfirm.tsx index fa709103669..92240a8c769 100644 --- a/src/pages/RFOX/components/Unstake/UnstakeConfirm.tsx +++ b/src/pages/RFOX/components/Unstake/UnstakeConfirm.tsx @@ -19,7 +19,6 @@ import type { RowProps } from 'components/Row/Row' import { Row } from 'components/Row/Row' import { SlideTransition } from 'components/SlideTransition' import { Timeline, TimelineItem } from 'components/Timeline/Timeline' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { bnOrZero } from 'lib/bignumber/bignumber' import { fromBaseUnit } from 'lib/math' import { selectAssetById, selectMarketDataByAssetIdUserCurrency } from 'state/slices/selectors' @@ -45,7 +44,6 @@ export const UnstakeConfirm: React.FC = }) => { const history = useHistory() const translate = useTranslate() - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) const stakingAsset = useAppSelector(state => selectAssetById(state, confirmedQuote.stakingAssetId), @@ -118,13 +116,9 @@ export const UnstakeConfirm: React.FC = const handleSubmit = useCallback(async () => { if (!stakingAsset) return - await checkLedgerAppOpenIfLedgerConnected(stakingAsset.chainId) - .then(async () => { - await handleUnstake() - history.push(UnstakeRoutePaths.Status) - }) - .catch(console.error) - }, [handleUnstake, history, stakingAsset, checkLedgerAppOpenIfLedgerConnected]) + await handleUnstake() + history.push(UnstakeRoutePaths.Status) + }, [handleUnstake, history, stakingAsset]) return ( diff --git a/src/pages/ThorChainLP/components/AddLiquidity/AddLiquidityInput.tsx b/src/pages/ThorChainLP/components/AddLiquidity/AddLiquidityInput.tsx index 4f4ba3fc6c4..f6c8f0e39ab 100644 --- a/src/pages/ThorChainLP/components/AddLiquidity/AddLiquidityInput.tsx +++ b/src/pages/ThorChainLP/components/AddLiquidity/AddLiquidityInput.tsx @@ -51,7 +51,6 @@ import { useBrowserRouter } from 'hooks/useBrowserRouter/useBrowserRouter' import { useFeatureFlag } from 'hooks/useFeatureFlag/useFeatureFlag' import { useIsSmartContractAddress } from 'hooks/useIsSmartContractAddress/useIsSmartContractAddress' import { useIsSnapInstalled } from 'hooks/useIsSnapInstalled/useIsSnapInstalled' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { useModal } from 'hooks/useModal/useModal' import { useToggle } from 'hooks/useToggle/useToggle' import { useWallet } from 'hooks/useWallet/useWallet' @@ -148,8 +147,6 @@ export const AddLiquidityInput: React.FC = ({ currentAccountIdByChainId, onAccountIdChange: handleAccountIdChange, }) => { - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) - const mixpanel = getMixPanel() const greenColor = useColorModeValue('green.600', 'green.200') const dispatch = useAppDispatch() @@ -625,10 +622,6 @@ export const AddLiquidityInput: React.FC = ({ from: poolAssetAccountId ? fromAccountId(poolAssetAccountId).account : undefined, accountNumber: poolAssetAccountNumber, }), - onMutate: async () => { - if (!poolAsset) return - await checkLedgerAppOpenIfLedgerConnected(poolAsset.chainId) - }, onSuccess: (txId: string) => { setApprovalTxId(txId) }, diff --git a/src/plugins/cosmos/hooks/useStakingAction/useStakingAction.tsx b/src/plugins/cosmos/hooks/useStakingAction/useStakingAction.tsx index 9321e343c7f..d463e40ab23 100644 --- a/src/plugins/cosmos/hooks/useStakingAction/useStakingAction.tsx +++ b/src/plugins/cosmos/hooks/useStakingAction/useStakingAction.tsx @@ -11,7 +11,6 @@ import { checkIsMetaMaskImpersonator, checkIsSnapInstalled, } from 'hooks/useIsSnapInstalled/useIsSnapInstalled' -import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { useWallet } from 'hooks/useWallet/useWallet' import { SHAPESHIFT_COSMOS_VALIDATOR_ADDRESS } from 'state/slices/opportunitiesSlice/resolvers/cosmosSdk/constants' @@ -35,7 +34,6 @@ type StakingInput = { export const useStakingAction = () => { const chainAdapterManager = getChainAdapterManager() - const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) const { state: { wallet }, } = useWallet() @@ -71,7 +69,6 @@ export const useStakingAction = () => { const { accountNumber } = bip44Params - await checkLedgerAppOpenIfLedgerConnected(asset.chainId) const address = await adapter.getAddress({ accountNumber, wallet }) const { txToSign, receiverAddress } = await (async () => { switch (action) { diff --git a/src/setupVitest.ts b/src/setupVitest.ts index c845f888eac..ace62d00197 100644 --- a/src/setupVitest.ts +++ b/src/setupVitest.ts @@ -6,9 +6,8 @@ import { beforeAll, vi } from 'vitest' // Redirect 'ethers' imports to 'ethers5' only for specific modules moduleAlias.addAlias('ethers', (fromPath: string) => { - if (fromPath.includes('/node_modules/@shapeshiftoss/hdwallet-shapeshift-multichain')) { - return path.resolve(__dirname, '../node_modules/ethers5') - } + const regex = /@shapeshiftoss\/hdwallet-(ledger|shapeshift-multichain)/ + if (regex.test(fromPath)) return path.resolve(__dirname, '../node_modules/ethers5') return 'ethers' })