From e5cb22742a352a6d6d5d18b064fea65efdc3a611 Mon Sep 17 00:00:00 2001 From: 0xKheops <26880866+0xKheops@users.noreply.github.com> Date: Fri, 20 Dec 2024 16:48:54 +0900 Subject: [PATCH] refactor: connect ledger component --- .../Shared/ConnectLedgerBase.tsx | 81 +++++++++++++++++ .../Shared/ConnectLedgerEthereum.tsx | 85 ++++-------------- .../Shared/ConnectLedgerSubstrateGeneric.tsx | 87 ++++--------------- .../Shared/ConnectLedgerSubstrateLegacy.tsx | 83 +++--------------- 4 files changed, 126 insertions(+), 210 deletions(-) create mode 100644 apps/extension/src/ui/domains/Account/AccountAdd/AccountAddLedger/Shared/ConnectLedgerBase.tsx diff --git a/apps/extension/src/ui/domains/Account/AccountAdd/AccountAddLedger/Shared/ConnectLedgerBase.tsx b/apps/extension/src/ui/domains/Account/AccountAdd/AccountAddLedger/Shared/ConnectLedgerBase.tsx new file mode 100644 index 000000000..b8653064f --- /dev/null +++ b/apps/extension/src/ui/domains/Account/AccountAdd/AccountAddLedger/Shared/ConnectLedgerBase.tsx @@ -0,0 +1,81 @@ +import { log } from "extension-shared" +import { FC, useCallback, useEffect, useRef, useState } from "react" +import { useTranslation } from "react-i18next" + +import { Spacer } from "@talisman/components/Spacer" +import { + LedgerConnectionStatus, + LedgerConnectionStatusProps, +} from "@ui/domains/Account/LedgerConnectionStatus" +import { getCustomTalismanLedgerError } from "@ui/hooks/ledger/errors" + +type ConnectLedgerBaseProps = { + appName: string + isReadyCheck: () => Promise + onReadyChanged: (ready: boolean) => void + className?: string +} + +export const ConnectLedgerBase: FC = ({ + appName, + isReadyCheck, + onReadyChanged, + className, +}) => { + const { t } = useTranslation("admin") + + // flag to prevents double connect attempt in dev mode + const refIsBusy = useRef(false) + + const [connectionStatus, setConnectionStatus] = useState({ + status: "connecting", + message: t("Connecting to Ledger..."), + }) + + const connect = useCallback(async () => { + if (refIsBusy.current) return + refIsBusy.current = true + + try { + onReadyChanged?.(false) + setConnectionStatus({ + status: "connecting", + message: t("Connecting to Ledger..."), + }) + + await isReadyCheck() + + setConnectionStatus({ + status: "ready", + message: t("Successfully connected to Ledger."), + }) + onReadyChanged?.(true) + } catch (err) { + const error = getCustomTalismanLedgerError(err) + log.error("ConnectLedgerSubstrateGeneric", { error }) + setConnectionStatus({ + status: "error", + message: error.message, + onRetryClick: connect, + }) + } finally { + refIsBusy.current = false + } + }, [isReadyCheck, onReadyChanged, t]) + + useEffect(() => { + connect() + }, [connect, isReadyCheck, onReadyChanged]) + + return ( +
+
+ {t("Connect and unlock your Ledger, then open the {{appName}} app on your Ledger.", { + appName, + })} +
+ + {!!connectionStatus && } +
+ ) +} diff --git a/apps/extension/src/ui/domains/Account/AccountAdd/AccountAddLedger/Shared/ConnectLedgerEthereum.tsx b/apps/extension/src/ui/domains/Account/AccountAdd/AccountAddLedger/Shared/ConnectLedgerEthereum.tsx index f15917686..9e01d519d 100644 --- a/apps/extension/src/ui/domains/Account/AccountAdd/AccountAddLedger/Shared/ConnectLedgerEthereum.tsx +++ b/apps/extension/src/ui/domains/Account/AccountAdd/AccountAddLedger/Shared/ConnectLedgerEthereum.tsx @@ -1,80 +1,27 @@ import { getEthLedgerDerivationPath } from "extension-core" -import { log } from "extension-shared" -import { useCallback, useEffect, useRef, useState } from "react" -import { Trans, useTranslation } from "react-i18next" +import { FC, useCallback } from "react" -import { Spacer } from "@talisman/components/Spacer" -import { - LedgerConnectionStatus, - LedgerConnectionStatusProps, -} from "@ui/domains/Account/LedgerConnectionStatus" -import { getCustomTalismanLedgerError } from "@ui/hooks/ledger/errors" import { useLedgerEthereum } from "@ui/hooks/ledger/useLedgerEthereum" -export const ConnectLedgerEthereum = ({ - onReadyChanged, - className, -}: { - onReadyChanged?: (ready: boolean) => void +import { ConnectLedgerBase } from "./ConnectLedgerBase" + +export const ConnectLedgerEthereum: FC<{ + onReadyChanged: (ready: boolean) => void className?: string -}) => { - const { t } = useTranslation("admin") +}> = ({ onReadyChanged, className }) => { const { getAddress } = useLedgerEthereum() - // flag to prevents double connect attempt in dev mode - const refIsBusy = useRef(false) - - const [connectionStatus, setConnectionStatus] = useState({ - status: "connecting", - message: t("Connecting to Ledger..."), - }) - - const connect = useCallback(async () => { - if (refIsBusy.current) return - refIsBusy.current = true - - try { - onReadyChanged?.(false) - setConnectionStatus({ - status: "connecting", - message: t("Connecting to Ledger..."), - }) - - const derivationPath = getEthLedgerDerivationPath("LedgerLive") - await getAddress(derivationPath) - - setConnectionStatus({ - status: "ready", - message: t("Successfully connected to Ledger."), - }) - onReadyChanged?.(true) - } catch (err) { - const error = getCustomTalismanLedgerError(err) - log.error("ConnectLedgerSubstrateGeneric", { error }) - setConnectionStatus({ - status: "error", - message: error.message, - onRetryClick: connect, - }) - } finally { - refIsBusy.current = false - } - }, [getAddress, onReadyChanged, t]) - - useEffect(() => { - connect() - }, [connect, getAddress, onReadyChanged]) + const isReadyCheck = useCallback(() => { + const derivationPath = getEthLedgerDerivationPath("LedgerLive") + return getAddress(derivationPath) + }, [getAddress]) return ( -
-
- - Connect and unlock your Ledger, then open the Ethereum{" "} - app on your Ledger. - -
- - -
+ ) } diff --git a/apps/extension/src/ui/domains/Account/AccountAdd/AccountAddLedger/Shared/ConnectLedgerSubstrateGeneric.tsx b/apps/extension/src/ui/domains/Account/AccountAdd/AccountAddLedger/Shared/ConnectLedgerSubstrateGeneric.tsx index 0d60c9137..e34db1426 100644 --- a/apps/extension/src/ui/domains/Account/AccountAdd/AccountAddLedger/Shared/ConnectLedgerSubstrateGeneric.tsx +++ b/apps/extension/src/ui/domains/Account/AccountAdd/AccountAddLedger/Shared/ConnectLedgerSubstrateGeneric.tsx @@ -1,85 +1,30 @@ -import { log } from "extension-shared" -import { FC, useCallback, useEffect, useRef, useState } from "react" -import { useTranslation } from "react-i18next" +import { FC, useCallback } from "react" -import { Spacer } from "@talisman/components/Spacer" -import { - LedgerConnectionStatus, - LedgerConnectionStatusProps, -} from "@ui/domains/Account/LedgerConnectionStatus" import { getPolkadotLedgerDerivationPath } from "@ui/hooks/ledger/common" -import { getCustomTalismanLedgerError } from "@ui/hooks/ledger/errors" import { useLedgerSubstrateAppByName } from "@ui/hooks/ledger/useLedgerSubstrateApp" import { useLedgerSubstrateGeneric } from "@ui/hooks/ledger/useLedgerSubstrateGeneric" -type ConnectLedgerSubstrateGenericProps = { - onReadyChanged?: (ready: boolean) => void +import { ConnectLedgerBase } from "./ConnectLedgerBase" + +export const ConnectLedgerSubstrateGeneric: FC<{ + onReadyChanged: (ready: boolean) => void className?: string legacyAppName?: string | null -} - -export const ConnectLedgerSubstrateGeneric: FC = ({ - onReadyChanged, - className, - legacyAppName, -}) => { - const { t } = useTranslation("admin") +}> = ({ onReadyChanged, className, legacyAppName }) => { const legacyApp = useLedgerSubstrateAppByName(legacyAppName) const { getAddress } = useLedgerSubstrateGeneric({ legacyApp }) - // flag to prevents double connect attempt in dev mode - const refIsBusy = useRef(false) - - const [connectionStatus, setConnectionStatus] = useState({ - status: "connecting", - message: t("Connecting to Ledger..."), - }) - - const connect = useCallback(async () => { - if (refIsBusy.current) return - refIsBusy.current = true - - try { - onReadyChanged?.(false) - setConnectionStatus({ - status: "connecting", - message: t("Connecting to Ledger..."), - }) - - const bip44path = getPolkadotLedgerDerivationPath({ legacyApp }) - await getAddress(bip44path) - - setConnectionStatus({ - status: "ready", - message: t("Successfully connected to Ledger."), - }) - onReadyChanged?.(true) - } catch (err) { - const error = getCustomTalismanLedgerError(err) - log.error("ConnectLedgerSubstrateGeneric", { error }) - setConnectionStatus({ - status: "error", - message: error.message, - onRetryClick: connect, - }) - } finally { - refIsBusy.current = false - } - }, [getAddress, legacyApp, onReadyChanged, t]) - - useEffect(() => { - connect() - }, [connect, getAddress, legacyApp, onReadyChanged]) + const isReadyCheck = useCallback(() => { + const derivationPath = getPolkadotLedgerDerivationPath({ legacyApp }) + return getAddress(derivationPath) + }, [getAddress, legacyApp]) return ( -
-
- {t("Connect and unlock your Ledger, then open the {{appName}} app on your Ledger.", { - appName: legacyApp ? "Polkadot Migration" : "Polkadot", - })} -
- - {!!connectionStatus && } -
+ ) } diff --git a/apps/extension/src/ui/domains/Account/AccountAdd/AccountAddLedger/Shared/ConnectLedgerSubstrateLegacy.tsx b/apps/extension/src/ui/domains/Account/AccountAdd/AccountAddLedger/Shared/ConnectLedgerSubstrateLegacy.tsx index 031a2024f..b609278af 100644 --- a/apps/extension/src/ui/domains/Account/AccountAdd/AccountAddLedger/Shared/ConnectLedgerSubstrateLegacy.tsx +++ b/apps/extension/src/ui/domains/Account/AccountAdd/AccountAddLedger/Shared/ConnectLedgerSubstrateLegacy.tsx @@ -1,83 +1,26 @@ -import { log } from "extension-shared" -import { FC, useCallback, useEffect, useRef, useState } from "react" -import { useTranslation } from "react-i18next" +import { FC, useCallback } from "react" -import { Spacer } from "@talisman/components/Spacer" -import { - LedgerConnectionStatus, - LedgerConnectionStatusProps, -} from "@ui/domains/Account/LedgerConnectionStatus" -import { getCustomTalismanLedgerError } from "@ui/hooks/ledger/errors" import { useLedgerSubstrateLegacy } from "@ui/hooks/ledger/useLedgerSubstrateLegacy" import { useChain } from "@ui/state" -type ConnectLedgerSubstrateLegacyProps = { +import { ConnectLedgerBase } from "./ConnectLedgerBase" + +export const ConnectLedgerSubstrateLegacy: FC<{ chainId: string - onReadyChanged?: (ready: boolean) => void + onReadyChanged: (ready: boolean) => void className?: string -} - -export const ConnectLedgerSubstrateLegacy: FC = ({ - chainId, - onReadyChanged, - className, -}) => { - const { t } = useTranslation("admin") +}> = ({ chainId, onReadyChanged, className }) => { const chain = useChain(chainId) const { app, getAddress } = useLedgerSubstrateLegacy(chain?.genesisHash) - // flag to prevents double connect attempt in dev mode - const refIsBusy = useRef(false) - - const [connectionStatus, setConnectionStatus] = useState({ - status: "connecting", - message: t("Connecting to Ledger..."), - }) - - const connect = useCallback(async () => { - if (refIsBusy.current) return - refIsBusy.current = true - - try { - onReadyChanged?.(false) - setConnectionStatus({ - status: "connecting", - message: t("Connecting to Ledger..."), - }) - - await getAddress(0, 0) - - setConnectionStatus({ - status: "ready", - message: t("Successfully connected to Ledger."), - }) - onReadyChanged?.(true) - } catch (err) { - const error = getCustomTalismanLedgerError(err) - log.error("ConnectLedgerSubstrateGeneric", { error }) - setConnectionStatus({ - status: "error", - message: error.message, - onRetryClick: connect, - }) - } finally { - refIsBusy.current = false - } - }, [getAddress, onReadyChanged, t]) - - useEffect(() => { - connect() - }, [connect, getAddress, onReadyChanged]) + const isReadyCheck = useCallback(() => getAddress(0, 0), [getAddress]) return ( -
-
- {t("Connect and unlock your Ledger, then open the {{appName}} app on your Ledger.", { - appName: app?.name ?? "UNKNOWN_APP", - })} -
- - {!!connectionStatus && } -
+ ) }