-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: ledger implementation rework (#1763)
* wip: ledger rework * wip: ledger rework * feat: update ledger legacy hooks and components to new model * feat: update ledger ethereum to new model * refactor: cleanup and remove suspenses * refactor: useSignLedgerBase * refactor: isSigning * refactor: useLedgerXxx * refactor: errors * feat: error if app needs to be upgraded to generic * refactor: connect ledger component * chore: cleanup LedgerConnectionStatus * chore: cleanup * chore: remove commented code
- Loading branch information
Showing
24 changed files
with
1,367 additions
and
1,617 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
81 changes: 81 additions & 0 deletions
81
...extension/src/ui/domains/Account/AccountAdd/AccountAddLedger/Shared/ConnectLedgerBase.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<unknown> | ||
onReadyChanged: (ready: boolean) => void | ||
className?: string | ||
} | ||
|
||
export const ConnectLedgerBase: FC<ConnectLedgerBaseProps> = ({ | ||
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<LedgerConnectionStatusProps>({ | ||
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 ( | ||
<div className={className}> | ||
<div className="text-body-secondary m-0"> | ||
{t("Connect and unlock your Ledger, then open the {{appName}} app on your Ledger.", { | ||
appName, | ||
})} | ||
</div> | ||
<Spacer small /> | ||
{!!connectionStatus && <LedgerConnectionStatus {...connectionStatus} />} | ||
</div> | ||
) | ||
} |
47 changes: 18 additions & 29 deletions
47
...nsion/src/ui/domains/Account/AccountAdd/AccountAddLedger/Shared/ConnectLedgerEthereum.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,27 @@ | ||
import { useEffect } from "react" | ||
import { Trans, useTranslation } from "react-i18next" | ||
import { getEthLedgerDerivationPath } from "extension-core" | ||
import { FC, useCallback } from "react" | ||
|
||
import { Spacer } from "@talisman/components/Spacer" | ||
import { LedgerConnectionStatus } from "@ui/domains/Account/LedgerConnectionStatus" | ||
import { useLedgerEthereum } from "@ui/hooks/ledger/useLedgerEthereum" | ||
|
||
export const ConnectLedgerEthereum = ({ | ||
onReadyChanged, | ||
className, | ||
}: { | ||
onReadyChanged?: (ready: boolean) => void | ||
className?: string | ||
}) => { | ||
const { t } = useTranslation("admin") | ||
const ledger = useLedgerEthereum(true) | ||
import { ConnectLedgerBase } from "./ConnectLedgerBase" | ||
|
||
useEffect(() => { | ||
onReadyChanged?.(ledger.isReady) | ||
export const ConnectLedgerEthereum: FC<{ | ||
onReadyChanged: (ready: boolean) => void | ||
className?: string | ||
}> = ({ onReadyChanged, className }) => { | ||
const { getAddress } = useLedgerEthereum() | ||
|
||
return () => { | ||
onReadyChanged?.(false) | ||
} | ||
}, [ledger.isReady, onReadyChanged]) | ||
const isReadyCheck = useCallback(() => { | ||
const derivationPath = getEthLedgerDerivationPath("LedgerLive") | ||
return getAddress(derivationPath) | ||
}, [getAddress]) | ||
|
||
return ( | ||
<div className={className}> | ||
<div className="text-body-secondary m-0"> | ||
<Trans t={t}> | ||
Connect and unlock your Ledger, then open the <span className="text-body">Ethereum</span>{" "} | ||
app on your Ledger. | ||
</Trans> | ||
</div> | ||
<Spacer small /> | ||
<LedgerConnectionStatus {...ledger} /> | ||
</div> | ||
<ConnectLedgerBase | ||
appName="Ethereum" | ||
className={className} | ||
isReadyCheck={isReadyCheck} | ||
onReadyChanged={onReadyChanged} | ||
/> | ||
) | ||
} |
53 changes: 20 additions & 33 deletions
53
...c/ui/domains/Account/AccountAdd/AccountAddLedger/Shared/ConnectLedgerSubstrateGeneric.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,43 +1,30 @@ | ||
import { FC, useEffect } from "react" | ||
import { useTranslation } from "react-i18next" | ||
import { FC, useCallback } from "react" | ||
|
||
import { Spacer } from "@talisman/components/Spacer" | ||
import { LedgerConnectionStatus } from "@ui/domains/Account/LedgerConnectionStatus" | ||
import { getPolkadotLedgerDerivationPath } from "@ui/hooks/ledger/common" | ||
import { useLedgerSubstrateAppByName } from "@ui/hooks/ledger/useLedgerSubstrateApp" | ||
import { useLedgerSubstrateGeneric } from "@ui/hooks/ledger/useLedgerSubstrateGeneric" | ||
|
||
type ConnectLedgerSubstrateGenericProps = { | ||
onReadyChanged?: (ready: boolean) => void | ||
className?: string | ||
appName?: string | null | ||
} | ||
import { ConnectLedgerBase } from "./ConnectLedgerBase" | ||
|
||
export const ConnectLedgerSubstrateGeneric: FC<ConnectLedgerSubstrateGenericProps> = ({ | ||
onReadyChanged, | ||
className, | ||
appName, | ||
}) => { | ||
const app = useLedgerSubstrateAppByName(appName) | ||
const ledger = useLedgerSubstrateGeneric({ persist: true, app }) | ||
const { t } = useTranslation("admin") | ||
|
||
useEffect(() => { | ||
onReadyChanged?.(ledger.isReady) | ||
export const ConnectLedgerSubstrateGeneric: FC<{ | ||
onReadyChanged: (ready: boolean) => void | ||
className?: string | ||
legacyAppName?: string | null | ||
}> = ({ onReadyChanged, className, legacyAppName }) => { | ||
const legacyApp = useLedgerSubstrateAppByName(legacyAppName) | ||
const { getAddress } = useLedgerSubstrateGeneric({ legacyApp }) | ||
|
||
return () => { | ||
onReadyChanged?.(false) | ||
} | ||
}, [ledger.isReady, onReadyChanged]) | ||
const isReadyCheck = useCallback(() => { | ||
const derivationPath = getPolkadotLedgerDerivationPath({ legacyApp }) | ||
return getAddress(derivationPath) | ||
}, [getAddress, legacyApp]) | ||
|
||
return ( | ||
<div className={className}> | ||
<div className="text-body-secondary m-0"> | ||
{t("Connect and unlock your Ledger, then open the {{appName}} app on your Ledger.", { | ||
appName: app ? "Polkadot Migration" : "Polkadot", | ||
})} | ||
</div> | ||
<Spacer small /> | ||
<LedgerConnectionStatus {...ledger} /> | ||
</div> | ||
<ConnectLedgerBase | ||
appName={legacyAppName ? "Polkadot Migration" : "Polkadot"} | ||
className={className} | ||
isReadyCheck={isReadyCheck} | ||
onReadyChanged={onReadyChanged} | ||
/> | ||
) | ||
} |
60 changes: 15 additions & 45 deletions
60
...rc/ui/domains/Account/AccountAdd/AccountAddLedger/Shared/ConnectLedgerSubstrateLegacy.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,26 @@ | ||
import { FC, useEffect } from "react" | ||
import { Trans, useTranslation } from "react-i18next" | ||
import { FC, useCallback } from "react" | ||
|
||
import { Spacer } from "@talisman/components/Spacer" | ||
import { LedgerConnectionStatus } from "@ui/domains/Account/LedgerConnectionStatus" | ||
import { useLedgerSubstrateAppByChain } from "@ui/hooks/ledger/useLedgerSubstrateApp" | ||
import { useLedgerSubstrateLegacy } from "@ui/hooks/ledger/useLedgerSubstrateLegacy" | ||
import { useChain, useToken } from "@ui/state" | ||
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<ConnectLedgerSubstrateLegacyProps> = ({ | ||
chainId, | ||
onReadyChanged, | ||
className, | ||
}) => { | ||
}> = ({ chainId, onReadyChanged, className }) => { | ||
const chain = useChain(chainId) | ||
const token = useToken(chain?.nativeToken?.id) | ||
const ledger = useLedgerSubstrateLegacy(chain?.genesisHash, true) | ||
const app = useLedgerSubstrateAppByChain(chain) | ||
const { t } = useTranslation("admin") | ||
|
||
useEffect(() => { | ||
onReadyChanged?.(ledger.isReady) | ||
|
||
return () => { | ||
onReadyChanged?.(false) | ||
} | ||
}, [ledger.isReady, onReadyChanged]) | ||
const { app, getAddress } = useLedgerSubstrateLegacy(chain?.genesisHash) | ||
|
||
if (!app) return null | ||
const isReadyCheck = useCallback(() => getAddress(0, 0), [getAddress]) | ||
|
||
return ( | ||
<div className={className}> | ||
<div className="text-body-secondary m-0"> | ||
<Trans | ||
t={t} | ||
components={{ | ||
AppName: ( | ||
<span className="text-body"> | ||
{app.name + (token?.symbol ? ` (${token.symbol})` : "")} | ||
</span> | ||
), | ||
}} | ||
defaults="Connect and unlock your Ledger, then open the <AppName /> app on your Ledger." | ||
/> | ||
</div> | ||
<Spacer small /> | ||
<LedgerConnectionStatus {...ledger} /> | ||
</div> | ||
<ConnectLedgerBase | ||
appName={app?.name ?? "Unknown App"} | ||
className={className} | ||
isReadyCheck={isReadyCheck} | ||
onReadyChanged={onReadyChanged} | ||
/> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.