@shapeshiftoss/hdwallet-keepkey 1.62.39 → 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.
- package/LICENSE.md +6 -6
- package/dist/cjs/.tsbuildinfo +1 -0
- package/dist/{adapter.d.ts → cjs/adapter.d.ts} +6 -7
- package/dist/cjs/adapter.js +146 -0
- package/dist/{binance.d.ts → cjs/binance.d.ts} +3 -4
- package/dist/cjs/binance.js +144 -0
- package/dist/{bitcoin.d.ts → cjs/bitcoin.d.ts} +3 -4
- package/dist/cjs/bitcoin.js +549 -0
- package/dist/{bnbencoding.d.ts → cjs/bnbencoding.d.ts} +3 -2
- package/dist/{bnbencoding.js → cjs/bnbencoding.js} +22 -22
- package/dist/{cosmos.d.ts → cjs/cosmos.d.ts} +4 -5
- package/dist/cjs/cosmos.js +219 -0
- package/dist/{eos.d.ts → cjs/eos.d.ts} +3 -4
- package/dist/cjs/eos.js +244 -0
- package/dist/{ethereum.d.ts → cjs/ethereum.d.ts} +4 -5
- package/dist/cjs/ethereum.js +264 -0
- package/dist/cjs/index.d.ts +5 -0
- package/dist/{index.js → cjs/index.js} +0 -1
- package/dist/{keepkey.d.ts → cjs/keepkey.d.ts} +45 -20
- package/dist/cjs/keepkey.js +959 -0
- package/dist/{mayachain.d.ts → cjs/mayachain.d.ts} +4 -5
- package/dist/cjs/mayachain.js +169 -0
- package/dist/{osmosis.d.ts → cjs/osmosis.d.ts} +4 -5
- package/dist/cjs/osmosis.js +270 -0
- package/dist/cjs/package.json +1 -0
- package/dist/{ripple.d.ts → cjs/ripple.d.ts} +3 -4
- package/dist/cjs/ripple.js +104 -0
- package/dist/{thorchain.d.ts → cjs/thorchain.d.ts} +4 -5
- package/dist/cjs/thorchain.js +169 -0
- package/dist/{transport.d.ts → cjs/transport.d.ts} +2 -3
- package/dist/cjs/transport.js +333 -0
- package/dist/{typeRegistry.d.ts → cjs/typeRegistry.d.ts} +2 -3
- package/dist/{typeRegistry.js → cjs/typeRegistry.js} +26 -13
- package/dist/{utils.d.ts → cjs/utils.d.ts} +1 -2
- package/dist/{utils.js → cjs/utils.js} +7 -8
- package/dist/esm/.tsbuildinfo +1 -0
- package/dist/esm/adapter.d.ts +35 -0
- package/dist/esm/adapter.js +119 -0
- package/dist/esm/binance.d.ts +5 -0
- package/dist/esm/binance.js +112 -0
- package/dist/esm/bitcoin.d.ts +11 -0
- package/dist/esm/bitcoin.js +511 -0
- package/dist/esm/bnbencoding.d.ts +11 -0
- package/dist/esm/bnbencoding.js +103 -0
- package/dist/esm/cosmos.d.ts +6 -0
- package/dist/esm/cosmos.js +187 -0
- package/dist/esm/eos.d.ts +5 -0
- package/dist/esm/eos.js +212 -0
- package/dist/esm/ethereum.d.ts +17 -0
- package/dist/esm/ethereum.js +229 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/keepkey.d.ts +177 -0
- package/dist/esm/keepkey.js +925 -0
- package/dist/esm/mayachain.d.ts +6 -0
- package/dist/esm/mayachain.js +137 -0
- package/dist/esm/osmosis.d.ts +6 -0
- package/dist/esm/osmosis.js +238 -0
- package/dist/esm/ripple.d.ts +5 -0
- package/dist/esm/ripple.js +72 -0
- package/dist/esm/thorchain.d.ts +6 -0
- package/dist/esm/thorchain.js +137 -0
- package/dist/esm/transport.d.ts +55 -0
- package/dist/esm/transport.js +306 -0
- package/dist/esm/typeRegistry.d.ts +4 -0
- package/dist/esm/typeRegistry.js +47 -0
- package/dist/esm/utils.d.ts +6 -0
- package/dist/esm/utils.js +56 -0
- package/package.json +33 -19
- package/dist/adapter.d.ts.map +0 -1
- package/dist/adapter.js +0 -175
- package/dist/adapter.js.map +0 -1
- package/dist/binance.d.ts.map +0 -1
- package/dist/binance.js +0 -146
- package/dist/binance.js.map +0 -1
- package/dist/bitcoin.d.ts.map +0 -1
- package/dist/bitcoin.js +0 -568
- package/dist/bitcoin.js.map +0 -1
- package/dist/bnbencoding.d.ts.map +0 -1
- package/dist/bnbencoding.js.map +0 -1
- package/dist/cosmos.d.ts.map +0 -1
- package/dist/cosmos.js +0 -230
- package/dist/cosmos.js.map +0 -1
- package/dist/eos.d.ts.map +0 -1
- package/dist/eos.js +0 -247
- package/dist/eos.js.map +0 -1
- package/dist/ethereum.d.ts.map +0 -1
- package/dist/ethereum.js +0 -281
- package/dist/ethereum.js.map +0 -1
- package/dist/index.d.ts +0 -6
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/keepkey.d.ts.map +0 -1
- package/dist/keepkey.js +0 -1027
- package/dist/keepkey.js.map +0 -1
- package/dist/mayachain.d.ts.map +0 -1
- package/dist/mayachain.js +0 -180
- package/dist/mayachain.js.map +0 -1
- package/dist/osmosis.d.ts.map +0 -1
- package/dist/osmosis.js +0 -278
- package/dist/osmosis.js.map +0 -1
- package/dist/ripple.d.ts.map +0 -1
- package/dist/ripple.js +0 -111
- package/dist/ripple.js.map +0 -1
- package/dist/thorchain.d.ts.map +0 -1
- package/dist/thorchain.js +0 -180
- package/dist/thorchain.js.map +0 -1
- package/dist/transport.d.ts.map +0 -1
- package/dist/transport.js +0 -365
- package/dist/transport.js.map +0 -1
- package/dist/typeRegistry.d.ts.map +0 -1
- package/dist/typeRegistry.js.map +0 -1
- package/dist/utils.d.ts.map +0 -1
- 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
|
+
}
|