diff --git a/packages/ledger-amino/README.md b/packages/ledger-amino/README.md index 8660351e9b..21db73ce25 100644 --- a/packages/ledger-amino/README.md +++ b/packages/ledger-amino/README.md @@ -27,15 +27,13 @@ yarn demo-node ### Browser -Build the package for web: +Serve the project locally: ```sh +# Build the package for web yarn pack-web -``` -Host the `ledger-amino` package directory, for example using Python 3: - -```sh +# Host the `ledger-amino` package directory, for example using Python 3 python3 -m http.server ``` diff --git a/packages/ledger-amino/demo/index.css b/packages/ledger-amino/demo/index.css index 974bced327..137a987793 100644 --- a/packages/ledger-amino/demo/index.css +++ b/packages/ledger-amino/demo/index.css @@ -1,4 +1,4 @@ -div { +section { display: flex; align-items: center; justify-content: center; diff --git a/packages/ledger-amino/demo/index.html b/packages/ledger-amino/demo/index.html index bb483690fb..d2ca617a76 100644 --- a/packages/ledger-amino/demo/index.html +++ b/packages/ledger-amino/demo/index.html @@ -8,40 +8,63 @@ -
+

Ledger Demo

-
-
+ +
  1. Connect the Ledger device via USB
  2. Open the Cosmos app on the Ledger device
  3. Click the buttons below
+
+
+
-
+
+

Accounts

-
-
-
- - -
-
- - -
-
- - -
-
- -
-
+ +
+

Sign

+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
diff --git a/packages/ledger-amino/src/demo/web.ts b/packages/ledger-amino/src/demo/web.ts index 028b0f114e..e029c88d26 100644 --- a/packages/ledger-amino/src/demo/web.ts +++ b/packages/ledger-amino/src/demo/web.ts @@ -1,4 +1,5 @@ import { AccountData, makeCosmoshubPath, StdSignDoc } from "@cosmjs/amino"; +import { pathToString, stringToPath } from "@cosmjs/crypto"; import { toBase64 } from "@cosmjs/encoding"; import { Uint53 } from "@cosmjs/math"; import { assert } from "@cosmjs/utils"; @@ -9,6 +10,9 @@ import { LedgerSigner } from "../ledgersigner"; declare const window: any; declare const document: any; +const accountNumbers = [0, 1, 2, 10]; +const paths = accountNumbers.map(makeCosmoshubPath); + let accounts: readonly AccountData[] = []; function createSignDoc(accountNumber: number, address: string): string { @@ -59,12 +63,22 @@ window.updateMessage = (accountNumberInput: unknown) => { signDocTextArea.textContent = createSignDoc(accountNumber, address); }; +window.setPath = (accountNumberInput: unknown) => { + assert(typeof accountNumberInput === "string"); + const accountNumber = Uint53.fromString(accountNumberInput).toNumber(); + + const path = pathToString(paths[accountNumber]); + const pathInput = document.getElementById("path"); + pathInput.value = path; +}; + +// This must be called by the user an cannot be done on load (see "TransportWebUSBGestureRequired"). window.createSigner = async function createSigner(): Promise { const interactiveTimeout = 120_000; const ledgerTransport = await TransportWebUSB.create(interactiveTimeout, interactiveTimeout); return new LedgerSigner(ledgerTransport, { testModeAllowed: true, - hdPaths: [makeCosmoshubPath(0), makeCosmoshubPath(1), makeCosmoshubPath(2)], + hdPaths: paths, }); }; @@ -73,7 +87,8 @@ window.getAccounts = async function getAccounts(signer: LedgerSigner | undefined console.error("Please wait for transport to connect"); return; } - const accountNumberInput = document.getElementById("account-number"); + const accountNumberInput1 = document.getElementById("account-number1"); + const accountNumberInput2 = document.getElementById("account-number2"); const addressInput = document.getElementById("address"); const accountsDiv = document.getElementById("accounts"); const signDocTextArea = document.getElementById("sign-doc"); @@ -87,16 +102,33 @@ window.getAccounts = async function getAccounts(signer: LedgerSigner | undefined })); accountsDiv.textContent = JSON.stringify(prettyAccounts, null, "\n"); const accountNumber = 0; - accountNumberInput.max = accounts.length - 1; - accountNumberInput.value = accountNumber; + + // Show address block + accountNumberInput1.max = accounts.length - 1; + accountNumberInput1.value = accountNumber; + window.setPath(accountNumber.toString()); + + // Sign block + accountNumberInput2.max = accounts.length - 1; + accountNumberInput2.value = accountNumber; const address = accounts[0].address; addressInput.value = address; signDocTextArea.textContent = createSignDoc(accountNumber, address); } catch (error) { + console.error(error); accountsDiv.textContent = error; } }; +window.showAddress = async function showAddress(signer: LedgerSigner | undefined): Promise { + if (signer === undefined) { + console.error("Please wait for transport to connect"); + return; + } + const path = stringToPath(document.getElementById("path").value); + await signer.showAddress(path); +}; + window.sign = async function sign(signer: LedgerSigner | undefined): Promise { if (signer === undefined) { console.error("Please wait for transport to connect"); @@ -115,7 +147,3 @@ window.sign = async function sign(signer: LedgerSigner | undefined): Promise { - window.signer = await window.createSigner(); -}; diff --git a/packages/ledger-amino/webpack.demo.config.js b/packages/ledger-amino/webpack.demo.config.js index aecae6aeae..47858f4119 100644 --- a/packages/ledger-amino/webpack.demo.config.js +++ b/packages/ledger-amino/webpack.demo.config.js @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ const glob = require("glob"); const path = require("path"); +const webpack = require("webpack"); const target = "web"; const demodir = path.join(__dirname, "dist", "demo"); @@ -14,6 +15,11 @@ module.exports = [ path: demodir, filename: "ledger.js", }, + plugins: [ + new webpack.ProvidePlugin({ + Buffer: ["buffer", "Buffer"], + }), + ], resolve: { fallback: { buffer: false,