From b5b080fa56c002028f4b07e847446a661d843b7c Mon Sep 17 00:00:00 2001 From: Petar Todorovic Date: Wed, 9 Apr 2025 23:21:25 +0200 Subject: [PATCH] feat: enhance account sorting logic in ledger connector --- .changeset/silent-clubs-cover.md | 5 ++ packages/widget/src/domain/types/chains.ts | 2 +- .../src/providers/ledger/ledger-connector.ts | 87 +++++++++++-------- 3 files changed, 59 insertions(+), 35 deletions(-) create mode 100644 .changeset/silent-clubs-cover.md diff --git a/.changeset/silent-clubs-cover.md b/.changeset/silent-clubs-cover.md new file mode 100644 index 00000000..ee35bd9b --- /dev/null +++ b/.changeset/silent-clubs-cover.md @@ -0,0 +1,5 @@ +--- +"@stakekit/widget": patch +--- + +feat: enhance account sorting logic in ledger connector diff --git a/packages/widget/src/domain/types/chains.ts b/packages/widget/src/domain/types/chains.ts index a87d6903..e48cec1c 100644 --- a/packages/widget/src/domain/types/chains.ts +++ b/packages/widget/src/domain/types/chains.ts @@ -223,7 +223,7 @@ export const supportedLedgerFamiliesWithCurrency = { family: "ethereum", skChainName: EvmNetworks.Optimism, }, - "avalanche-c": { + avalanche_c_chain: { currencyId: "avalanche_c_chain", family: "ethereum", skChainName: EvmNetworks.AvalancheC, diff --git a/packages/widget/src/providers/ledger/ledger-connector.ts b/packages/widget/src/providers/ledger/ledger-connector.ts index a9696dde..c29c17f7 100644 --- a/packages/widget/src/providers/ledger/ledger-connector.ts +++ b/packages/widget/src/providers/ledger/ledger-connector.ts @@ -4,6 +4,7 @@ import { WindowMessageTransport, deserializeTransaction, } from "@ledgerhq/wallet-api-client"; +import { Networks } from "@stakekit/common"; import type { Chain, WalletDetailsParams, @@ -117,28 +118,44 @@ const createLedgerLiveConnector = ({ ledgerAccounts = accounts; - const accountsWithChain = accounts.reduce( - (acc, next) => { - const family = ledgerCurrencies.get(next.currency); + const chainPriority = new Map([ + [Networks.Polkadot, 1], + [Networks.AvalancheC, 2], + [Networks.Tron, 3], + [Networks.Binance, 4], + [Networks.Cronos, 5], + [Networks.Polygon, 6], + ]); - if (!family) return acc; + const accountsWithChain = accounts + .reduce( + (acc, next) => { + const family = ledgerCurrencies.get(next.currency); - const itemMap = filteredSupportedLedgerFamiliesWithCurrency.get( - family as SupportedLedgerLiveFamilies - ); + if (!family) return acc; - if (!family || !itemMap) return acc; + const itemMap = filteredSupportedLedgerFamiliesWithCurrency.get( + family as SupportedLedgerLiveFamilies + ); - const chainItem = itemMap.get("*") || itemMap.get(next.currency); + if (!family || !itemMap) return acc; - if (chainItem) { - acc.push({ account: next, chainItem }); - } + const chainItem = itemMap.get("*") || itemMap.get(next.currency); - return acc; - }, - [] as { account: Account; chainItem: ChainItem }[] - ); + if (chainItem) { + acc.push({ account: next, chainItem }); + } + + return acc; + }, + [] as { account: Account; chainItem: ChainItem }[] + ) + .sort((a, b) => { + const aPriority = chainPriority.get(a.chainItem.skChainName) || 999; + const bPriority = chainPriority.get(b.chainItem.skChainName) || 999; + + return aPriority - bPriority; + }); if (!accountsWithChain.length) { const defaultChain = Maybe.fromNullable( @@ -161,8 +178,8 @@ const createLedgerLiveConnector = ({ }; } - const preferredAccount = Maybe.fromNullable(queryParams.accountId) - .chain((accId) => + const preferredAccount = Maybe.fromNullable(queryParams.accountId).chain( + (accId) => Maybe.encase(() => { if (accId.startsWith("js:")) { const [, , , address] = accId.split(":"); @@ -172,24 +189,26 @@ const createLedgerLiveConnector = ({ return { type: "accountId", accountId: accId }; }) - ) - .extractNullable(); - - const accountWithChain = List.find((v) => { - if (v.chainItem.skChainName !== queryParams.network) { - return false; - } - - if (preferredAccount) { - if (preferredAccount.type === "address") { - return v.account.address === preferredAccount.address; - } + ); - return v.account.id === preferredAccount.accountId; - } + const accountWithChain = preferredAccount + .chain((pa) => + List.find((v) => { + if (pa.type === "address") { + return v.account.address === pa.address; + } - return true; - }, accountsWithChain) + return v.account.id === pa.accountId; + }, accountsWithChain) + ) + .altLazy(() => + Maybe.fromNullable(queryParams.network).chain((network) => + List.find( + (v) => v.chainItem.skChainName === network, + accountsWithChain + ) + ) + ) .altLazy(() => List.head(accountsWithChain)) .toEither(new Error("Account not found")) .unsafeCoerce();