@shapeshiftoss/hdwallet-metamask-multichain 1.55.10-mipd.0

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 (66) hide show
  1. package/LICENSE.md +21 -0
  2. package/dist/adapter.d.ts +11 -0
  3. package/dist/adapter.d.ts.map +1 -0
  4. package/dist/adapter.js +95 -0
  5. package/dist/adapter.js.map +1 -0
  6. package/dist/bitcoin.d.ts +8 -0
  7. package/dist/bitcoin.d.ts.map +1 -0
  8. package/dist/bitcoin.js +43 -0
  9. package/dist/bitcoin.js.map +1 -0
  10. package/dist/bitcoincash.d.ts +8 -0
  11. package/dist/bitcoincash.d.ts.map +1 -0
  12. package/dist/bitcoincash.js +43 -0
  13. package/dist/bitcoincash.js.map +1 -0
  14. package/dist/common.d.ts +2 -0
  15. package/dist/common.d.ts.map +1 -0
  16. package/dist/common.js +6 -0
  17. package/dist/common.js.map +1 -0
  18. package/dist/cosmos.d.ts +7 -0
  19. package/dist/cosmos.d.ts.map +1 -0
  20. package/dist/cosmos.js +64 -0
  21. package/dist/cosmos.js.map +1 -0
  22. package/dist/dogecoin.d.ts +8 -0
  23. package/dist/dogecoin.d.ts.map +1 -0
  24. package/dist/dogecoin.js +43 -0
  25. package/dist/dogecoin.js.map +1 -0
  26. package/dist/ethereum.d.ts +9 -0
  27. package/dist/ethereum.d.ts.map +1 -0
  28. package/dist/ethereum.js +159 -0
  29. package/dist/ethereum.js.map +1 -0
  30. package/dist/index.d.ts +3 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +19 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/litecoin.d.ts +8 -0
  35. package/dist/litecoin.d.ts.map +1 -0
  36. package/dist/litecoin.js +43 -0
  37. package/dist/litecoin.js.map +1 -0
  38. package/dist/shapeshift-multichain.d.ts +203 -0
  39. package/dist/shapeshift-multichain.d.ts.map +1 -0
  40. package/dist/shapeshift-multichain.js +883 -0
  41. package/dist/shapeshift-multichain.js.map +1 -0
  42. package/dist/thorchain.d.ts +7 -0
  43. package/dist/thorchain.d.ts.map +1 -0
  44. package/dist/thorchain.js +64 -0
  45. package/dist/thorchain.js.map +1 -0
  46. package/dist/utxo.d.ts +6 -0
  47. package/dist/utxo.d.ts.map +1 -0
  48. package/dist/utxo.js +205 -0
  49. package/dist/utxo.js.map +1 -0
  50. package/package.json +32 -0
  51. package/src/adapter.ts +62 -0
  52. package/src/bitcoin.ts +32 -0
  53. package/src/bitcoincash.ts +32 -0
  54. package/src/common.ts +2 -0
  55. package/src/cosmos.ts +30 -0
  56. package/src/dogecoin.ts +32 -0
  57. package/src/ethereum.ts +125 -0
  58. package/src/index.ts +2 -0
  59. package/src/litecoin.ts +31 -0
  60. package/src/shapeshift-multichain.test.ts +170 -0
  61. package/src/shapeshift-multichain.ts +871 -0
  62. package/src/thorchain.ts +30 -0
  63. package/src/utxo.ts +201 -0
  64. package/tsconfig.json +10 -0
  65. package/tsconfig.tsbuildinfo +1 -0
  66. package/yarn-error.log +18555 -0
@@ -0,0 +1,871 @@
1
+ import * as core from "@shapeshiftoss/hdwallet-core";
2
+ import { AddEthereumChainParameter } from "@shapeshiftoss/hdwallet-core";
3
+ import { ethErrors, serializeError } from "eth-rpc-errors";
4
+ import _ from "lodash";
5
+
6
+ import * as Btc from "./bitcoin";
7
+ import * as BtcCash from "./bitcoincash";
8
+ import * as Cosmos from "./cosmos";
9
+ import * as Doge from "./dogecoin";
10
+ import * as Eth from "./ethereum";
11
+ import * as Litecoin from "./litecoin";
12
+ import * as Thorchain from "./thorchain";
13
+ import * as utxo from "./utxo";
14
+
15
+ export function isMetaMask(wallet: core.HDWallet): wallet is MetaMaskShapeShiftMultiChainHDWallet {
16
+ return _.isObject(wallet) && (wallet as any)._isMetaMask;
17
+ }
18
+
19
+ export class MetaMaskShapeShiftMultiChainHDWalletInfo implements core.HDWalletInfo, core.ETHWalletInfo {
20
+ ethGetChainId?(): Promise<number | null> {
21
+ throw new Error("Method not implemented.");
22
+ }
23
+
24
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
25
+ ethSwitchChain?(params: core.AddEthereumChainParameter): Promise<void> {
26
+ throw new Error("Method not implemented.");
27
+ }
28
+
29
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
30
+ ethAddChain?(params: core.AddEthereumChainParameter): Promise<void> {
31
+ throw new Error("Method not implemented.");
32
+ }
33
+ readonly _supportsBTCInfo = true;
34
+ readonly _supportsETHInfo = true;
35
+ readonly _supportsCosmosInfo = true;
36
+ readonly _supportsBinanceInfo = false;
37
+ readonly _supportsRippleInfo = false;
38
+ readonly _supportsEosInfo = false;
39
+ readonly _supportsFioInfo = false;
40
+ readonly _supportsThorchainInfo = true;
41
+
42
+ public getVendor(): string {
43
+ return "MetaMask";
44
+ }
45
+
46
+ public hasOnDevicePinEntry(): boolean {
47
+ return false;
48
+ }
49
+
50
+ public hasOnDevicePassphrase(): boolean {
51
+ return true;
52
+ }
53
+
54
+ public hasOnDeviceDisplay(): boolean {
55
+ return true;
56
+ }
57
+
58
+ public hasOnDeviceRecovery(): boolean {
59
+ return true;
60
+ }
61
+
62
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
63
+ public hasNativeShapeShift(srcCoin: core.Coin, dstCoin: core.Coin): boolean {
64
+ return false;
65
+ }
66
+
67
+ public supportsBip44Accounts(): boolean {
68
+ // Multi-account not supported in MM/snap, the only BIP44 bits we derive is diff slip44s than 60 (meaning, we support EVM chains)
69
+ return false;
70
+ }
71
+
72
+ public supportsOfflineSigning(): boolean {
73
+ return false;
74
+ }
75
+
76
+ public supportsBroadcast(): boolean {
77
+ return true;
78
+ }
79
+
80
+ public describePath(msg: core.DescribePath): core.PathDescription {
81
+ switch (msg.coin) {
82
+ case "bitcoin":
83
+ case "bitcoincash":
84
+ case "dogecoin":
85
+ case "litecoin": {
86
+ const unknown = core.unknownUTXOPath(msg.path, msg.coin, msg.scriptType);
87
+
88
+ if (!msg.scriptType) return unknown;
89
+ if (!utxo.utxoSupportsCoin(msg.coin)) return unknown;
90
+ if (!utxo.utxoSupportsScriptType(msg.coin, msg.scriptType)) return unknown;
91
+
92
+ return core.describeUTXOPath(msg.path, msg.coin, msg.scriptType);
93
+ }
94
+
95
+ case "atom":
96
+ return core.cosmosDescribePath(msg.path);
97
+
98
+ case "ethereum":
99
+ return core.describeETHPath(msg.path);
100
+
101
+ case "rune":
102
+ case "trune":
103
+ case "thorchain":
104
+ return core.thorchainDescribePath(msg.path);
105
+
106
+ default:
107
+ throw new Error("Unsupported path");
108
+ }
109
+ }
110
+
111
+ public async bitcoinSupportsNetwork(chainId = 0): Promise<boolean> {
112
+ return chainId === 0;
113
+ }
114
+
115
+ public async bitcoinSupportsSecureTransfer(): Promise<boolean> {
116
+ return false;
117
+ }
118
+
119
+ public bitcoinSupportsNativeShapeShift(): boolean {
120
+ return false;
121
+ }
122
+
123
+ public bitcoinGetAccountPaths(msg: core.BTCGetAccountPaths): Array<core.BTCAccountPath> {
124
+ return Btc.bitcoinGetAccountPaths(msg);
125
+ }
126
+
127
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
128
+ public bitcoinNextAccountPath(msg: core.BTCAccountPath): core.BTCAccountPath | undefined {
129
+ // TODO: What do we do here?
130
+ return undefined;
131
+ }
132
+
133
+ public async bitcoinCashSupportsNetwork(chainId = 145): Promise<boolean> {
134
+ return chainId === 145;
135
+ }
136
+
137
+ public async bitcoinCashSupportsSecureTransfer(): Promise<boolean> {
138
+ return false;
139
+ }
140
+
141
+ public bitcoinCashSupportsNativeShapeShift(): boolean {
142
+ return false;
143
+ }
144
+
145
+ public bitcoinCashGetAccountPaths(msg: core.BTCGetAccountPaths): Array<core.BTCAccountPath> {
146
+ return Btc.bitcoinGetAccountPaths(msg);
147
+ }
148
+
149
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
150
+ public bitcoinCashNextAccountPath(msg: core.BTCAccountPath): core.BTCAccountPath | undefined {
151
+ // TODO: What do we do here?
152
+ return undefined;
153
+ }
154
+
155
+ public async cosmosSupportsNetwork(chainId = 118): Promise<boolean> {
156
+ return chainId === 118;
157
+ }
158
+
159
+ public async cosmosSupportsSecureTransfer(): Promise<boolean> {
160
+ return false;
161
+ }
162
+
163
+ public cosmosSupportsNativeShapeShift(): boolean {
164
+ return false;
165
+ }
166
+
167
+ public cosmosGetAccountPaths(msg: core.CosmosGetAccountPaths): Array<core.CosmosAccountPath> {
168
+ return Cosmos.cosmosGetAccountPaths(msg);
169
+ }
170
+
171
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
172
+ public cosmosNextAccountPath(msg: core.CosmosAccountPath): core.CosmosAccountPath | undefined {
173
+ // TODO: What do we do here?
174
+ return undefined;
175
+ }
176
+
177
+ public async dogecoinSupportsNetwork(chainId = 3): Promise<boolean> {
178
+ return chainId === 3;
179
+ }
180
+
181
+ public async dogecoinSupportsSecureTransfer(): Promise<boolean> {
182
+ return false;
183
+ }
184
+
185
+ public dogecoinSupportsNativeShapeShift(): boolean {
186
+ return false;
187
+ }
188
+
189
+ public dogecoinGetAccountPaths(msg: core.BTCGetAccountPaths): Array<core.BTCAccountPath> {
190
+ return Doge.dogecoinGetAccountPaths(msg);
191
+ }
192
+
193
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
194
+ public dogecoinNextAccountPath(msg: core.BTCAccountPath): core.BTCAccountPath | undefined {
195
+ // TODO: What do we do here?
196
+ return undefined;
197
+ }
198
+
199
+ public async ethSupportsNetwork(chainId: number): Promise<boolean> {
200
+ return chainId === 1;
201
+ }
202
+
203
+ public async ethSupportsSecureTransfer(): Promise<boolean> {
204
+ return false;
205
+ }
206
+
207
+ public ethSupportsNativeShapeShift(): boolean {
208
+ return false;
209
+ }
210
+
211
+ public ethGetAccountPaths(msg: core.ETHGetAccountPath): Array<core.ETHAccountPath> {
212
+ return Eth.ethGetAccountPaths(msg);
213
+ }
214
+
215
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
216
+ public ethNextAccountPath(msg: core.ETHAccountPath): core.ETHAccountPath | undefined {
217
+ // TODO: What do we do here?
218
+ return undefined;
219
+ }
220
+
221
+ public async ethSupportsEIP1559(): Promise<boolean> {
222
+ return true;
223
+ }
224
+
225
+ public async litecoinSupportsNetwork(chainId = 2): Promise<boolean> {
226
+ return chainId === 2;
227
+ }
228
+
229
+ public async litecoinSupportsSecureTransfer(): Promise<boolean> {
230
+ return false;
231
+ }
232
+
233
+ public litecoinSupportsNativeShapeShift(): boolean {
234
+ return false;
235
+ }
236
+
237
+ public litecoinGetAccountPaths(msg: core.BTCGetAccountPaths): Array<core.BTCAccountPath> {
238
+ return Litecoin.litecoinGetAccountPaths(msg);
239
+ }
240
+
241
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
242
+ public litecoinNextAccountPath(msg: core.BTCAccountPath): core.BTCAccountPath | undefined {
243
+ // TODO: What do we do here?
244
+ return undefined;
245
+ }
246
+
247
+ public async thorchainSupportsNetwork(chainId = 931): Promise<boolean> {
248
+ return chainId === 931;
249
+ }
250
+
251
+ public async thorchainSupportsSecureTransfer(): Promise<boolean> {
252
+ return false;
253
+ }
254
+
255
+ public thorchainSupportsNativeShapeShift(): boolean {
256
+ return false;
257
+ }
258
+
259
+ public thorchainGetAccountPaths(msg: core.ThorchainGetAccountPaths): Array<core.ThorchainAccountPath> {
260
+ return Thorchain.thorchainGetAccountPaths(msg);
261
+ }
262
+
263
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
264
+ public thorchainNextAccountPath(msg: core.ThorchainAccountPath): core.ThorchainAccountPath | undefined {
265
+ // TODO: What do we do here?
266
+ return undefined;
267
+ }
268
+ }
269
+
270
+ export class MetaMaskShapeShiftMultiChainHDWallet
271
+ implements core.HDWallet, core.BTCWallet, core.ETHWallet, core.CosmosWallet, core.ThorchainWallet
272
+ {
273
+ readonly _supportsETH = true;
274
+ readonly _supportsETHInfo = true;
275
+ readonly _supportsBTCInfo = true;
276
+ readonly _supportsBTC = true;
277
+ readonly _supportsCosmosInfo = true;
278
+ readonly _supportsCosmos = true;
279
+ readonly _supportsEthSwitchChain = true;
280
+ readonly _supportsAvalanche = true;
281
+ readonly _supportsOptimism = true;
282
+ readonly _supportsBSC = true;
283
+ readonly _supportsPolygon = true;
284
+ readonly _supportsGnosis = true;
285
+ readonly _supportsArbitrum = true;
286
+ readonly _supportsArbitrumNova = true;
287
+ readonly _supportsBase = true;
288
+ readonly _supportsOsmosisInfo = true;
289
+ readonly _supportsOsmosis = true;
290
+ readonly _supportsBinanceInfo = false;
291
+ readonly _supportsBinance = false;
292
+ readonly _supportsDebugLink = false;
293
+ readonly _isPortis = false;
294
+ readonly _isMetaMask = true;
295
+ readonly _supportsRippleInfo = false;
296
+ readonly _supportsRipple = false;
297
+ readonly _supportsEosInfo = false;
298
+ readonly _supportsEos = false;
299
+ readonly _supportsFioInfo = false;
300
+ readonly _supportsFio = false;
301
+ readonly _supportsThorchainInfo = true;
302
+ readonly _supportsThorchain = true;
303
+
304
+ info: MetaMaskShapeShiftMultiChainHDWalletInfo & core.HDWalletInfo;
305
+ bitcoinAddress?: string | null;
306
+ bitcoinCashAddress?: string | null;
307
+ cosmosAddress?: string | null;
308
+ dogecoinAddress?: string | null;
309
+ ethAddress?: string | null;
310
+ litecoinAddress?: string | null;
311
+ osmosisAddress?: string | null;
312
+ thorchainAddress?: string | null;
313
+ provider: any;
314
+
315
+ constructor(provider: unknown) {
316
+ this.info = new MetaMaskShapeShiftMultiChainHDWalletInfo();
317
+ this.provider = provider;
318
+ }
319
+
320
+ transport?: core.Transport | undefined;
321
+
322
+ async getFeatures(): Promise<Record<string, any>> {
323
+ return {};
324
+ }
325
+
326
+ public async isLocked(): Promise<boolean> {
327
+ try {
328
+ return !this.provider._metamask.isUnlocked();
329
+ } catch (e) {
330
+ // This may not be properly implemented in MM impersonators, e.g
331
+ // https://github.com/zeriontech/zerion-wallet-extension/blob/294630a4e1ef303205a6e6dd681245a27c8d1eec/src/modules/ethereum/provider.ts#L36C1-L39
332
+ // Assume unlocked, but log the error regardless in case this happens with *actual* MM
333
+ console.error(e);
334
+ return false;
335
+ }
336
+ }
337
+
338
+ public getVendor(): string {
339
+ return "MetaMask";
340
+ }
341
+
342
+ public async getModel(): Promise<string> {
343
+ return "MetaMask";
344
+ }
345
+
346
+ public async getLabel(): Promise<string> {
347
+ return "MetaMask";
348
+ }
349
+
350
+ public async initialize(): Promise<void> {
351
+ // nothing to initialize
352
+ }
353
+
354
+ public hasOnDevicePinEntry(): boolean {
355
+ return this.info.hasOnDevicePinEntry();
356
+ }
357
+
358
+ public hasOnDevicePassphrase(): boolean {
359
+ return this.info.hasOnDevicePassphrase();
360
+ }
361
+
362
+ public hasOnDeviceDisplay(): boolean {
363
+ return this.info.hasOnDeviceDisplay();
364
+ }
365
+
366
+ public hasOnDeviceRecovery(): boolean {
367
+ return this.info.hasOnDeviceRecovery();
368
+ }
369
+
370
+ public hasNativeShapeShift(srcCoin: core.Coin, dstCoin: core.Coin): boolean {
371
+ return this.info.hasNativeShapeShift(srcCoin, dstCoin);
372
+ }
373
+
374
+ public supportsBip44Accounts(): boolean {
375
+ return this.info.supportsBip44Accounts();
376
+ }
377
+
378
+ public supportsOfflineSigning(): boolean {
379
+ return false;
380
+ }
381
+
382
+ public supportsBroadcast(): boolean {
383
+ return true;
384
+ }
385
+
386
+ public async clearSession(): Promise<void> {
387
+ // TODO: Can we lock MetaMask from here?
388
+ }
389
+
390
+ public async ping(msg: core.Ping): Promise<core.Pong> {
391
+ // no ping function for MetaMask, so just returning Core.Pong
392
+ return { msg: msg.msg };
393
+ }
394
+
395
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
396
+ public async sendPin(pin: string): Promise<void> {
397
+ // no concept of pin in MetaMask
398
+ }
399
+
400
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
401
+ public async sendPassphrase(passphrase: string): Promise<void> {
402
+ // cannot send passphrase to MetaMask. Could show the widget?
403
+ }
404
+
405
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
406
+ public async sendCharacter(charater: string): Promise<void> {
407
+ // no concept of sendCharacter in MetaMask
408
+ }
409
+
410
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
411
+ public async sendWord(word: string): Promise<void> {
412
+ // no concept of sendWord in MetaMask
413
+ }
414
+
415
+ public async cancel(): Promise<void> {
416
+ // no concept of cancel in MetaMask
417
+ }
418
+
419
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
420
+ public async wipe(): Promise<void> {}
421
+
422
+ // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
423
+ public async reset(msg: core.ResetDevice): Promise<void> {}
424
+
425
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
426
+ public async recover(msg: core.RecoverDevice): Promise<void> {
427
+ // no concept of recover in MetaMask
428
+ }
429
+
430
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
431
+ public async loadDevice(msg: core.LoadDevice): Promise<void> {
432
+ // TODO: Does MetaMask allow this to be done programatically?
433
+ }
434
+
435
+ public describePath(msg: core.DescribePath): core.PathDescription {
436
+ return this.info.describePath(msg);
437
+ }
438
+
439
+ publicKeysCache: Map<string, Array<core.PublicKey | null>> = new Map();
440
+ public async getPublicKeys(msg: Array<core.GetPublicKey>): Promise<Array<core.PublicKey | null>> {
441
+ const key = JSON.stringify(msg);
442
+ const maybeCachedPublicKeys = this.publicKeysCache.get(key);
443
+
444
+ if (maybeCachedPublicKeys) {
445
+ return maybeCachedPublicKeys;
446
+ }
447
+
448
+ const pubKeys = await Promise.all(
449
+ msg.map(async (getPublicKey) => {
450
+ switch (getPublicKey.coin) {
451
+ case "Bitcoin":
452
+ return Btc.bitcoinGetPublicKeys(getPublicKey);
453
+ case "Litecoin":
454
+ return Litecoin.litecoinGetPublicKeys(getPublicKey);
455
+ case "Dogecoin":
456
+ return Doge.dogecoinGetPublicKeys(getPublicKey);
457
+ case "BitcoinCash":
458
+ return BtcCash.bitcoinCashGetPublicKeys(getPublicKey);
459
+ default:
460
+ return null;
461
+ }
462
+ })
463
+ );
464
+
465
+ const flattened = pubKeys.flat();
466
+ const filtered = flattened.filter((x) => x !== null) as Array<core.PublicKey>;
467
+
468
+ // Cache the result
469
+ this.publicKeysCache.set(key, filtered);
470
+
471
+ return filtered;
472
+ }
473
+ public async isInitialized(): Promise<boolean> {
474
+ return true;
475
+ }
476
+
477
+ /** INSERT NEW CODE HERE */
478
+
479
+ /** BITCOIN */
480
+
481
+ public async btcSupportsSecureTransfer(): Promise<boolean> {
482
+ return false;
483
+ }
484
+
485
+ public btcSupportsNativeShapeShift(): boolean {
486
+ return false;
487
+ }
488
+
489
+ public btcGetAccountPaths(msg: core.BTCGetAccountPaths): Array<core.BTCAccountPath> {
490
+ return Btc.bitcoinGetAccountPaths(msg);
491
+ }
492
+
493
+ public btcNextAccountPath(msg: core.BTCAccountPath): core.BTCAccountPath | undefined {
494
+ return this.info.bitcoinNextAccountPath(msg);
495
+ }
496
+
497
+ addressCache: Map<string, string> = new Map();
498
+ public async btcGetAddress(msg: core.BTCGetAddress): Promise<string | null> {
499
+ const key = JSON.stringify(msg);
500
+ const maybeCachedAddress = this.addressCache.get(key);
501
+ if (maybeCachedAddress) return maybeCachedAddress;
502
+ const value = await (async () => {
503
+ switch (msg.coin) {
504
+ case "Bitcoin":
505
+ return Btc.bitcoinGetAddress(msg);
506
+ case "Litecoin":
507
+ return Litecoin.litecoinGetAddress(msg);
508
+ case "Dogecoin":
509
+ return Doge.dogecoinGetAddress(msg);
510
+ case "BitcoinCash":
511
+ return BtcCash.bitcoinCashGetAddress(msg);
512
+ default:
513
+ return null;
514
+ }
515
+ })();
516
+ if (!value || typeof value !== "string") return null;
517
+
518
+ this.addressCache.set(key, value);
519
+ return value;
520
+ }
521
+
522
+ public async btcSignTx(msg: core.BTCSignTx): Promise<core.BTCSignedTx | null> {
523
+ const { coin } = msg;
524
+ switch (coin) {
525
+ case "Bitcoin":
526
+ return Btc.bitcoinSignTx(msg);
527
+ case "Litecoin":
528
+ return Litecoin.litecoinSignTx(msg);
529
+ case "Dogecoin":
530
+ return Doge.dogecoinSignTx(msg);
531
+ case "BitcoinCash":
532
+ return BtcCash.bitcoinCashSignTx(msg);
533
+ default:
534
+ return null;
535
+ }
536
+ }
537
+
538
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
539
+ public async btcSignMessage(msg: core.BTCSignMessage): Promise<core.BTCSignedMessage | null> {
540
+ throw new Error("Method not implemented.");
541
+ }
542
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
543
+ public async btcVerifyMessage(msg: core.BTCVerifyMessage): Promise<boolean | null> {
544
+ throw new Error("Method not implemented.");
545
+ }
546
+
547
+ public async btcSupportsScriptType(coin: string, scriptType?: core.BTCInputScriptType | undefined): Promise<boolean> {
548
+ return utxo.utxoSupportsScriptType(coin, scriptType);
549
+ }
550
+
551
+ public async btcSupportsCoin(coin: core.Coin): Promise<boolean> {
552
+ return utxo.utxoSupportsCoin(coin);
553
+ }
554
+
555
+ /** BITCOIN CASH */
556
+
557
+ public async bitcoinCashSupportsSecureTransfer(): Promise<boolean> {
558
+ return false;
559
+ }
560
+
561
+ public bitcoinCashSupportsNativeShapeShift(): boolean {
562
+ return false;
563
+ }
564
+
565
+ public bitcoinCashGetAccountPaths(msg: core.BTCGetAccountPaths): Array<core.BTCAccountPath> {
566
+ return BtcCash.bitcoinCashGetAccountPaths(msg);
567
+ }
568
+
569
+ public bitcoinCashNextAccountPath(msg: core.BTCAccountPath): core.BTCAccountPath | undefined {
570
+ return this.info.bitcoinCashNextAccountPath(msg);
571
+ }
572
+
573
+ public async bitcoinCashGetAddress(msg: core.BTCGetAddress): Promise<string | null> {
574
+ if (this.bitcoinCashAddress) {
575
+ return this.bitcoinCashAddress;
576
+ }
577
+ const address = await BtcCash.bitcoinCashGetAddress(msg);
578
+ if (address && typeof address === "string") {
579
+ this.bitcoinCashAddress = address;
580
+ return address;
581
+ } else {
582
+ this.bitcoinCashAddress = null;
583
+ return null;
584
+ }
585
+ }
586
+
587
+ public async bitcoinCashSignTx(msg: core.BTCSignTx): Promise<core.BTCSignedTx | null> {
588
+ const address = await this.bitcoinCashGetAddress(this.provider);
589
+ return address ? Btc.bitcoinSignTx(msg) : null;
590
+ }
591
+
592
+ /** COSMOS */
593
+
594
+ public async cosmosSupportsSecureTransfer(): Promise<boolean> {
595
+ return false;
596
+ }
597
+
598
+ public cosmosSupportsNativeShapeShift(): boolean {
599
+ return false;
600
+ }
601
+
602
+ public cosmosGetAccountPaths(msg: core.CosmosGetAccountPaths): Array<core.CosmosAccountPath> {
603
+ return Cosmos.cosmosGetAccountPaths(msg);
604
+ }
605
+
606
+ public cosmosNextAccountPath(msg: core.CosmosAccountPath): core.CosmosAccountPath | undefined {
607
+ return this.info.cosmosNextAccountPath(msg);
608
+ }
609
+
610
+ public async cosmosGetAddress(msg: core.CosmosGetAddress): Promise<string | null> {
611
+ if (this.cosmosAddress) {
612
+ return this.cosmosAddress;
613
+ }
614
+ const address = await Cosmos.cosmosGetAddress(msg);
615
+ if (address && typeof address === "string") {
616
+ this.cosmosAddress = address;
617
+ return address;
618
+ } else {
619
+ this.cosmosAddress = null;
620
+ return null;
621
+ }
622
+ }
623
+
624
+ public async cosmosSignTx(msg: core.CosmosSignTx): Promise<core.CosmosSignedTx | null> {
625
+ const address = await this.cosmosGetAddress(this.provider);
626
+ return address ? Cosmos.cosmosSignTx(msg) : null;
627
+ }
628
+
629
+ /** DOGECOIN */
630
+
631
+ public async dogecoinSupportsSecureTransfer(): Promise<boolean> {
632
+ return false;
633
+ }
634
+
635
+ public dogecoinSupportsNativeShapeShift(): boolean {
636
+ return false;
637
+ }
638
+
639
+ public dogecoinGetAccountPaths(msg: core.BTCGetAccountPaths): Array<core.BTCAccountPath> {
640
+ return Doge.dogecoinGetAccountPaths(msg);
641
+ }
642
+
643
+ public dogecoinNextAccountPath(msg: core.BTCAccountPath): core.BTCAccountPath | undefined {
644
+ return this.info.dogecoinNextAccountPath(msg);
645
+ }
646
+
647
+ public async dogecoinGetAddress(msg: core.BTCGetAddress): Promise<string | null> {
648
+ if (this.dogecoinAddress) {
649
+ return this.dogecoinAddress;
650
+ }
651
+ const address = await Doge.dogecoinGetAddress(msg);
652
+ if (address && typeof address === "string") {
653
+ this.dogecoinAddress = address;
654
+ return address;
655
+ } else {
656
+ this.dogecoinAddress = null;
657
+ return null;
658
+ }
659
+ }
660
+
661
+ public async dogecoinSignTx(msg: core.BTCSignTx): Promise<core.BTCSignedTx | null> {
662
+ const address = await this.dogecoinGetAddress(this.provider);
663
+ return address ? Doge.dogecoinSignTx(msg) : null;
664
+ }
665
+
666
+ /** ETHEREUM */
667
+
668
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
669
+ public async disconnect(): Promise<void> {}
670
+
671
+ public async ethSupportsNetwork(chainId = 1): Promise<boolean> {
672
+ return chainId === 1;
673
+ }
674
+
675
+ public async ethGetChainId(): Promise<number | null> {
676
+ try {
677
+ // chainId as hex string
678
+ const chainId: string = await this.provider.request({ method: "eth_chainId" });
679
+ return parseInt(chainId, 16);
680
+ } catch (e) {
681
+ console.error(e);
682
+ return null;
683
+ }
684
+ }
685
+
686
+ public async ethAddChain(params: AddEthereumChainParameter): Promise<void> {
687
+ // at this point, we know that we're in the context of a valid MetaMask provider
688
+ await this.provider.request({ method: "wallet_addEthereumChain", params: [params] });
689
+ }
690
+
691
+ public async ethSwitchChain(params: AddEthereumChainParameter): Promise<void> {
692
+ try {
693
+ // at this point, we know that we're in the context of a valid MetaMask provider
694
+ await this.provider.request({ method: "wallet_switchEthereumChain", params: [{ chainId: params.chainId }] });
695
+ } catch (e: any) {
696
+ const error = serializeError(e);
697
+ // https://docs.metamask.io/guide/ethereum-provider.html#errors
698
+ // Internal error, which in the case of wallet_switchEthereumChain call means the chain isn't currently added to the wallet
699
+ if (error.code === -32603) {
700
+ try {
701
+ await this.ethAddChain(params);
702
+ return;
703
+ } catch (addChainE: any) {
704
+ const addChainError = serializeError(addChainE);
705
+
706
+ if (addChainError.code === 4001) {
707
+ throw ethErrors.provider.userRejectedRequest();
708
+ }
709
+
710
+ throw (addChainError.data as any).originalError as {
711
+ code: number;
712
+ message: string;
713
+ stack: string;
714
+ };
715
+ }
716
+ }
717
+
718
+ if (error.code === 4001) {
719
+ throw ethErrors.provider.userRejectedRequest();
720
+ }
721
+
722
+ throw (error.data as any).originalError as {
723
+ code: number;
724
+ message: string;
725
+ stack: string;
726
+ };
727
+ }
728
+ }
729
+
730
+ public async ethSupportsSecureTransfer(): Promise<boolean> {
731
+ return false;
732
+ }
733
+
734
+ public ethSupportsNativeShapeShift(): boolean {
735
+ return false;
736
+ }
737
+
738
+ public async ethSupportsEIP1559(): Promise<boolean> {
739
+ return true;
740
+ }
741
+
742
+ public ethGetAccountPaths(msg: core.ETHGetAccountPath): Array<core.ETHAccountPath> {
743
+ return Eth.ethGetAccountPaths(msg);
744
+ }
745
+
746
+ public ethNextAccountPath(msg: core.ETHAccountPath): core.ETHAccountPath | undefined {
747
+ return this.info.ethNextAccountPath(msg);
748
+ }
749
+
750
+ // TODO: Respect msg.addressNList!
751
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
752
+ public async ethGetAddress(msg: core.ETHGetAddress): Promise<string | null> {
753
+ if (this.ethAddress) {
754
+ return this.ethAddress;
755
+ }
756
+ const address = await Eth.ethGetAddress(this.provider);
757
+ if (address) {
758
+ this.ethAddress = address;
759
+ return address;
760
+ } else {
761
+ this.ethAddress = null;
762
+ return null;
763
+ }
764
+ }
765
+
766
+ public async ethSignTx(msg: core.ETHSignTx): Promise<core.ETHSignedTx | null> {
767
+ const address = await this.ethGetAddress(this.provider);
768
+ return address ? Eth.ethSignTx(msg, this.provider, address) : null;
769
+ }
770
+
771
+ public async ethSendTx(msg: core.ETHSignTx): Promise<core.ETHTxHash | null> {
772
+ const txid = await this.ethGetAddress(this.provider);
773
+ return txid ? Eth.ethSendTx(msg, this.provider, txid) : null;
774
+ }
775
+
776
+ public async ethSignMessage(msg: core.ETHSignMessage): Promise<core.ETHSignedMessage | null> {
777
+ const address = await this.ethGetAddress(this.provider);
778
+ return address ? Eth.ethSignMessage(msg, this.provider, address) : null;
779
+ }
780
+
781
+ async ethSignTypedData(msg: core.ETHSignTypedData): Promise<core.ETHSignedTypedData | null> {
782
+ const address = await this.ethGetAddress(this.provider);
783
+ return address ? Eth.ethSignTypedData(msg, this.provider, address) : null;
784
+ }
785
+
786
+ public async ethVerifyMessage(msg: core.ETHVerifyMessage): Promise<boolean | null> {
787
+ return Eth.ethVerifyMessage(msg, this.provider);
788
+ }
789
+
790
+ /** LITECOIN */
791
+
792
+ public async litecoinSupportsSecureTransfer(): Promise<boolean> {
793
+ return false;
794
+ }
795
+
796
+ public litecoinSupportsNativeShapeShift(): boolean {
797
+ return false;
798
+ }
799
+
800
+ public litecoinGetAccountPaths(msg: core.BTCGetAccountPaths): Array<core.BTCAccountPath> {
801
+ return Litecoin.litecoinGetAccountPaths(msg);
802
+ }
803
+
804
+ public litecoinNextAccountPath(msg: core.BTCAccountPath): core.BTCAccountPath | undefined {
805
+ return this.info.litecoinNextAccountPath(msg);
806
+ }
807
+
808
+ public async litecoinGetAddress(msg: core.BTCGetAddress): Promise<string | null> {
809
+ if (this.litecoinAddress) {
810
+ return this.litecoinAddress;
811
+ }
812
+ const address = await Litecoin.litecoinGetAddress(msg);
813
+ if (address && typeof address === "string") {
814
+ this.litecoinAddress = address;
815
+ return address;
816
+ } else {
817
+ this.litecoinAddress = null;
818
+ return null;
819
+ }
820
+ }
821
+
822
+ public async litecoinSignTx(msg: core.BTCSignTx): Promise<core.BTCSignedTx | null> {
823
+ const address = await this.litecoinGetAddress(this.provider);
824
+ return address ? Litecoin.litecoinSignTx(msg) : null;
825
+ }
826
+
827
+ /** THORCHAIN */
828
+
829
+ public async thorchainSupportsSecureTransfer(): Promise<boolean> {
830
+ return false;
831
+ }
832
+
833
+ public thorchainSupportsNativeShapeShift(): boolean {
834
+ return false;
835
+ }
836
+
837
+ public thorchainGetAccountPaths(msg: core.ThorchainGetAccountPaths): Array<core.ThorchainAccountPath> {
838
+ return Thorchain.thorchainGetAccountPaths(msg);
839
+ }
840
+
841
+ public thorchainNextAccountPath(msg: core.ThorchainAccountPath): core.ThorchainAccountPath | undefined {
842
+ return this.info.thorchainNextAccountPath(msg);
843
+ }
844
+
845
+ public async thorchainGetAddress(msg: core.ThorchainGetAddress): Promise<string | null> {
846
+ if (this.thorchainAddress) {
847
+ return this.thorchainAddress;
848
+ }
849
+ const address = await Thorchain.thorchainGetAddress(msg);
850
+ if (address && typeof address === "string") {
851
+ this.thorchainAddress = address;
852
+ return address;
853
+ } else {
854
+ this.thorchainAddress = null;
855
+ return null;
856
+ }
857
+ }
858
+
859
+ public async thorchainSignTx(msg: core.ThorchainSignTx): Promise<core.ThorchainSignedTx | null> {
860
+ const address = await this.thorchainGetAddress(this.provider);
861
+ return address ? Thorchain.thorchainSignTx(msg) : null;
862
+ }
863
+
864
+ public async getDeviceID(): Promise<string> {
865
+ return "metaMask:" + (await this.ethGetAddress(this.provider));
866
+ }
867
+
868
+ public async getFirmwareVersion(): Promise<string> {
869
+ return "metaMask";
870
+ }
871
+ }