@dfinity/hardware-wallet-cli 0.2.1 → 0.2.2
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/.github/CODEOWNERS +1 -1
- package/build/index.js +28 -28
- package/build/src/ledger/secp256k1.js +16 -0
- package/index.ts +37 -30
- package/package.json +4 -3
- package/src/ledger/secp256k1.ts +21 -0
- package/dfinity-hardware-wallet-cli-0.2.1.tgz +0 -0
package/.github/CODEOWNERS
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# The codebase is owned by the Governance & Identity Experience team at DFINITY
|
|
2
|
-
|
|
2
|
+
# For questions, reach out to: <gix@dfinity.org>
|
package/build/index.js
CHANGED
|
@@ -39,16 +39,24 @@ async function getAgent(identity) {
|
|
|
39
39
|
}
|
|
40
40
|
return agent;
|
|
41
41
|
}
|
|
42
|
+
async function getLedgerIdentity() {
|
|
43
|
+
const principalPath = tryParseInt(program.opts().principal);
|
|
44
|
+
if (principalPath < 0 || principalPath > 255) {
|
|
45
|
+
throw new commander_1.InvalidArgumentError("Principal path must be between 0 and 255 inclusive.");
|
|
46
|
+
}
|
|
47
|
+
return identity_1.LedgerIdentity.create(`m/44'/223'/0'/0/${principalPath}`);
|
|
48
|
+
}
|
|
42
49
|
/**
|
|
43
50
|
* Fetches the balance of the main account on the wallet.
|
|
44
51
|
*/
|
|
45
52
|
async function getBalance() {
|
|
46
|
-
const identity = await
|
|
53
|
+
const identity = await getLedgerIdentity();
|
|
47
54
|
const accountIdentifier = nns_1.AccountIdentifier.fromPrincipal({
|
|
48
55
|
principal: identity.getPrincipal(),
|
|
49
56
|
});
|
|
50
57
|
const ledger = nns_1.LedgerCanister.create({
|
|
51
58
|
agent: await getAgent(new agent_1.AnonymousIdentity()),
|
|
59
|
+
hardwareWallet: true,
|
|
52
60
|
});
|
|
53
61
|
const balance = await ledger.accountBalance({
|
|
54
62
|
accountIdentifier: accountIdentifier,
|
|
@@ -62,9 +70,10 @@ async function getBalance() {
|
|
|
62
70
|
* @param amount Amount to send in e8s.
|
|
63
71
|
*/
|
|
64
72
|
async function sendICP(to, amount) {
|
|
65
|
-
const identity = await
|
|
73
|
+
const identity = await getLedgerIdentity();
|
|
66
74
|
const ledger = nns_1.LedgerCanister.create({
|
|
67
75
|
agent: await getAgent(identity),
|
|
76
|
+
hardwareWallet: true,
|
|
68
77
|
});
|
|
69
78
|
const blockHeight = await ledger.transfer({
|
|
70
79
|
to: to,
|
|
@@ -77,12 +86,14 @@ async function sendICP(to, amount) {
|
|
|
77
86
|
* Shows the principal and account idenifier on the terminal and on the wallet's screen.
|
|
78
87
|
*/
|
|
79
88
|
async function showInfo(showOnDevice) {
|
|
80
|
-
const identity = await
|
|
89
|
+
const identity = await getLedgerIdentity();
|
|
81
90
|
const accountIdentifier = nns_1.AccountIdentifier.fromPrincipal({
|
|
82
91
|
principal: identity.getPrincipal(),
|
|
83
92
|
});
|
|
93
|
+
const publicKey = identity.getPublicKey();
|
|
84
94
|
log(chalk_1.default.bold(`Principal: `) + identity.getPrincipal());
|
|
85
95
|
log(chalk_1.default.bold(`Address (${identity.derivePath}): `) + accountIdentifier.toHex());
|
|
96
|
+
log(chalk_1.default.bold('Public key: ') + publicKey.toHex());
|
|
86
97
|
if (showOnDevice) {
|
|
87
98
|
log("Displaying the principal and the address on the device...");
|
|
88
99
|
await identity.showAddressAndPubKeyOnDevice();
|
|
@@ -94,7 +105,7 @@ async function showInfo(showOnDevice) {
|
|
|
94
105
|
* @param amount Amount to stake in e8s.
|
|
95
106
|
*/
|
|
96
107
|
async function stakeNeuron(stake) {
|
|
97
|
-
const identity = await
|
|
108
|
+
const identity = await getLedgerIdentity();
|
|
98
109
|
const ledger = nns_1.LedgerCanister.create({
|
|
99
110
|
agent: await getAgent(identity),
|
|
100
111
|
});
|
|
@@ -126,7 +137,7 @@ async function stakeNeuron(stake) {
|
|
|
126
137
|
}
|
|
127
138
|
}
|
|
128
139
|
async function increaseDissolveDelay(neuronId, years, days, minutes, seconds) {
|
|
129
|
-
const identity = await
|
|
140
|
+
const identity = await getLedgerIdentity();
|
|
130
141
|
const governance = nns_1.GovernanceCanister.create({
|
|
131
142
|
agent: await getAgent(identity),
|
|
132
143
|
hardwareWallet: true,
|
|
@@ -142,7 +153,7 @@ async function increaseDissolveDelay(neuronId, years, days, minutes, seconds) {
|
|
|
142
153
|
ok();
|
|
143
154
|
}
|
|
144
155
|
async function disburseNeuron(neuronId, to, amount) {
|
|
145
|
-
const identity = await
|
|
156
|
+
const identity = await getLedgerIdentity();
|
|
146
157
|
const governance = nns_1.GovernanceCanister.create({
|
|
147
158
|
agent: await getAgent(identity),
|
|
148
159
|
hardwareWallet: true,
|
|
@@ -155,7 +166,7 @@ async function disburseNeuron(neuronId, to, amount) {
|
|
|
155
166
|
ok();
|
|
156
167
|
}
|
|
157
168
|
async function spawnNeuron(neuronId, controller) {
|
|
158
|
-
const identity = await
|
|
169
|
+
const identity = await getLedgerIdentity();
|
|
159
170
|
const governance = nns_1.GovernanceCanister.create({
|
|
160
171
|
agent: await getAgent(identity),
|
|
161
172
|
hardwareWallet: true,
|
|
@@ -167,7 +178,7 @@ async function spawnNeuron(neuronId, controller) {
|
|
|
167
178
|
ok(`Spawned neuron with ID ${spawnedNeuronId}`);
|
|
168
179
|
}
|
|
169
180
|
async function startDissolving(neuronId) {
|
|
170
|
-
const identity = await
|
|
181
|
+
const identity = await getLedgerIdentity();
|
|
171
182
|
const governance = nns_1.GovernanceCanister.create({
|
|
172
183
|
agent: await getAgent(identity),
|
|
173
184
|
hardwareWallet: true,
|
|
@@ -176,7 +187,7 @@ async function startDissolving(neuronId) {
|
|
|
176
187
|
ok();
|
|
177
188
|
}
|
|
178
189
|
async function stopDissolving(neuronId) {
|
|
179
|
-
const identity = await
|
|
190
|
+
const identity = await getLedgerIdentity();
|
|
180
191
|
const governance = nns_1.GovernanceCanister.create({
|
|
181
192
|
agent: await getAgent(identity),
|
|
182
193
|
hardwareWallet: true,
|
|
@@ -185,7 +196,7 @@ async function stopDissolving(neuronId) {
|
|
|
185
196
|
ok();
|
|
186
197
|
}
|
|
187
198
|
async function addHotkey(neuronId, principal) {
|
|
188
|
-
const identity = await
|
|
199
|
+
const identity = await getLedgerIdentity();
|
|
189
200
|
const governance = nns_1.GovernanceCanister.create({
|
|
190
201
|
agent: await getAgent(identity),
|
|
191
202
|
hardwareWallet: true,
|
|
@@ -197,7 +208,7 @@ async function addHotkey(neuronId, principal) {
|
|
|
197
208
|
ok();
|
|
198
209
|
}
|
|
199
210
|
async function removeHotkey(neuronId, principal) {
|
|
200
|
-
const identity = await
|
|
211
|
+
const identity = await getLedgerIdentity();
|
|
201
212
|
const governance = nns_1.GovernanceCanister.create({
|
|
202
213
|
agent: await getAgent(identity),
|
|
203
214
|
hardwareWallet: true,
|
|
@@ -209,7 +220,7 @@ async function removeHotkey(neuronId, principal) {
|
|
|
209
220
|
ok();
|
|
210
221
|
}
|
|
211
222
|
async function listNeurons() {
|
|
212
|
-
const identity = await
|
|
223
|
+
const identity = await getLedgerIdentity();
|
|
213
224
|
const governance = nns_1.GovernanceCanister.create({
|
|
214
225
|
agent: await getAgent(identity),
|
|
215
226
|
hardwareWallet: true,
|
|
@@ -227,30 +238,18 @@ async function listNeurons() {
|
|
|
227
238
|
ok("No neurons found.");
|
|
228
239
|
}
|
|
229
240
|
}
|
|
230
|
-
const buf2hex = (buffer) => {
|
|
231
|
-
return [...new Uint8Array(buffer)]
|
|
232
|
-
.map((x) => x.toString(16).padStart(2, "0"))
|
|
233
|
-
.join("");
|
|
234
|
-
};
|
|
235
241
|
/**
|
|
236
242
|
* Fetches the balance of the main account on the wallet.
|
|
237
243
|
*/
|
|
238
244
|
async function claimNeurons() {
|
|
239
|
-
const identity = await
|
|
240
|
-
const
|
|
241
|
-
const hexPubKey =
|
|
242
|
-
const isHex = hexPubKey.match("^[0-9a-fA-F]+$");
|
|
243
|
-
if (!isHex) {
|
|
244
|
-
throw new Error(`${hexPubKey} is not a hex string.`);
|
|
245
|
-
}
|
|
246
|
-
if (hexPubKey.length < 130 || hexPubKey.length > 150) {
|
|
247
|
-
throw new Error(`The key must be >= 130 characters and <= 150 characters.`);
|
|
248
|
-
}
|
|
245
|
+
const identity = await getLedgerIdentity();
|
|
246
|
+
const publicKey = identity.getPublicKey();
|
|
247
|
+
const hexPubKey = publicKey.toHex();
|
|
249
248
|
const governance = await nns_1.GenesisTokenCanister.create({
|
|
250
249
|
agent: await getAgent(identity),
|
|
251
250
|
});
|
|
252
251
|
const claimedNeuronIds = await governance.claimNeurons({
|
|
253
|
-
hexPubKey
|
|
252
|
+
hexPubKey,
|
|
254
253
|
});
|
|
255
254
|
ok(`Successfully claimed the following neurons: ${claimedNeuronIds}`);
|
|
256
255
|
}
|
|
@@ -388,6 +387,7 @@ async function main() {
|
|
|
388
387
|
.addOption(new commander_1.Option("--network <network>", "The IC network to talk to.")
|
|
389
388
|
.default("https://ic0.app")
|
|
390
389
|
.env("IC_NETWORK"))
|
|
390
|
+
.addOption(new commander_1.Option("--principal <principal>", "The derivation path to use for the principal.\n(e.g. --principal 123 will result in a derivation path of m/44'/223'/0'/0/123)\nMust be >= 0 && <= 255").default(0))
|
|
391
391
|
.addCommand(new commander_1.Command("info")
|
|
392
392
|
.option("-n --no-show-on-device")
|
|
393
393
|
.description("Show the wallet's principal, address, and balance.")
|
|
@@ -14,6 +14,11 @@ function equals(b1, b2) {
|
|
|
14
14
|
}
|
|
15
15
|
return true;
|
|
16
16
|
}
|
|
17
|
+
const buf2hex = (buffer) => {
|
|
18
|
+
return [...new Uint8Array(buffer)]
|
|
19
|
+
.map((x) => x.toString(16).padStart(2, "0"))
|
|
20
|
+
.join("");
|
|
21
|
+
};
|
|
17
22
|
// This implementation is adjusted from the Ed25519PublicKey.
|
|
18
23
|
// The RAW_KEY_LENGTH and DER_PREFIX are modified accordingly
|
|
19
24
|
class Secp256k1PublicKey {
|
|
@@ -58,6 +63,17 @@ class Secp256k1PublicKey {
|
|
|
58
63
|
toRaw() {
|
|
59
64
|
return this.rawKey;
|
|
60
65
|
}
|
|
66
|
+
toHex() {
|
|
67
|
+
const hexPubKey = buf2hex(this.toRaw());
|
|
68
|
+
const isHex = hexPubKey.match("^[0-9a-fA-F]+$");
|
|
69
|
+
if (!isHex) {
|
|
70
|
+
throw new Error(`${hexPubKey} is not a hex string.`);
|
|
71
|
+
}
|
|
72
|
+
if (hexPubKey.length < 130 || hexPubKey.length > 150) {
|
|
73
|
+
throw new Error(`The key must be >= 130 characters and <= 150 characters.`);
|
|
74
|
+
}
|
|
75
|
+
return hexPubKey;
|
|
76
|
+
}
|
|
61
77
|
}
|
|
62
78
|
exports.Secp256k1PublicKey = Secp256k1PublicKey;
|
|
63
79
|
// The length of secp256k1 public keys is always 65 bytes.
|
package/index.ts
CHANGED
|
@@ -56,17 +56,28 @@ async function getAgent(identity: Identity): Promise<Agent> {
|
|
|
56
56
|
return agent;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
async function getLedgerIdentity(): Promise<LedgerIdentity> {
|
|
60
|
+
const principalPath = tryParseInt(program.opts().principal);
|
|
61
|
+
if (principalPath < 0 || principalPath > 255) {
|
|
62
|
+
throw new InvalidArgumentError(
|
|
63
|
+
"Principal path must be between 0 and 255 inclusive."
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
return LedgerIdentity.create(`m/44'/223'/0'/0/${principalPath}`);
|
|
67
|
+
}
|
|
68
|
+
|
|
59
69
|
/**
|
|
60
70
|
* Fetches the balance of the main account on the wallet.
|
|
61
71
|
*/
|
|
62
72
|
async function getBalance() {
|
|
63
|
-
const identity = await
|
|
73
|
+
const identity = await getLedgerIdentity();
|
|
64
74
|
const accountIdentifier = AccountIdentifier.fromPrincipal({
|
|
65
75
|
principal: identity.getPrincipal(),
|
|
66
76
|
});
|
|
67
77
|
|
|
68
78
|
const ledger = LedgerCanister.create({
|
|
69
79
|
agent: await getAgent(new AnonymousIdentity()),
|
|
80
|
+
hardwareWallet: true,
|
|
70
81
|
});
|
|
71
82
|
|
|
72
83
|
const balance = await ledger.accountBalance({
|
|
@@ -83,9 +94,10 @@ async function getBalance() {
|
|
|
83
94
|
* @param amount Amount to send in e8s.
|
|
84
95
|
*/
|
|
85
96
|
async function sendICP(to: AccountIdentifier, amount: ICP) {
|
|
86
|
-
const identity = await
|
|
97
|
+
const identity = await getLedgerIdentity();
|
|
87
98
|
const ledger = LedgerCanister.create({
|
|
88
99
|
agent: await getAgent(identity),
|
|
100
|
+
hardwareWallet: true,
|
|
89
101
|
});
|
|
90
102
|
|
|
91
103
|
const blockHeight = await ledger.transfer({
|
|
@@ -101,15 +113,19 @@ async function sendICP(to: AccountIdentifier, amount: ICP) {
|
|
|
101
113
|
* Shows the principal and account idenifier on the terminal and on the wallet's screen.
|
|
102
114
|
*/
|
|
103
115
|
async function showInfo(showOnDevice?: boolean) {
|
|
104
|
-
const identity = await
|
|
116
|
+
const identity = await getLedgerIdentity();
|
|
105
117
|
const accountIdentifier = AccountIdentifier.fromPrincipal({
|
|
106
118
|
principal: identity.getPrincipal(),
|
|
107
119
|
});
|
|
120
|
+
const publicKey = identity.getPublicKey() as Secp256k1PublicKey;
|
|
108
121
|
|
|
109
122
|
log(chalk.bold(`Principal: `) + identity.getPrincipal());
|
|
110
123
|
log(
|
|
111
124
|
chalk.bold(`Address (${identity.derivePath}): `) + accountIdentifier.toHex()
|
|
112
125
|
);
|
|
126
|
+
log(
|
|
127
|
+
chalk.bold('Public key: ') + publicKey.toHex()
|
|
128
|
+
)
|
|
113
129
|
|
|
114
130
|
if (showOnDevice) {
|
|
115
131
|
log("Displaying the principal and the address on the device...");
|
|
@@ -123,7 +139,7 @@ async function showInfo(showOnDevice?: boolean) {
|
|
|
123
139
|
* @param amount Amount to stake in e8s.
|
|
124
140
|
*/
|
|
125
141
|
async function stakeNeuron(stake: ICP) {
|
|
126
|
-
const identity = await
|
|
142
|
+
const identity = await getLedgerIdentity();
|
|
127
143
|
const ledger = LedgerCanister.create({
|
|
128
144
|
agent: await getAgent(identity),
|
|
129
145
|
});
|
|
@@ -162,7 +178,7 @@ async function increaseDissolveDelay(
|
|
|
162
178
|
minutes: number,
|
|
163
179
|
seconds: number
|
|
164
180
|
) {
|
|
165
|
-
const identity = await
|
|
181
|
+
const identity = await getLedgerIdentity();
|
|
166
182
|
const governance = GovernanceCanister.create({
|
|
167
183
|
agent: await getAgent(identity),
|
|
168
184
|
hardwareWallet: true,
|
|
@@ -183,7 +199,7 @@ async function increaseDissolveDelay(
|
|
|
183
199
|
}
|
|
184
200
|
|
|
185
201
|
async function disburseNeuron(neuronId: bigint, to?: string, amount?: bigint) {
|
|
186
|
-
const identity = await
|
|
202
|
+
const identity = await getLedgerIdentity();
|
|
187
203
|
const governance = GovernanceCanister.create({
|
|
188
204
|
agent: await getAgent(identity),
|
|
189
205
|
hardwareWallet: true,
|
|
@@ -199,7 +215,7 @@ async function disburseNeuron(neuronId: bigint, to?: string, amount?: bigint) {
|
|
|
199
215
|
}
|
|
200
216
|
|
|
201
217
|
async function spawnNeuron(neuronId: string, controller?: Principal) {
|
|
202
|
-
const identity = await
|
|
218
|
+
const identity = await getLedgerIdentity();
|
|
203
219
|
const governance = GovernanceCanister.create({
|
|
204
220
|
agent: await getAgent(identity),
|
|
205
221
|
hardwareWallet: true,
|
|
@@ -213,7 +229,7 @@ async function spawnNeuron(neuronId: string, controller?: Principal) {
|
|
|
213
229
|
}
|
|
214
230
|
|
|
215
231
|
async function startDissolving(neuronId: bigint) {
|
|
216
|
-
const identity = await
|
|
232
|
+
const identity = await getLedgerIdentity();
|
|
217
233
|
const governance = GovernanceCanister.create({
|
|
218
234
|
agent: await getAgent(identity),
|
|
219
235
|
hardwareWallet: true,
|
|
@@ -225,7 +241,7 @@ async function startDissolving(neuronId: bigint) {
|
|
|
225
241
|
}
|
|
226
242
|
|
|
227
243
|
async function stopDissolving(neuronId: bigint) {
|
|
228
|
-
const identity = await
|
|
244
|
+
const identity = await getLedgerIdentity();
|
|
229
245
|
const governance = GovernanceCanister.create({
|
|
230
246
|
agent: await getAgent(identity),
|
|
231
247
|
hardwareWallet: true,
|
|
@@ -237,7 +253,7 @@ async function stopDissolving(neuronId: bigint) {
|
|
|
237
253
|
}
|
|
238
254
|
|
|
239
255
|
async function addHotkey(neuronId: bigint, principal: Principal) {
|
|
240
|
-
const identity = await
|
|
256
|
+
const identity = await getLedgerIdentity();
|
|
241
257
|
const governance = GovernanceCanister.create({
|
|
242
258
|
agent: await getAgent(identity),
|
|
243
259
|
hardwareWallet: true,
|
|
@@ -252,7 +268,7 @@ async function addHotkey(neuronId: bigint, principal: Principal) {
|
|
|
252
268
|
}
|
|
253
269
|
|
|
254
270
|
async function removeHotkey(neuronId: bigint, principal: Principal) {
|
|
255
|
-
const identity = await
|
|
271
|
+
const identity = await getLedgerIdentity();
|
|
256
272
|
const governance = GovernanceCanister.create({
|
|
257
273
|
agent: await getAgent(identity),
|
|
258
274
|
hardwareWallet: true,
|
|
@@ -267,7 +283,7 @@ async function removeHotkey(neuronId: bigint, principal: Principal) {
|
|
|
267
283
|
}
|
|
268
284
|
|
|
269
285
|
async function listNeurons() {
|
|
270
|
-
const identity = await
|
|
286
|
+
const identity = await getLedgerIdentity();
|
|
271
287
|
const governance = GovernanceCanister.create({
|
|
272
288
|
agent: await getAgent(identity),
|
|
273
289
|
hardwareWallet: true,
|
|
@@ -287,35 +303,21 @@ async function listNeurons() {
|
|
|
287
303
|
}
|
|
288
304
|
}
|
|
289
305
|
|
|
290
|
-
const buf2hex = (buffer: ArrayBuffer): string => {
|
|
291
|
-
return [...new Uint8Array(buffer)]
|
|
292
|
-
.map((x) => x.toString(16).padStart(2, "0"))
|
|
293
|
-
.join("");
|
|
294
|
-
};
|
|
295
|
-
|
|
296
306
|
/**
|
|
297
307
|
* Fetches the balance of the main account on the wallet.
|
|
298
308
|
*/
|
|
299
309
|
async function claimNeurons() {
|
|
300
|
-
const identity = await
|
|
301
|
-
|
|
302
|
-
const bufferKey = identity.getPublicKey() as Secp256k1PublicKey;
|
|
303
|
-
const hexPubKey = buf2hex(bufferKey.toRaw());
|
|
304
|
-
const isHex = hexPubKey.match("^[0-9a-fA-F]+$");
|
|
305
|
-
if (!isHex) {
|
|
306
|
-
throw new Error(`${hexPubKey} is not a hex string.`);
|
|
307
|
-
}
|
|
310
|
+
const identity = await getLedgerIdentity();
|
|
308
311
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
}
|
|
312
|
+
const publicKey = identity.getPublicKey() as Secp256k1PublicKey;
|
|
313
|
+
const hexPubKey = publicKey.toHex();
|
|
312
314
|
|
|
313
315
|
const governance = await GenesisTokenCanister.create({
|
|
314
316
|
agent: await getAgent(identity),
|
|
315
317
|
});
|
|
316
318
|
|
|
317
319
|
const claimedNeuronIds = await governance.claimNeurons({
|
|
318
|
-
hexPubKey
|
|
320
|
+
hexPubKey,
|
|
319
321
|
});
|
|
320
322
|
|
|
321
323
|
ok(`Successfully claimed the following neurons: ${claimedNeuronIds}`);
|
|
@@ -528,6 +530,11 @@ async function main() {
|
|
|
528
530
|
.default("https://ic0.app")
|
|
529
531
|
.env("IC_NETWORK")
|
|
530
532
|
)
|
|
533
|
+
.addOption(
|
|
534
|
+
new Option("--principal <principal>", "The derivation path to use for the principal.\n(e.g. --principal 123 will result in a derivation path of m/44'/223'/0'/0/123)\nMust be >= 0 && <= 255").default(
|
|
535
|
+
0
|
|
536
|
+
)
|
|
537
|
+
)
|
|
531
538
|
.addCommand(
|
|
532
539
|
new Command("info")
|
|
533
540
|
.option("-n --no-show-on-device")
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dfinity/hardware-wallet-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
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": {
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"prepack": "npm run build",
|
|
11
11
|
"clean": "tsc --build --clean",
|
|
12
12
|
"refresh": "rm -rf ./node_modules ./package-lock.json && npm install",
|
|
13
|
-
"execute": "ts-node ./index.ts"
|
|
13
|
+
"execute": "ts-node ./index.ts",
|
|
14
|
+
"update:nns": "npm update @dfinity/nns"
|
|
14
15
|
},
|
|
15
16
|
"repository": {
|
|
16
17
|
"type": "git",
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
"homepage": "https://github.com/dfinity/hardware-wallet-cli#readme",
|
|
25
26
|
"dependencies": {
|
|
26
27
|
"@dfinity/agent": "^0.11.2",
|
|
27
|
-
"@dfinity/nns": "
|
|
28
|
+
"@dfinity/nns": "nightly",
|
|
28
29
|
"@ledgerhq/hw-transport-node-hid-noevents": "^6.3.0",
|
|
29
30
|
"@ledgerhq/hw-transport-webhid": "^6.27.1",
|
|
30
31
|
"@zondax/ledger-icp": "^0.6.0",
|
package/src/ledger/secp256k1.ts
CHANGED
|
@@ -15,6 +15,12 @@ function equals(b1: ArrayBuffer, b2: ArrayBuffer): boolean {
|
|
|
15
15
|
return true;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
const buf2hex = (buffer: ArrayBuffer): string => {
|
|
19
|
+
return [...new Uint8Array(buffer)]
|
|
20
|
+
.map((x) => x.toString(16).padStart(2, "0"))
|
|
21
|
+
.join("");
|
|
22
|
+
};
|
|
23
|
+
|
|
18
24
|
// This implementation is adjusted from the Ed25519PublicKey.
|
|
19
25
|
// The RAW_KEY_LENGTH and DER_PREFIX are modified accordingly
|
|
20
26
|
export class Secp256k1PublicKey implements PublicKey {
|
|
@@ -93,4 +99,19 @@ export class Secp256k1PublicKey implements PublicKey {
|
|
|
93
99
|
public toRaw(): ArrayBuffer {
|
|
94
100
|
return this.rawKey;
|
|
95
101
|
}
|
|
102
|
+
|
|
103
|
+
public toHex(): string {
|
|
104
|
+
const hexPubKey = buf2hex(this.toRaw());
|
|
105
|
+
|
|
106
|
+
const isHex = hexPubKey.match("^[0-9a-fA-F]+$");
|
|
107
|
+
if (!isHex) {
|
|
108
|
+
throw new Error(`${hexPubKey} is not a hex string.`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (hexPubKey.length < 130 || hexPubKey.length > 150) {
|
|
112
|
+
throw new Error(`The key must be >= 130 characters and <= 150 characters.`);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return hexPubKey;
|
|
116
|
+
}
|
|
96
117
|
}
|
|
Binary file
|