@dfinity/hardware-wallet-cli 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -3
- package/build/index.js +13 -6
- package/build/src/ledger/identity.js +5 -3
- package/dfinity-hardware-wallet-cli-0.2.1.tgz +0 -0
- package/index.ts +17 -7
- package/package.json +6 -3
- package/src/ledger/identity.ts +0 -2
package/README.md
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
A CLI to interact with the Internet Computer App on Ledger Nano S/X devices.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Quick Start
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
* Install `npm >= 6.14`.
|
|
8
|
+
* Install the CLI: `npm install -g @dfinity/hardware-wallet-cli`
|
|
9
|
+
* Run the CLI: `ic-hardware-wallet --help`
|
|
9
10
|
|
|
10
11
|
## USB connection issues with Ledger Live
|
|
11
12
|
|
|
@@ -15,3 +16,16 @@ Live desktop app running on your computer. If you are facing connection issues
|
|
|
15
16
|
when doing so, Ledger provides platform-specific
|
|
16
17
|
[troubleshooting instructions](https://support.ledger.com/hc/en-us/articles/115005165269-Fix-USB-connection-issues-with-Ledger-Live?support=true)
|
|
17
18
|
on their support site.
|
|
19
|
+
|
|
20
|
+
## Development
|
|
21
|
+
|
|
22
|
+
Clone the repository.
|
|
23
|
+
|
|
24
|
+
Install dependencies with `npm install`.
|
|
25
|
+
|
|
26
|
+
To execute a command, you can use `npm run execute -- <args>`.
|
|
27
|
+
|
|
28
|
+
For example
|
|
29
|
+
|
|
30
|
+
* The command `ic-hardware-wallet --network https://nnsdapp.dfinity.network icp balance`.
|
|
31
|
+
* Would be `npm run execute -- --network https://nnsdapp.dfinity.network icp balance` for development.
|
package/build/index.js
CHANGED
|
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
const commander_1 = require("commander");
|
|
11
11
|
const identity_1 = require("./src/ledger/identity");
|
|
12
12
|
const nns_1 = require("@dfinity/nns");
|
|
13
|
+
const principal_1 = require("@dfinity/principal");
|
|
13
14
|
const agent_1 = require("@dfinity/agent");
|
|
14
15
|
const chalk_1 = __importDefault(require("chalk"));
|
|
15
16
|
// Add polyfill for `window` for `TransportWebHID` checks to work.
|
|
@@ -17,7 +18,6 @@ require("node-window-polyfill/register");
|
|
|
17
18
|
// Add polyfill for `window.fetch` for agent-js to work.
|
|
18
19
|
// @ts-ignore (no types are available)
|
|
19
20
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
20
|
-
const principal_1 = require("@dfinity/principal");
|
|
21
21
|
global.fetch = node_fetch_1.default;
|
|
22
22
|
window.fetch = node_fetch_1.default;
|
|
23
23
|
const program = new commander_1.Command();
|
|
@@ -145,7 +145,7 @@ async function disburseNeuron(neuronId, to, amount) {
|
|
|
145
145
|
const identity = await identity_1.LedgerIdentity.create();
|
|
146
146
|
const governance = nns_1.GovernanceCanister.create({
|
|
147
147
|
agent: await getAgent(identity),
|
|
148
|
-
hardwareWallet:
|
|
148
|
+
hardwareWallet: true,
|
|
149
149
|
});
|
|
150
150
|
await governance.disburse({
|
|
151
151
|
neuronId: BigInt(neuronId),
|
|
@@ -227,10 +227,18 @@ async function listNeurons() {
|
|
|
227
227
|
ok("No neurons found.");
|
|
228
228
|
}
|
|
229
229
|
}
|
|
230
|
+
const buf2hex = (buffer) => {
|
|
231
|
+
return [...new Uint8Array(buffer)]
|
|
232
|
+
.map((x) => x.toString(16).padStart(2, "0"))
|
|
233
|
+
.join("");
|
|
234
|
+
};
|
|
230
235
|
/**
|
|
231
236
|
* Fetches the balance of the main account on the wallet.
|
|
232
237
|
*/
|
|
233
|
-
async function claimNeurons(
|
|
238
|
+
async function claimNeurons() {
|
|
239
|
+
const identity = await identity_1.LedgerIdentity.create();
|
|
240
|
+
const bufferKey = identity.getPublicKey();
|
|
241
|
+
const hexPubKey = buf2hex(bufferKey.toRaw());
|
|
234
242
|
const isHex = hexPubKey.match("^[0-9a-fA-F]+$");
|
|
235
243
|
if (!isHex) {
|
|
236
244
|
throw new Error(`${hexPubKey} is not a hex string.`);
|
|
@@ -238,7 +246,6 @@ async function claimNeurons(hexPubKey) {
|
|
|
238
246
|
if (hexPubKey.length < 130 || hexPubKey.length > 150) {
|
|
239
247
|
throw new Error(`The key must be >= 130 characters and <= 150 characters.`);
|
|
240
248
|
}
|
|
241
|
-
const identity = await identity_1.LedgerIdentity.create();
|
|
242
249
|
const governance = await nns_1.GenesisTokenCanister.create({
|
|
243
250
|
agent: await getAgent(identity),
|
|
244
251
|
});
|
|
@@ -360,8 +367,8 @@ async function main() {
|
|
|
360
367
|
.requiredOption("--principal <principal>", "Principal", tryParsePrincipal)
|
|
361
368
|
.action((args) => run(() => removeHotkey(args.neuronId, args.principal))))
|
|
362
369
|
.addCommand(new commander_1.Command("claim")
|
|
363
|
-
.
|
|
364
|
-
.action((args) => run(() => claimNeurons(
|
|
370
|
+
.description("Claim the caller's GTC neurons.")
|
|
371
|
+
.action((args) => run(() => claimNeurons())));
|
|
365
372
|
const icp = new commander_1.Command("icp")
|
|
366
373
|
.description("Commands for managing ICP.")
|
|
367
374
|
.showSuggestionAfterError()
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -158,8 +162,6 @@ class LedgerIdentity extends agent_1.SignIdentity {
|
|
|
158
162
|
return this._publicKey;
|
|
159
163
|
}
|
|
160
164
|
async sign(blob) {
|
|
161
|
-
console.log("About to sign");
|
|
162
|
-
console.log(Buffer.from(blob).toString("hex"));
|
|
163
165
|
return await this._executeWithApp(async (app) => {
|
|
164
166
|
const resp = await app.sign(this.derivePath, Buffer.from(blob), this._neuronStakeFlag ? 1 : 0);
|
|
165
167
|
// Remove the "neuron stake" flag, since we already signed the transaction.
|
|
Binary file
|
package/index.ts
CHANGED
|
@@ -15,6 +15,8 @@ import {
|
|
|
15
15
|
InsufficientAmountError,
|
|
16
16
|
InsufficientFundsError,
|
|
17
17
|
} from "@dfinity/nns";
|
|
18
|
+
import { Principal } from "@dfinity/principal";
|
|
19
|
+
import type { Secp256k1PublicKey } from "src/ledger/secp256k1";
|
|
18
20
|
import { Agent, AnonymousIdentity, HttpAgent, Identity } from "@dfinity/agent";
|
|
19
21
|
import chalk from "chalk";
|
|
20
22
|
|
|
@@ -24,7 +26,7 @@ import "node-window-polyfill/register";
|
|
|
24
26
|
// Add polyfill for `window.fetch` for agent-js to work.
|
|
25
27
|
// @ts-ignore (no types are available)
|
|
26
28
|
import fetch from "node-fetch";
|
|
27
|
-
|
|
29
|
+
|
|
28
30
|
global.fetch = fetch;
|
|
29
31
|
window.fetch = fetch;
|
|
30
32
|
|
|
@@ -184,7 +186,7 @@ async function disburseNeuron(neuronId: bigint, to?: string, amount?: bigint) {
|
|
|
184
186
|
const identity = await LedgerIdentity.create();
|
|
185
187
|
const governance = GovernanceCanister.create({
|
|
186
188
|
agent: await getAgent(identity),
|
|
187
|
-
hardwareWallet:
|
|
189
|
+
hardwareWallet: true,
|
|
188
190
|
});
|
|
189
191
|
|
|
190
192
|
await governance.disburse({
|
|
@@ -285,10 +287,20 @@ async function listNeurons() {
|
|
|
285
287
|
}
|
|
286
288
|
}
|
|
287
289
|
|
|
290
|
+
const buf2hex = (buffer: ArrayBuffer): string => {
|
|
291
|
+
return [...new Uint8Array(buffer)]
|
|
292
|
+
.map((x) => x.toString(16).padStart(2, "0"))
|
|
293
|
+
.join("");
|
|
294
|
+
};
|
|
295
|
+
|
|
288
296
|
/**
|
|
289
297
|
* Fetches the balance of the main account on the wallet.
|
|
290
298
|
*/
|
|
291
|
-
async function claimNeurons(
|
|
299
|
+
async function claimNeurons() {
|
|
300
|
+
const identity = await LedgerIdentity.create();
|
|
301
|
+
|
|
302
|
+
const bufferKey = identity.getPublicKey() as Secp256k1PublicKey;
|
|
303
|
+
const hexPubKey = buf2hex(bufferKey.toRaw());
|
|
292
304
|
const isHex = hexPubKey.match("^[0-9a-fA-F]+$");
|
|
293
305
|
if (!isHex) {
|
|
294
306
|
throw new Error(`${hexPubKey} is not a hex string.`);
|
|
@@ -298,7 +310,6 @@ async function claimNeurons(hexPubKey: string) {
|
|
|
298
310
|
throw new Error(`The key must be >= 130 characters and <= 150 characters.`);
|
|
299
311
|
}
|
|
300
312
|
|
|
301
|
-
const identity = await LedgerIdentity.create();
|
|
302
313
|
const governance = await GenesisTokenCanister.create({
|
|
303
314
|
agent: await getAgent(identity),
|
|
304
315
|
});
|
|
@@ -477,11 +488,10 @@ async function main() {
|
|
|
477
488
|
)
|
|
478
489
|
.addCommand(
|
|
479
490
|
new Command("claim")
|
|
480
|
-
.
|
|
481
|
-
"--hex-public-key <public-key>",
|
|
491
|
+
.description(
|
|
482
492
|
"Claim the caller's GTC neurons."
|
|
483
493
|
)
|
|
484
|
-
.action((args) => run(() => claimNeurons(
|
|
494
|
+
.action((args) => run(() => claimNeurons()))
|
|
485
495
|
);
|
|
486
496
|
|
|
487
497
|
const icp = new Command("icp")
|
package/package.json
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dfinity/hardware-wallet-cli",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "A CLI to interact with the Internet Computer App on Ledger Nano S/X devices.",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"format": "prettier --write .",
|
|
8
8
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
9
9
|
"build": "tsc --build",
|
|
10
|
+
"prepack": "npm run build",
|
|
10
11
|
"clean": "tsc --build --clean",
|
|
11
|
-
"refresh": "rm -rf ./node_modules ./package-lock.json && npm install"
|
|
12
|
+
"refresh": "rm -rf ./node_modules ./package-lock.json && npm install",
|
|
13
|
+
"execute": "ts-node ./index.ts"
|
|
12
14
|
},
|
|
13
15
|
"repository": {
|
|
14
16
|
"type": "git",
|
|
@@ -35,7 +37,8 @@
|
|
|
35
37
|
"@types/google-protobuf": "^3.15.6",
|
|
36
38
|
"@types/node": "^17.0.16",
|
|
37
39
|
"@types/node-hid": "^1.3.1",
|
|
38
|
-
"prettier": "^2.6.2"
|
|
40
|
+
"prettier": "^2.6.2",
|
|
41
|
+
"ts-node": "^10.8.0"
|
|
39
42
|
},
|
|
40
43
|
"bin": {
|
|
41
44
|
"ic-hardware-wallet": "./build/index.js"
|
package/src/ledger/identity.ts
CHANGED
|
@@ -165,8 +165,6 @@ export class LedgerIdentity extends SignIdentity {
|
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
public async sign(blob: ArrayBuffer): Promise<Signature> {
|
|
168
|
-
console.log("About to sign");
|
|
169
|
-
console.log(Buffer.from(blob).toString("hex"));
|
|
170
168
|
return await this._executeWithApp(async (app: LedgerApp) => {
|
|
171
169
|
const resp: ResponseSign = await app.sign(
|
|
172
170
|
this.derivePath,
|