Refactor we demo and add show address functionality

This commit is contained in:
Simon Warta 2022-01-25 17:57:02 +01:00
parent 9d35df3d91
commit 5176fad733
5 changed files with 93 additions and 38 deletions

View File

@ -27,15 +27,13 @@ yarn demo-node
### Browser ### Browser
Build the package for web: Serve the project locally:
```sh ```sh
# Build the package for web
yarn pack-web yarn pack-web
```
Host the `ledger-amino` package directory, for example using Python 3: # Host the `ledger-amino` package directory, for example using Python 3
```sh
python3 -m http.server python3 -m http.server
``` ```

View File

@ -1,4 +1,4 @@
div { section {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;

View File

@ -8,40 +8,63 @@
<script src="../dist/demo/ledger.js"></script> <script src="../dist/demo/ledger.js"></script>
</head> </head>
<body> <body>
<div> <section>
<h1>Ledger Demo</h1> <h1>Ledger Demo</h1>
</div> </section>
<div> <section>
<ol> <ol>
<li>Connect the Ledger device via USB</li> <li>Connect the Ledger device via USB</li>
<li>Open the Cosmos app on the Ledger device</li> <li>Open the Cosmos app on the Ledger device</li>
<li>Click the buttons below</li> <li>Click the buttons below</li>
</ol> </ol>
</section>
<section>
<button onclick="createSigner().then((signer) => {window.signer = signer; console.log('Connected')}, console.error)">
Connect to Ledger
</button>
</div> </div>
<div> <section>
<h2>Accounts</h2>
<button onclick="getAccounts(window.signer)"> <button onclick="getAccounts(window.signer)">
Get Accounts Get Accounts
</button> </button>
</div> <div id="accounts"></div>
<div id="accounts"></div> </section>
<div> <section>
<label>Account No.</label> <h2>Show address</h2>
<input id="account-number" type="number" value="" onchange="updateMessage(this.value)" min="0" max="0"></input> <div>
</div> <label>Account No.</label>
<div> <input id="account-number1" type="number" value="" onchange="setPath(this.value)" min="0" max="0"></input>
<label>Address</label> </div>
<input id="address" type="text" value="" disabled></input> <div>
</div> <label>Path</label>
<div> <input id="path" type="text" value="" disabled></input>
<label>Message</label> </div>
<textarea id="sign-doc"> <button onclick="showAddress(window.signer)">
</textarea> Show address
</div>
<div>
<button onclick="sign(window.signer)">
Sign Message
</button> </button>
</div> </section>
<div id="signature"></div> <section>
<h2>Sign</h2>
<div>
<label>Account No.</label>
<input id="account-number2" type="number" value="" onchange="updateMessage(this.value)" min="0" max="0"></input>
</div>
<div>
<label>Address</label>
<input id="address" type="text" value="" disabled></input>
</div>
<div>
<label>Message</label>
<textarea id="sign-doc">
</textarea>
</div>
<div>
<button onclick="sign(window.signer)">
Sign Message
</button>
</div>
<div id="signature"></div>
</section>
</body> </body>
</html> </html>

View File

@ -1,4 +1,5 @@
import { AccountData, makeCosmoshubPath, StdSignDoc } from "@cosmjs/amino"; import { AccountData, makeCosmoshubPath, StdSignDoc } from "@cosmjs/amino";
import { pathToString, stringToPath } from "@cosmjs/crypto";
import { toBase64 } from "@cosmjs/encoding"; import { toBase64 } from "@cosmjs/encoding";
import { Uint53 } from "@cosmjs/math"; import { Uint53 } from "@cosmjs/math";
import { assert } from "@cosmjs/utils"; import { assert } from "@cosmjs/utils";
@ -9,6 +10,9 @@ import { LedgerSigner } from "../ledgersigner";
declare const window: any; declare const window: any;
declare const document: any; declare const document: any;
const accountNumbers = [0, 1, 2, 10];
const paths = accountNumbers.map(makeCosmoshubPath);
let accounts: readonly AccountData[] = []; let accounts: readonly AccountData[] = [];
function createSignDoc(accountNumber: number, address: string): string { function createSignDoc(accountNumber: number, address: string): string {
@ -59,12 +63,22 @@ window.updateMessage = (accountNumberInput: unknown) => {
signDocTextArea.textContent = createSignDoc(accountNumber, address); 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<LedgerSigner> { window.createSigner = async function createSigner(): Promise<LedgerSigner> {
const interactiveTimeout = 120_000; const interactiveTimeout = 120_000;
const ledgerTransport = await TransportWebUSB.create(interactiveTimeout, interactiveTimeout); const ledgerTransport = await TransportWebUSB.create(interactiveTimeout, interactiveTimeout);
return new LedgerSigner(ledgerTransport, { return new LedgerSigner(ledgerTransport, {
testModeAllowed: true, 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"); console.error("Please wait for transport to connect");
return; 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 addressInput = document.getElementById("address");
const accountsDiv = document.getElementById("accounts"); const accountsDiv = document.getElementById("accounts");
const signDocTextArea = document.getElementById("sign-doc"); 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"); accountsDiv.textContent = JSON.stringify(prettyAccounts, null, "\n");
const accountNumber = 0; 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; const address = accounts[0].address;
addressInput.value = address; addressInput.value = address;
signDocTextArea.textContent = createSignDoc(accountNumber, address); signDocTextArea.textContent = createSignDoc(accountNumber, address);
} catch (error) { } catch (error) {
console.error(error);
accountsDiv.textContent = error; accountsDiv.textContent = error;
} }
}; };
window.showAddress = async function showAddress(signer: LedgerSigner | undefined): Promise<void> {
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<void> { window.sign = async function sign(signer: LedgerSigner | undefined): Promise<void> {
if (signer === undefined) { if (signer === undefined) {
console.error("Please wait for transport to connect"); console.error("Please wait for transport to connect");
@ -115,7 +147,3 @@ window.sign = async function sign(signer: LedgerSigner | undefined): Promise<voi
signatureDiv.textContent = error; signatureDiv.textContent = error;
} }
}; };
window.onload = async function onLoad(): Promise<void> {
window.signer = await window.createSigner();
};

View File

@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/naming-convention */ /* eslint-disable @typescript-eslint/naming-convention */
const glob = require("glob"); const glob = require("glob");
const path = require("path"); const path = require("path");
const webpack = require("webpack");
const target = "web"; const target = "web";
const demodir = path.join(__dirname, "dist", "demo"); const demodir = path.join(__dirname, "dist", "demo");
@ -14,6 +15,11 @@ module.exports = [
path: demodir, path: demodir,
filename: "ledger.js", filename: "ledger.js",
}, },
plugins: [
new webpack.ProvidePlugin({
Buffer: ["buffer", "Buffer"],
}),
],
resolve: { resolve: {
fallback: { fallback: {
buffer: false, buffer: false,