From a5cd5906f8778bf4e225d6229a573f2328830913 Mon Sep 17 00:00:00 2001 From: lbqds Date: Fri, 11 Oct 2024 18:47:14 +0800 Subject: [PATCH 1/9] Display HD path --- .../extension/locales/en-US/translation.json | 2 ++ .../accountEdit/AccountEditScreen.tsx | 29 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/packages/extension/locales/en-US/translation.json b/packages/extension/locales/en-US/translation.json index efd8dfd7..ad25c7b0 100644 --- a/packages/extension/locales/en-US/translation.json +++ b/packages/extension/locales/en-US/translation.json @@ -74,8 +74,10 @@ "Export private key": "Export private key", "Enter your password to export your private key.": "Enter your password to export your private key.", "Click to copy public key": "Click to copy public key", + "Click to copy HD path": "Click to copy HD path", "This is your private key (click to copy)": "This is your private key (click to copy)", "Public Key": "Public Key", + "HD Path": "HD Path", "NFTs": "NFTs", "Error loading": "Error loading", "Loading": "Loading", diff --git a/packages/extension/src/ui/features/accountEdit/AccountEditScreen.tsx b/packages/extension/src/ui/features/accountEdit/AccountEditScreen.tsx index 2861f334..32c6b50c 100644 --- a/packages/extension/src/ui/features/accountEdit/AccountEditScreen.tsx +++ b/packages/extension/src/ui/features/accountEdit/AccountEditScreen.tsx @@ -26,6 +26,7 @@ import { useCurrentNetwork } from "../networks/useNetworks" import { AccountEditName } from "./AccountEditName" import { Button, CopyTooltip } from "@argent/ui" import { useTranslation } from "react-i18next" +import { getHDWalletPath } from "@alephium/web3-wallet" const { ExpandIcon, HideIcon, AlertIcon } = icons @@ -145,6 +146,18 @@ export const AccountEditScreen: FC = () => { } + { account !== undefined && +
+ +
+ } { ) } +const HDPathCopyButton: FC<{ hdPath: string }> = ({ hdPath }) => { + const { t } = useTranslation() + return ( + + + + ) +} + const PublicKeyCopyButton: FC<{ publicKey: string }> = ({ publicKey }) => { const { t } = useTranslation() return ( From a467551423aedf59dad45f34e1e9887e014cb2a0 Mon Sep 17 00:00:00 2001 From: lbqds Date: Fri, 11 Oct 2024 20:21:37 +0800 Subject: [PATCH 2/9] Minor refactor --- .../actions/ApproveTransactionScreen.tsx | 17 +--- .../features/funding/FundingQrCodeScreen.tsx | 12 +-- .../src/ui/features/ledger/start.tsx | 9 +- .../extension/src/ui/features/ledger/utils.ts | 99 ++++++++++++------- 4 files changed, 74 insertions(+), 63 deletions(-) diff --git a/packages/extension/src/ui/features/actions/ApproveTransactionScreen.tsx b/packages/extension/src/ui/features/actions/ApproveTransactionScreen.tsx index 0cd83198..6980099f 100644 --- a/packages/extension/src/ui/features/actions/ApproveTransactionScreen.tsx +++ b/packages/extension/src/ui/features/actions/ApproveTransactionScreen.tsx @@ -1,6 +1,4 @@ -import { AlephiumApp as LedgerApp } from "@alephium/ledger-app" import { ALPH_TOKEN_ID, ONE_ALPH, prettifyTokenAmount, TransactionBuilder } from "@alephium/web3" -import { getHDWalletPath } from "@alephium/web3-wallet" import { L1, icons } from "@argent/ui" import { Flex, Text } from "@chakra-ui/react" import { FC, useCallback, useEffect, useState } from "react" @@ -17,7 +15,7 @@ import { usePageTracking } from "../../services/analytics" import { rejectAction } from "../../services/backgroundActions" import { Account } from "../accounts/Account" import { useAllTokensWithBalance } from "../accountTokens/tokens.state" -import { getLedgerApp } from "../ledger/utils" +import { LedgerAlephium } from "../ledger/utils" import { useNetwork } from "../networks/useNetworks" import { ConfirmScreen } from "./ConfirmScreen" import { ConfirmPageProps } from "./DeprecatedConfirmScreen" @@ -214,7 +212,7 @@ export const ApproveTransactionScreen: FC = ({ const [ledgerState, setLedgerState] = useState< "detecting" | "notfound" | "signing" | "succeeded" | "failed" >() - const [ledgerApp, setLedgerApp] = useState() + const [ledgerApp, setLedgerApp] = useState() const { tokenDetails: allUserTokens, tokenDetailsIsInitialising } = useAllTokensWithBalance(selectedAccount) // TODO: handle error @@ -252,20 +250,15 @@ export const ApproveTransactionScreen: FC = ({ setLedgerState(oldState => oldState === undefined ? "detecting" : oldState) if (buildResult) { - let app: LedgerApp | undefined + let app: LedgerAlephium | undefined try { - app = await getLedgerApp() + app = await LedgerAlephium.create() setLedgerApp(app) setLedgerState("signing") - const path = getHDWalletPath( - selectedAccount.signer.keyType, - selectedAccount.signer.derivationIndex, - ) const unsignedTx = Buffer.from(buildResult.result.unsignedTx, "hex") - const signature = await app.signUnsignedTx(path, unsignedTx) + const signature = await app.signUnsignedTx(selectedAccount, unsignedTx) setLedgerState("succeeded") onSubmit({ ...buildResult, signature }) - await app.close() } catch (e) { if (app === undefined) { setLedgerState(oldState => oldState === undefined || oldState === "detecting" ? "notfound" : oldState) diff --git a/packages/extension/src/ui/features/funding/FundingQrCodeScreen.tsx b/packages/extension/src/ui/features/funding/FundingQrCodeScreen.tsx index 2300cc48..58cad85a 100644 --- a/packages/extension/src/ui/features/funding/FundingQrCodeScreen.tsx +++ b/packages/extension/src/ui/features/funding/FundingQrCodeScreen.tsx @@ -18,11 +18,10 @@ import { import { useSelectedAccount } from "../accounts/accounts.state" import { QrCode } from "./QrCode" import { testNodeWallet } from '@alephium/web3-test' -import { getHDWalletPath } from "@alephium/web3-wallet" import { Flex } from "@chakra-ui/react" import i18n from "../../../i18n" import { useTranslation } from "react-i18next" -import { getLedgerApp } from '../ledger/utils' +import { LedgerAlephium } from '../ledger/utils' import { set } from 'lodash-es' const Container = styled.div` @@ -136,7 +135,7 @@ export const FundingQrCodeScreen: FC = () => { const verifyLedger = useCallback(async () => { if (account?.signer.type === 'ledger') { - const app = await getLedgerApp().catch((error) => { + const app = await LedgerAlephium.create().catch((error) => { console.error(`Failed in connecting with ledger`, error) setAlterMessageIndex(2) setAlertDialogIsOpen(true) @@ -145,12 +144,7 @@ export const FundingQrCodeScreen: FC = () => { if (!app) { return } - const path = getHDWalletPath( - account.signer.keyType, - account.signer.derivationIndex, - ) - const [deviceAccount, _] = await app.getAccount(path, undefined, account.signer.keyType, true) - if (deviceAccount.address !== account.address) { + if (await app.verifyAccount(account)) { setAlterMessageIndex(3) setAlertDialogIsOpen(true) } diff --git a/packages/extension/src/ui/features/ledger/start.tsx b/packages/extension/src/ui/features/ledger/start.tsx index 2c2bb403..9b5b858f 100644 --- a/packages/extension/src/ui/features/ledger/start.tsx +++ b/packages/extension/src/ui/features/ledger/start.tsx @@ -13,8 +13,8 @@ import { BlackCircle } from "./assets/BlackCircle" import { LedgerStartIllustration } from "./assets/LedgerStart" import { LedgerPage } from "./LedgerPage" import { Steps } from "./Steps" -import { deriveAccount } from "./utils" -import { addLedgerAccount, getAllLedgerAccounts } from "../accounts/useAddAccount" +import { LedgerAlephium } from "./utils" +import { addLedgerAccount } from "../accounts/useAddAccount" import { useTranslation } from "react-i18next" export const StyledButton = styled(Button)` @@ -81,8 +81,9 @@ export const LedgerStartScreen: FC = () => { setDetecting(true) try { - const ledgerAccounts = await getAllLedgerAccounts(networkId) - const [account, hdIndex] = await deriveAccount(ledgerAccounts, addressGroup, keyType ?? "default") + const [account, hdIndex] = await LedgerAlephium + .create() + .then((ledger) => ledger.createNewAccount(networkId, addressGroup, keyType ?? "default")) addLedgerAccount(networkId, account, hdIndex) navigate(routes.ledgerDone()) } catch (e) { diff --git a/packages/extension/src/ui/features/ledger/utils.ts b/packages/extension/src/ui/features/ledger/utils.ts index a44b7d8d..089d0aa9 100644 --- a/packages/extension/src/ui/features/ledger/utils.ts +++ b/packages/extension/src/ui/features/ledger/utils.ts @@ -1,29 +1,77 @@ import { AlephiumApp as LedgerApp } from '@alephium/ledger-app' -import Transport from "@ledgerhq/hw-transport" import TransportWebHID from "@ledgerhq/hw-transport-webhid"; import TransportWebUSB from "@ledgerhq/hw-transport-webusb"; import { WalletAccount } from '../../../shared/wallet.model'; import { getHDWalletPath } from '@alephium/web3-wallet'; +import { getAllLedgerAccounts } from '../accounts/useAddAccount'; +import { Account } from '../accounts/Account'; export const getLedgerTransport = async () => { - let transport: Transport - try { - transport = await TransportWebHID.create() - return transport + return TransportWebHID.create() } catch (e) { console.log('Web HID not supported.', e) } - - transport = await TransportWebUSB.create() - return transport + return TransportWebUSB.create() } -export const getLedgerApp = async () => { - const transport = await getLedgerTransport() - const app = new LedgerApp(transport) - await app.getVersion() - return app +export class LedgerAlephium { + app: LedgerApp + + static async create(): Promise { + const transport = await getLedgerTransport() + const app = new LedgerApp(transport) + const version = await app.getVersion() + console.debug(`Ledger app version: ${version}`) + return new LedgerAlephium(app) + } + + private constructor(app: LedgerApp) { + this.app = app + } + + async createNewAccount(networkId: string, targetAddressGroup: number | undefined, keyType: string) { + if (keyType !== "default") { + throw Error("Unsupported key type: " + keyType) + } + + const existingLedgerAccounts = await getAllLedgerAccounts(networkId) + const relevantAccounts = existingLedgerAccounts.filter((account) => + account.signer.keyType === keyType && isAddressGroupMatched(account, targetAddressGroup) + ) + relevantAccounts.sort((a, b) => a.signer.derivationIndex - b.signer.derivationIndex) + for (let i = 0; i < relevantAccounts.length; i++) { + const existingAccount = relevantAccounts[i] + const path = getHDWalletPath(keyType, existingAccount.signer.derivationIndex + 1) + const [newAccount, hdIndex] = await this.app.getAccount(path, targetAddressGroup, keyType) + if (existingLedgerAccounts.find((account) => account.address === newAccount.address) === undefined) { + await this.app.close() + return [newAccount, hdIndex] as const + } + } + const path = getHDWalletPath(keyType, 0) + const result = await this.app.getAccount(path, targetAddressGroup, keyType) + await this.app.close() + return result + } + + async verifyAccount(account: Account): Promise { + const path = getHDWalletPath(account.signer.keyType, account.signer.derivationIndex) + const [deviceAccount, _] = await this.app.getAccount(path, undefined, account.signer.keyType, true) + await this.app.close() + return deviceAccount.address !== account.address + } + + async signUnsignedTx(account: Account, unsignedTx: Buffer) { + const hdPath = getHDWalletPath(account.signer.keyType, account.signer.derivationIndex) + const signature = await this.app.signUnsignedTx(hdPath, unsignedTx) + await this.app.close() + return signature + } + + async close() { + await this.app.close() + } } const isAddressGroupMatched = (account: WalletAccount, targetAddressGroup: number | undefined) => { @@ -33,28 +81,3 @@ const isAddressGroupMatched = (account: WalletAccount, targetAddressGroup: numbe return account.signer.group === targetAddressGroup } } - -export const deriveAccount = async (existingLedgerAccounts: WalletAccount[], targetAddressGroup: number | undefined, keyType: string) => { - if (keyType !== "default") { - throw Error("Unsupported key type: " + keyType) - } - - const app = await getLedgerApp() - const relevantAccounts = existingLedgerAccounts.filter((account) => - account.signer.keyType === keyType && isAddressGroupMatched(account, targetAddressGroup) - ) - relevantAccounts.sort((a, b) => a.signer.derivationIndex - b.signer.derivationIndex) - for (let i = 0; i < relevantAccounts.length; i++) { - const existingAccount = relevantAccounts[i] - const path = getHDWalletPath(keyType, existingAccount.signer.derivationIndex + 1) - const [newAccount, hdIndex] = await app.getAccount(path, targetAddressGroup, keyType) - if (existingLedgerAccounts.find((account) => account.address === newAccount.address) === undefined) { - await app.close() - return [newAccount, hdIndex] as const - } - } - const path = getHDWalletPath(keyType, 0) - const result = await app.getAccount(path, targetAddressGroup, keyType) - await app.close() - return result -} From 9837a6b383d5f72a070c0051e2bc2e8a2b7bc461 Mon Sep 17 00:00:00 2001 From: lbqds Date: Fri, 11 Oct 2024 21:09:08 +0800 Subject: [PATCH 3/9] Improve the creation of Ledger accounts --- .../extension/src/ui/features/ledger/utils.ts | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/packages/extension/src/ui/features/ledger/utils.ts b/packages/extension/src/ui/features/ledger/utils.ts index 089d0aa9..bc89d496 100644 --- a/packages/extension/src/ui/features/ledger/utils.ts +++ b/packages/extension/src/ui/features/ledger/utils.ts @@ -36,23 +36,16 @@ export class LedgerAlephium { } const existingLedgerAccounts = await getAllLedgerAccounts(networkId) - const relevantAccounts = existingLedgerAccounts.filter((account) => - account.signer.keyType === keyType && isAddressGroupMatched(account, targetAddressGroup) - ) - relevantAccounts.sort((a, b) => a.signer.derivationIndex - b.signer.derivationIndex) - for (let i = 0; i < relevantAccounts.length; i++) { - const existingAccount = relevantAccounts[i] - const path = getHDWalletPath(keyType, existingAccount.signer.derivationIndex + 1) + var index = 0 + while (true) { + const path = getHDWalletPath(keyType, index) const [newAccount, hdIndex] = await this.app.getAccount(path, targetAddressGroup, keyType) if (existingLedgerAccounts.find((account) => account.address === newAccount.address) === undefined) { await this.app.close() return [newAccount, hdIndex] as const } + index = hdIndex + 1 } - const path = getHDWalletPath(keyType, 0) - const result = await this.app.getAccount(path, targetAddressGroup, keyType) - await this.app.close() - return result } async verifyAccount(account: Account): Promise { From 580c55faccecf9baceed798480904f3c853c2cdd Mon Sep 17 00:00:00 2001 From: lbqds Date: Mon, 14 Oct 2024 11:07:17 +0800 Subject: [PATCH 4/9] Discover active ledger accounts --- packages/extension/src/background/wallet.ts | 100 +++++------------- packages/extension/src/shared/discovery.ts | 66 ++++++++++++ .../extension/src/ui/features/ledger/utils.ts | 58 +++++++++- 3 files changed, 145 insertions(+), 79 deletions(-) create mode 100644 packages/extension/src/shared/discovery.ts diff --git a/packages/extension/src/background/wallet.ts b/packages/extension/src/background/wallet.ts index 7c945f98..9b3fbdf8 100644 --- a/packages/extension/src/background/wallet.ts +++ b/packages/extension/src/background/wallet.ts @@ -11,8 +11,7 @@ import { groupOfAddress, KeyType, Account, - ExplorerProvider, - TOTAL_NUMBER_OF_GROUPS + ExplorerProvider } from "@alephium/web3" import { PrivateKeyWallet, @@ -35,11 +34,10 @@ import { } from "../shared/storage" import { BaseWalletAccount, WalletAccount } from "../shared/wallet.model" import { accountsEqual } from "../shared/wallet.service" -import { - getNextPathIndex, -} from "./keys/keyDerivation" +import { getNextPathIndex } from "./keys/keyDerivation" import backupSchema from "./schema/backup.schema" import { BrowserStorage, walletEncrypt, walletOpen } from './utils/walletStore' +import { AccountDiscovery } from '../shared/discovery' const isDev = process.env.NODE_ENV === "development" @@ -81,13 +79,15 @@ export const sessionStore = new ObjectStorage(null, { export type GetNetwork = (networkId: string) => Promise -export class Wallet { +export class Wallet extends AccountDiscovery { constructor( private readonly store: IKeyValueStorage, private readonly walletStore: IArrayStorage, private readonly sessionStore: IObjectStorage, private readonly getNetwork: GetNetwork, - ) { } + ) { + super() + } async signAndSubmitUnsignedTx( account: WalletAccount, @@ -461,87 +461,35 @@ export class Wallet { const accountsForNetwork = await this.walletStore.get(account => account.networkId == networkId) const selectedAccount = await this.getSelectedAccount() - console.info(`start discovering active accounts for ${networkId}`) - const walletAccounts = await this.deriveActiveAccountsForNetwork(networkId) - const newDiscoveredAccounts = walletAccounts.filter(account => !accountsForNetwork.find(a => a.address === account.address)) - - if (newDiscoveredAccounts.length > 0) { - await this.walletStore.push(newDiscoveredAccounts) - if (selectedAccount === undefined) { - await this.selectAccount(newDiscoveredAccounts[0]) - } - } - console.info(`Discovered ${newDiscoveredAccounts.length} new active accounts for ${networkId}`) - return newDiscoveredAccounts - } - - public async deriveActiveAccountsForNetwork(networkId: string): Promise { - console.log(`derived active accounts for ${networkId}`) const session = await this.sessionStore.get() if (!(await this.isSessionOpen()) || !session) { throw Error("no open session") } const network = await this.getNetwork(networkId) - - const walletAccounts: WalletAccount[] = [] - - for (let group = 0; group < TOTAL_NUMBER_OF_GROUPS; group++) { - const walletAccountsForGroup = await this.deriveActiveAccountsForGroup(session.secret, network, 'default', group, [], []) - walletAccounts.push(...walletAccountsForGroup) - } - - return walletAccounts - } - - public async deriveActiveAccountsForGroup( - secret: string, - network: Network, - keyType: KeyType, - forGroup: number, - allWalletAccounts: { wallet: WalletAccount, active: boolean }[], - activeWalletAccounts: WalletAccount[] - ): Promise { - const minGap = 5 - const derivationBatchSize = 10 if (!network.explorerUrl) { return [] } - const explorerService = new ExplorerProvider(network.explorerApiUrl) - const gapSatisfied = (allWalletAccounts.length >= minGap) && allWalletAccounts.slice(-minGap).every(item => !item.active); - - if (gapSatisfied) { - return activeWalletAccounts - } else { - let startIndex = getNextPathIndex(allWalletAccounts.map(account => account.wallet.signer.derivationIndex)) - const newWalletAccounts = [] - for (let i = 0; i < derivationBatchSize; i++) { - const newWalletAccount = this.deriveAccount(secret, startIndex, network.id, keyType, forGroup) - newWalletAccounts.push(newWalletAccount) - startIndex = newWalletAccount.signer.derivationIndex + 1 - } - - const results = await explorerService.addresses.postAddressesUsed(newWalletAccounts.map(account => account.address)) + console.info(`start discovering active accounts for ${networkId}`) + const explorerProvider = new ExplorerProvider(network.explorerApiUrl) + const discoverAccount = (startIndex: number, group?: number): Promise => { + return Promise.resolve(this.deriveAccount(session.secret, startIndex, network.id, 'default', group)) + } + const walletAccounts = await this.deriveActiveAccountsForNetwork(explorerProvider, discoverAccount) + const newDiscoveredAccounts = walletAccounts.filter(account => !accountsForNetwork.find(a => a.address === account.address)) - const updatedActiveWalletAccounts = activeWalletAccounts - for (let i = 0; i < derivationBatchSize; i++) { - const newWalletAccount = newWalletAccounts[i] - const result = results[i] - if (result) { - updatedActiveWalletAccounts.push(newWalletAccount) - } - allWalletAccounts.push({ wallet: newWalletAccount, active: result }) + if (newDiscoveredAccounts.length > 0) { + await this.walletStore.push(newDiscoveredAccounts) + if (selectedAccount === undefined) { + await this.selectAccount(newDiscoveredAccounts[0]) } - - return this.deriveActiveAccountsForGroup( - secret, - network, - keyType, - forGroup, - allWalletAccounts, - updatedActiveWalletAccounts - ) } + console.info(`Discovered ${newDiscoveredAccounts.length} new active accounts for ${networkId}`) + return newDiscoveredAccounts + } + + nextPathIndexForDiscovery(indexes: number[]): number { + return getNextPathIndex(indexes) } } diff --git a/packages/extension/src/shared/discovery.ts b/packages/extension/src/shared/discovery.ts new file mode 100644 index 00000000..83354af2 --- /dev/null +++ b/packages/extension/src/shared/discovery.ts @@ -0,0 +1,66 @@ +import { ExplorerProvider, TOTAL_NUMBER_OF_GROUPS } from '@alephium/web3' +import { WalletAccount } from './wallet.model' + +const minGap = 5 +const derivationBatchSize = 10 + +export abstract class AccountDiscovery { + abstract nextPathIndexForDiscovery(indexes: number[]): number + + public async deriveActiveAccountsForNetwork( + explorerProvider: ExplorerProvider, + deriveAccount: (startIndex: number, group?: number) => Promise + ): Promise { + const walletAccounts: WalletAccount[] = [] + for (let group = 0; group < TOTAL_NUMBER_OF_GROUPS; group++) { + const walletAccountsForGroup = await this.deriveActiveAccountsForGroup( + explorerProvider, + [], + [], + (startIndex: number) => deriveAccount(startIndex, group) + ) + walletAccounts.push(...walletAccountsForGroup) + } + + return walletAccounts + } + + private async deriveActiveAccountsForGroup( + explorerProvider: ExplorerProvider, + allWalletAccounts: { wallet: WalletAccount, active: boolean }[], + activeWalletAccounts: WalletAccount[], + deriveAccount: (startIndex: number) => Promise + ): Promise { + const gapSatisfied = (allWalletAccounts.length >= minGap) && allWalletAccounts.slice(-minGap).every(item => !item.active); + if (gapSatisfied) { + return activeWalletAccounts + } else { + let startIndex = this.nextPathIndexForDiscovery(allWalletAccounts.map(account => account.wallet.signer.derivationIndex)) + const newWalletAccounts = [] + for (let i = 0; i < derivationBatchSize; i++) { + const newWalletAccount = await deriveAccount(startIndex) + newWalletAccounts.push(newWalletAccount) + startIndex = newWalletAccount.signer.derivationIndex + 1 + } + + const results = await explorerProvider.addresses.postAddressesUsed(newWalletAccounts.map(account => account.address)) + + const updatedActiveWalletAccounts = activeWalletAccounts + for (let i = 0; i < derivationBatchSize; i++) { + const newWalletAccount = newWalletAccounts[i] + const result = results[i] + if (result) { + updatedActiveWalletAccounts.push(newWalletAccount) + } + allWalletAccounts.push({ wallet: newWalletAccount, active: result }) + } + + return this.deriveActiveAccountsForGroup( + explorerProvider, + allWalletAccounts, + updatedActiveWalletAccounts, + deriveAccount + ) + } + } +} \ No newline at end of file diff --git a/packages/extension/src/ui/features/ledger/utils.ts b/packages/extension/src/ui/features/ledger/utils.ts index bc89d496..92444d39 100644 --- a/packages/extension/src/ui/features/ledger/utils.ts +++ b/packages/extension/src/ui/features/ledger/utils.ts @@ -5,6 +5,10 @@ import { WalletAccount } from '../../../shared/wallet.model'; import { getHDWalletPath } from '@alephium/web3-wallet'; import { getAllLedgerAccounts } from '../accounts/useAddAccount'; import { Account } from '../accounts/Account'; +import { AccountDiscovery } from '../../../shared/discovery'; +import { getNextPathIndex } from '../../../background/keys/keyDerivation'; +import { ExplorerProvider, groupOfAddress, KeyType } from '@alephium/web3'; +import { getNetwork } from '../../../shared/network'; export const getLedgerTransport = async () => { try { @@ -15,7 +19,7 @@ export const getLedgerTransport = async () => { return TransportWebUSB.create() } -export class LedgerAlephium { +export class LedgerAlephium extends AccountDiscovery { app: LedgerApp static async create(): Promise { @@ -27,9 +31,36 @@ export class LedgerAlephium { } private constructor(app: LedgerApp) { + super() this.app = app } + private async getAccount(startIndex: number, group: number | undefined, keyType: KeyType) { + const path = getHDWalletPath(keyType, startIndex) + return await this.app.getAccount(path, group, keyType) + } + + private async deriveAccount( + networkId: string, + startIndex: number, + keyType: KeyType, + group?: number + ): Promise { + const [newAccount, hdIndex] = await this.getAccount(startIndex, group, keyType) + return { + address: newAccount.address, + networkId: networkId, + signer: { + type: "ledger" as const, + publicKey: newAccount.publicKey, + keyType: newAccount.keyType, + derivationIndex: hdIndex, + group: groupOfAddress(newAccount.address) + }, + type: "alephium", + } + } + async createNewAccount(networkId: string, targetAddressGroup: number | undefined, keyType: string) { if (keyType !== "default") { throw Error("Unsupported key type: " + keyType) @@ -38,8 +69,7 @@ export class LedgerAlephium { const existingLedgerAccounts = await getAllLedgerAccounts(networkId) var index = 0 while (true) { - const path = getHDWalletPath(keyType, index) - const [newAccount, hdIndex] = await this.app.getAccount(path, targetAddressGroup, keyType) + const [newAccount, hdIndex] = await this.getAccount(index, targetAddressGroup, keyType) if (existingLedgerAccounts.find((account) => account.address === newAccount.address) === undefined) { await this.app.close() return [newAccount, hdIndex] as const @@ -65,6 +95,28 @@ export class LedgerAlephium { async close() { await this.app.close() } + + public async discoverActiveAccounts(networkId: string): Promise { + const existingLedgerAccounts = await getAllLedgerAccounts(networkId) + const network = await getNetwork(networkId) + if (!network.explorerUrl) { + return [] + } + + console.info(`start discovering active ledger accounts for ${networkId}`) + const explorerProvider = new ExplorerProvider(network.explorerApiUrl) + const discoverAccount = (startIndex: number, group?: number): Promise => { + return this.deriveAccount(network.id, startIndex, 'default', group) + } + const walletAccounts = await this.deriveActiveAccountsForNetwork(explorerProvider, discoverAccount) + const newDiscoveredAccounts = walletAccounts.filter(account => !existingLedgerAccounts.find(a => a.address === account.address)) + console.info(`Discovered ${newDiscoveredAccounts.length} new active accounts for ${networkId}`) + return newDiscoveredAccounts + } + + nextPathIndexForDiscovery(indexes: number[]): number { + return getNextPathIndex(indexes) + } } const isAddressGroupMatched = (account: WalletAccount, targetAddressGroup: number | undefined) => { From 413e1dbba851797ef5195574a3d06612669b824f Mon Sep 17 00:00:00 2001 From: lbqds Date: Mon, 14 Oct 2024 17:35:34 +0800 Subject: [PATCH 5/9] Discover ledger accounts when clicking the discover button --- .../features/settings/DeveloperSettings.tsx | 40 +++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/packages/extension/src/ui/features/settings/DeveloperSettings.tsx b/packages/extension/src/ui/features/settings/DeveloperSettings.tsx index a9a68820..170d776a 100644 --- a/packages/extension/src/ui/features/settings/DeveloperSettings.tsx +++ b/packages/extension/src/ui/features/settings/DeveloperSettings.tsx @@ -13,6 +13,8 @@ import { LoadingScreen } from "../actions/LoadingScreen" import { mapWalletAccountsToAccounts } from "../accounts/accounts.state" import { getDefaultAccountNameByIndex, useAccountMetadata } from "../accounts/accountMetadata.state" import { useTranslation } from "react-i18next" +import { LedgerAlephium } from "../ledger/utils" +import { addLedgerAccount } from "../accounts/useAddAccount" const { SearchIcon } = icons @@ -35,15 +37,13 @@ const DeveloperSettings: FC = () => { }) }, []) - const onDiscoverAccounts = useCallback(async () => { - setLoading(true) + const discoveryLocalAccounts = useCallback(async () => { try { const allWalletAccounts = await getAccounts(true) const allWalletAccountsOnNetwork = accountsOnNetwork(allWalletAccounts, currentNetwork.id) const result = await discoverAccounts(currentNetwork.id) if (result === "error") { - console.log("Error discovering accounts") - setLoading(false) + console.log("Error discovering local accounts") } else { const discoveredAccounts = mapWalletAccountsToAccounts(result.accounts) let accountIndex = allWalletAccountsOnNetwork.length @@ -51,14 +51,40 @@ const DeveloperSettings: FC = () => { setAccountName(account.networkId, account.address, getDefaultAccountNameByIndex(account, accountIndex)) accountIndex++ }) - setLoading(false) } } catch (e) { - console.log("Error discovering accounts", e) - setLoading(false) + console.log("Error discovering local accounts", e) } }, [currentNetwork.id, setAccountName]) + const discoveryLedgerAccounts = useCallback(async () => { + try { + const allWalletAccounts = await getAccounts(true) + const allWalletAccountsOnNetwork = accountsOnNetwork(allWalletAccounts, currentNetwork.id) + let accountIndex = allWalletAccountsOnNetwork.length + const result = await LedgerAlephium.create().then((ledger) => ledger.discoverActiveAccounts(currentNetwork.id)) + const discoveredAccounts = mapWalletAccountsToAccounts(result) + for (const account of discoveredAccounts) { + await addLedgerAccount( + currentNetwork.id, + { keyType: account.signer.keyType, address: account.address, group: account.signer.group, publicKey: account.signer.publicKey }, + account.signer.derivationIndex + ) + setAccountName(account.networkId, account.address, getDefaultAccountNameByIndex(account, accountIndex)) + accountIndex++ + } + } catch (e) { + console.log("Error discovering ledger accounts", e) + } + }, [currentNetwork.id, setAccountName]) + + const onDiscoverAccounts = useCallback(async () => { + setLoading(true) + await discoveryLocalAccounts() + await discoveryLedgerAccounts() + setLoading(false) + }, [setLoading, discoveryLocalAccounts, discoveryLedgerAccounts]) + if (loading) { return } From 6b37bd8216ed0d437916022fd0194b01f15ea0b2 Mon Sep 17 00:00:00 2001 From: lbqds Date: Mon, 14 Oct 2024 17:43:43 +0800 Subject: [PATCH 6/9] Simplify the add ledger account message --- .../extension/src/background/accountMessaging.ts | 6 +++--- packages/extension/src/background/wallet.ts | 14 +------------- .../src/shared/messages/AccountMessage.ts | 4 ++-- .../src/ui/features/accounts/useAddAccount.ts | 9 +++++---- .../extension/src/ui/features/ledger/start.tsx | 4 ++-- packages/extension/src/ui/features/ledger/utils.ts | 14 +++----------- .../src/ui/features/settings/DeveloperSettings.tsx | 6 +----- .../src/ui/services/backgroundAccounts.ts | 6 +++--- 8 files changed, 20 insertions(+), 43 deletions(-) diff --git a/packages/extension/src/background/accountMessaging.ts b/packages/extension/src/background/accountMessaging.ts index 6929aa96..814789c9 100644 --- a/packages/extension/src/background/accountMessaging.ts +++ b/packages/extension/src/background/accountMessaging.ts @@ -91,9 +91,9 @@ export const handleAccountMessage: HandleMessage = async ({ throw Error("you need an open session") } - const { account, hdIndex, networkId } = msg.data + const { account } = msg.data try { - const baseAccount = await wallet.importLedgerAccount(account, hdIndex, networkId) + const baseAccount = await wallet.importLedgerAccount(account) return sendMessageToUi({ type: "ALPH_NEW_LEDGER_ACCOUNT_RES", data: { @@ -105,7 +105,7 @@ export const handleAccountMessage: HandleMessage = async ({ analytics.track("createAccount", { status: "failure", - networkId: networkId, + networkId: account.networkId, errorMessage: error, }) diff --git a/packages/extension/src/background/wallet.ts b/packages/extension/src/background/wallet.ts index 9b3fbdf8..8074b313 100644 --- a/packages/extension/src/background/wallet.ts +++ b/packages/extension/src/background/wallet.ts @@ -258,19 +258,7 @@ export class Wallet extends AccountDiscovery { } } - public async importLedgerAccount(account: Account, hdIndex: number, networkId: string): Promise { - const walletAccount: WalletAccount = { - address: account.address, - networkId: networkId, - signer: { - type: "ledger" as const, - publicKey: account.publicKey, - keyType: account.keyType, - derivationIndex: hdIndex, - group: groupOfAddress(account.address) - }, - type: "alephium", - } + public async importLedgerAccount(walletAccount: WalletAccount): Promise { await this.walletStore.push([walletAccount]) await this.selectAccount(walletAccount) return walletAccount diff --git a/packages/extension/src/shared/messages/AccountMessage.ts b/packages/extension/src/shared/messages/AccountMessage.ts index db3b314f..7de0d114 100644 --- a/packages/extension/src/shared/messages/AccountMessage.ts +++ b/packages/extension/src/shared/messages/AccountMessage.ts @@ -1,4 +1,4 @@ -import { KeyType, Account } from "@alephium/web3"; +import { KeyType } from "@alephium/web3"; import { ArgentAccountType, BaseWalletAccount, @@ -15,7 +15,7 @@ export type AccountMessage = } } | { type: "ALPH_NEW_ACCOUNT_REJ"; data: { error: string } } - | { type: "ALPH_NEW_LEDGER_ACCOUNT"; data: { account: Account; hdIndex: number, networkId: string } } + | { type: "ALPH_NEW_LEDGER_ACCOUNT"; data: { account: WalletAccount } } | { type: "ALPH_NEW_LEDGER_ACCOUNT_RES" data: { diff --git a/packages/extension/src/ui/features/accounts/useAddAccount.ts b/packages/extension/src/ui/features/accounts/useAddAccount.ts index dca53c84..74364ceb 100644 --- a/packages/extension/src/ui/features/accounts/useAddAccount.ts +++ b/packages/extension/src/ui/features/accounts/useAddAccount.ts @@ -1,4 +1,4 @@ -import { KeyType, Account } from "@alephium/web3" +import { KeyType } from "@alephium/web3" import { useCallback } from "react" import { useNavigate } from "react-router-dom" @@ -7,6 +7,7 @@ import { getAccounts, selectAccount } from "../../services/backgroundAccounts" import { recover } from "../recovery/recovery.service" import { createAccount } from "./accounts.service" import { importNewLedgerAccount } from '../../services/backgroundAccounts' +import { WalletAccount } from "../../../shared/wallet.model" export const useAddAccount = () => { const navigate = useNavigate() @@ -22,10 +23,10 @@ export const useAddAccount = () => { return { addAccount } } -export const addLedgerAccount = async (networkId: string, account: Account, hdIndex: number) => { - await importNewLedgerAccount(account, hdIndex, networkId) +export const addLedgerAccount = async (account: WalletAccount) => { + await importNewLedgerAccount(account) // switch background wallet to the account that was selected - await selectAccount({ address: account.address, networkId: networkId }) + await selectAccount({ address: account.address, networkId: account.networkId }) } export const getAllLedgerAccounts = async (networkId: string) => { diff --git a/packages/extension/src/ui/features/ledger/start.tsx b/packages/extension/src/ui/features/ledger/start.tsx index 9b5b858f..b4902b77 100644 --- a/packages/extension/src/ui/features/ledger/start.tsx +++ b/packages/extension/src/ui/features/ledger/start.tsx @@ -81,10 +81,10 @@ export const LedgerStartScreen: FC = () => { setDetecting(true) try { - const [account, hdIndex] = await LedgerAlephium + const account = await LedgerAlephium .create() .then((ledger) => ledger.createNewAccount(networkId, addressGroup, keyType ?? "default")) - addLedgerAccount(networkId, account, hdIndex) + addLedgerAccount(account) navigate(routes.ledgerDone()) } catch (e) { console.error(e) diff --git a/packages/extension/src/ui/features/ledger/utils.ts b/packages/extension/src/ui/features/ledger/utils.ts index 92444d39..c5b74a78 100644 --- a/packages/extension/src/ui/features/ledger/utils.ts +++ b/packages/extension/src/ui/features/ledger/utils.ts @@ -69,12 +69,12 @@ export class LedgerAlephium extends AccountDiscovery { const existingLedgerAccounts = await getAllLedgerAccounts(networkId) var index = 0 while (true) { - const [newAccount, hdIndex] = await this.getAccount(index, targetAddressGroup, keyType) + const newAccount = await this.deriveAccount(networkId, index, keyType, targetAddressGroup) if (existingLedgerAccounts.find((account) => account.address === newAccount.address) === undefined) { await this.app.close() - return [newAccount, hdIndex] as const + return newAccount } - index = hdIndex + 1 + index = newAccount.signer.derivationIndex + 1 } } @@ -118,11 +118,3 @@ export class LedgerAlephium extends AccountDiscovery { return getNextPathIndex(indexes) } } - -const isAddressGroupMatched = (account: WalletAccount, targetAddressGroup: number | undefined) => { - if (targetAddressGroup === undefined) { - return true - } else { - return account.signer.group === targetAddressGroup - } -} diff --git a/packages/extension/src/ui/features/settings/DeveloperSettings.tsx b/packages/extension/src/ui/features/settings/DeveloperSettings.tsx index 170d776a..b5af7db2 100644 --- a/packages/extension/src/ui/features/settings/DeveloperSettings.tsx +++ b/packages/extension/src/ui/features/settings/DeveloperSettings.tsx @@ -65,11 +65,7 @@ const DeveloperSettings: FC = () => { const result = await LedgerAlephium.create().then((ledger) => ledger.discoverActiveAccounts(currentNetwork.id)) const discoveredAccounts = mapWalletAccountsToAccounts(result) for (const account of discoveredAccounts) { - await addLedgerAccount( - currentNetwork.id, - { keyType: account.signer.keyType, address: account.address, group: account.signer.group, publicKey: account.signer.publicKey }, - account.signer.derivationIndex - ) + await addLedgerAccount(account) setAccountName(account.networkId, account.address, getDefaultAccountNameByIndex(account, accountIndex)) accountIndex++ } diff --git a/packages/extension/src/ui/services/backgroundAccounts.ts b/packages/extension/src/ui/services/backgroundAccounts.ts index 60877903..e726a1f8 100644 --- a/packages/extension/src/ui/services/backgroundAccounts.ts +++ b/packages/extension/src/ui/services/backgroundAccounts.ts @@ -1,4 +1,4 @@ -import { KeyType, Account } from "@alephium/web3" +import { KeyType } from "@alephium/web3" import { sendMessage, waitForMessage } from "../../shared/messages" import { ArgentAccountType, @@ -33,8 +33,8 @@ export const discoverAccounts = async (networkId: string) => { } } -export const importNewLedgerAccount = async (account: Account, hdIndex: number, networkId: string) => { - sendMessage({ type: "ALPH_NEW_LEDGER_ACCOUNT", data: { account, hdIndex, networkId } }) +export const importNewLedgerAccount = async (account: WalletAccount) => { + sendMessage({ type: "ALPH_NEW_LEDGER_ACCOUNT", data: { account } }) try { return await Promise.race([ waitForMessage("ALPH_NEW_LEDGER_ACCOUNT_RES"), From 7a5cbdb0e296af2d178a272ddb82869fbbc6f9d1 Mon Sep 17 00:00:00 2001 From: lbqds Date: Tue, 22 Oct 2024 08:36:11 +0800 Subject: [PATCH 7/9] Improve account discovery --- packages/extension/src/background/wallet.ts | 9 +-- packages/extension/src/shared/discovery.ts | 76 ++++++++----------- .../extension/src/ui/features/ledger/utils.ts | 11 +-- 3 files changed, 37 insertions(+), 59 deletions(-) diff --git a/packages/extension/src/background/wallet.ts b/packages/extension/src/background/wallet.ts index 8074b313..00e8140d 100644 --- a/packages/extension/src/background/wallet.ts +++ b/packages/extension/src/background/wallet.ts @@ -10,7 +10,6 @@ import { publicKeyFromPrivateKey, groupOfAddress, KeyType, - Account, ExplorerProvider } from "@alephium/web3" import { @@ -461,8 +460,8 @@ export class Wallet extends AccountDiscovery { console.info(`start discovering active accounts for ${networkId}`) const explorerProvider = new ExplorerProvider(network.explorerApiUrl) - const discoverAccount = (startIndex: number, group?: number): Promise => { - return Promise.resolve(this.deriveAccount(session.secret, startIndex, network.id, 'default', group)) + const discoverAccount = (startIndex: number): Promise => { + return Promise.resolve(this.deriveAccount(session.secret, startIndex, network.id, 'default')) } const walletAccounts = await this.deriveActiveAccountsForNetwork(explorerProvider, discoverAccount) const newDiscoveredAccounts = walletAccounts.filter(account => !accountsForNetwork.find(a => a.address === account.address)) @@ -476,8 +475,4 @@ export class Wallet extends AccountDiscovery { console.info(`Discovered ${newDiscoveredAccounts.length} new active accounts for ${networkId}`) return newDiscoveredAccounts } - - nextPathIndexForDiscovery(indexes: number[]): number { - return getNextPathIndex(indexes) - } } diff --git a/packages/extension/src/shared/discovery.ts b/packages/extension/src/shared/discovery.ts index 83354af2..425cc102 100644 --- a/packages/extension/src/shared/discovery.ts +++ b/packages/extension/src/shared/discovery.ts @@ -4,63 +4,51 @@ import { WalletAccount } from './wallet.model' const minGap = 5 const derivationBatchSize = 10 -export abstract class AccountDiscovery { - abstract nextPathIndexForDiscovery(indexes: number[]): number +class DerivedAccountsPerGroup { + accounts: WalletAccount[] + gap: number - public async deriveActiveAccountsForNetwork( - explorerProvider: ExplorerProvider, - deriveAccount: (startIndex: number, group?: number) => Promise - ): Promise { - const walletAccounts: WalletAccount[] = [] - for (let group = 0; group < TOTAL_NUMBER_OF_GROUPS; group++) { - const walletAccountsForGroup = await this.deriveActiveAccountsForGroup( - explorerProvider, - [], - [], - (startIndex: number) => deriveAccount(startIndex, group) - ) - walletAccounts.push(...walletAccountsForGroup) + constructor() { + this.accounts = [] + this.gap = 0 + } + + addAccount(account: WalletAccount, active: boolean) { + if (!this.isComplete()) { + if (!active) { + this.gap += 1 + } else { + this.gap = 0 + this.accounts.push(account) + } } + } - return walletAccounts + isComplete(): boolean { + return this.gap >= minGap } +} - private async deriveActiveAccountsForGroup( +export abstract class AccountDiscovery { + public async deriveActiveAccountsForNetwork( explorerProvider: ExplorerProvider, - allWalletAccounts: { wallet: WalletAccount, active: boolean }[], - activeWalletAccounts: WalletAccount[], deriveAccount: (startIndex: number) => Promise ): Promise { - const gapSatisfied = (allWalletAccounts.length >= minGap) && allWalletAccounts.slice(-minGap).every(item => !item.active); - if (gapSatisfied) { - return activeWalletAccounts - } else { - let startIndex = this.nextPathIndexForDiscovery(allWalletAccounts.map(account => account.wallet.signer.derivationIndex)) + const allAccounts = Array.from(Array(TOTAL_NUMBER_OF_GROUPS)).map(() => new DerivedAccountsPerGroup()) + let startIndex = 0 + while (allAccounts.some((a) => !a.isComplete())) { const newWalletAccounts = [] for (let i = 0; i < derivationBatchSize; i++) { - const newWalletAccount = await deriveAccount(startIndex) + const newWalletAccount = await deriveAccount(startIndex + i) newWalletAccounts.push(newWalletAccount) - startIndex = newWalletAccount.signer.derivationIndex + 1 } - + startIndex += derivationBatchSize const results = await explorerProvider.addresses.postAddressesUsed(newWalletAccounts.map(account => account.address)) - - const updatedActiveWalletAccounts = activeWalletAccounts - for (let i = 0; i < derivationBatchSize; i++) { - const newWalletAccount = newWalletAccounts[i] - const result = results[i] - if (result) { - updatedActiveWalletAccounts.push(newWalletAccount) - } - allWalletAccounts.push({ wallet: newWalletAccount, active: result }) - } - - return this.deriveActiveAccountsForGroup( - explorerProvider, - allWalletAccounts, - updatedActiveWalletAccounts, - deriveAccount - ) + newWalletAccounts.forEach((account, index) => { + const accountsPerGroup = allAccounts[account.signer.group] + accountsPerGroup.addAccount(account, results[index]) + }) } + return allAccounts.flatMap((a) => a.accounts) } } \ No newline at end of file diff --git a/packages/extension/src/ui/features/ledger/utils.ts b/packages/extension/src/ui/features/ledger/utils.ts index c5b74a78..793e153d 100644 --- a/packages/extension/src/ui/features/ledger/utils.ts +++ b/packages/extension/src/ui/features/ledger/utils.ts @@ -6,7 +6,6 @@ import { getHDWalletPath } from '@alephium/web3-wallet'; import { getAllLedgerAccounts } from '../accounts/useAddAccount'; import { Account } from '../accounts/Account'; import { AccountDiscovery } from '../../../shared/discovery'; -import { getNextPathIndex } from '../../../background/keys/keyDerivation'; import { ExplorerProvider, groupOfAddress, KeyType } from '@alephium/web3'; import { getNetwork } from '../../../shared/network'; @@ -67,7 +66,7 @@ export class LedgerAlephium extends AccountDiscovery { } const existingLedgerAccounts = await getAllLedgerAccounts(networkId) - var index = 0 + let index = 0 while (true) { const newAccount = await this.deriveAccount(networkId, index, keyType, targetAddressGroup) if (existingLedgerAccounts.find((account) => account.address === newAccount.address) === undefined) { @@ -105,16 +104,12 @@ export class LedgerAlephium extends AccountDiscovery { console.info(`start discovering active ledger accounts for ${networkId}`) const explorerProvider = new ExplorerProvider(network.explorerApiUrl) - const discoverAccount = (startIndex: number, group?: number): Promise => { - return this.deriveAccount(network.id, startIndex, 'default', group) + const discoverAccount = (startIndex: number): Promise => { + return this.deriveAccount(network.id, startIndex, 'default') } const walletAccounts = await this.deriveActiveAccountsForNetwork(explorerProvider, discoverAccount) const newDiscoveredAccounts = walletAccounts.filter(account => !existingLedgerAccounts.find(a => a.address === account.address)) console.info(`Discovered ${newDiscoveredAccounts.length} new active accounts for ${networkId}`) return newDiscoveredAccounts } - - nextPathIndexForDiscovery(indexes: number[]): number { - return getNextPathIndex(indexes) - } } From d1c05aafa18379275022b53b5d519b94cc04aabc Mon Sep 17 00:00:00 2001 From: lbqds Date: Tue, 22 Oct 2024 08:48:50 +0800 Subject: [PATCH 8/9] Add discover ledger accounts button --- packages/extension/locales/en-US/translation.json | 1 + .../src/ui/features/settings/DeveloperSettings.tsx | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/extension/locales/en-US/translation.json b/packages/extension/locales/en-US/translation.json index ad25c7b0..58438b6d 100644 --- a/packages/extension/locales/en-US/translation.json +++ b/packages/extension/locales/en-US/translation.json @@ -313,6 +313,7 @@ "Experimental": "Experimental", "Update Token List": "Update Token List", "Discover accounts": "Discover accounts", + "Discover ledger accounts": "Discover ledger accounts", "Developer settings": "Developer settings", "Developer Settings": "Developer Settings", "Add network": "Add network", diff --git a/packages/extension/src/ui/features/settings/DeveloperSettings.tsx b/packages/extension/src/ui/features/settings/DeveloperSettings.tsx index b5af7db2..5a3cd0ce 100644 --- a/packages/extension/src/ui/features/settings/DeveloperSettings.tsx +++ b/packages/extension/src/ui/features/settings/DeveloperSettings.tsx @@ -77,9 +77,14 @@ const DeveloperSettings: FC = () => { const onDiscoverAccounts = useCallback(async () => { setLoading(true) await discoveryLocalAccounts() + setLoading(false) + }, [setLoading, discoveryLocalAccounts]) + + const onDiscoverLedgerAccounts = useCallback(async () => { + setLoading(true) await discoveryLedgerAccounts() setLoading(false) - }, [setLoading, discoveryLocalAccounts, discoveryLedgerAccounts]) + }, [setLoading, discoveryLedgerAccounts]) if (loading) { return @@ -119,6 +124,13 @@ const DeveloperSettings: FC = () => { > {t("Discover accounts")} + } + onClick={onDiscoverLedgerAccounts} + title={t("Discover ledger accounts")} + > + {t("Discover ledger accounts")} + ) From 200b0c93b0ab5c7044d92dfe54accc9ec519407e Mon Sep 17 00:00:00 2001 From: lbqds Date: Tue, 22 Oct 2024 14:38:44 +0800 Subject: [PATCH 9/9] Revert "Add discover ledger accounts button" This reverts commit d1c05aafa18379275022b53b5d519b94cc04aabc. --- packages/extension/locales/en-US/translation.json | 1 - .../src/ui/features/settings/DeveloperSettings.tsx | 14 +------------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/packages/extension/locales/en-US/translation.json b/packages/extension/locales/en-US/translation.json index 58438b6d..ad25c7b0 100644 --- a/packages/extension/locales/en-US/translation.json +++ b/packages/extension/locales/en-US/translation.json @@ -313,7 +313,6 @@ "Experimental": "Experimental", "Update Token List": "Update Token List", "Discover accounts": "Discover accounts", - "Discover ledger accounts": "Discover ledger accounts", "Developer settings": "Developer settings", "Developer Settings": "Developer Settings", "Add network": "Add network", diff --git a/packages/extension/src/ui/features/settings/DeveloperSettings.tsx b/packages/extension/src/ui/features/settings/DeveloperSettings.tsx index 5a3cd0ce..b5af7db2 100644 --- a/packages/extension/src/ui/features/settings/DeveloperSettings.tsx +++ b/packages/extension/src/ui/features/settings/DeveloperSettings.tsx @@ -77,14 +77,9 @@ const DeveloperSettings: FC = () => { const onDiscoverAccounts = useCallback(async () => { setLoading(true) await discoveryLocalAccounts() - setLoading(false) - }, [setLoading, discoveryLocalAccounts]) - - const onDiscoverLedgerAccounts = useCallback(async () => { - setLoading(true) await discoveryLedgerAccounts() setLoading(false) - }, [setLoading, discoveryLedgerAccounts]) + }, [setLoading, discoveryLocalAccounts, discoveryLedgerAccounts]) if (loading) { return @@ -124,13 +119,6 @@ const DeveloperSettings: FC = () => { > {t("Discover accounts")} - } - onClick={onDiscoverLedgerAccounts} - title={t("Discover ledger accounts")} - > - {t("Discover ledger accounts")} - )