From edf7210898fc5abd1853924ce1abdec5ccc553cd Mon Sep 17 00:00:00 2001 From: Calvin Kei Date: Mon, 4 Oct 2021 22:01:39 +0800 Subject: [PATCH 1/8] added custom ledger app name support --- packages/ledger-amino/src/launchpadledger.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/ledger-amino/src/launchpadledger.ts b/packages/ledger-amino/src/launchpadledger.ts index 0e58bd40..581cb255 100644 --- a/packages/ledger-amino/src/launchpadledger.ts +++ b/packages/ledger-amino/src/launchpadledger.ts @@ -24,18 +24,21 @@ function unharden(hdPath: HdPath): number[] { const cosmosHdPath = makeCosmoshubPath(0); const cosmosBech32Prefix = "cosmos"; +const cosmosLedgerAppName = "cosmos"; const requiredCosmosAppVersion = "1.5.3"; export interface LaunchpadLedgerOptions { readonly hdPaths?: readonly HdPath[]; readonly prefix?: string; readonly testModeAllowed?: boolean; + readonly ledgerAppName?: string } export class LaunchpadLedger { private readonly testModeAllowed: boolean; private readonly hdPaths: readonly HdPath[]; private readonly prefix: string; + private readonly ledgerAppName: string; private readonly app: CosmosApp; public constructor(transport: Transport, options: LaunchpadLedgerOptions = {}) { @@ -43,11 +46,13 @@ export class LaunchpadLedger { hdPaths: [cosmosHdPath], prefix: cosmosBech32Prefix, testModeAllowed: false, + ledgerAppName: cosmosLedgerAppName }; this.testModeAllowed = options.testModeAllowed ?? defaultOptions.testModeAllowed; this.hdPaths = options.hdPaths ?? defaultOptions.hdPaths; this.prefix = options.prefix ?? defaultOptions.prefix; + this.ledgerAppName = options.ledgerAppName ?? defaultOptions.ledgerAppName this.app = new CosmosApp(transport); } @@ -125,8 +130,8 @@ export class LaunchpadLedger { if (appName.toLowerCase() === `dashboard`) { throw new Error(`Please open the Cosmos Ledger app on your Ledger device.`); } - if (appName.toLowerCase() !== `cosmos`) { - throw new Error(`Please close ${appName} and open the Cosmos Ledger app on your Ledger device.`); + if (appName.toLowerCase() !== this.ledgerAppName.toLowerCase()) { + throw new Error(`Please close ${appName} and open the ${this.ledgerAppName} Ledger app on your Ledger device.`); } } From c33f5ed114a52802b7b877dd245390be5bfadcc3 Mon Sep 17 00:00:00 2001 From: Calvin Kei Date: Wed, 6 Oct 2021 14:00:53 +0800 Subject: [PATCH 2/8] Update packages/ledger-amino/src/launchpadledger.ts Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> --- packages/ledger-amino/src/launchpadledger.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/ledger-amino/src/launchpadledger.ts b/packages/ledger-amino/src/launchpadledger.ts index 581cb255..4afd31e2 100644 --- a/packages/ledger-amino/src/launchpadledger.ts +++ b/packages/ledger-amino/src/launchpadledger.ts @@ -31,6 +31,14 @@ export interface LaunchpadLedgerOptions { readonly hdPaths?: readonly HdPath[]; readonly prefix?: string; readonly testModeAllowed?: boolean; + /** + * The name of the app the user must have opened on the Ledger. + * This allows you to use this connector with forks of the Cosmos Hub Ledger app. + * Support is provided on an best effort basis and only as long as those forks do not + * significantly differ from the original app. + * + * Defaults to "cosmos". + */ readonly ledgerAppName?: string } From b8ea9a6f08c7116029e025b51e45477c1b595f6c Mon Sep 17 00:00:00 2001 From: Calvin Kei Date: Wed, 6 Oct 2021 23:15:41 +0800 Subject: [PATCH 3/8] generalize ledger app name and allow customizing ledger app version --- packages/ledger-amino/src/launchpadledger.ts | 26 +++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/packages/ledger-amino/src/launchpadledger.ts b/packages/ledger-amino/src/launchpadledger.ts index 581cb255..88f011ca 100644 --- a/packages/ledger-amino/src/launchpadledger.ts +++ b/packages/ledger-amino/src/launchpadledger.ts @@ -32,6 +32,7 @@ export interface LaunchpadLedgerOptions { readonly prefix?: string; readonly testModeAllowed?: boolean; readonly ledgerAppName?: string + readonly requiredLedgerAppVersion?: string } export class LaunchpadLedger { @@ -39,6 +40,7 @@ export class LaunchpadLedger { private readonly hdPaths: readonly HdPath[]; private readonly prefix: string; private readonly ledgerAppName: string; + private readonly requiredLedgerAppVersion: string; private readonly app: CosmosApp; public constructor(transport: Transport, options: LaunchpadLedgerOptions = {}) { @@ -46,19 +48,21 @@ export class LaunchpadLedger { hdPaths: [cosmosHdPath], prefix: cosmosBech32Prefix, testModeAllowed: false, - ledgerAppName: cosmosLedgerAppName + ledgerAppName: cosmosLedgerAppName, + requiredLedgerAppVersion: requiredCosmosAppVersion }; this.testModeAllowed = options.testModeAllowed ?? defaultOptions.testModeAllowed; this.hdPaths = options.hdPaths ?? defaultOptions.hdPaths; this.prefix = options.prefix ?? defaultOptions.prefix; this.ledgerAppName = options.ledgerAppName ?? defaultOptions.ledgerAppName + this.requiredLedgerAppVersion = options.requiredLedgerAppVersion ?? defaultOptions.requiredLedgerAppVersion this.app = new CosmosApp(transport); } public async getCosmosAppVersion(): Promise { await this.verifyCosmosAppIsOpen(); - assert(this.app, "Cosmos Ledger App is not connected"); + assert(this.app, `${this.ledgerAppName} Ledger App is not connected`); const response = await this.app.getVersion(); this.handleLedgerErrors(response); @@ -70,7 +74,7 @@ export class LaunchpadLedger { public async getPubkey(hdPath?: HdPath): Promise { await this.verifyDeviceIsReady(); - assert(this.app, "Cosmos Ledger App is not connected"); + assert(this.app, `${this.ledgerAppName} Ledger App is not connected`); const hdPathToUse = hdPath || this.hdPaths[0]; // ledger-cosmos-js hardens the first three indices @@ -94,7 +98,7 @@ export class LaunchpadLedger { public async sign(message: Uint8Array, hdPath?: HdPath): Promise { await this.verifyDeviceIsReady(); - assert(this.app, "Cosmos Ledger App is not connected"); + assert(this.app, `${this.ledgerAppName} Ledger App is not connected`); const hdPathToUse = hdPath || this.hdPaths[0]; // ledger-cosmos-js hardens the first three indices @@ -105,12 +109,12 @@ export class LaunchpadLedger { private verifyAppMode(testMode: boolean): void { if (testMode && !this.testModeAllowed) { - throw new Error(`DANGER: The Cosmos Ledger app is in test mode and should not be used on mainnet!`); + throw new Error(`DANGER: The ${this.ledgerAppName} Ledger app is in test mode and should not be used on mainnet!`); } } private async getOpenAppName(): Promise { - assert(this.app, "Cosmos Ledger App is not connected"); + assert(this.app, `${this.ledgerAppName} Ledger App is not connected`); const response = await this.app.appInfo(); this.handleLedgerErrors(response); @@ -119,8 +123,8 @@ export class LaunchpadLedger { private async verifyAppVersion(): Promise { const version = await this.getCosmosAppVersion(); - if (!semver.gte(version, requiredCosmosAppVersion)) { - throw new Error("Outdated version: Please update Cosmos Ledger App to the latest version."); + if (!semver.gte(version, this.requiredLedgerAppVersion)) { + throw new Error(`Outdated version: Please update ${this.ledgerAppName} Ledger App to the latest version.`); } } @@ -128,7 +132,7 @@ export class LaunchpadLedger { const appName = await this.getOpenAppName(); if (appName.toLowerCase() === `dashboard`) { - throw new Error(`Please open the Cosmos Ledger app on your Ledger device.`); + throw new Error(`Please open the ${this.ledgerAppName} Ledger app on your Ledger device.`); } if (appName.toLowerCase() !== this.ledgerAppName.toLowerCase()) { throw new Error(`Please close ${appName} and open the ${this.ledgerAppName} Ledger app on your Ledger device.`); @@ -156,7 +160,7 @@ export class LaunchpadLedger { case "U2F: Timeout": throw new Error("Connection timed out. Please try again."); case "Cosmos app does not seem to be open": - throw new Error("Cosmos app is not open"); + throw new Error(`${this.ledgerAppName} app is not open`); case "Command not allowed": throw new Error("Transaction rejected"); case "Transaction rejected": @@ -165,7 +169,7 @@ export class LaunchpadLedger { throw new Error("Ledger’s screensaver mode is on"); case "Instruction not supported": throw new Error( - `Your Cosmos Ledger App is not up to date. Please update to version ${requiredCosmosAppVersion}.`, + `Your ${this.ledgerAppName} Ledger App is not up to date. Please update to version ${this.requiredLedgerAppVersion}.`, ); case "No errors": break; From 7f0620ad4909f017e53ca96ff47cb0a73d6011c6 Mon Sep 17 00:00:00 2001 From: Calvin Kei Date: Wed, 6 Oct 2021 23:19:21 +0800 Subject: [PATCH 4/8] capitalize default ledger app name --- packages/ledger-amino/src/launchpadledger.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ledger-amino/src/launchpadledger.ts b/packages/ledger-amino/src/launchpadledger.ts index acd12dd8..875ec177 100644 --- a/packages/ledger-amino/src/launchpadledger.ts +++ b/packages/ledger-amino/src/launchpadledger.ts @@ -24,7 +24,7 @@ function unharden(hdPath: HdPath): number[] { const cosmosHdPath = makeCosmoshubPath(0); const cosmosBech32Prefix = "cosmos"; -const cosmosLedgerAppName = "cosmos"; +const cosmosLedgerAppName = "Cosmos"; const requiredCosmosAppVersion = "1.5.3"; export interface LaunchpadLedgerOptions { From ba4509ac28d4d83dd052a2d29e30e946e6c08019 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 20 Oct 2021 11:54:18 +0200 Subject: [PATCH 5/8] Format code --- packages/ledger-amino/src/launchpadledger.ts | 23 +++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/packages/ledger-amino/src/launchpadledger.ts b/packages/ledger-amino/src/launchpadledger.ts index 875ec177..890fdb60 100644 --- a/packages/ledger-amino/src/launchpadledger.ts +++ b/packages/ledger-amino/src/launchpadledger.ts @@ -39,8 +39,8 @@ export interface LaunchpadLedgerOptions { * * Defaults to "cosmos". */ - readonly ledgerAppName?: string - readonly requiredLedgerAppVersion?: string + readonly ledgerAppName?: string; + readonly requiredLedgerAppVersion?: string; } export class LaunchpadLedger { @@ -57,14 +57,15 @@ export class LaunchpadLedger { prefix: cosmosBech32Prefix, testModeAllowed: false, ledgerAppName: cosmosLedgerAppName, - requiredLedgerAppVersion: requiredCosmosAppVersion + requiredLedgerAppVersion: requiredCosmosAppVersion, }; this.testModeAllowed = options.testModeAllowed ?? defaultOptions.testModeAllowed; this.hdPaths = options.hdPaths ?? defaultOptions.hdPaths; this.prefix = options.prefix ?? defaultOptions.prefix; - this.ledgerAppName = options.ledgerAppName ?? defaultOptions.ledgerAppName - this.requiredLedgerAppVersion = options.requiredLedgerAppVersion ?? defaultOptions.requiredLedgerAppVersion + this.ledgerAppName = options.ledgerAppName ?? defaultOptions.ledgerAppName; + this.requiredLedgerAppVersion = + options.requiredLedgerAppVersion ?? defaultOptions.requiredLedgerAppVersion; this.app = new CosmosApp(transport); } @@ -117,7 +118,9 @@ export class LaunchpadLedger { private verifyAppMode(testMode: boolean): void { if (testMode && !this.testModeAllowed) { - throw new Error(`DANGER: The ${this.ledgerAppName} Ledger app is in test mode and should not be used on mainnet!`); + throw new Error( + `DANGER: The ${this.ledgerAppName} Ledger app is in test mode and should not be used on mainnet!`, + ); } } @@ -132,7 +135,9 @@ export class LaunchpadLedger { private async verifyAppVersion(): Promise { const version = await this.getCosmosAppVersion(); if (!semver.gte(version, this.requiredLedgerAppVersion)) { - throw new Error(`Outdated version: Please update ${this.ledgerAppName} Ledger App to the latest version.`); + throw new Error( + `Outdated version: Please update ${this.ledgerAppName} Ledger App to the latest version.`, + ); } } @@ -143,7 +148,9 @@ export class LaunchpadLedger { throw new Error(`Please open the ${this.ledgerAppName} Ledger app on your Ledger device.`); } if (appName.toLowerCase() !== this.ledgerAppName.toLowerCase()) { - throw new Error(`Please close ${appName} and open the ${this.ledgerAppName} Ledger app on your Ledger device.`); + throw new Error( + `Please close ${appName} and open the ${this.ledgerAppName} Ledger app on your Ledger device.`, + ); } } From a1861add4eb3f032acda914a29f7a3be868639a5 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 20 Oct 2021 12:04:41 +0200 Subject: [PATCH 6/8] Clarify error text on min version --- packages/ledger-amino/src/launchpadledger.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/ledger-amino/src/launchpadledger.ts b/packages/ledger-amino/src/launchpadledger.ts index 890fdb60..f0af4085 100644 --- a/packages/ledger-amino/src/launchpadledger.ts +++ b/packages/ledger-amino/src/launchpadledger.ts @@ -40,7 +40,7 @@ export interface LaunchpadLedgerOptions { * Defaults to "cosmos". */ readonly ledgerAppName?: string; - readonly requiredLedgerAppVersion?: string; + readonly minLedgerAppVersion?: string; } export class LaunchpadLedger { @@ -48,7 +48,7 @@ export class LaunchpadLedger { private readonly hdPaths: readonly HdPath[]; private readonly prefix: string; private readonly ledgerAppName: string; - private readonly requiredLedgerAppVersion: string; + private readonly minLedgerAppVersion: string; private readonly app: CosmosApp; public constructor(transport: Transport, options: LaunchpadLedgerOptions = {}) { @@ -64,8 +64,7 @@ export class LaunchpadLedger { this.hdPaths = options.hdPaths ?? defaultOptions.hdPaths; this.prefix = options.prefix ?? defaultOptions.prefix; this.ledgerAppName = options.ledgerAppName ?? defaultOptions.ledgerAppName; - this.requiredLedgerAppVersion = - options.requiredLedgerAppVersion ?? defaultOptions.requiredLedgerAppVersion; + this.minLedgerAppVersion = options.minLedgerAppVersion ?? defaultOptions.requiredLedgerAppVersion; this.app = new CosmosApp(transport); } @@ -134,7 +133,7 @@ export class LaunchpadLedger { private async verifyAppVersion(): Promise { const version = await this.getCosmosAppVersion(); - if (!semver.gte(version, this.requiredLedgerAppVersion)) { + if (!semver.gte(version, this.minLedgerAppVersion)) { throw new Error( `Outdated version: Please update ${this.ledgerAppName} Ledger App to the latest version.`, ); @@ -184,7 +183,7 @@ export class LaunchpadLedger { throw new Error("Ledger’s screensaver mode is on"); case "Instruction not supported": throw new Error( - `Your ${this.ledgerAppName} Ledger App is not up to date. Please update to version ${this.requiredLedgerAppVersion}.`, + `Your ${this.ledgerAppName} Ledger App is not up to date. Please update to version ${this.minLedgerAppVersion} or newer.`, ); case "No errors": break; From 456c9c8645772f70b8e905ca0b01ad6eedfa7c12 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 20 Oct 2021 12:05:09 +0200 Subject: [PATCH 7/8] Improve docs on ledgerAppName/requiredLedgerAppVersion --- packages/ledger-amino/src/launchpadledger.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/ledger-amino/src/launchpadledger.ts b/packages/ledger-amino/src/launchpadledger.ts index f0af4085..37d2d0bf 100644 --- a/packages/ledger-amino/src/launchpadledger.ts +++ b/packages/ledger-amino/src/launchpadledger.ts @@ -37,9 +37,17 @@ export interface LaunchpadLedgerOptions { * Support is provided on an best effort basis and only as long as those forks do not * significantly differ from the original app. * - * Defaults to "cosmos". + * Defaults to "Cosmos". */ readonly ledgerAppName?: string; + /** + * The min version of the app the user must have opened on the Ledger. + * This allows you to use this connector with forks of the Cosmos Hub Ledger app. + * Support is provided on an best effort basis and only as long as those forks do not + * significantly differ from the original app. + * + * Defaults to "1.5.3". + */ readonly minLedgerAppVersion?: string; } From 55e84a109c1f509c7c7da0fd92f660aa779d4000 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 20 Oct 2021 11:59:37 +0200 Subject: [PATCH 8/8] Add CHANGELOG entry --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 562c2eef..e2b99d52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ and this project adheres to ## [Unreleased] +### Added + +- @cosmjs/ledger-amino: Add support for using forks of the Cosmos Ledger app by + adding the fields `LaunchpadLedgerOptions.ledgerAppName` and + `.minLedgerAppVersion`. + ## [0.26.2] - 2021-10-12 ### Fixed