From 14aa9e9329104195e3038b89349a685afdc0c765 Mon Sep 17 00:00:00 2001 From: S2kael Date: Thu, 12 Dec 2024 12:17:45 +0700 Subject: [PATCH 1/6] [Issue-3915] [Ledger] Hotfix to add `Avail Recovery` app --- .../src/background/KoniTypes.ts | 2 ++ .../src/Popup/Account/ConnectLedger.tsx | 4 +++- .../extension-koni-ui/src/constants/ledger.ts | 22 +++++++++++++++---- .../src/utils/connector/Ledger/index.ts | 2 +- patches/@polkadot+hw-ledger+12.6.2.patch | 7 +++--- patches/@zondax+ledger-substrate+0.44.2.patch | 16 ++++++++++++++ 6 files changed, 44 insertions(+), 9 deletions(-) create mode 100644 patches/@zondax+ledger-substrate+0.44.2.patch diff --git a/packages/extension-base/src/background/KoniTypes.ts b/packages/extension-base/src/background/KoniTypes.ts index ff96b76aeb..ae7f1508a9 100644 --- a/packages/extension-base/src/background/KoniTypes.ts +++ b/packages/extension-base/src/background/KoniTypes.ts @@ -1264,6 +1264,8 @@ export interface LedgerNetwork { isEthereum: boolean; /** Hide networks that are supported by the dot migration app */ isHide?: boolean; + /** Recovery app */ + isRecovery?: boolean; /** Slip44 in the derivation path */ slip44: number; } diff --git a/packages/extension-koni-ui/src/Popup/Account/ConnectLedger.tsx b/packages/extension-koni-ui/src/Popup/Account/ConnectLedger.tsx index c303b72158..6a0e146228 100644 --- a/packages/extension-koni-ui/src/Popup/Account/ConnectLedger.tsx +++ b/packages/extension-koni-ui/src/Popup/Account/ConnectLedger.tsx @@ -57,7 +57,9 @@ const Component: React.FC = (props: Props) => { const networks = useMemo((): ChainItemType[] => supportedLedger .filter(({ isHide }) => !isHide) .map((network) => ({ - name: !network.isGeneric ? network.networkName.replace(' network', '') : network.networkName, + name: !network.isGeneric + ? network.networkName.replace(' network', '').concat(network.isRecovery ? ' Recovery' : '') + : network.networkName, slug: network.slug })), [supportedLedger]); diff --git a/packages/extension-koni-ui/src/constants/ledger.ts b/packages/extension-koni-ui/src/constants/ledger.ts index 4a1d3635d3..e9768862a9 100644 --- a/packages/extension-koni-ui/src/constants/ledger.ts +++ b/packages/extension-koni-ui/src/constants/ledger.ts @@ -105,18 +105,32 @@ export const PredefinedLedgerNetwork: LedgerNetwork[] = [ slip44: 434, isHide: true }, + // { + // accountName: 'Avail', + // appName: 'Avail', + // networkName: 'Avail network', + // genesisHash: ChainInfoMap.avail_mainnet.substrateInfo?.genesisHash || '0xb91746b45e0346cc2f815a520b9c6cb4d5c0902af848db0a80f85932d2e8276a', + // icon: 'substrate', + // network: 'avail', + // slug: ChainInfoMap.avail_mainnet.slug, + // isDevMode: false, + // isGeneric: false, + // isEthereum: false, + // slip44: 709 + // }, { - accountName: 'Avail', - appName: 'Avail', + accountName: 'Avail Recovery', + appName: 'Avail Recovery', networkName: 'Avail network', genesisHash: ChainInfoMap.avail_mainnet.substrateInfo?.genesisHash || '0xb91746b45e0346cc2f815a520b9c6cb4d5c0902af848db0a80f85932d2e8276a', icon: 'substrate', - network: 'avail', + network: 'availRecovery', slug: ChainInfoMap.avail_mainnet.slug, isDevMode: false, isGeneric: false, isEthereum: false, - slip44: 709 + isRecovery: true, + slip44: 354 }, { accountName: 'Acala', diff --git a/packages/extension-koni-ui/src/utils/connector/Ledger/index.ts b/packages/extension-koni-ui/src/utils/connector/Ledger/index.ts index a88dc0a337..b1b8d7e188 100644 --- a/packages/extension-koni-ui/src/utils/connector/Ledger/index.ts +++ b/packages/extension-koni-ui/src/utils/connector/Ledger/index.ts @@ -47,7 +47,7 @@ export const convertLedgerError = (err: Error, t: TFunction, network: string, is } if (message.includes('Data is invalid')) { - if (isGetAddress) { + if (!isGetAddress) { return { status: 'error', message: t('Unable to sign. Open “{{network}}” on Ledger, refresh and approve again', { replace: { network: network } }) diff --git a/patches/@polkadot+hw-ledger+12.6.2.patch b/patches/@polkadot+hw-ledger+12.6.2.patch index 9dbdf99e5c..6bd660f208 100644 --- a/patches/@polkadot+hw-ledger+12.6.2.patch +++ b/patches/@polkadot+hw-ledger+12.6.2.patch @@ -1,12 +1,13 @@ diff --git a/node_modules/@polkadot/hw-ledger/defaults.js b/node_modules/@polkadot/hw-ledger/defaults.js -index 9f06432..97efba8 100644 +index 9f06432..4daa29a 100644 --- a/node_modules/@polkadot/hw-ledger/defaults.js +++ b/node_modules/@polkadot/hw-ledger/defaults.js -@@ -37,5 +37,6 @@ export const ledgerApps = { +@@ -37,5 +37,7 @@ export const ledgerApps = { unique: 'Unique', vtb: 'VTB', xxnetwork: 'XXNetwork', - zeitgeist: 'Zeitgeist' + zeitgeist: 'Zeitgeist', -+ avail: 'Avail' ++ avail: 'Avail', ++ availRecovery: 'AvailRecovery', }; diff --git a/patches/@zondax+ledger-substrate+0.44.2.patch b/patches/@zondax+ledger-substrate+0.44.2.patch new file mode 100644 index 0000000000..834a01fe07 --- /dev/null +++ b/patches/@zondax+ledger-substrate+0.44.2.patch @@ -0,0 +1,16 @@ +diff --git a/node_modules/@zondax/ledger-substrate/dist/supported_apps.js b/node_modules/@zondax/ledger-substrate/dist/supported_apps.js +index 13b6e54..203d4eb 100644 +--- a/node_modules/@zondax/ledger-substrate/dist/supported_apps.js ++++ b/node_modules/@zondax/ledger-substrate/dist/supported_apps.js +@@ -284,5 +284,11 @@ exports.supportedApps = [ + slip0044: 0x800002c5, + ss58_addr_type: 42, + }, ++ { ++ name: 'AvailRecovery', ++ cla: 0xbc, ++ slip0044: 0x80000162, ++ ss58_addr_type: 42, ++ }, + ]; + //# sourceMappingURL=supported_apps.js.map From 33a383310d10ffe9ab77a81d6bba97644e4e2ef3 Mon Sep 17 00:00:00 2001 From: S2kael Date: Wed, 18 Dec 2024 20:06:42 +0700 Subject: [PATCH 2/6] [Issue-3915] [Ledger] Hotfix to connect with Avail Recovery --- package.json | 2 +- patches/@zondax+ledger-substrate+0.44.2.patch | 16 ---------- yarn.lock | 30 +++++++++---------- 3 files changed, 16 insertions(+), 32 deletions(-) delete mode 100644 patches/@zondax+ledger-substrate+0.44.2.patch diff --git a/package.json b/package.json index ee1306914c..fa582794f9 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "@subwallet/react-ui": "5.1.2-b79", "@subwallet/ui-keyring": "0.1.8-beta.0", "@types/bn.js": "^5.1.6", - "@zondax/ledger-substrate": "0.44.2", + "@zondax/ledger-substrate": "1.0.1", "babel-core": "^7.0.0-bridge.0", "babel-jest": "^29.3.1", "browserify-sign": "^4.2.2", diff --git a/patches/@zondax+ledger-substrate+0.44.2.patch b/patches/@zondax+ledger-substrate+0.44.2.patch deleted file mode 100644 index 834a01fe07..0000000000 --- a/patches/@zondax+ledger-substrate+0.44.2.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/node_modules/@zondax/ledger-substrate/dist/supported_apps.js b/node_modules/@zondax/ledger-substrate/dist/supported_apps.js -index 13b6e54..203d4eb 100644 ---- a/node_modules/@zondax/ledger-substrate/dist/supported_apps.js -+++ b/node_modules/@zondax/ledger-substrate/dist/supported_apps.js -@@ -284,5 +284,11 @@ exports.supportedApps = [ - slip0044: 0x800002c5, - ss58_addr_type: 42, - }, -+ { -+ name: 'AvailRecovery', -+ cla: 0xbc, -+ slip0044: 0x80000162, -+ ss58_addr_type: 42, -+ }, - ]; - //# sourceMappingURL=supported_apps.js.map diff --git a/yarn.lock b/yarn.lock index a8e0f8cd0c..402b38b4f2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9243,23 +9243,23 @@ __metadata: languageName: node linkType: hard -"@zondax/ledger-js@npm:^0.8.2": - version: 0.8.2 - resolution: "@zondax/ledger-js@npm:0.8.2" +"@zondax/ledger-js@npm:^0.11.0": + version: 0.11.0 + resolution: "@zondax/ledger-js@npm:0.11.0" dependencies: "@ledgerhq/hw-transport": 6.30.6 - checksum: 7b33cd87d8569732028a57e594a4674f9fa232155c227031a00985bf9b6af62774a5cdbed59a5754c998122862ded64060b042c97850a38e6b734455828b362d + checksum: 38743b887fceaeb13460d70a127cb385f5df034fe014f698d4f164f0d111add71dd01381c182ac71135c7fb43f38e7b21218d5df7d87d69ddaee17dd9c57d392 languageName: node linkType: hard -"@zondax/ledger-substrate@npm:0.44.2": - version: 0.44.2 - resolution: "@zondax/ledger-substrate@npm:0.44.2" +"@zondax/ledger-substrate@npm:1.0.1": + version: 1.0.1 + resolution: "@zondax/ledger-substrate@npm:1.0.1" dependencies: - "@ledgerhq/hw-transport": 6.30.6 - "@zondax/ledger-js": ^0.8.2 - axios: ^1.6.8 - checksum: 1f0035725c88335c8e1c234fc75ebdbc39666d8567bb3d77734ed861f85a49b87d358f520bef76287ff2e75914f790a5454cb27b7814489292100730023a9541 + "@ledgerhq/hw-transport": 6.31.2 + "@zondax/ledger-js": ^0.11.0 + axios: ^1.7.4 + checksum: e5fd0743bb6a5638c7a633131a0f4db84e9e8eec720fa659f6f116a8fe6629125b6d472184683c1a64a88fadf89bb54c6e3ffa4fa063470b4395df87d7be0bb0 languageName: node linkType: hard @@ -10133,14 +10133,14 @@ __metadata: languageName: node linkType: hard -"axios@npm:^1.6.8": - version: 1.6.8 - resolution: "axios@npm:1.6.8" +"axios@npm:^1.7.4": + version: 1.7.9 + resolution: "axios@npm:1.7.9" dependencies: follow-redirects: ^1.15.6 form-data: ^4.0.0 proxy-from-env: ^1.1.0 - checksum: bf007fa4b207d102459300698620b3b0873503c6d47bf5a8f6e43c0c64c90035a4f698b55027ca1958f61ab43723df2781c38a99711848d232cad7accbcdfcdd + checksum: cb8ce291818effda09240cb60f114d5625909b345e10f389a945320e06acf0bc949d0f8422d25720f5dd421362abee302c99f5e97edec4c156c8939814b23d19 languageName: node linkType: hard From 9c4b8453cd67563e7d7375b91f9e70fe9bee9426 Mon Sep 17 00:00:00 2001 From: PDTnhah Date: Tue, 24 Dec 2024 19:23:56 +0700 Subject: [PATCH 3/6] [Issue-3915] Extension - Ledger - Support Avail Recovery app --- .../src/background/KoniTypes.ts | 1 + .../context/handlers/Ledger.ts | 5 ++-- .../src/types/account/info/keyring.ts | 1 + .../src/Popup/Account/ConnectLedger.tsx | 5 ++-- .../Confirmations/parts/Sign/Substrate.tsx | 2 +- .../extension-koni-ui/src/constants/ledger.ts | 29 ++++++++++--------- .../src/contexts/ThemeContext.tsx | 2 +- .../src/hooks/ledger/useLedger.ts | 20 ++++++++----- 8 files changed, 37 insertions(+), 28 deletions(-) diff --git a/packages/extension-base/src/background/KoniTypes.ts b/packages/extension-base/src/background/KoniTypes.ts index ae7f1508a9..063e4e0cd0 100644 --- a/packages/extension-base/src/background/KoniTypes.ts +++ b/packages/extension-base/src/background/KoniTypes.ts @@ -792,6 +792,7 @@ export interface CreateHardwareAccountItem { name: string; isEthereum: boolean; isGeneric: boolean; + isLedgerRecovery?: boolean; } export interface RequestAccountCreateHardwareV2 extends CreateHardwareAccountItem { diff --git a/packages/extension-base/src/services/keyring-service/context/handlers/Ledger.ts b/packages/extension-base/src/services/keyring-service/context/handlers/Ledger.ts index 439a0efd8a..f06654aca1 100644 --- a/packages/extension-base/src/services/keyring-service/context/handlers/Ledger.ts +++ b/packages/extension-base/src/services/keyring-service/context/handlers/Ledger.ts @@ -86,7 +86,7 @@ export class AccountLedgerHandler extends AccountBaseHandler { const pairs: KeyringPair[] = []; for (const account of accounts) { - const { accountIndex, address, addressOffset, genesisHash, hardwareType, isEthereum, isGeneric, name, originGenesisHash } = account; + const { accountIndex, address, addressOffset, genesisHash, hardwareType, isEthereum, isGeneric, isLedgerRecovery, name, originGenesisHash } = account; const baseMeta: KeyringPair$Meta = { name, @@ -95,7 +95,8 @@ export class AccountLedgerHandler extends AccountBaseHandler { addressOffset, genesisHash, originGenesisHash, - isGeneric + isGeneric, + isLedgerRecovery }; const type = isEthereum ? 'ethereum' : 'sr25519'; diff --git a/packages/extension-base/src/types/account/info/keyring.ts b/packages/extension-base/src/types/account/info/keyring.ts index ca66298e62..cde868e8d6 100644 --- a/packages/extension-base/src/types/account/info/keyring.ts +++ b/packages/extension-base/src/types/account/info/keyring.ts @@ -59,6 +59,7 @@ export interface AccountLedgerData { originGenesisHash?: string | null; /** Ledger's availableGenesisHashes */ availableGenesisHashes?: string[]; + isLedgerRecovery?: boolean; } /** diff --git a/packages/extension-koni-ui/src/Popup/Account/ConnectLedger.tsx b/packages/extension-koni-ui/src/Popup/Account/ConnectLedger.tsx index 6a0e146228..7a05a6dd76 100644 --- a/packages/extension-koni-ui/src/Popup/Account/ConnectLedger.tsx +++ b/packages/extension-koni-ui/src/Popup/Account/ConnectLedger.tsx @@ -95,7 +95,7 @@ const Component: React.FC = (props: Props) => { return chainMigrateMode && selectedChain ? `${selectedChain.accountName}` : ''; }, [chainMigrateMode, migrateSupportLedger]); - const { error, getAllAddress, isLoading, isLocked, ledger, refresh, warning } = useLedger(chain, true, false, false, selectedChainMigrateMode?.genesisHash); + const { error, getAllAddress, isLoading, isLocked, ledger, refresh, warning } = useLedger(chain, true, false, false, selectedChainMigrateMode?.genesisHash, selectedChain?.isRecovery); const onPreviousStep = useCallback(() => { setFirstStep(true); @@ -250,7 +250,8 @@ const Component: React.FC = (props: Props) => { hardwareType: 'ledger', name: item.name, isEthereum: selectedChain.isEthereum, - isGeneric: selectedChain.isGeneric + isGeneric: selectedChain.isGeneric, + isLedgerRecovery: selectedChain?.isRecovery })) }) .then(() => { diff --git a/packages/extension-koni-ui/src/Popup/Confirmations/parts/Sign/Substrate.tsx b/packages/extension-koni-ui/src/Popup/Confirmations/parts/Sign/Substrate.tsx index 3f612e37e0..98142c2207 100644 --- a/packages/extension-koni-ui/src/Popup/Confirmations/parts/Sign/Substrate.tsx +++ b/packages/extension-koni-ui/src/Popup/Confirmations/parts/Sign/Substrate.tsx @@ -257,7 +257,7 @@ const Component: React.FC = (props: Props) => { refresh: refreshLedger, signMessage: ledgerSignMessage, signTransaction: ledgerSignTransaction, - warning: ledgerWarning } = useLedger(chainSlug, activeLedger, true, forceUseMigrationApp, account?.originGenesisHash); + warning: ledgerWarning } = useLedger(chainSlug, activeLedger, true, forceUseMigrationApp, account?.originGenesisHash, account?.isLedgerRecovery); const isLedgerConnected = useMemo(() => !isLocked && !isLedgerLoading && !!ledger, [isLedgerLoading, isLocked, ledger]); diff --git a/packages/extension-koni-ui/src/constants/ledger.ts b/packages/extension-koni-ui/src/constants/ledger.ts index e9768862a9..af6be77b60 100644 --- a/packages/extension-koni-ui/src/constants/ledger.ts +++ b/packages/extension-koni-ui/src/constants/ledger.ts @@ -105,19 +105,20 @@ export const PredefinedLedgerNetwork: LedgerNetwork[] = [ slip44: 434, isHide: true }, - // { - // accountName: 'Avail', - // appName: 'Avail', - // networkName: 'Avail network', - // genesisHash: ChainInfoMap.avail_mainnet.substrateInfo?.genesisHash || '0xb91746b45e0346cc2f815a520b9c6cb4d5c0902af848db0a80f85932d2e8276a', - // icon: 'substrate', - // network: 'avail', - // slug: ChainInfoMap.avail_mainnet.slug, - // isDevMode: false, - // isGeneric: false, - // isEthereum: false, - // slip44: 709 - // }, + { + accountName: 'Avail', + appName: 'Avail', + networkName: 'Avail network', + genesisHash: ChainInfoMap.avail_mainnet.substrateInfo?.genesisHash || '0xb91746b45e0346cc2f815a520b9c6cb4d5c0902af848db0a80f85932d2e8276a', + icon: 'substrate', + network: 'avail', + slug: ChainInfoMap.avail_mainnet.slug, + isDevMode: false, + isGeneric: false, + isEthereum: false, + isRecovery: false, + slip44: 709 + }, { accountName: 'Avail Recovery', appName: 'Avail Recovery', @@ -125,7 +126,7 @@ export const PredefinedLedgerNetwork: LedgerNetwork[] = [ genesisHash: ChainInfoMap.avail_mainnet.substrateInfo?.genesisHash || '0xb91746b45e0346cc2f815a520b9c6cb4d5c0902af848db0a80f85932d2e8276a', icon: 'substrate', network: 'availRecovery', - slug: ChainInfoMap.avail_mainnet.slug, + slug: 'avail_mainnet_recovery', isDevMode: false, isGeneric: false, isEthereum: false, diff --git a/packages/extension-koni-ui/src/contexts/ThemeContext.tsx b/packages/extension-koni-ui/src/contexts/ThemeContext.tsx index 9d915801a7..0fd5ad817a 100644 --- a/packages/extension-koni-ui/src/contexts/ThemeContext.tsx +++ b/packages/extension-koni-ui/src/contexts/ThemeContext.tsx @@ -361,7 +361,7 @@ export function ThemeProvider ({ children }: ThemeProviderProps): React.ReactEle const themeConfig = useMemo(() => { const config = SW_THEME_CONFIGS[themeName]; - Object.assign(config.logoMap.network, logoMaps.chainLogoMap); + Object.assign(config.logoMap.network, logoMaps.chainLogoMap, { avail_mainnet_recovery: logoMaps.chainLogoMap.avail_mainnet }); Object.assign(config.logoMap.symbol, logoMaps.assetLogoMap); return config; diff --git a/packages/extension-koni-ui/src/hooks/ledger/useLedger.ts b/packages/extension-koni-ui/src/hooks/ledger/useLedger.ts index 1158f9cff4..f4ef25c3b9 100644 --- a/packages/extension-koni-ui/src/hooks/ledger/useLedger.ts +++ b/packages/extension-koni-ui/src/hooks/ledger/useLedger.ts @@ -42,7 +42,11 @@ const baseState: StateBase = { // && uiSettings.ledgerConn !== 'none' }; -const getNetwork = (ledgerChains: LedgerNetwork[], slug: string, isEthereumNetwork: boolean): LedgerNetwork | undefined => { +const getNetwork = (ledgerChains: LedgerNetwork[], slug: string, isEthereumNetwork: boolean, isRecovery?: boolean): LedgerNetwork | undefined => { + if (isRecovery) { + return ledgerChains.find((network) => network.isRecovery); + } + return ledgerChains.find((network) => network.slug === slug || (network.isEthereum && isEthereumNetwork)); }; @@ -50,12 +54,12 @@ const getNetworkByGenesisHash = (ledgerChains: MigrationLedgerNetwork[], genesis return ledgerChains.find((network) => network.genesisHash === genesisHash); }; -const retrieveLedger = (chainSlug: string, ledgerChains: LedgerNetwork[], migrateLedgerChains: MigrationLedgerNetwork[], isEthereumNetwork: boolean, forceMigration: boolean, originGenesisHash?: string | null): Ledger => { +const retrieveLedger = (chainSlug: string, ledgerChains: LedgerNetwork[], migrateLedgerChains: MigrationLedgerNetwork[], isEthereumNetwork: boolean, forceMigration: boolean, originGenesisHash?: string | null, isRecovery?: boolean): Ledger => { const { isLedgerCapable } = baseState; assert(isLedgerCapable, ledgerIncompatible); - const def = getNetwork(ledgerChains, chainSlug, isEthereumNetwork); + const def = getNetwork(ledgerChains, chainSlug, isEthereumNetwork, isRecovery); assert(def, 'There is no known Ledger app available for this chain'); @@ -86,7 +90,7 @@ const retrieveLedger = (chainSlug: string, ledgerChains: LedgerNetwork[], migrat } }; -export function useLedger (chainSlug?: string, active = true, isSigning = false, forceMigration = false, originGenesisHash?: string | null): Result { +export function useLedger (chainSlug?: string, active = true, isSigning = false, forceMigration = false, originGenesisHash?: string | null, isRecovery?: boolean): Result { const { t } = useTranslation(); const [ledgerChains, migrateLedgerChains] = useGetSupportedLedger(); @@ -133,14 +137,14 @@ export function useLedger (chainSlug?: string, active = true, isSigning = false, } try { - return retrieveLedger(chainSlug, ledgerChains, migrateLedgerChains, isEvmNetwork, forceMigration, originGenesisHash); + return retrieveLedger(chainSlug, ledgerChains, migrateLedgerChains, isEvmNetwork, forceMigration, originGenesisHash, isRecovery); } catch (error) { setError((error as Error).message); } } return null; - }, [refreshLock, chainSlug, active, ledgerChains, migrateLedgerChains, isEvmNetwork, forceMigration, originGenesisHash]); + }, [refreshLock, chainSlug, active, ledgerChains, migrateLedgerChains, isEvmNetwork, forceMigration, originGenesisHash, isRecovery]); const appName = useMemo(() => { const unknownNetwork = 'unknown network'; @@ -151,7 +155,7 @@ export function useLedger (chainSlug?: string, active = true, isSigning = false, const chainInfo = chainInfoMap[chainSlug]; const isEthereumNetwork = chainInfo ? _isChainEvmCompatible(chainInfo) : false; - const { appName, isEthereum, isGeneric } = getNetwork(ledgerChains, chainSlug, isEthereumNetwork) || { appName: 'Polkadot Migration', isGeneric: true }; + const { appName, isEthereum, isGeneric } = getNetwork(ledgerChains, chainSlug, isEthereumNetwork, isRecovery) || { appName: 'Polkadot Migration', isGeneric: true }; if (!isGeneric && forceMigration && !isEthereum) { if (NotNeedMigrationGens.includes(chainInfo?.substrateInfo?.genesisHash || '')) { @@ -162,7 +166,7 @@ export function useLedger (chainSlug?: string, active = true, isSigning = false, } return appName; - }, [chainInfoMap, forceMigration, ledgerChains, chainSlug]); + }, [chainInfoMap, forceMigration, ledgerChains, chainSlug, isRecovery]); const refresh = useCallback(() => { setRefreshLock(true); From a4473fe3b94f8671de52f46264c9a4caa29adf4b Mon Sep 17 00:00:00 2001 From: PDTnhah Date: Wed, 25 Dec 2024 17:50:49 +0700 Subject: [PATCH 4/6] [Issue-3915] Extension - Ledger - Support Avail Recovery app --- .../src/types/account/info/keyring.ts | 1 + .../src/Popup/Account/ConnectLedger.tsx | 13 +- .../components/Field/LedgerChainSelector.tsx | 190 ++++++++++++++++++ .../extension-koni-ui/src/constants/ledger.ts | 3 +- .../src/contexts/ThemeContext.tsx | 2 +- .../src/hooks/ledger/useLedger.ts | 2 +- .../src/utils/account/ledger.ts | 4 +- 7 files changed, 206 insertions(+), 9 deletions(-) create mode 100644 packages/extension-koni-ui/src/components/Field/LedgerChainSelector.tsx diff --git a/packages/extension-base/src/types/account/info/keyring.ts b/packages/extension-base/src/types/account/info/keyring.ts index cde868e8d6..5891a41ca9 100644 --- a/packages/extension-base/src/types/account/info/keyring.ts +++ b/packages/extension-base/src/types/account/info/keyring.ts @@ -59,6 +59,7 @@ export interface AccountLedgerData { originGenesisHash?: string | null; /** Ledger's availableGenesisHashes */ availableGenesisHashes?: string[]; + /** Is Ledger recovery chain */ isLedgerRecovery?: boolean; } diff --git a/packages/extension-koni-ui/src/Popup/Account/ConnectLedger.tsx b/packages/extension-koni-ui/src/Popup/Account/ConnectLedger.tsx index 7a05a6dd76..9d5de9940c 100644 --- a/packages/extension-koni-ui/src/Popup/Account/ConnectLedger.tsx +++ b/packages/extension-koni-ui/src/Popup/Account/ConnectLedger.tsx @@ -18,6 +18,8 @@ import { useSelector } from 'react-redux'; import styled from 'styled-components'; import DefaultLogosMap from '../../assets/logo'; +import { LedgerChainSelector, LedgerItemType } from '@subwallet/extension-koni-ui/components/Field/LedgerChainSelector'; +import { convertKey } from '@subwallet/extension-koni-ui/utils'; type Props = ThemeProps; @@ -54,13 +56,14 @@ const Component: React.FC = (props: Props) => { const { accounts } = useSelector((state: RootState) => state.accountState); - const networks = useMemo((): ChainItemType[] => supportedLedger + const networks = useMemo((): LedgerItemType[] => supportedLedger .filter(({ isHide }) => !isHide) .map((network) => ({ name: !network.isGeneric ? network.networkName.replace(' network', '').concat(network.isRecovery ? ' Recovery' : '') : network.networkName, - slug: network.slug + chain: network.slug, + slug: convertKey(network) })), [supportedLedger]); const networkMigrates = useMemo((): ChainItemType[] => migrateSupportLedger @@ -80,7 +83,7 @@ const Component: React.FC = (props: Props) => { const [isSubmitting, setIsSubmitting] = useState(false); const selectedChain = useMemo((): LedgerNetwork | undefined => { - return supportedLedger.find((n) => n.slug === chain); + return supportedLedger.find((n) => convertKey(n) === chain); }, [chain, supportedLedger]); const selectedChainMigrateMode = useMemo((): MigrationLedgerNetwork | undefined => { @@ -95,7 +98,7 @@ const Component: React.FC = (props: Props) => { return chainMigrateMode && selectedChain ? `${selectedChain.accountName}` : ''; }, [chainMigrateMode, migrateSupportLedger]); - const { error, getAllAddress, isLoading, isLocked, ledger, refresh, warning } = useLedger(chain, true, false, false, selectedChainMigrateMode?.genesisHash, selectedChain?.isRecovery); + const { error, getAllAddress, isLoading, isLocked, ledger, refresh, warning } = useLedger(selectedChain?.slug, true, false, false, selectedChainMigrateMode?.genesisHash, selectedChain?.isRecovery); const onPreviousStep = useCallback(() => { setFirstStep(true); @@ -329,7 +332,7 @@ const Component: React.FC = (props: Props) => { sizeSquircleBorder={108} /> - ; + +function Component (props: Props, ref: ForwardedRef): React.ReactElement { + const { className = '', disabled, id = 'address-input', items, label, loading, messageTooltip, placeholder, statusHelp, title, tooltip, value } = props; + const { t } = useTranslation(); + const { token } = useTheme() as Theme; + const { onSelect } = useSelectModalInputHelper(props, ref); + + const renderChainSelected = useCallback((item: LedgerItemType) => { + if (loading) { + return ( +
{t('Loading ...')}
+ ); + } + + return ( +
{item.name}
+ ); + }, [loading, t]); + + const searchFunction = useCallback((item: LedgerItemType, searchText: string) => { + const searchTextLowerCase = searchText.toLowerCase(); + + return ( + item.name.toLowerCase().includes(searchTextLowerCase) + ); + }, []); + + const chainLogo = useMemo(() => { + const chain = value?.replaceAll(RECOVERY_SLUG, '') || ''; + + return ( + + ); + }, [token.controlHeightSM, value]); + + const renderItem = useCallback((item: LedgerItemType, selected: boolean) => { + if (item.disabled && !!messageTooltip) { + return ( + +
+ + +
)} + /> + +
+ ); + } + + return ( + + + )} + /> + ); + }, [messageTooltip, t, token.colorSuccess]); + + return ( + ('Network name')} + selected={value || ''} + statusHelp={statusHelp} + title={title || label || placeholder || t('Select network')} + tooltip={tooltip} + /> + ); +} + +export const LedgerChainSelector = styled(forwardRef(Component))(({ theme: { token } }: Props) => { + return ({ + '&.ant-select-modal-input-container .ant-select-modal-input-wrapper': { + paddingLeft: 12, + paddingRight: 12 + }, + + '&.chain-selector-input': { + '.__selected-item, .__loading-text': { + whiteSpace: 'nowrap', + overflow: 'hidden', + textOverflow: 'ellipsis' + }, + + '.__selected-item': { + color: token.colorText, + fontWeight: 500, + lineHeight: token.lineHeightHeading6 + }, + + '.__loading-text': { + color: token.colorTextLight4 + } + }, + + '.chain-logo': { + margin: '-1px 0' + }, + + '.ant-network-item .__check-icon': { + display: 'flex', + width: 40, + justifyContent: 'center' + }, + + '.ant-network-item.disabled': { + opacity: token.opacityDisable, + '.ant-network-item-content': { + cursor: 'not-allowed', + + '&:hover': { + backgroundColor: token.colorBgSecondary + } + } + } + }); +}); diff --git a/packages/extension-koni-ui/src/constants/ledger.ts b/packages/extension-koni-ui/src/constants/ledger.ts index af6be77b60..61dd559cab 100644 --- a/packages/extension-koni-ui/src/constants/ledger.ts +++ b/packages/extension-koni-ui/src/constants/ledger.ts @@ -8,6 +8,7 @@ export const SUBSTRATE_GENERIC_KEY = 'substrate_generic'; export const SUBSTRATE_MIGRATION_KEY = 'substrate_migration'; export const POLKADOT_KEY = 'polkadot'; export const POLKADOT_SLIP_44 = 354; +export const RECOVERY_SLUG = '_recovery'; export const PredefinedLedgerNetwork: LedgerNetwork[] = [ { @@ -126,7 +127,7 @@ export const PredefinedLedgerNetwork: LedgerNetwork[] = [ genesisHash: ChainInfoMap.avail_mainnet.substrateInfo?.genesisHash || '0xb91746b45e0346cc2f815a520b9c6cb4d5c0902af848db0a80f85932d2e8276a', icon: 'substrate', network: 'availRecovery', - slug: 'avail_mainnet_recovery', + slug: ChainInfoMap.avail_mainnet.slug, isDevMode: false, isGeneric: false, isEthereum: false, diff --git a/packages/extension-koni-ui/src/contexts/ThemeContext.tsx b/packages/extension-koni-ui/src/contexts/ThemeContext.tsx index 0fd5ad817a..9d915801a7 100644 --- a/packages/extension-koni-ui/src/contexts/ThemeContext.tsx +++ b/packages/extension-koni-ui/src/contexts/ThemeContext.tsx @@ -361,7 +361,7 @@ export function ThemeProvider ({ children }: ThemeProviderProps): React.ReactEle const themeConfig = useMemo(() => { const config = SW_THEME_CONFIGS[themeName]; - Object.assign(config.logoMap.network, logoMaps.chainLogoMap, { avail_mainnet_recovery: logoMaps.chainLogoMap.avail_mainnet }); + Object.assign(config.logoMap.network, logoMaps.chainLogoMap); Object.assign(config.logoMap.symbol, logoMaps.assetLogoMap); return config; diff --git a/packages/extension-koni-ui/src/hooks/ledger/useLedger.ts b/packages/extension-koni-ui/src/hooks/ledger/useLedger.ts index f4ef25c3b9..7cca4c9ffb 100644 --- a/packages/extension-koni-ui/src/hooks/ledger/useLedger.ts +++ b/packages/extension-koni-ui/src/hooks/ledger/useLedger.ts @@ -44,7 +44,7 @@ const baseState: StateBase = { const getNetwork = (ledgerChains: LedgerNetwork[], slug: string, isEthereumNetwork: boolean, isRecovery?: boolean): LedgerNetwork | undefined => { if (isRecovery) { - return ledgerChains.find((network) => network.isRecovery); + return ledgerChains.find((network) => network.slug === slug && network.isRecovery); } return ledgerChains.find((network) => network.slug === slug || (network.isEthereum && isEthereumNetwork)); diff --git a/packages/extension-koni-ui/src/utils/account/ledger.ts b/packages/extension-koni-ui/src/utils/account/ledger.ts index 9a44b3c6e6..4310237a9d 100644 --- a/packages/extension-koni-ui/src/utils/account/ledger.ts +++ b/packages/extension-koni-ui/src/utils/account/ledger.ts @@ -5,7 +5,7 @@ import { _ChainInfo } from '@subwallet/chain-list/types'; import { LedgerNetwork } from '@subwallet/extension-base/background/KoniTypes'; import { _ChainState } from '@subwallet/extension-base/services/chain-service/types'; import { _isChainEvmCompatible } from '@subwallet/extension-base/services/chain-service/utils'; -import { PredefinedLedgerNetwork } from '@subwallet/extension-koni-ui/constants/ledger'; +import { PredefinedLedgerNetwork, RECOVERY_SLUG } from '@subwallet/extension-koni-ui/constants/ledger'; interface ChainItem extends _ChainState { isEthereum: boolean; @@ -25,3 +25,5 @@ export const getSupportedLedger = (networkInfoMap: Record, n return networkInfoItems.find((item) => ledgerNetwork.slug === item.slug || (ledgerNetwork.isEthereum && item.isEthereum)); }); }; + +export const convertKey = (network: LedgerNetwork) => network.slug.concat(network.isRecovery ? RECOVERY_SLUG : ''); From 9f8b532fdc4c1a311487b760a774a1dd216f0f77 Mon Sep 17 00:00:00 2001 From: PDTnhah Date: Wed, 25 Dec 2024 18:08:55 +0700 Subject: [PATCH 5/6] [Issue-3915] Fix lint --- .../extension-koni-ui/src/Popup/Account/ConnectLedger.tsx | 6 +++--- packages/extension-koni-ui/src/utils/account/ledger.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/extension-koni-ui/src/Popup/Account/ConnectLedger.tsx b/packages/extension-koni-ui/src/Popup/Account/ConnectLedger.tsx index 9d5de9940c..c775661bcc 100644 --- a/packages/extension-koni-ui/src/Popup/Account/ConnectLedger.tsx +++ b/packages/extension-koni-ui/src/Popup/Account/ConnectLedger.tsx @@ -19,7 +19,7 @@ import styled from 'styled-components'; import DefaultLogosMap from '../../assets/logo'; import { LedgerChainSelector, LedgerItemType } from '@subwallet/extension-koni-ui/components/Field/LedgerChainSelector'; -import { convertKey } from '@subwallet/extension-koni-ui/utils'; +import { convertNetworkSlug } from '@subwallet/extension-koni-ui/utils'; type Props = ThemeProps; @@ -63,7 +63,7 @@ const Component: React.FC = (props: Props) => { ? network.networkName.replace(' network', '').concat(network.isRecovery ? ' Recovery' : '') : network.networkName, chain: network.slug, - slug: convertKey(network) + slug: convertNetworkSlug(network) })), [supportedLedger]); const networkMigrates = useMemo((): ChainItemType[] => migrateSupportLedger @@ -83,7 +83,7 @@ const Component: React.FC = (props: Props) => { const [isSubmitting, setIsSubmitting] = useState(false); const selectedChain = useMemo((): LedgerNetwork | undefined => { - return supportedLedger.find((n) => convertKey(n) === chain); + return supportedLedger.find((n) => convertNetworkSlug(n) === chain); }, [chain, supportedLedger]); const selectedChainMigrateMode = useMemo((): MigrationLedgerNetwork | undefined => { diff --git a/packages/extension-koni-ui/src/utils/account/ledger.ts b/packages/extension-koni-ui/src/utils/account/ledger.ts index 4310237a9d..8f7e6c00ed 100644 --- a/packages/extension-koni-ui/src/utils/account/ledger.ts +++ b/packages/extension-koni-ui/src/utils/account/ledger.ts @@ -26,4 +26,4 @@ export const getSupportedLedger = (networkInfoMap: Record, n }); }; -export const convertKey = (network: LedgerNetwork) => network.slug.concat(network.isRecovery ? RECOVERY_SLUG : ''); +export const convertNetworkSlug = (network: LedgerNetwork) => network.slug.concat(network.isRecovery ? RECOVERY_SLUG : ''); From 15c3560d3c9eb38d8af46112bfacfa658e67aeb2 Mon Sep 17 00:00:00 2001 From: PDTnhah Date: Wed, 25 Dec 2024 18:11:07 +0700 Subject: [PATCH 6/6] [Issue-3915] Fix lint --- .../extension-koni-ui/src/Popup/Account/ConnectLedger.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/extension-koni-ui/src/Popup/Account/ConnectLedger.tsx b/packages/extension-koni-ui/src/Popup/Account/ConnectLedger.tsx index c775661bcc..f2e0588060 100644 --- a/packages/extension-koni-ui/src/Popup/Account/ConnectLedger.tsx +++ b/packages/extension-koni-ui/src/Popup/Account/ConnectLedger.tsx @@ -4,11 +4,13 @@ import { LedgerNetwork, MigrationLedgerNetwork } from '@subwallet/extension-base/background/KoniTypes'; import { reformatAddress } from '@subwallet/extension-base/utils'; import { AccountItemWithName, AccountWithNameSkeleton, BasicOnChangeFunction, ChainSelector, DualLogo, InfoIcon, Layout, PageWrapper } from '@subwallet/extension-koni-ui/components'; +import { LedgerChainSelector, LedgerItemType } from '@subwallet/extension-koni-ui/components/Field/LedgerChainSelector'; import { ATTACH_ACCOUNT_MODAL, SUBSTRATE_MIGRATION_KEY, USER_GUIDE_URL } from '@subwallet/extension-koni-ui/constants'; import { useAutoNavigateToCreatePassword, useCompleteCreateAccount, useGetSupportedLedger, useGoBackFromCreateAccount, useLedger } from '@subwallet/extension-koni-ui/hooks'; import { createAccountHardwareMultiple } from '@subwallet/extension-koni-ui/messaging'; import { RootState } from '@subwallet/extension-koni-ui/stores'; import { ChainItemType, ThemeProps } from '@subwallet/extension-koni-ui/types'; +import { convertNetworkSlug } from '@subwallet/extension-koni-ui/utils'; import { BackgroundIcon, Button, Icon, Image, SwList } from '@subwallet/react-ui'; import CN from 'classnames'; import { CheckCircle, CircleNotch, Swatches } from 'phosphor-react'; @@ -18,8 +20,6 @@ import { useSelector } from 'react-redux'; import styled from 'styled-components'; import DefaultLogosMap from '../../assets/logo'; -import { LedgerChainSelector, LedgerItemType } from '@subwallet/extension-koni-ui/components/Field/LedgerChainSelector'; -import { convertNetworkSlug } from '@subwallet/extension-koni-ui/utils'; type Props = ThemeProps;