@shapeshiftoss/hdwallet-keepkey 1.62.41 → 1.62.42

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.
Files changed (114) hide show
  1. package/LICENSE.md +6 -6
  2. package/dist/cjs/.tsbuildinfo +1 -0
  3. package/dist/{adapter.d.ts → cjs/adapter.d.ts} +6 -7
  4. package/dist/cjs/adapter.js +146 -0
  5. package/dist/{binance.d.ts → cjs/binance.d.ts} +3 -4
  6. package/dist/cjs/binance.js +144 -0
  7. package/dist/{bitcoin.d.ts → cjs/bitcoin.d.ts} +3 -4
  8. package/dist/cjs/bitcoin.js +549 -0
  9. package/dist/{bnbencoding.d.ts → cjs/bnbencoding.d.ts} +3 -2
  10. package/dist/{bnbencoding.js → cjs/bnbencoding.js} +22 -22
  11. package/dist/{cosmos.d.ts → cjs/cosmos.d.ts} +4 -5
  12. package/dist/cjs/cosmos.js +219 -0
  13. package/dist/{eos.d.ts → cjs/eos.d.ts} +3 -4
  14. package/dist/cjs/eos.js +244 -0
  15. package/dist/{ethereum.d.ts → cjs/ethereum.d.ts} +4 -5
  16. package/dist/cjs/ethereum.js +264 -0
  17. package/dist/cjs/index.d.ts +5 -0
  18. package/dist/{index.js → cjs/index.js} +0 -1
  19. package/dist/{keepkey.d.ts → cjs/keepkey.d.ts} +45 -20
  20. package/dist/cjs/keepkey.js +959 -0
  21. package/dist/{mayachain.d.ts → cjs/mayachain.d.ts} +4 -5
  22. package/dist/cjs/mayachain.js +169 -0
  23. package/dist/{osmosis.d.ts → cjs/osmosis.d.ts} +4 -5
  24. package/dist/cjs/osmosis.js +270 -0
  25. package/dist/cjs/package.json +1 -0
  26. package/dist/{ripple.d.ts → cjs/ripple.d.ts} +3 -4
  27. package/dist/cjs/ripple.js +104 -0
  28. package/dist/{thorchain.d.ts → cjs/thorchain.d.ts} +4 -5
  29. package/dist/cjs/thorchain.js +169 -0
  30. package/dist/{transport.d.ts → cjs/transport.d.ts} +2 -3
  31. package/dist/cjs/transport.js +333 -0
  32. package/dist/{typeRegistry.d.ts → cjs/typeRegistry.d.ts} +2 -3
  33. package/dist/{typeRegistry.js → cjs/typeRegistry.js} +26 -13
  34. package/dist/{utils.d.ts → cjs/utils.d.ts} +1 -2
  35. package/dist/{utils.js → cjs/utils.js} +7 -8
  36. package/dist/esm/.tsbuildinfo +1 -0
  37. package/dist/esm/adapter.d.ts +35 -0
  38. package/dist/esm/adapter.js +119 -0
  39. package/dist/esm/binance.d.ts +5 -0
  40. package/dist/esm/binance.js +112 -0
  41. package/dist/esm/bitcoin.d.ts +11 -0
  42. package/dist/esm/bitcoin.js +511 -0
  43. package/dist/esm/bnbencoding.d.ts +11 -0
  44. package/dist/esm/bnbencoding.js +103 -0
  45. package/dist/esm/cosmos.d.ts +6 -0
  46. package/dist/esm/cosmos.js +187 -0
  47. package/dist/esm/eos.d.ts +5 -0
  48. package/dist/esm/eos.js +212 -0
  49. package/dist/esm/ethereum.d.ts +17 -0
  50. package/dist/esm/ethereum.js +229 -0
  51. package/dist/esm/index.d.ts +5 -0
  52. package/dist/esm/index.js +5 -0
  53. package/dist/esm/keepkey.d.ts +177 -0
  54. package/dist/esm/keepkey.js +925 -0
  55. package/dist/esm/mayachain.d.ts +6 -0
  56. package/dist/esm/mayachain.js +137 -0
  57. package/dist/esm/osmosis.d.ts +6 -0
  58. package/dist/esm/osmosis.js +238 -0
  59. package/dist/esm/ripple.d.ts +5 -0
  60. package/dist/esm/ripple.js +72 -0
  61. package/dist/esm/thorchain.d.ts +6 -0
  62. package/dist/esm/thorchain.js +137 -0
  63. package/dist/esm/transport.d.ts +55 -0
  64. package/dist/esm/transport.js +306 -0
  65. package/dist/esm/typeRegistry.d.ts +4 -0
  66. package/dist/esm/typeRegistry.js +47 -0
  67. package/dist/esm/utils.d.ts +6 -0
  68. package/dist/esm/utils.js +56 -0
  69. package/package.json +33 -19
  70. package/dist/adapter.d.ts.map +0 -1
  71. package/dist/adapter.js +0 -175
  72. package/dist/adapter.js.map +0 -1
  73. package/dist/binance.d.ts.map +0 -1
  74. package/dist/binance.js +0 -146
  75. package/dist/binance.js.map +0 -1
  76. package/dist/bitcoin.d.ts.map +0 -1
  77. package/dist/bitcoin.js +0 -568
  78. package/dist/bitcoin.js.map +0 -1
  79. package/dist/bnbencoding.d.ts.map +0 -1
  80. package/dist/bnbencoding.js.map +0 -1
  81. package/dist/cosmos.d.ts.map +0 -1
  82. package/dist/cosmos.js +0 -230
  83. package/dist/cosmos.js.map +0 -1
  84. package/dist/eos.d.ts.map +0 -1
  85. package/dist/eos.js +0 -247
  86. package/dist/eos.js.map +0 -1
  87. package/dist/ethereum.d.ts.map +0 -1
  88. package/dist/ethereum.js +0 -281
  89. package/dist/ethereum.js.map +0 -1
  90. package/dist/index.d.ts +0 -6
  91. package/dist/index.d.ts.map +0 -1
  92. package/dist/index.js.map +0 -1
  93. package/dist/keepkey.d.ts.map +0 -1
  94. package/dist/keepkey.js +0 -1027
  95. package/dist/keepkey.js.map +0 -1
  96. package/dist/mayachain.d.ts.map +0 -1
  97. package/dist/mayachain.js +0 -180
  98. package/dist/mayachain.js.map +0 -1
  99. package/dist/osmosis.d.ts.map +0 -1
  100. package/dist/osmosis.js +0 -278
  101. package/dist/osmosis.js.map +0 -1
  102. package/dist/ripple.d.ts.map +0 -1
  103. package/dist/ripple.js +0 -111
  104. package/dist/ripple.js.map +0 -1
  105. package/dist/thorchain.d.ts.map +0 -1
  106. package/dist/thorchain.js +0 -180
  107. package/dist/thorchain.js.map +0 -1
  108. package/dist/transport.d.ts.map +0 -1
  109. package/dist/transport.js +0 -365
  110. package/dist/transport.js.map +0 -1
  111. package/dist/typeRegistry.d.ts.map +0 -1
  112. package/dist/typeRegistry.js.map +0 -1
  113. package/dist/utils.d.ts.map +0 -1
  114. package/dist/utils.js.map +0 -1
@@ -0,0 +1,925 @@
1
+ import * as Messages from '@keepkey/device-protocol/lib/messages_pb';
2
+ import * as Types from '@keepkey/device-protocol/lib/types_pb';
3
+ import * as core from '@shapeshiftoss/hdwallet-core';
4
+ import isObject from 'lodash/isObject';
5
+ import semver from 'semver';
6
+ import * as Binance from './binance.js';
7
+ import * as Btc from './bitcoin.js';
8
+ import * as Cosmos from './cosmos.js';
9
+ import * as Eos from './eos.js';
10
+ import * as Eth from './ethereum.js';
11
+ import * as Mayachain from './mayachain.js';
12
+ import * as Osmosis from './osmosis.js';
13
+ import * as Ripple from './ripple.js';
14
+ import * as Thorchain from './thorchain.js';
15
+ import { messageTypeRegistry } from './typeRegistry.js';
16
+ import { protoFieldToSetMethod, translateInputScriptType } from './utils.js';
17
+ export function isKeepKey(wallet) {
18
+ return isObject(wallet) && wallet._isKeepKey;
19
+ }
20
+ function describeUTXOPath(path, coin, scriptType) {
21
+ const pathStr = core.addressNListToBIP32(path);
22
+ const unknown = {
23
+ verbose: pathStr,
24
+ coin,
25
+ scriptType,
26
+ isKnown: false,
27
+ };
28
+ if (!scriptType)
29
+ return unknown;
30
+ if (!Btc.btcSupportsCoin(coin))
31
+ return unknown;
32
+ if (!Btc.btcSupportsScriptType(coin, scriptType))
33
+ return unknown;
34
+ if (path.length !== 3 && path.length !== 5)
35
+ return unknown;
36
+ if ((path[0] & 0x80000000) >>> 0 !== 0x80000000)
37
+ return unknown;
38
+ const purpose = path[0] & 0x7fffffff;
39
+ if (![44, 49, 84].includes(purpose))
40
+ return unknown;
41
+ if (purpose === 44 && scriptType !== core.BTCInputScriptType.SpendAddress)
42
+ return unknown;
43
+ if (purpose === 49 && scriptType !== core.BTCInputScriptType.SpendP2SHWitness)
44
+ return unknown;
45
+ if (purpose === 84 && scriptType !== core.BTCInputScriptType.SpendWitness)
46
+ return unknown;
47
+ const wholeAccount = path.length === 3;
48
+ const script = scriptType
49
+ ? {
50
+ [core.BTCInputScriptType.SpendAddress]: ['Legacy'],
51
+ [core.BTCInputScriptType.SpendP2SHWitness]: [],
52
+ [core.BTCInputScriptType.SpendWitness]: ['Segwit Native'],
53
+ }[scriptType] ?? []
54
+ : [];
55
+ let isPrefork = false;
56
+ const slip44 = core.slip44ByCoin(coin);
57
+ if (slip44 === undefined)
58
+ return unknown;
59
+ if (path[1] !== 0x80000000 + slip44) {
60
+ switch (coin) {
61
+ case 'BitcoinCash':
62
+ case 'BitcoinGold': {
63
+ if (path[1] === 0x80000000 + core.slip44ByCoin('Bitcoin')) {
64
+ isPrefork = true;
65
+ break;
66
+ }
67
+ return unknown;
68
+ }
69
+ case 'BitcoinSV': {
70
+ if (path[1] === 0x80000000 + core.slip44ByCoin('Bitcoin') ||
71
+ path[1] === 0x80000000 + core.slip44ByCoin('BitcoinCash')) {
72
+ isPrefork = true;
73
+ break;
74
+ }
75
+ return unknown;
76
+ }
77
+ default:
78
+ return unknown;
79
+ }
80
+ }
81
+ let attributes = isPrefork ? ['Prefork'] : [];
82
+ switch (coin) {
83
+ case 'Bitcoin':
84
+ case 'Litecoin':
85
+ case 'BitcoinGold':
86
+ case 'Testnet': {
87
+ attributes = attributes.concat(script);
88
+ break;
89
+ }
90
+ default:
91
+ break;
92
+ }
93
+ const attr = attributes.length ? ` (${attributes.join(', ')})` : '';
94
+ const accountIdx = path[2] & 0x7fffffff;
95
+ if (wholeAccount) {
96
+ return {
97
+ coin,
98
+ verbose: `${coin} Account #${accountIdx}${attr}`,
99
+ accountIdx,
100
+ wholeAccount: true,
101
+ isKnown: true,
102
+ scriptType,
103
+ isPrefork,
104
+ };
105
+ }
106
+ else {
107
+ const change = path[3] === 1 ? 'Change ' : '';
108
+ const addressIdx = path[4];
109
+ return {
110
+ coin,
111
+ verbose: `${coin} Account #${accountIdx}, ${change}Address #${addressIdx}${attr}`,
112
+ accountIdx,
113
+ addressIdx,
114
+ wholeAccount: false,
115
+ isKnown: true,
116
+ isChange: path[3] === 1,
117
+ scriptType,
118
+ isPrefork,
119
+ };
120
+ }
121
+ }
122
+ function describeEosPath(path) {
123
+ const pathStr = core.addressNListToBIP32(path);
124
+ const unknown = {
125
+ verbose: pathStr,
126
+ coin: 'Eos',
127
+ isKnown: false,
128
+ };
129
+ if (path.length != 5) {
130
+ return unknown;
131
+ }
132
+ if (path[0] != 0x80000000 + 44) {
133
+ return unknown;
134
+ }
135
+ if (path[1] != 0x80000000 + core.slip44ByCoin('Eos')) {
136
+ return unknown;
137
+ }
138
+ if ((path[2] & 0x80000000) >>> 0 !== 0x80000000) {
139
+ return unknown;
140
+ }
141
+ if (path[3] !== 0 || path[4] !== 0) {
142
+ return unknown;
143
+ }
144
+ const index = path[2] & 0x7fffffff;
145
+ return {
146
+ verbose: `Eos Account #${index}`,
147
+ accountIdx: index,
148
+ wholeAccount: true,
149
+ coin: 'Eos',
150
+ isKnown: true,
151
+ isPrefork: false,
152
+ };
153
+ }
154
+ function describeRipplePath(path) {
155
+ const pathStr = core.addressNListToBIP32(path);
156
+ const unknown = {
157
+ verbose: pathStr,
158
+ coin: 'Ripple',
159
+ isKnown: false,
160
+ };
161
+ if (path.length != 5) {
162
+ return unknown;
163
+ }
164
+ if (path[0] != 0x80000000 + 44) {
165
+ return unknown;
166
+ }
167
+ if (path[1] != 0x80000000 + core.slip44ByCoin('Ripple')) {
168
+ return unknown;
169
+ }
170
+ if ((path[2] & 0x80000000) >>> 0 !== 0x80000000) {
171
+ return unknown;
172
+ }
173
+ if (path[3] !== 0 || path[4] !== 0) {
174
+ return unknown;
175
+ }
176
+ const index = path[2] & 0x7fffffff;
177
+ return {
178
+ verbose: `Ripple Account #${index}`,
179
+ accountIdx: index,
180
+ wholeAccount: true,
181
+ coin: 'Ripple',
182
+ isKnown: true,
183
+ isPrefork: false,
184
+ };
185
+ }
186
+ export class KeepKeyHDWalletInfo {
187
+ _supportsBTCInfo = true;
188
+ _supportsETHInfo = true;
189
+ _supportsCosmosInfo = true;
190
+ _supportsOsmosisInfo = true;
191
+ _supportsRippleInfo = true;
192
+ _supportsBinanceInfo = true;
193
+ _supportsEosInfo = true;
194
+ _supportsThorchainInfo = true;
195
+ _supportsMayachainInfo = true;
196
+ getVendor() {
197
+ return 'KeepKey';
198
+ }
199
+ async btcSupportsCoin(coin) {
200
+ return Btc.btcSupportsCoin(coin);
201
+ }
202
+ async btcSupportsScriptType(coin, scriptType) {
203
+ return Btc.btcSupportsScriptType(coin, scriptType);
204
+ }
205
+ async btcSupportsSecureTransfer() {
206
+ return Btc.btcSupportsSecureTransfer();
207
+ }
208
+ btcSupportsNativeShapeShift() {
209
+ return Btc.btcSupportsNativeShapeShift();
210
+ }
211
+ btcGetAccountPaths(msg) {
212
+ return Btc.btcGetAccountPaths(msg);
213
+ }
214
+ async ethSupportsNetwork(chain_id) {
215
+ return Eth.ethSupportsNetwork(chain_id);
216
+ }
217
+ async ethSupportsSecureTransfer() {
218
+ return Eth.ethSupportsSecureTransfer();
219
+ }
220
+ ethSupportsNativeShapeShift() {
221
+ return Eth.ethSupportsNativeShapeShift();
222
+ }
223
+ async ethSupportsEIP1559() {
224
+ // EIP1559 support starts in v7.2.1
225
+ // return semver.gte(await this.getFirmwareVersion(), "v7.2.1");
226
+ // disable EIP1559 support until edge case fail states are fixed across all evm chains
227
+ return false;
228
+ }
229
+ ethGetAccountPaths(msg) {
230
+ return Eth.ethGetAccountPaths(msg);
231
+ }
232
+ cosmosGetAccountPaths(msg) {
233
+ return Cosmos.cosmosGetAccountPaths(msg);
234
+ }
235
+ osmosisGetAccountPaths(msg) {
236
+ return Osmosis.osmosisGetAccountPaths(msg);
237
+ }
238
+ thorchainGetAccountPaths(msg) {
239
+ return Thorchain.thorchainGetAccountPaths(msg);
240
+ }
241
+ mayachainGetAccountPaths(msg) {
242
+ return Mayachain.mayachainGetAccountPaths(msg);
243
+ }
244
+ rippleGetAccountPaths(msg) {
245
+ return Ripple.rippleGetAccountPaths(msg);
246
+ }
247
+ binanceGetAccountPaths(msg) {
248
+ return Binance.binanceGetAccountPaths(msg);
249
+ }
250
+ eosGetAccountPaths(msg) {
251
+ return Eos.eosGetAccountPaths(msg);
252
+ }
253
+ hasOnDevicePinEntry() {
254
+ return false;
255
+ }
256
+ hasOnDevicePassphrase() {
257
+ return false;
258
+ }
259
+ hasOnDeviceDisplay() {
260
+ return true;
261
+ }
262
+ hasOnDeviceRecovery() {
263
+ return false;
264
+ }
265
+ hasNativeShapeShift(_srcCoin, _dstCoin) {
266
+ return true;
267
+ }
268
+ supportsBip44Accounts() {
269
+ return true;
270
+ }
271
+ supportsOfflineSigning() {
272
+ return true;
273
+ }
274
+ supportsBroadcast() {
275
+ return false;
276
+ }
277
+ describePath(msg) {
278
+ switch (msg.coin) {
279
+ case 'Ethereum':
280
+ return core.describeETHPath(msg.path);
281
+ case 'Atom':
282
+ return core.cosmosDescribePath(msg.path);
283
+ case 'Osmo':
284
+ return core.osmosisDescribePath(msg.path);
285
+ case 'Binance':
286
+ return core.binanceDescribePath(msg.path);
287
+ case 'Ripple':
288
+ return describeRipplePath(msg.path);
289
+ case 'Eos':
290
+ return describeEosPath(msg.path);
291
+ case 'Thorchain':
292
+ return core.thorchainDescribePath(msg.path);
293
+ case 'Mayachain':
294
+ return core.mayachainDescribePath(msg.path);
295
+ default:
296
+ return describeUTXOPath(msg.path, msg.coin, msg.scriptType);
297
+ }
298
+ }
299
+ btcNextAccountPath(msg) {
300
+ const description = describeUTXOPath(msg.addressNList, msg.coin, msg.scriptType);
301
+ if (!description.isKnown) {
302
+ return undefined;
303
+ }
304
+ const addressNList = msg.addressNList;
305
+ if (addressNList[0] === 0x80000000 + 44 ||
306
+ addressNList[0] === 0x80000000 + 49 ||
307
+ addressNList[0] === 0x80000000 + 84) {
308
+ addressNList[2] += 1;
309
+ return {
310
+ ...msg,
311
+ addressNList,
312
+ };
313
+ }
314
+ return undefined;
315
+ }
316
+ ethNextAccountPath(msg) {
317
+ const addressNList = msg.hardenedPath.concat(msg.relPath);
318
+ const description = core.describeETHPath(addressNList);
319
+ if (!description.isKnown) {
320
+ return undefined;
321
+ }
322
+ if (addressNList[0] === 0x80000000 + 44) {
323
+ addressNList[2] += 1;
324
+ return {
325
+ ...msg,
326
+ addressNList,
327
+ hardenedPath: core.hardenedPath(addressNList),
328
+ relPath: core.relativePath(addressNList),
329
+ };
330
+ }
331
+ return undefined;
332
+ }
333
+ cosmosNextAccountPath(msg) {
334
+ const description = core.cosmosDescribePath(msg.addressNList);
335
+ if (!description.isKnown) {
336
+ return undefined;
337
+ }
338
+ const addressNList = msg.addressNList;
339
+ addressNList[2] += 1;
340
+ return {
341
+ ...msg,
342
+ addressNList,
343
+ };
344
+ }
345
+ osmosisNextAccountPath(msg) {
346
+ const description = core.osmosisDescribePath(msg.addressNList);
347
+ if (!description.isKnown) {
348
+ return undefined;
349
+ }
350
+ const addressNList = msg.addressNList;
351
+ addressNList[2] += 1;
352
+ return {
353
+ ...msg,
354
+ addressNList,
355
+ };
356
+ }
357
+ thorchainNextAccountPath(msg) {
358
+ const description = core.thorchainDescribePath(msg.addressNList);
359
+ if (!description.isKnown)
360
+ return undefined;
361
+ const addressNList = msg.addressNList;
362
+ addressNList[2] += 1;
363
+ return {
364
+ ...msg,
365
+ addressNList,
366
+ };
367
+ }
368
+ mayachainNextAccountPath(msg) {
369
+ const description = core.mayachainDescribePath(msg.addressNList);
370
+ if (!description.isKnown)
371
+ return undefined;
372
+ const addressNList = msg.addressNList;
373
+ addressNList[2] += 1;
374
+ return {
375
+ ...msg,
376
+ addressNList,
377
+ };
378
+ }
379
+ rippleNextAccountPath(msg) {
380
+ const description = describeRipplePath(msg.addressNList);
381
+ if (!description.isKnown) {
382
+ return undefined;
383
+ }
384
+ const addressNList = msg.addressNList;
385
+ addressNList[2] += 1;
386
+ return {
387
+ ...msg,
388
+ addressNList,
389
+ };
390
+ }
391
+ binanceNextAccountPath(msg) {
392
+ const description = core.binanceDescribePath(msg.addressNList);
393
+ if (!description.isKnown) {
394
+ return undefined;
395
+ }
396
+ const addressNList = msg.addressNList;
397
+ addressNList[2] += 1;
398
+ return {
399
+ ...msg,
400
+ addressNList,
401
+ };
402
+ }
403
+ eosNextAccountPath(msg) {
404
+ const description = describeEosPath(msg.addressNList);
405
+ if (!description.isKnown) {
406
+ return undefined;
407
+ }
408
+ const addressNList = msg.addressNList;
409
+ addressNList[2] += 1;
410
+ return {
411
+ ...msg,
412
+ addressNList,
413
+ };
414
+ }
415
+ }
416
+ export class KeepKeyHDWallet extends KeepKeyHDWalletInfo {
417
+ _supportsDebugLink;
418
+ _isKeepKey = true;
419
+ _supportsETH = true;
420
+ _supportsEthSwitchChain = false;
421
+ _supportsAvalanche = false;
422
+ _supportsOptimism = true;
423
+ _supportsBSC = true;
424
+ _supportsPolygon = true;
425
+ _supportsGnosis = true;
426
+ _supportsArbitrum = true;
427
+ _supportsArbitrumNova = false;
428
+ _supportsBase = true;
429
+ _supportsMonad = false;
430
+ _supportsPlasma = false;
431
+ _supportsPlume = false;
432
+ _supportsKatana = false;
433
+ _supportsEthereal = false;
434
+ _supportsStory = false;
435
+ _supportsSonic = false;
436
+ _supportsBob = false;
437
+ _supportsMode = false;
438
+ _supportsSei = false;
439
+ _supportsHyperEvm = false;
440
+ _supportsMantle = false;
441
+ _supportsInk = false;
442
+ _supportsMegaEth = false;
443
+ _supportsZkSyncEra = false;
444
+ _supportsBlast = false;
445
+ _supportsAbstract = false;
446
+ _supportsWorldChain = false;
447
+ _supportsHemi = false;
448
+ _supportsFlowEvm = false;
449
+ _supportsCelo = false;
450
+ _supportsBerachain = false;
451
+ _supportsLinea = false;
452
+ _supportsScroll = false;
453
+ _supportsCronos = false;
454
+ _supportsUnichain = false;
455
+ _supportsSoneium = false;
456
+ _supportsRobinhood = false;
457
+ _supportsBTC = true;
458
+ _supportsCosmos = true;
459
+ _supportsOsmosis = true;
460
+ _supportsRipple = true;
461
+ _supportsBinance = true;
462
+ _supportsEos = true;
463
+ _supportsThorchain = true;
464
+ _supportsMayachain = true;
465
+ transport;
466
+ features;
467
+ info;
468
+ featuresCache;
469
+ constructor(transport) {
470
+ super();
471
+ this.transport = transport;
472
+ this._supportsDebugLink = transport.debugLink;
473
+ this.info = new KeepKeyHDWalletInfo();
474
+ }
475
+ static async create(transport) {
476
+ return new KeepKeyHDWallet(transport);
477
+ }
478
+ async getDeviceID() {
479
+ const featuresId = (await this.getFeatures(/*cached=*/ true)).deviceId;
480
+ // Devices in bootloader mode show up with empty string deviceId's in their features object.
481
+ if (featuresId)
482
+ return featuresId;
483
+ // Grabbing the one from the transport seems to be a reasonable fallback.
484
+ return await this.transport.getDeviceID();
485
+ }
486
+ async getModel() {
487
+ return core.mustBeDefined((await this.getFeatures(/*cached=*/ true)).model);
488
+ }
489
+ async getFirmwareVersion() {
490
+ const features = await this.getFeatures(/*cached=*/ true);
491
+ return `v${features.majorVersion}.${features.minorVersion}.${features.patchVersion}`;
492
+ }
493
+ async getLabel() {
494
+ return (await this.getFeatures(/*cached=*/ true)).label ?? '';
495
+ }
496
+ async isInitialized() {
497
+ return !!(await this.getFeatures()).initialized;
498
+ }
499
+ async isLocked() {
500
+ const features = await this.getFeatures();
501
+ if (features.pinProtection && !features.pinCached)
502
+ return true;
503
+ if (features.passphraseProtection && !features.passphraseCached)
504
+ return true;
505
+ return false;
506
+ }
507
+ async getPublicKeys(getPublicKeys) {
508
+ const publicKeys = [];
509
+ for (let i = 0; i < getPublicKeys.length; i++) {
510
+ const { coin, addressNList, curve, showDisplay, scriptType } = getPublicKeys[i];
511
+ const GPK = new Messages.GetPublicKey();
512
+ if (coin)
513
+ GPK.setCoinName(coin);
514
+ GPK.setAddressNList(addressNList);
515
+ GPK.setShowDisplay(showDisplay || false);
516
+ GPK.setEcdsaCurveName(curve || 'secp256k1');
517
+ GPK.setScriptType(translateInputScriptType(scriptType || core.BTCInputScriptType.SpendAddress));
518
+ const event = await this.transport.call(Messages.MessageType.MESSAGETYPE_GETPUBLICKEY, GPK, {
519
+ msgTimeout: showDisplay ? core.LONG_TIMEOUT : core.DEFAULT_TIMEOUT,
520
+ });
521
+ const publicKey = event.proto;
522
+ publicKeys.push({ xpub: core.mustBeDefined(publicKey.getXpub()) });
523
+ }
524
+ return publicKeys;
525
+ }
526
+ async ping(msg) {
527
+ const ping = new Messages.Ping();
528
+ ping.setMessage(msg.msg);
529
+ ping.setButtonProtection(msg.button || false);
530
+ ping.setPinProtection(msg.pin || false);
531
+ ping.setPassphraseProtection(msg.passphrase || false);
532
+ const event = await this.transport.call(Messages.MessageType.MESSAGETYPE_PING, ping, {
533
+ msgTimeout: msg.button || msg.pin || msg.passphrase ? core.LONG_TIMEOUT : core.DEFAULT_TIMEOUT,
534
+ });
535
+ const message = event.proto;
536
+ return { msg: core.mustBeDefined(message.getMessage()) };
537
+ }
538
+ async reset(msg) {
539
+ const resetDevice = new Messages.ResetDevice();
540
+ resetDevice.setStrength(msg.entropy || 128);
541
+ resetDevice.setDisplayRandom(false);
542
+ resetDevice.setPassphraseProtection(msg.passphrase || false);
543
+ resetDevice.setPinProtection(msg.pin || false);
544
+ resetDevice.setLabel(msg.label);
545
+ if (msg.autoLockDelayMs) {
546
+ resetDevice.setAutoLockDelayMs(msg.autoLockDelayMs);
547
+ }
548
+ resetDevice.setU2fCounter(msg.u2fCounter || Math.floor(+new Date() / 1000));
549
+ // resetDevice.setWordsPerGape(wordsPerScreen) // Re-enable when patch gets in
550
+ // Send
551
+ await this.transport.call(Messages.MessageType.MESSAGETYPE_RESETDEVICE, resetDevice, {
552
+ msgTimeout: core.LONG_TIMEOUT,
553
+ });
554
+ this.cacheFeatures(undefined);
555
+ }
556
+ async recover(r) {
557
+ const msg = new Messages.RecoveryDevice();
558
+ msg.setWordCount({ 128: 12, 192: 18, 256: 24 }[r.entropy]);
559
+ msg.setPassphraseProtection(r.passphrase);
560
+ msg.setPinProtection(r.pin);
561
+ msg.setLabel(r.label);
562
+ msg.setLanguage(r.language || 'english');
563
+ msg.setEnforceWordlist(true);
564
+ msg.setUseCharacterCipher(true);
565
+ if (r.autoLockDelayMs) {
566
+ msg.setAutoLockDelayMs(r.autoLockDelayMs);
567
+ }
568
+ msg.setU2fCounter(r.u2fCounter || Math.floor(+new Date() / 1000));
569
+ await this.transport.call(Messages.MessageType.MESSAGETYPE_RECOVERYDEVICE, msg, {
570
+ msgTimeout: core.LONG_TIMEOUT,
571
+ });
572
+ this.cacheFeatures(undefined);
573
+ }
574
+ async pressYes() {
575
+ return this.press(true);
576
+ }
577
+ async pressNo() {
578
+ return this.press(false);
579
+ }
580
+ async press(isYes) {
581
+ const decision = new Messages.DebugLinkDecision();
582
+ decision.setYesNo(isYes);
583
+ await this.transport.call(Messages.MessageType.MESSAGETYPE_DEBUGLINKDECISION, decision, {
584
+ noWait: true,
585
+ debugLink: true,
586
+ });
587
+ }
588
+ async sendPin(pin) {
589
+ const matrixAck = new Messages.PinMatrixAck();
590
+ matrixAck.setPin(pin);
591
+ await this.transport.call(Messages.MessageType.MESSAGETYPE_PINMATRIXACK, matrixAck, {
592
+ msgTimeout: core.DEFAULT_TIMEOUT,
593
+ omitLock: true,
594
+ noWait: true,
595
+ });
596
+ }
597
+ async sendPassphrase(passphrase) {
598
+ const passphraseAck = new Messages.PassphraseAck();
599
+ passphraseAck.setPassphrase(passphrase);
600
+ await this.transport.call(Messages.MessageType.MESSAGETYPE_PASSPHRASEACK, passphraseAck, {
601
+ msgTimeout: core.DEFAULT_TIMEOUT,
602
+ omitLock: true,
603
+ noWait: true,
604
+ });
605
+ }
606
+ async sendCharacter(character) {
607
+ await this.sendCharacterProto(character, false, false);
608
+ }
609
+ async sendCharacterDelete() {
610
+ await this.sendCharacterProto('', true, false);
611
+ }
612
+ async sendCharacterDone() {
613
+ await this.sendCharacterProto('', false, true);
614
+ }
615
+ async sendWord(_word) {
616
+ throw new Error('Not Yet Implemented :(');
617
+ }
618
+ async sendCharacterProto(character, _delete, _done) {
619
+ const characterAck = new Messages.CharacterAck();
620
+ if (character !== '') {
621
+ characterAck.setCharacter(character);
622
+ }
623
+ else if (_delete) {
624
+ characterAck.setDelete(_delete);
625
+ }
626
+ else if (_done) {
627
+ characterAck.setDone(_done);
628
+ }
629
+ await this.transport.call(Messages.MessageType.MESSAGETYPE_CHARACTERACK, characterAck, {
630
+ msgTimeout: core.DEFAULT_TIMEOUT,
631
+ omitLock: true,
632
+ noWait: true,
633
+ });
634
+ }
635
+ // ApplyPolicy enables or disables a named policy such as "ShapeShift" on the device
636
+ async applyPolicy(p) {
637
+ const policy = new Types.PolicyType();
638
+ policy.setPolicyName(p.policyName);
639
+ policy.setEnabled(p.enabled);
640
+ const applyPolicies = new Messages.ApplyPolicies();
641
+ applyPolicies.setPolicyList([policy]);
642
+ await this.transport.call(Messages.MessageType.MESSAGETYPE_APPLYPOLICIES, applyPolicies, {
643
+ msgTimeout: core.LONG_TIMEOUT,
644
+ });
645
+ this.cacheFeatures(undefined);
646
+ }
647
+ // ApplySettings changes the label, language, and enabling/disabling the passphrase
648
+ // The default language is english
649
+ async applySettings(s) {
650
+ const applySettings = new Messages.ApplySettings();
651
+ if (s.label) {
652
+ applySettings.setLabel(s.label);
653
+ }
654
+ if (s.language) {
655
+ applySettings.setLanguage(s.language);
656
+ }
657
+ if (s.usePassphrase !== undefined) {
658
+ applySettings.setUsePassphrase(s.usePassphrase);
659
+ }
660
+ if (s.autoLockDelayMs) {
661
+ applySettings.setAutoLockDelayMs(s.autoLockDelayMs);
662
+ }
663
+ if (s.u2fCounter) {
664
+ applySettings.setU2fCounter(s.u2fCounter);
665
+ }
666
+ await this.transport.call(Messages.MessageType.MESSAGETYPE_APPLYSETTINGS, applySettings);
667
+ this.cacheFeatures(undefined);
668
+ }
669
+ // Cancel aborts the last device action that required user interaction
670
+ // It can follow a button request, passphrase request, or pin request
671
+ async cancel() {
672
+ await this.transport.cancel();
673
+ }
674
+ // ChangePin requests setting/changing the pin
675
+ async changePin() {
676
+ const changePin = new Messages.ChangePin();
677
+ // User may be propmpted for button press up to 2 times
678
+ await this.transport.call(Messages.MessageType.MESSAGETYPE_CHANGEPIN, changePin, {
679
+ msgTimeout: core.LONG_TIMEOUT,
680
+ });
681
+ }
682
+ // CipherKeyValue encrypts or decrypts a value with a given key, nodepath, and initializationVector
683
+ // This method encrypts if encrypt is true and decrypts if false, the confirm paramater determines wether
684
+ // the user is prompted on the device. See EncryptKeyValue() and DecryptKeyValue() for convenience methods
685
+ // NOTE: If the length of the value in bytes is not divisible by 16 it will be zero padded
686
+ async cipherKeyValue(v) {
687
+ // if(val.length % 16 !== 0) val = val.concat() TODO THIS
688
+ const cipherKeyValue = new Messages.CipherKeyValue();
689
+ cipherKeyValue.setAddressNList(v.addressNList);
690
+ cipherKeyValue.setKey(v.key);
691
+ cipherKeyValue.setValue(v.value);
692
+ cipherKeyValue.setEncrypt(!!v.encrypt);
693
+ cipherKeyValue.setAskOnEncrypt(v.askOnEncrypt || false);
694
+ cipherKeyValue.setAskOnDecrypt(v.askOnDecrypt || false);
695
+ cipherKeyValue.setIv(v.iv || '');
696
+ const response = await this.transport.call(Messages.MessageType.MESSAGETYPE_CIPHERKEYVALUE, cipherKeyValue);
697
+ const ckv = response.message;
698
+ return ckv.getValue();
699
+ }
700
+ // ClearSession clears cached session values such as the pin and passphrase
701
+ async clearSession() {
702
+ const clearSession = new Messages.ClearSession();
703
+ await this.transport.call(Messages.MessageType.MESSAGETYPE_CLEARSESSION, clearSession);
704
+ this.cacheFeatures(undefined);
705
+ }
706
+ // DecryptKeyValue is a convenience method around decrypting with CipherKeyValue().
707
+ // For more granular control of the process use CipherKeyValue()
708
+ async decryptKeyValue(v) {
709
+ return this.cipherKeyValue(v);
710
+ }
711
+ // FirmwareErase askes the device to erase its firmware
712
+ async firmwareErase() {
713
+ const firmwareErase = new Messages.FirmwareErase();
714
+ // send
715
+ await this.transport.call(Messages.MessageType.MESSAGETYPE_FIRMWAREERASE, firmwareErase);
716
+ this.cacheFeatures(undefined);
717
+ }
718
+ async firmwareUpload(firmware) {
719
+ const firmwareUpload = new Messages.FirmwareUpload();
720
+ const hash = await this.transport.getFirmwareHash(firmware);
721
+ firmwareUpload.setPayload(firmware);
722
+ firmwareUpload.setPayloadHash(hash);
723
+ await this.transport.call(Messages.MessageType.MESSAGETYPE_FIRMWAREUPLOAD, firmwareUpload);
724
+ this.cacheFeatures(undefined);
725
+ }
726
+ // Initialize assigns a hid connection to this KeepKey and send initialize message to device
727
+ async initialize() {
728
+ const initialize = new Messages.Initialize();
729
+ const event = await this.transport.call(Messages.MessageType.MESSAGETYPE_INITIALIZE, initialize);
730
+ if (!event.message)
731
+ throw event;
732
+ const out = event.message;
733
+ this.features = out;
734
+ // v6.1.0 firmware changed usb serial numbers to match STM32 desig_device_id
735
+ // If the deviceId in the features table doesn't match, then we need to
736
+ // add another k-v pair to the keyring so it can be looked up either way.
737
+ const transportDeviceID = await this.transport.getDeviceID();
738
+ if (out.deviceId && transportDeviceID !== out.deviceId) {
739
+ this.transport.keyring.addAlias(transportDeviceID, out.deviceId);
740
+ }
741
+ const fwVersion = `v${out.majorVersion}.${out.minorVersion}.${out.patchVersion}`;
742
+ //Lost Support per proto 44.3
743
+ this._supportsOsmosis = semver.gte(fwVersion, 'v7.7.0');
744
+ this._supportsCosmos = semver.gte(fwVersion, 'v7.3.0');
745
+ this._supportsRipple = semver.gte(fwVersion, 'v6.4.0');
746
+ this._supportsBinance = semver.gte(fwVersion, 'v6.4.0');
747
+ this._supportsEos = semver.gte(fwVersion, 'v6.4.0');
748
+ // this._supportsThorchain = semver.get(fwVersion, "v7.3.0");
749
+ this.cacheFeatures(out);
750
+ return out;
751
+ }
752
+ // GetFeatures returns the features and other device information such as the version, label, and supported coins
753
+ async getFeatures(cached = false) {
754
+ if (cached && this.featuresCache)
755
+ return this.featuresCache;
756
+ const features = new Messages.GetFeatures();
757
+ const event = await this.transport.call(Messages.MessageType.MESSAGETYPE_GETFEATURES, features);
758
+ this.cacheFeatures(event.message);
759
+ return event.message;
760
+ }
761
+ cacheFeatures(features) {
762
+ this.featuresCache = features;
763
+ }
764
+ // GetEntropy requests sample data from the hardware RNG
765
+ async getEntropy(size) {
766
+ const getEntropy = new Messages.GetEntropy();
767
+ getEntropy.setSize(size);
768
+ // send
769
+ const event = await this.transport.call(Messages.MessageType.MESSAGETYPE_GETENTROPY, getEntropy, {
770
+ msgTimeout: core.LONG_TIMEOUT,
771
+ });
772
+ return core.mustBeDefined(event.proto).getEntropy_asU8();
773
+ }
774
+ // GetNumCoins returns the number of coins supported by the device regardless of if the hanve funds.
775
+ async getNumCoins() {
776
+ const getCoinTable = new Messages.GetCoinTable();
777
+ const response = await this.transport.call(Messages.MessageType.MESSAGETYPE_GETCOINTABLE, getCoinTable);
778
+ return core.mustBeDefined(core.mustBeDefined(response.proto).getNumCoins());
779
+ }
780
+ // GetCoinTable returns an array of Types.CoinTypes, with start and end arguments for paging.
781
+ // You cannot request more than 10 at a time.
782
+ async getCoinTable(start = 0, end = start + 10) {
783
+ const getCoinTable = new Messages.GetCoinTable();
784
+ getCoinTable.setStart(start);
785
+ getCoinTable.setEnd(end);
786
+ const response = await this.transport.call(Messages.MessageType.MESSAGETYPE_GETCOINTABLE, getCoinTable);
787
+ const coinTable = response.message;
788
+ return coinTable.tableList;
789
+ }
790
+ // LoadDevice loads a provided seed onto the device and applies the provided settings
791
+ // including setting a pin/device label, enabling/disabling the passphrase, and whether to
792
+ // check the checksum of the provided mnemonic
793
+ async loadDevice(msg) {
794
+ const loadDevice = new Messages.LoadDevice();
795
+ loadDevice.setMnemonic(msg.mnemonic);
796
+ loadDevice.setPassphraseProtection(!!msg.passphrase);
797
+ loadDevice.setSkipChecksum(!!msg.skipChecksum);
798
+ if (msg.pin)
799
+ loadDevice.setPin(msg.pin);
800
+ if (msg.label)
801
+ loadDevice.setLabel(msg.label);
802
+ // send
803
+ await this.transport.call(Messages.MessageType.MESSAGETYPE_LOADDEVICE, loadDevice, {
804
+ msgTimeout: core.LONG_TIMEOUT,
805
+ });
806
+ this.cacheFeatures(undefined);
807
+ }
808
+ // RemovePin disables pin protection for the device. If a pin is currently enabled
809
+ // it will prompt the user to enter the current pin
810
+ async removePin() {
811
+ const changePin = new Messages.ChangePin();
812
+ changePin.setRemove(true);
813
+ // send
814
+ await this.transport.call(Messages.MessageType.MESSAGETYPE_CHANGEPIN, changePin);
815
+ this.cacheFeatures(undefined);
816
+ }
817
+ async send(events) {
818
+ for (const event of events) {
819
+ const MessageType = messageTypeRegistry[core.mustBeDefined(event.message_enum)];
820
+ const msg = new MessageType();
821
+ Object.entries(event.message).forEach(([key, value]) => {
822
+ const setterMethod = protoFieldToSetMethod(key);
823
+ if (msg[setterMethod]) {
824
+ // Assume setter methods are always of the format: strength -> setStrength
825
+ // until this exists https://github.com/protocolbuffers/protobuf/issues/1591
826
+ msg[setterMethod](value);
827
+ }
828
+ });
829
+ await this.transport.call(core.mustBeDefined(event.message_enum), msg);
830
+ }
831
+ }
832
+ // SoftReset power cycles the device. The device only responds to
833
+ // this message while in manufacturer mode
834
+ async softReset() {
835
+ const softReset = new Messages.SoftReset();
836
+ // send
837
+ await this.transport.call(Messages.MessageType.MESSAGETYPE_SOFTRESET, softReset);
838
+ this.cacheFeatures(undefined);
839
+ }
840
+ // WipeDevice wipes all sensitive data and settings
841
+ async wipe() {
842
+ const wipeDevice = new Messages.WipeDevice();
843
+ // send
844
+ await this.transport.call(Messages.MessageType.MESSAGETYPE_WIPEDEVICE, wipeDevice);
845
+ this.cacheFeatures(undefined);
846
+ }
847
+ async btcGetAddress(msg) {
848
+ return Btc.btcGetAddress(this, this.transport, msg);
849
+ }
850
+ async btcSignTx(msg) {
851
+ return Btc.btcSignTx(this, this.transport, msg);
852
+ }
853
+ async btcSignMessage(msg) {
854
+ return Btc.btcSignMessage(this, this.transport, msg);
855
+ }
856
+ async btcVerifyMessage(msg) {
857
+ return Btc.btcVerifyMessage(this, this.transport, msg);
858
+ }
859
+ async ethSignTx(msg) {
860
+ return Eth.ethSignTx(this.transport, msg);
861
+ }
862
+ async ethGetAddress(msg) {
863
+ return Eth.ethGetAddress(this.transport, msg);
864
+ }
865
+ async ethSignMessage(msg) {
866
+ return Eth.ethSignMessage(this.transport, msg);
867
+ }
868
+ async ethSignTypedData(msg) {
869
+ return Eth.ethSignTypedData(this.transport, msg);
870
+ }
871
+ async ethVerifyMessage(msg) {
872
+ return Eth.ethVerifyMessage(this.transport, msg);
873
+ }
874
+ rippleGetAddress(msg) {
875
+ return Ripple.rippleGetAddress(this.transport, msg);
876
+ }
877
+ rippleSignTx(msg) {
878
+ return Ripple.rippleSignTx(this.transport, msg);
879
+ }
880
+ cosmosGetAddress(msg) {
881
+ return Cosmos.cosmosGetAddress(this.transport, msg);
882
+ }
883
+ cosmosSignTx(msg) {
884
+ return Cosmos.cosmosSignTx(this.transport, msg);
885
+ }
886
+ osmosisGetAddress(msg) {
887
+ return Osmosis.osmosisGetAddress(this.transport, msg);
888
+ }
889
+ osmosisSignTx(msg) {
890
+ return Osmosis.osmosisSignTx(this.transport, msg);
891
+ }
892
+ thorchainGetAddress(msg) {
893
+ return Thorchain.thorchainGetAddress(this.transport, msg);
894
+ }
895
+ thorchainSignTx(msg) {
896
+ return Thorchain.thorchainSignTx(this.transport, msg);
897
+ }
898
+ mayachainGetAddress(msg) {
899
+ return Mayachain.mayachainGetAddress(this.transport, msg);
900
+ }
901
+ mayachainSignTx(msg) {
902
+ return Mayachain.mayachainSignTx(this.transport, msg);
903
+ }
904
+ binanceGetAddress(msg) {
905
+ return Binance.binanceGetAddress(this.transport, msg);
906
+ }
907
+ binanceSignTx(msg) {
908
+ return Binance.binanceSignTx(this.transport, msg);
909
+ }
910
+ eosGetPublicKey(msg) {
911
+ return Eos.eosGetPublicKey(this.transport, msg);
912
+ }
913
+ eosSignTx(msg) {
914
+ return Eos.eosSignTx(this.transport, msg);
915
+ }
916
+ disconnect() {
917
+ return this.transport.disconnect();
918
+ }
919
+ }
920
+ export function info() {
921
+ return new KeepKeyHDWalletInfo();
922
+ }
923
+ export function create(transport) {
924
+ return new KeepKeyHDWallet(transport);
925
+ }