diff --git a/apps/extension/src/Setup/Ledger/LedgerConnect.tsx b/apps/extension/src/Setup/Ledger/LedgerConnect.tsx index 6c88eb1b2d..03c4fbbe36 100644 --- a/apps/extension/src/Setup/Ledger/LedgerConnect.tsx +++ b/apps/extension/src/Setup/Ledger/LedgerConnect.tsx @@ -15,10 +15,16 @@ type Props = { setPath: (path: Bip44Path) => void; }; +enum LedgerReviewPrompt { + AddressAndPublicKey = "address and public key", + ViewingKey = "viewing key", + ProofGenerationKeys = "proof generation keys", +} + export const LedgerConnect: React.FC = ({ path, setPath }) => { const navigate = useNavigate(); const [error, setError] = useState(); - const [isLedgerConnecting, setIsLedgerConnecting] = useState(false); + const [reviewPrompt, setReviewPrompt] = useState(); const [ledger, setLedger] = useState(); const queryLedger = async (ledger: LedgerApp): Promise => { @@ -32,17 +38,23 @@ export const LedgerConnect: React.FC = ({ path, setPath }) => { throw new Error(errorMessage); } - setIsLedgerConnecting(true); - const { address, publicKey } = await ledger.showAddressAndPublicKey( - makeBip44Path(chains.namada.bip44.coinType, path) - ); - - const response = await ledger.getShieldedKeys( - makeBip44Path(chains.namada.bip44.coinType, path), - true - ); - console.log({ shieldedResponse: response }); - setIsLedgerConnecting(false); + const bip44Path = makeBip44Path(chains.namada.bip44.coinType, path); + + setReviewPrompt(LedgerReviewPrompt.AddressAndPublicKey); + const { address, publicKey } = + await ledger.showAddressAndPublicKey(bip44Path); + + setReviewPrompt(LedgerReviewPrompt.ViewingKey); + const viewingKey = await ledger.getViewingKey(bip44Path, true); + console.log({ viewingKey }); + + setReviewPrompt(LedgerReviewPrompt.ProofGenerationKeys); + const proofGenerationKeys = + await ledger.getProofGenerationKeys(bip44Path); + + console.log({ proofGenerationKeys }); + setReviewPrompt(undefined); + navigate(routes.ledgerImport(), { state: { address, @@ -50,7 +62,7 @@ export const LedgerConnect: React.FC = ({ path, setPath }) => { }, }); } catch (e) { - setIsLedgerConnecting(false); + setReviewPrompt(undefined); handleError(e); } finally { await ledger.closeTransport(); @@ -100,8 +112,8 @@ export const LedgerConnect: React.FC = ({ path, setPath }) => { )} - {isLedgerConnecting && ( - Review on your Ledger + {reviewPrompt && ( + Review {reviewPrompt} on your Ledger )} = ({ path, setPath }) => { active={!!ledger} complete={false} onClick={() => connectNamadaApp()} - buttonDisabled={!ledger || isLedgerConnecting} + buttonDisabled={!ledger || Boolean(reviewPrompt)} image={ } diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index dd9b9c5a62..188dc09b84 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -6,8 +6,8 @@ export { } from "./ledger"; export type { LedgerAddressAndPublicKey, - LedgerShieldedKeys, LedgerStatus, + LedgerViewingKey, } from "./ledger"; // Export types diff --git a/packages/sdk/src/ledger.ts b/packages/sdk/src/ledger.ts index b52747b14a..820132824c 100644 --- a/packages/sdk/src/ledger.ts +++ b/packages/sdk/src/ledger.ts @@ -18,16 +18,15 @@ import { makeBip44Path } from "./utils"; const { coinType } = chains.namada.bip44; export type LedgerAddressAndPublicKey = { address: string; publicKey: string }; -export type LedgerShieldedKeys = { - viewingKey: { - viewKey?: string; - ivk?: string; - ovk?: string; - }; - proofGenerationKey: { - ak?: string; - nsk?: string; - }; +// TODO: This should be xfvk, awaiting an updated version! +export type LedgerViewingKey = { + viewKey?: string; + ivk?: string; + ovk?: string; +}; +export type LedgerProofGenerationKey = { + ak?: string; + nsk?: string; }; export type LedgerStatus = { @@ -148,42 +147,56 @@ export class Ledger { } /** - * Prompt user to get viewing and proof gen key associated with optional path, otherwise, use default path. + * Prompt user to get viewing key associated with optional path, otherwise, use default path. * Throw exception if app is not initialized. * @async * @param [path] Bip44 path for deriving key * @param [promptUser] boolean to determine whether to display on Ledger device and require approval - * @returns ShieldedKeys + * @returns LedgerViewingKey */ - public async getShieldedKeys( + public async getViewingKey( path: string = DEFAULT_LEDGER_BIP44_PATH, promptUser = true - ): Promise { + ): Promise { try { const { viewKey, ivk, ovk }: ResponseViewKey = await this.namadaApp.retrieveKeys(path, NamadaKeys.ViewKey, promptUser); - // NOTE: If promptUser is false, the proof generation keys will not be defined + return { + viewKey: viewKey ? toHex(new Uint8Array(viewKey)) : undefined, + ivk: ivk ? toHex(new Uint8Array(ivk)) : undefined, + ovk: ovk ? toHex(new Uint8Array(ovk)) : undefined, + }; + } catch (e) { + throw new Error(`Could not retrieve Viewing Key: ${e}`); + } + } + + /** + * Prompt user to get proof generation keys associated with optional path, otherwise, use default path. + * Throw exception if app is not initialized. + * @async + * @param [path] Bip44 path for deriving key + * @returns LedgerProofGenerationKey + */ + public async getProofGenerationKeys( + path: string = DEFAULT_LEDGER_BIP44_PATH + ): Promise { + try { const { ak, nsk }: ResponseProofGenKey = await this.namadaApp.retrieveKeys( path, NamadaKeys.ProofGenerationKey, - promptUser + // NOTE: Setting this to false will result in undefined values + true ); return { - viewingKey: { - viewKey: viewKey ? toHex(viewKey) : undefined, - ivk: ivk ? toHex(ivk) : undefined, - ovk: ovk ? toHex(ovk) : undefined, - }, - proofGenerationKey: { - ak: ak ? toHex(ak) : undefined, - nsk: nsk ? toHex(nsk) : undefined, - }, + ak: ak ? toHex(new Uint8Array(ak)) : undefined, + nsk: nsk ? toHex(new Uint8Array(nsk)) : undefined, }; } catch (e) { - throw new Error(`Could not retrieve Viewing Key`); + throw new Error(`Could not retrive Proof Generation Keys: ${e}`); } }