From d79dd01711f2a9e86833a3fa7f0d83a4bc32ad55 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Tue, 29 Sep 2020 15:58:13 +0200 Subject: [PATCH 1/9] Add initial Ledger tests --- .../launchpad-ledger/jasmine-testrunner.js | 33 +++++++ packages/launchpad-ledger/package.json | 6 +- .../launchpad-ledger/src/ledgersigner.spec.ts | 94 +++++++++++++++++++ .../launchpad-ledger/src/testutils.spec.ts | 19 ++++ 4 files changed, 150 insertions(+), 2 deletions(-) create mode 100755 packages/launchpad-ledger/jasmine-testrunner.js create mode 100644 packages/launchpad-ledger/src/ledgersigner.spec.ts create mode 100644 packages/launchpad-ledger/src/testutils.spec.ts diff --git a/packages/launchpad-ledger/jasmine-testrunner.js b/packages/launchpad-ledger/jasmine-testrunner.js new file mode 100755 index 00000000..7a17962e --- /dev/null +++ b/packages/launchpad-ledger/jasmine-testrunner.js @@ -0,0 +1,33 @@ +#!/usr/bin/env node + +/* eslint-disable @typescript-eslint/naming-convention */ +require("source-map-support").install(); +const defaultSpecReporterConfig = require("../../jasmine-spec-reporter.config.json"); + +// setup Jasmine +const Jasmine = require("jasmine"); +const jasmine = new Jasmine(); +jasmine.loadConfig({ + spec_dir: "build", + spec_files: ["**/*.spec.js"], + helpers: [], + random: false, + seed: null, + stopSpecOnExpectationFailure: false, +}); +jasmine.jasmine.DEFAULT_TIMEOUT_INTERVAL = 15 * 1000; + +// setup reporter +const { SpecReporter } = require("jasmine-spec-reporter"); +const reporter = new SpecReporter({ + ...defaultSpecReporterConfig, + spec: { + ...defaultSpecReporterConfig.spec, + displaySuccessful: !process.argv.includes("--quiet"), + }, +}); + +// initialize and execute +jasmine.env.clearReporters(); +jasmine.addReporter(reporter); +jasmine.execute(); diff --git a/packages/launchpad-ledger/package.json b/packages/launchpad-ledger/package.json index 2e882555..022644b0 100644 --- a/packages/launchpad-ledger/package.json +++ b/packages/launchpad-ledger/package.json @@ -28,13 +28,15 @@ "format-text": "prettier --write --prose-wrap always --print-width 80 \"./*.md\"", "lint": "eslint --max-warnings 0 \"**/*.{js,ts}\"", "lint-fix": "eslint --max-warnings 0 \"**/*.{js,ts}\" --fix", - "move-types": "shx rm -rf ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -rf ./types/demo", + "premove-types": "shx rm -rf ./build/types/demo", + "move-types": "shx rm -r ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", "prebuild": "shx rm -rf ./build", "build": "tsc", "postbuild": "yarn move-types && yarn format-types", "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", - "test": "echo 'Please check README for information on how to manually run the demo'", + "test-node": "node jasmine-testrunner.js", + "test": "yarn build-or-skip && yarn test-node", "demo-node": "yarn build-or-skip && node ./demo/node.js", "coverage": "nyc --reporter=text --reporter=lcov yarn test --quiet", "pack-web": "yarn build-or-skip && webpack --mode development --config webpack.demo.config.js" diff --git a/packages/launchpad-ledger/src/ledgersigner.spec.ts b/packages/launchpad-ledger/src/ledgersigner.spec.ts new file mode 100644 index 00000000..4b0941ca --- /dev/null +++ b/packages/launchpad-ledger/src/ledgersigner.spec.ts @@ -0,0 +1,94 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { Secp256k1, Secp256k1Signature, Sha256 } from "@cosmjs/crypto"; +import { fromBase64 } from "@cosmjs/encoding"; +import { coins, makeCosmoshubPath, makeSignDoc, Msg, serializeSignDoc, StdFee } from "@cosmjs/launchpad"; + +import { LedgerSigner } from "./ledgersigner"; +import { pendingWithoutLedger, pendingWithoutLedgerInteractive } from "./testutils.spec"; + +const interactiveTimeout = 120_000; + +describe("LedgerSigner", () => { + const defaultChainId = "testing"; + const defaultFee: StdFee = { + amount: coins(100, "ucosm"), + gas: "250", + }; + const defaultMemo = "Some memo"; + const defaultSequence = "0"; + const defaultAccountNumber = "42"; + const defaultRecipient = "cosmos1p6xs63q4g7np99ttv5nd3yzkt8n4qxa47w8aea"; + + describe("getAccount", () => { + it("works", async () => { + pendingWithoutLedger(); + const signer = new LedgerSigner({ + testModeAllowed: true, + hdPaths: [makeCosmoshubPath(0), makeCosmoshubPath(1), makeCosmoshubPath(10)], + }); + + const accounts = await signer.getAccounts(); + expect(accounts.length).toEqual(3); + expect(accounts).toEqual([ + { + address: "cosmos1p6xs63q4g7np99ttv5nd3yzkt8n4qxa47w8aea", + algo: "secp256k1", + pubkey: fromBase64("A66JoCNaNSXDsyj4qW7JgqXPTz5rOnfE6EKEArf4jJEK"), + }, + { + address: "cosmos1meeu3jl268txxytwmmrsljk8rawh6n2majstn2", + algo: "secp256k1", + pubkey: fromBase64("AtvmGuZvEN3NwL05BQdxl3XygUf+Vl/930fhFMt1HTyU"), + }, + { + address: "cosmos1f3pws3ztnp3s4nn5zxqdrl9vlqv5avkqmlrus4", + algo: "secp256k1", + pubkey: fromBase64("A2ZnLEcbpyjS30H5UF1vezq29aBcT9oo5EARATIW9Cpj"), + }, + ]); + }); + }); + + describe("sign", () => { + it( + "works", + async () => { + pendingWithoutLedgerInteractive(); + const signer = new LedgerSigner({ + testModeAllowed: true, + hdPaths: [makeCosmoshubPath(0), makeCosmoshubPath(1), makeCosmoshubPath(10)], + }); + + const [fistAccount] = await signer.getAccounts(); + + const msgs: readonly Msg[] = [ + { + type: "cosmos-sdk/MsgSend", + value: { + amount: coins(1234567, "ucosm"), + from_address: fistAccount.address, + to_address: defaultRecipient, + }, + }, + ]; + const signDoc = makeSignDoc( + msgs, + defaultFee, + defaultChainId, + defaultMemo, + defaultAccountNumber, + defaultSequence, + ); + const { signed, signature } = await signer.sign(fistAccount.address, signDoc); + expect(signed).toEqual(signDoc); + const valid = await Secp256k1.verifySignature( + Secp256k1Signature.fromFixedLength(fromBase64(signature.signature)), + new Sha256(serializeSignDoc(signed)).digest(), + fistAccount.pubkey, + ); + expect(valid).toEqual(true); + }, + interactiveTimeout, + ); + }); +}); diff --git a/packages/launchpad-ledger/src/testutils.spec.ts b/packages/launchpad-ledger/src/testutils.spec.ts new file mode 100644 index 00000000..b4e493cf --- /dev/null +++ b/packages/launchpad-ledger/src/testutils.spec.ts @@ -0,0 +1,19 @@ +export function ledgerEnabled(): boolean { + return !!process.env.LEDGER_ENABLED; +} + +export function pendingWithoutLedger(): void { + if (!ledgerEnabled()) { + return pending("Set LEDGER_ENABLED to enable Wasmd based tests"); + } +} + +export function ledgerInteractiveEnabled(): boolean { + return !!process.env.LEDGER_INTERACTIVE_ENABLED; +} + +export function pendingWithoutLedgerInteractive(): void { + if (!ledgerInteractiveEnabled()) { + return pending("Set LEDGER_INTERACTIVE_ENABLED to enable Wasmd based tests"); + } +} From 53b20f533877e0396a19e5b1c19bbfd287a6166d Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Tue, 29 Sep 2020 17:40:33 +0200 Subject: [PATCH 2/9] Refactor ensureConnected --- .../launchpad-ledger/src/launchpadledger.ts | 41 +++++++++---------- .../types/launchpadledger.d.ts | 2 +- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/packages/launchpad-ledger/src/launchpadledger.ts b/packages/launchpad-ledger/src/launchpadledger.ts index 316c9fb1..80ce8cb8 100644 --- a/packages/launchpad-ledger/src/launchpadledger.ts +++ b/packages/launchpad-ledger/src/launchpadledger.ts @@ -81,25 +81,8 @@ export class LaunchpadLedger { } } - public async connect(timeout = defaultInteractionTimeout): Promise { - // assume good connection if connected once - if (this.cosmosApp) { - return this; - } - - if (this.platform !== "node") { - verifyBrowserIsSupported(this.platform, this.userAgent); - } - - const transport = await this.createTransport(timeout * 1000); - this.cosmosApp = new CosmosApp(transport); - - await this.verifyDeviceIsReady(); - return this; - } - public async getCosmosAppVersion(): Promise { - await this.connect(); + await this.ensureConnected(); assert(this.cosmosApp, "Cosmos Ledger App is not connected"); const response = await this.cosmosApp.getVersion(); @@ -111,7 +94,7 @@ export class LaunchpadLedger { } public async getPubkey(hdPath?: HdPath): Promise { - await this.connect(); + await this.ensureConnected(); assert(this.cosmosApp, "Cosmos Ledger App is not connected"); const hdPathToUse = hdPath || this.hdPaths[0]; @@ -135,7 +118,7 @@ export class LaunchpadLedger { } public async sign(message: Uint8Array, hdPath?: HdPath): Promise { - await this.connect(); + await this.ensureConnected(); assert(this.cosmosApp, "Cosmos Ledger App is not connected"); const hdPathToUse = hdPath || this.hdPaths[0]; @@ -145,6 +128,22 @@ export class LaunchpadLedger { return Secp256k1Signature.fromDer((response as SignResponse).signature).toFixedLength(); } + private async ensureConnected(timeout = defaultInteractionTimeout): Promise { + // assume good connection if connected once + if (this.cosmosApp) { + return; + } + + if (this.platform !== "node") { + verifyBrowserIsSupported(this.platform, this.userAgent); + } + + const transport = await this.createTransport(timeout * 1000); + this.cosmosApp = new CosmosApp(transport); + + await this.verifyDeviceIsReady(); + } + private async createTransport(timeout: number): Promise { // HACK: Use a variable to get webpack to ignore this const nodeJsTransportPackageName = "@ledgerhq/hw-transport-node-hid"; @@ -189,7 +188,7 @@ export class LaunchpadLedger { } private async getOpenAppName(): Promise { - await this.connect(); + await this.ensureConnected(); assert(this.cosmosApp, "Cosmos Ledger App is not connected"); const response = await this.cosmosApp.appInfo(); diff --git a/packages/launchpad-ledger/types/launchpadledger.d.ts b/packages/launchpad-ledger/types/launchpadledger.d.ts index 2cc42f18..459d82fe 100644 --- a/packages/launchpad-ledger/types/launchpadledger.d.ts +++ b/packages/launchpad-ledger/types/launchpadledger.d.ts @@ -16,12 +16,12 @@ export declare class LaunchpadLedger { readonly platform: string; readonly userAgent: string | null; constructor(options?: LaunchpadLedgerOptions); - connect(timeout?: number): Promise; getCosmosAppVersion(): Promise; getPubkey(hdPath?: HdPath): Promise; getPubkeys(): Promise; getCosmosAddress(pubkey?: Uint8Array): Promise; sign(message: Uint8Array, hdPath?: HdPath): Promise; + private ensureConnected; private createTransport; private verifyAppMode; private getOpenAppName; From 9106d17c4d5a06c2b1c8bf72557790fd6e89be38 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Tue, 29 Sep 2020 18:01:41 +0200 Subject: [PATCH 3/9] Support running multiple tests in one process --- .../launchpad-ledger/src/launchpadledger.ts | 40 +++++++++++++------ .../launchpad-ledger/src/ledgersigner.spec.ts | 4 ++ packages/launchpad-ledger/src/ledgersigner.ts | 4 ++ .../types/launchpadledger.d.ts | 3 +- .../launchpad-ledger/types/ledgersigner.d.ts | 1 + 5 files changed, 39 insertions(+), 13 deletions(-) diff --git a/packages/launchpad-ledger/src/launchpadledger.ts b/packages/launchpad-ledger/src/launchpadledger.ts index 80ce8cb8..fc74738f 100644 --- a/packages/launchpad-ledger/src/launchpadledger.ts +++ b/packages/launchpad-ledger/src/launchpadledger.ts @@ -18,6 +18,12 @@ export interface LedgerAppErrorResponse { } /* eslint-enable */ +interface ConnectedApp { + /** The transport used by the app */ + readonly transport: Transport; + readonly app: CosmosApp; +} + const defaultInteractionTimeout = 120; // seconds to wait for user action on Ledger, currently is always limited to 60 const requiredCosmosAppVersion = "1.5.3"; @@ -53,7 +59,7 @@ export class LaunchpadLedger { private readonly testModeAllowed: boolean; private readonly hdPaths: readonly HdPath[]; private readonly prefix: string; - private cosmosApp: CosmosApp | null; + private connectedApp: ConnectedApp | null; public readonly platform: string; public readonly userAgent: string | null; @@ -70,7 +76,7 @@ export class LaunchpadLedger { this.testModeAllowed = testModeAllowed; this.hdPaths = hdPaths; this.prefix = prefix; - this.cosmosApp = null; + this.connectedApp = null; try { this.platform = navigator.platform; @@ -83,9 +89,9 @@ export class LaunchpadLedger { public async getCosmosAppVersion(): Promise { await this.ensureConnected(); - assert(this.cosmosApp, "Cosmos Ledger App is not connected"); + assert(this.connectedApp, "Cosmos Ledger App is not connected"); - const response = await this.cosmosApp.getVersion(); + const response = await this.connectedApp.app.getVersion(); this.handleLedgerErrors(response); // eslint-disable-next-line @typescript-eslint/naming-convention const { major, minor, patch, test_mode: testMode } = response as VersionResponse; @@ -95,11 +101,11 @@ export class LaunchpadLedger { public async getPubkey(hdPath?: HdPath): Promise { await this.ensureConnected(); - assert(this.cosmosApp, "Cosmos Ledger App is not connected"); + assert(this.connectedApp, "Cosmos Ledger App is not connected"); const hdPathToUse = hdPath || this.hdPaths[0]; // ledger-cosmos-js hardens the first three indices - const response = await this.cosmosApp.publicKey(unharden(hdPathToUse)); + const response = await this.connectedApp.app.publicKey(unharden(hdPathToUse)); this.handleLedgerErrors(response); return Uint8Array.from((response as PublicKeyResponse).compressed_pk); } @@ -119,18 +125,25 @@ export class LaunchpadLedger { public async sign(message: Uint8Array, hdPath?: HdPath): Promise { await this.ensureConnected(); - assert(this.cosmosApp, "Cosmos Ledger App is not connected"); + assert(this.connectedApp, "Cosmos Ledger App is not connected"); const hdPathToUse = hdPath || this.hdPaths[0]; // ledger-cosmos-js hardens the first three indices - const response = await this.cosmosApp.sign(unharden(hdPathToUse), fromUtf8(message)); + const response = await this.connectedApp.app.sign(unharden(hdPathToUse), fromUtf8(message)); this.handleLedgerErrors(response, "Transaction signing request was rejected by the user"); return Secp256k1Signature.fromDer((response as SignResponse).signature).toFixedLength(); } + public async disconnect(): Promise { + if (this.connectedApp) { + await this.connectedApp.transport.close(); + this.connectedApp = null; + } + } + private async ensureConnected(timeout = defaultInteractionTimeout): Promise { // assume good connection if connected once - if (this.cosmosApp) { + if (this.connectedApp) { return; } @@ -139,7 +152,10 @@ export class LaunchpadLedger { } const transport = await this.createTransport(timeout * 1000); - this.cosmosApp = new CosmosApp(transport); + this.connectedApp = { + transport: transport, + app: new CosmosApp(transport), + }; await this.verifyDeviceIsReady(); } @@ -189,9 +205,9 @@ export class LaunchpadLedger { private async getOpenAppName(): Promise { await this.ensureConnected(); - assert(this.cosmosApp, "Cosmos Ledger App is not connected"); + assert(this.connectedApp, "Cosmos Ledger App is not connected"); - const response = await this.cosmosApp.appInfo(); + const response = await this.connectedApp.app.appInfo(); this.handleLedgerErrors(response); return (response as AppInfoResponse).appName; } diff --git a/packages/launchpad-ledger/src/ledgersigner.spec.ts b/packages/launchpad-ledger/src/ledgersigner.spec.ts index 4b0941ca..8fe88e9c 100644 --- a/packages/launchpad-ledger/src/ledgersigner.spec.ts +++ b/packages/launchpad-ledger/src/ledgersigner.spec.ts @@ -46,6 +46,8 @@ describe("LedgerSigner", () => { pubkey: fromBase64("A2ZnLEcbpyjS30H5UF1vezq29aBcT9oo5EARATIW9Cpj"), }, ]); + + await signer.disconnect(); }); }); @@ -87,6 +89,8 @@ describe("LedgerSigner", () => { fistAccount.pubkey, ); expect(valid).toEqual(true); + + await signer.disconnect(); }, interactiveTimeout, ); diff --git a/packages/launchpad-ledger/src/ledgersigner.ts b/packages/launchpad-ledger/src/ledgersigner.ts index 224a55e7..8c863165 100644 --- a/packages/launchpad-ledger/src/ledgersigner.ts +++ b/packages/launchpad-ledger/src/ledgersigner.ts @@ -52,4 +52,8 @@ export class LedgerSigner implements OfflineSigner { signature: encodeSecp256k1Signature(accountForAddress.pubkey, signature), }; } + + public async disconnect(): Promise { + return this.ledger.disconnect(); + } } diff --git a/packages/launchpad-ledger/types/launchpadledger.d.ts b/packages/launchpad-ledger/types/launchpadledger.d.ts index 459d82fe..6e729254 100644 --- a/packages/launchpad-ledger/types/launchpadledger.d.ts +++ b/packages/launchpad-ledger/types/launchpadledger.d.ts @@ -12,7 +12,7 @@ export declare class LaunchpadLedger { private readonly testModeAllowed; private readonly hdPaths; private readonly prefix; - private cosmosApp; + private connectedApp; readonly platform: string; readonly userAgent: string | null; constructor(options?: LaunchpadLedgerOptions); @@ -21,6 +21,7 @@ export declare class LaunchpadLedger { getPubkeys(): Promise; getCosmosAddress(pubkey?: Uint8Array): Promise; sign(message: Uint8Array, hdPath?: HdPath): Promise; + disconnect(): Promise; private ensureConnected; private createTransport; private verifyAppMode; diff --git a/packages/launchpad-ledger/types/ledgersigner.d.ts b/packages/launchpad-ledger/types/ledgersigner.d.ts index 6ddfee8b..8a81c649 100644 --- a/packages/launchpad-ledger/types/ledgersigner.d.ts +++ b/packages/launchpad-ledger/types/ledgersigner.d.ts @@ -8,4 +8,5 @@ export declare class LedgerSigner implements OfflineSigner { constructor(options?: LaunchpadLedgerOptions); getAccounts(): Promise; sign(signerAddress: string, signDoc: StdSignDoc): Promise; + disconnect(): Promise; } From 334df80061f7a0292efa63d57abbf66bc28b1d8a Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Tue, 29 Sep 2020 18:43:04 +0200 Subject: [PATCH 4/9] Create broadcasting test --- .../launchpad-ledger/src/ledgersigner.spec.ts | 35 +++++++++++++++++-- .../launchpad-ledger/src/testutils.spec.ts | 5 +++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/packages/launchpad-ledger/src/ledgersigner.spec.ts b/packages/launchpad-ledger/src/ledgersigner.spec.ts index 8fe88e9c..6314e2cd 100644 --- a/packages/launchpad-ledger/src/ledgersigner.spec.ts +++ b/packages/launchpad-ledger/src/ledgersigner.spec.ts @@ -1,10 +1,20 @@ /* eslint-disable @typescript-eslint/naming-convention */ import { Secp256k1, Secp256k1Signature, Sha256 } from "@cosmjs/crypto"; import { fromBase64 } from "@cosmjs/encoding"; -import { coins, makeCosmoshubPath, makeSignDoc, Msg, serializeSignDoc, StdFee } from "@cosmjs/launchpad"; +import { + coins, + isBroadcastTxSuccess, + makeCosmoshubPath, + makeSignDoc, + Msg, + serializeSignDoc, + SigningCosmosClient, + StdFee, +} from "@cosmjs/launchpad"; +import { assert } from "@cosmjs/utils"; import { LedgerSigner } from "./ledgersigner"; -import { pendingWithoutLedger, pendingWithoutLedgerInteractive } from "./testutils.spec"; +import { pendingWithoutLedger, pendingWithoutLedgerInteractive, wasmd } from "./testutils.spec"; const interactiveTimeout = 120_000; @@ -53,7 +63,7 @@ describe("LedgerSigner", () => { describe("sign", () => { it( - "works", + "returns valid signature", async () => { pendingWithoutLedgerInteractive(); const signer = new LedgerSigner({ @@ -94,5 +104,24 @@ describe("LedgerSigner", () => { }, interactiveTimeout, ); + + it( + "creates signature accepted by launchpad backend", + async () => { + pendingWithoutLedgerInteractive(); + const signer = new LedgerSigner({ + testModeAllowed: true, + hdPaths: [makeCosmoshubPath(0), makeCosmoshubPath(1), makeCosmoshubPath(10)], + }); + const [fistAccount] = await signer.getAccounts(); + + const client = new SigningCosmosClient(wasmd.endpoint, fistAccount.address, signer); + const result = await client.sendTokens(defaultRecipient, coins(1234567, "ucosm")); + assert(isBroadcastTxSuccess(result)); + + await signer.disconnect(); + }, + interactiveTimeout, + ); }); }); diff --git a/packages/launchpad-ledger/src/testutils.spec.ts b/packages/launchpad-ledger/src/testutils.spec.ts index b4e493cf..598501a3 100644 --- a/packages/launchpad-ledger/src/testutils.spec.ts +++ b/packages/launchpad-ledger/src/testutils.spec.ts @@ -17,3 +17,8 @@ export function pendingWithoutLedgerInteractive(): void { return pending("Set LEDGER_INTERACTIVE_ENABLED to enable Wasmd based tests"); } } + +export const wasmd = { + endpoint: "http://localhost:1317", + chainId: "testing", +}; From 698d241d8086e6a1c16abd6ee6292c39fce0a96f Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 30 Sep 2020 12:57:22 +0200 Subject: [PATCH 5/9] Add some time to recover --- packages/launchpad-ledger/src/ledgersigner.spec.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/launchpad-ledger/src/ledgersigner.spec.ts b/packages/launchpad-ledger/src/ledgersigner.spec.ts index 6314e2cd..9a03645b 100644 --- a/packages/launchpad-ledger/src/ledgersigner.spec.ts +++ b/packages/launchpad-ledger/src/ledgersigner.spec.ts @@ -11,7 +11,7 @@ import { SigningCosmosClient, StdFee, } from "@cosmjs/launchpad"; -import { assert } from "@cosmjs/utils"; +import { assert, sleep } from "@cosmjs/utils"; import { LedgerSigner } from "./ledgersigner"; import { pendingWithoutLedger, pendingWithoutLedgerInteractive, wasmd } from "./testutils.spec"; @@ -62,6 +62,11 @@ describe("LedgerSigner", () => { }); describe("sign", () => { + afterEach(async () => { + // It seems the Ledger device needs a bit of time to recover + await sleep(500); + }); + it( "returns valid signature", async () => { From f0b2df8a6c5f8e833507d4124ef8a03d93edf7be Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 30 Sep 2020 13:00:43 +0200 Subject: [PATCH 6/9] Check WASMD_ENABLED --- packages/launchpad-ledger/src/ledgersigner.spec.ts | 8 +++++++- packages/launchpad-ledger/src/testutils.spec.ts | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/launchpad-ledger/src/ledgersigner.spec.ts b/packages/launchpad-ledger/src/ledgersigner.spec.ts index 9a03645b..bb21f89d 100644 --- a/packages/launchpad-ledger/src/ledgersigner.spec.ts +++ b/packages/launchpad-ledger/src/ledgersigner.spec.ts @@ -14,7 +14,12 @@ import { import { assert, sleep } from "@cosmjs/utils"; import { LedgerSigner } from "./ledgersigner"; -import { pendingWithoutLedger, pendingWithoutLedgerInteractive, wasmd } from "./testutils.spec"; +import { + pendingWithoutLedger, + pendingWithoutLedgerInteractive, + pendingWithoutWasmd, + wasmd, +} from "./testutils.spec"; const interactiveTimeout = 120_000; @@ -114,6 +119,7 @@ describe("LedgerSigner", () => { "creates signature accepted by launchpad backend", async () => { pendingWithoutLedgerInteractive(); + pendingWithoutWasmd(); const signer = new LedgerSigner({ testModeAllowed: true, hdPaths: [makeCosmoshubPath(0), makeCosmoshubPath(1), makeCosmoshubPath(10)], diff --git a/packages/launchpad-ledger/src/testutils.spec.ts b/packages/launchpad-ledger/src/testutils.spec.ts index 598501a3..9ef1871d 100644 --- a/packages/launchpad-ledger/src/testutils.spec.ts +++ b/packages/launchpad-ledger/src/testutils.spec.ts @@ -18,6 +18,16 @@ export function pendingWithoutLedgerInteractive(): void { } } +export function wasmdEnabled(): boolean { + return !!process.env.WASMD_ENABLED; +} + +export function pendingWithoutWasmd(): void { + if (!wasmdEnabled()) { + return pending("Set WASMD_ENABLED to enable Wasmd based tests"); + } +} + export const wasmd = { endpoint: "http://localhost:1317", chainId: "testing", From 639208b7c63773c1a3ce8776e113e84259579726 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 30 Sep 2020 13:15:46 +0200 Subject: [PATCH 7/9] Document running Ledger tests --- packages/launchpad-ledger/README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/packages/launchpad-ledger/README.md b/packages/launchpad-ledger/README.md index 671258cf..7929748a 100644 --- a/packages/launchpad-ledger/README.md +++ b/packages/launchpad-ledger/README.md @@ -53,6 +53,25 @@ http://localhost:8000/demo. Then follow the instructions on that page. +## Runnng tests + +The tests in this package require a Ledger device initialized with the mnemonic +from +[scripts/wasmd/README.md#preset-accounts](https://github.com/CosmWasm/cosmjs/blob/master/scripts/wasmd/README.md#preset-accounts) +(see "Ledger: accounts for Ledger based demos and tests") with an installed +"Cosmos (ATOM)" app. The device must be connected via USB, unlocked and the +Cosmos app must be opened. The tests require the user to manually approve +transactions. Start a local wasmd blockchain as described in +[scripts/wasmd/README.md](https://github.com/CosmWasm/cosmjs/blob/master/scripts/wasmd/README.md) +and execute: + +```sh +export LEDGER_INTERACTIVE_ENABLED=1 +export LEDGER_ENABLED=1 +export WASMD_ENABLED=1 +yarn test +``` + ## License This package is part of the cosmjs repository, licensed under the Apache License From 873f8c05f5405f16459120d4bb53a6b41c888cdb Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 30 Sep 2020 14:39:34 +0200 Subject: [PATCH 8/9] Add link how to initialize a Ledger --- packages/launchpad-ledger/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/launchpad-ledger/README.md b/packages/launchpad-ledger/README.md index 7929748a..03438965 100644 --- a/packages/launchpad-ledger/README.md +++ b/packages/launchpad-ledger/README.md @@ -55,7 +55,8 @@ Then follow the instructions on that page. ## Runnng tests -The tests in this package require a Ledger device initialized with the mnemonic +The tests in this package require a Ledger device +[initialized with the mnemonic](https://support.ledger.com/hc/en-us/articles/360005434914) from [scripts/wasmd/README.md#preset-accounts](https://github.com/CosmWasm/cosmjs/blob/master/scripts/wasmd/README.md#preset-accounts) (see "Ledger: accounts for Ledger based demos and tests") with an installed From 127dbd6d937b552a94b75f1d51a266ba20025f04 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 30 Sep 2020 14:50:59 +0200 Subject: [PATCH 9/9] Remove LEDGER_INTERACTIVE_ENABLED --- packages/launchpad-ledger/README.md | 1 - packages/launchpad-ledger/src/ledgersigner.spec.ts | 11 +++-------- packages/launchpad-ledger/src/testutils.spec.ts | 10 ---------- 3 files changed, 3 insertions(+), 19 deletions(-) diff --git a/packages/launchpad-ledger/README.md b/packages/launchpad-ledger/README.md index 03438965..b1c736ad 100644 --- a/packages/launchpad-ledger/README.md +++ b/packages/launchpad-ledger/README.md @@ -67,7 +67,6 @@ transactions. Start a local wasmd blockchain as described in and execute: ```sh -export LEDGER_INTERACTIVE_ENABLED=1 export LEDGER_ENABLED=1 export WASMD_ENABLED=1 yarn test diff --git a/packages/launchpad-ledger/src/ledgersigner.spec.ts b/packages/launchpad-ledger/src/ledgersigner.spec.ts index bb21f89d..9ab4addf 100644 --- a/packages/launchpad-ledger/src/ledgersigner.spec.ts +++ b/packages/launchpad-ledger/src/ledgersigner.spec.ts @@ -14,12 +14,7 @@ import { import { assert, sleep } from "@cosmjs/utils"; import { LedgerSigner } from "./ledgersigner"; -import { - pendingWithoutLedger, - pendingWithoutLedgerInteractive, - pendingWithoutWasmd, - wasmd, -} from "./testutils.spec"; +import { pendingWithoutLedger, pendingWithoutWasmd, wasmd } from "./testutils.spec"; const interactiveTimeout = 120_000; @@ -75,7 +70,7 @@ describe("LedgerSigner", () => { it( "returns valid signature", async () => { - pendingWithoutLedgerInteractive(); + pendingWithoutLedger(); const signer = new LedgerSigner({ testModeAllowed: true, hdPaths: [makeCosmoshubPath(0), makeCosmoshubPath(1), makeCosmoshubPath(10)], @@ -118,7 +113,7 @@ describe("LedgerSigner", () => { it( "creates signature accepted by launchpad backend", async () => { - pendingWithoutLedgerInteractive(); + pendingWithoutLedger(); pendingWithoutWasmd(); const signer = new LedgerSigner({ testModeAllowed: true, diff --git a/packages/launchpad-ledger/src/testutils.spec.ts b/packages/launchpad-ledger/src/testutils.spec.ts index 9ef1871d..d9b011b3 100644 --- a/packages/launchpad-ledger/src/testutils.spec.ts +++ b/packages/launchpad-ledger/src/testutils.spec.ts @@ -8,16 +8,6 @@ export function pendingWithoutLedger(): void { } } -export function ledgerInteractiveEnabled(): boolean { - return !!process.env.LEDGER_INTERACTIVE_ENABLED; -} - -export function pendingWithoutLedgerInteractive(): void { - if (!ledgerInteractiveEnabled()) { - return pending("Set LEDGER_INTERACTIVE_ENABLED to enable Wasmd based tests"); - } -} - export function wasmdEnabled(): boolean { return !!process.env.WASMD_ENABLED; }