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
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
```

View File

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

View File

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

View File

@ -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<LedgerSigner> {
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<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> {
if (signer === undefined) {
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;
}
};
window.onload = async function onLoad(): Promise<void> {
window.signer = await window.createSigner();
};

View File

@ -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,