Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ledger improvements #434

Merged
merged 3 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 30 additions & 48 deletions packages/background/src/ledger/ledger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,15 @@ import {
ErrFailedGetVersion,
ErrFailedInit,
ErrFailedSign,
ErrModuleLedgerSign,
} from "./types";
import { WalletError } from "@keplr-wallet/router";

export enum LedgerApp {
Cosmos = "cosmos",
Ethereum = "ethereum",
}

export enum LedgerInitErrorOn {
Transport,
App,
Unknown,
}

export const LedgerWebUSBIniter: TransportIniter = async () => {
return await TransportWebUSB.create();
};
Expand All @@ -38,19 +34,6 @@ export const LedgerWebHIDIniter: TransportIniter = async () => {
return await TransportWebHID.create();
};

export class LedgerInitError extends Error {
public readonly errorOn: LedgerInitErrorOn;
public readonly code: number;

constructor(errorOn: LedgerInitErrorOn, code: number, message?: string) {
super(message);
this.errorOn = errorOn;
this.code = code;

Object.setPrototypeOf(this, LedgerInitError.prototype);
}
}

export class Ledger {
constructor(
public readonly cosmosApp: CosmosApp | undefined = undefined,
Expand All @@ -67,8 +50,8 @@ export class Ledger {
try {
transport = await transportIniter(...initArgs);
} catch (e) {
throw new LedgerInitError(
LedgerInitErrorOn.Transport,
throw new WalletError(
ErrModuleLedgerSign,
ErrFailedInit,
"Connect and unlock your Ledger device."
);
Expand All @@ -95,8 +78,8 @@ export class Ledger {
// However, it is almost same as that the device is not unlocked to user-side.
// So, handle this case as initializing failed in `Transport`.
if (versionResponse.deviceLocked) {
throw new LedgerInitError(
LedgerInitErrorOn.Transport,
throw new WalletError(
ErrModuleLedgerSign,
ErrCodeDeviceLocked,
"Unlock your Ledger device."
);
Expand All @@ -110,8 +93,8 @@ export class Ledger {
console.log(e);
}
if (appName && appName !== cosmosLikeApp) {
throw new LedgerInitError(
LedgerInitErrorOn.App,
throw new WalletError(
ErrModuleLedgerSign,
ErrCodeUnsupportedApp,
"Invalid cosmos app selected"
);
Expand All @@ -122,22 +105,21 @@ export class Ledger {
if (transport) {
await transport.close();
}
console.log("Testing1::", e.message);

if (
e.message === "Device is on screen saver" ||
e.message?.includes("Unknown Status Code: 21781")
) {
throw new LedgerInitError(
LedgerInitErrorOn.Transport,
throw new WalletError(
ErrModuleLedgerSign,
ErrCodeDeviceLocked,
"Unlock your Ledger device."
);
}

throw new LedgerInitError(
LedgerInitErrorOn.App,
ErrFailedInit,
throw new WalletError(
ErrModuleLedgerSign,
ErrCodeAppNotInitialised,
`Open the ${cosmosLikeApp} app on Ledger and try again.`
);
}
Expand All @@ -152,8 +134,8 @@ export class Ledger {
testMode: boolean;
}> {
if (!this.cosmosApp) {
throw new LedgerInitError(
LedgerInitErrorOn.App,
throw new WalletError(
ErrModuleLedgerSign,
ErrCodeAppNotInitialised,
"Please initialize Cosmos app first"
);
Expand All @@ -162,8 +144,8 @@ export class Ledger {
const result = await this.cosmosApp.getVersion();

if (result.error_message !== "No errors") {
throw new LedgerInitError(
LedgerInitErrorOn.App,
throw new WalletError(
ErrModuleLedgerSign,
ErrFailedGetVersion,
result.error_message
);
Expand All @@ -182,8 +164,8 @@ export class Ledger {
async getPublicKey(app: LedgerApp, fields: BIP44HDPath): Promise<Uint8Array> {
if (app === LedgerApp.Ethereum) {
if (!this.ethereumApp) {
throw new LedgerInitError(
LedgerInitErrorOn.App,
throw new WalletError(
ErrModuleLedgerSign,
ErrCodeAppNotInitialised,
"Please initialize Ethereum app first"
);
Expand All @@ -198,12 +180,12 @@ export class Ledger {
// Compress the public key
return publicKeyConvert(pubKey, true);
} catch (e: any) {
throw new LedgerInitError(LedgerInitErrorOn.App, e);
throw new WalletError(ErrModuleLedgerSign, e);
}
} else {
if (!this.cosmosApp) {
throw new LedgerInitError(
LedgerInitErrorOn.App,
throw new WalletError(
ErrModuleLedgerSign,
ErrCodeAppNotInitialised,
"Please initialize Cosmos app first"
);
Expand All @@ -215,8 +197,8 @@ export class Ledger {
fields.addressIndex
);
if (result.error_message !== "No errors") {
throw new LedgerInitError(
LedgerInitErrorOn.App,
throw new WalletError(
ErrModuleLedgerSign,
ErrFailedGetPublicKey,
result.error_message
);
Expand All @@ -228,8 +210,8 @@ export class Ledger {

async sign(fields: BIP44HDPath, message: Uint8Array): Promise<Uint8Array> {
if (!this.cosmosApp) {
throw new LedgerInitError(
LedgerInitErrorOn.App,
throw new WalletError(
ErrModuleLedgerSign,
ErrCodeAppNotInitialised,
"Please initialize Cosmos app first"
);
Expand All @@ -242,8 +224,8 @@ export class Ledger {
message
);
if (result.error_message !== "No errors") {
throw new LedgerInitError(
LedgerInitErrorOn.App,
throw new WalletError(
ErrModuleLedgerSign,
ErrFailedSign,
result.error_message
);
Expand All @@ -259,8 +241,8 @@ export class Ledger {
message: Uint8Array
) {
if (!this.ethereumApp) {
throw new LedgerInitError(
LedgerInitErrorOn.App,
throw new WalletError(
ErrModuleLedgerSign,
ErrCodeAppNotInitialised,
"Please initialize Ethereum app first"
);
Expand Down
1 change: 1 addition & 0 deletions packages/background/src/ledger/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export type TransportIniter = (...args: any[]) => Promise<Transport>;

export interface LedgerOptions {
defaultMode: string;
platform: string;
transportIniters: {
[mode: string]: TransportIniter;
};
Expand Down
Loading
Loading