@metamask/eth-ledger-bridge-keyring 8.0.5 → 9.0.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.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [9.0.0]
11
+
12
+ ### Changed
13
+
14
+ - **BREAKING:** `LedgerKeyring` now implements the `Keyring` type ([#194](https://github.com/MetaMask/accounts/pull/194))
15
+ - The class does not extend `EventEmitter` anymore.
16
+ - The `LedgerKeyring.accounts` class variable is now a `readonly Hex[]` array.
17
+ - The `addAccounts` method signature has been changed:
18
+ - An `amount` number parameter is now required to specify the number of accounts to add.
19
+ - The method now returns a promise resolving to an array of `Hex` addresses.
20
+ - The `unlock` method now returns `Promise<Hex>`.
21
+ - The `getAccounts` method now returns `Promise<Hex[]>`.
22
+ - The `deserialize` method now requires a `LedgerKeyringSerializedState` typed parameter.
23
+ - The `signTransaction` method now accepts an `Hex` typed value as the `address` parameter.
24
+ - The `signMessage` method now accepts an `Hex` typed value as the `withAccount` parameter.
25
+ - The `signPersonalMessage` method now accepts an `Hex` typed value as the `withAccount` parameter.
26
+ - The `signTypedData` method now accepts an `Hex` typed value as the `withAccount` parameter.
27
+ - The `unlockAccountByAddress` method now accepts an `Hex` typed value as the `address` parameter.
28
+
29
+ ### Removed
30
+
31
+ - **BREAKING:** The `exportAccount` method has been removed ([#194](https://github.com/MetaMask/accounts/pull/194))
32
+
10
33
  ## [8.0.5]
11
34
 
12
35
  ### Changed
@@ -261,7 +284,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
261
284
 
262
285
  - Support new versions of ethereumjs/tx ([#68](https://github.com/MetaMask/eth-ledger-bridge-keyring/pull/68))
263
286
 
264
- [Unreleased]: https://github.com/MetaMask/accounts/compare/@metamask/eth-ledger-bridge-keyring@8.0.5...HEAD
287
+ [Unreleased]: https://github.com/MetaMask/accounts/compare/@metamask/eth-ledger-bridge-keyring@9.0.0...HEAD
288
+ [9.0.0]: https://github.com/MetaMask/accounts/compare/@metamask/eth-ledger-bridge-keyring@8.0.5...@metamask/eth-ledger-bridge-keyring@9.0.0
265
289
  [8.0.5]: https://github.com/MetaMask/accounts/compare/@metamask/eth-ledger-bridge-keyring@8.0.4...@metamask/eth-ledger-bridge-keyring@8.0.5
266
290
  [8.0.4]: https://github.com/MetaMask/accounts/compare/@metamask/eth-ledger-bridge-keyring@8.0.3...@metamask/eth-ledger-bridge-keyring@8.0.4
267
291
  [8.0.3]: https://github.com/MetaMask/accounts/compare/@metamask/eth-ledger-bridge-keyring@8.0.2...@metamask/eth-ledger-bridge-keyring@8.0.3
@@ -1,27 +1,4 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
26
3
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
27
4
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
@@ -30,15 +7,15 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
30
7
  var __importDefault = (this && this.__importDefault) || function (mod) {
31
8
  return (mod && mod.__esModule) ? mod : { "default": mod };
32
9
  };
33
- var _LedgerKeyring_instances, _LedgerKeyring_migrateAccountDetails, _LedgerKeyring_signTransaction, _LedgerKeyring_convertSaltIfAny, _LedgerKeyring_getPage, _LedgerKeyring_getAccountsBIP44, _LedgerKeyring_getAccountsLegacy, _LedgerKeyring_addressFromIndex, _LedgerKeyring_pathFromAddress, _LedgerKeyring_getPathForIndex, _LedgerKeyring_isLedgerLiveHdPath, _LedgerKeyring_toLedgerPath, _LedgerKeyring_hasPreviousTransactions, _LedgerKeyring_getApiUrl;
10
+ var _LedgerKeyring_instances, _LedgerKeyring_migrateAccountDetails, _LedgerKeyring_signTransaction, _LedgerKeyring_convertSaltIfAny, _LedgerKeyring_getPage, _LedgerKeyring_getAccountsBIP44, _LedgerKeyring_getAccountsLegacy, _LedgerKeyring_addressFromIndex, _LedgerKeyring_pathFromAddress, _LedgerKeyring_getPathForIndex, _LedgerKeyring_isLedgerLiveHdPath, _LedgerKeyring_toLedgerPath, _LedgerKeyring_hasPreviousTransactions, _LedgerKeyring_getApiUrl, _LedgerKeyring_getChecksumHexAddress;
34
11
  Object.defineProperty(exports, "__esModule", { value: true });
35
12
  exports.LedgerKeyring = void 0;
36
13
  const rlp_1 = require("@ethereumjs/rlp");
37
14
  const tx_1 = require("@ethereumjs/tx");
38
- const ethUtil = __importStar(require("@ethereumjs/util"));
15
+ const util_1 = require("@ethereumjs/util");
39
16
  const eth_sig_util_1 = require("@metamask/eth-sig-util");
17
+ const utils_1 = require("@metamask/utils");
40
18
  const buffer_1 = require("buffer");
41
- const events_1 = require("events");
42
19
  const hdkey_1 = __importDefault(require("hdkey"));
43
20
  const pathBase = 'm';
44
21
  const hdPathString = `${pathBase}/44'/60'/0'`;
@@ -68,9 +45,8 @@ var NetworkApiUrls;
68
45
  function isOldStyleEthereumjsTx(tx) {
69
46
  return 'getChainId' in tx && typeof tx.getChainId === 'function';
70
47
  }
71
- class LedgerKeyring extends events_1.EventEmitter {
48
+ class LedgerKeyring {
72
49
  constructor({ bridge }) {
73
- super();
74
50
  _LedgerKeyring_instances.add(this);
75
51
  this.deviceId = '';
76
52
  this.type = keyringType;
@@ -98,13 +74,13 @@ class LedgerKeyring extends events_1.EventEmitter {
98
74
  async serialize() {
99
75
  return {
100
76
  hdPath: this.hdPath,
101
- accounts: this.accounts,
77
+ accounts: this.accounts.slice(),
102
78
  deviceId: this.deviceId,
103
79
  accountDetails: this.accountDetails,
104
80
  implementFullBIP44: false,
105
81
  };
106
82
  }
107
- async deserialize(opts = {}) {
83
+ async deserialize(opts) {
108
84
  this.hdPath = opts.hdPath ?? hdPathString;
109
85
  this.accounts = opts.accounts ?? [];
110
86
  this.deviceId = opts.deviceId ?? '';
@@ -115,7 +91,7 @@ class LedgerKeyring extends events_1.EventEmitter {
115
91
  this.implementFullBIP44 = opts.implementFullBIP44 ?? false;
116
92
  const keys = new Set(Object.keys(this.accountDetails));
117
93
  // Remove accounts that don't have corresponding account details
118
- this.accounts = this.accounts.filter((account) => keys.has(ethUtil.toChecksumAddress(account)));
94
+ this.accounts = this.accounts.filter((account) => keys.has(__classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, account)));
119
95
  return Promise.resolve();
120
96
  }
121
97
  setDeviceId(deviceId) {
@@ -142,7 +118,10 @@ class LedgerKeyring extends events_1.EventEmitter {
142
118
  }
143
119
  async unlock(hdPath, updateHdk = true) {
144
120
  if (this.isUnlocked() && !hdPath) {
145
- return 'already unlocked';
121
+ // if the device is already unlocked and no path is provided,
122
+ // we return the checksummed address of the public key stored in
123
+ // `this.hdk`, which is the root address of the last unlocked path.
124
+ return __classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, (0, util_1.publicToAddress)(this.hdk.publicKey, true).toString('hex'));
146
125
  }
147
126
  const path = hdPath ? __classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_toLedgerPath).call(this, hdPath) : this.hdPath;
148
127
  let payload;
@@ -160,9 +139,9 @@ class LedgerKeyring extends events_1.EventEmitter {
160
139
  this.hdk.publicKey = buffer_1.Buffer.from(payload.publicKey, 'hex');
161
140
  this.hdk.chainCode = buffer_1.Buffer.from(payload.chainCode, 'hex');
162
141
  }
163
- return payload.address;
142
+ return (0, utils_1.add0x)(payload.address);
164
143
  }
165
- async addAccounts(amount = 1) {
144
+ async addAccounts(amount) {
166
145
  return new Promise((resolve, reject) => {
167
146
  this.unlock()
168
147
  .then(async (_) => {
@@ -178,7 +157,7 @@ class LedgerKeyring extends events_1.EventEmitter {
178
157
  else {
179
158
  address = __classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_addressFromIndex).call(this, pathBase, i);
180
159
  }
181
- this.accountDetails[ethUtil.toChecksumAddress(address)] = {
160
+ this.accountDetails[__classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, address)] = {
182
161
  // TODO: consider renaming this property, as the current name is misleading
183
162
  // It's currently used to represent whether an account uses the Ledger Live path.
184
163
  bip44: __classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_isLedgerLiveHdPath).call(this),
@@ -217,7 +196,7 @@ class LedgerKeyring extends events_1.EventEmitter {
217
196
  throw new Error(`Address ${address} not found in this keyring`);
218
197
  }
219
198
  this.accounts = filteredAccounts;
220
- delete this.accountDetails[ethUtil.toChecksumAddress(address)];
199
+ delete this.accountDetails[__classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, address)];
221
200
  }
222
201
  async attemptMakeApp() {
223
202
  return this.bridge.attemptMakeApp();
@@ -239,7 +218,7 @@ class LedgerKeyring extends events_1.EventEmitter {
239
218
  // value. In newer versions the chainId is communicated via the 'Common'
240
219
  // object.
241
220
  // @ts-expect-error tx.v should be a Buffer, but we are assigning a string
242
- tx.v = ethUtil.bufferToHex(tx.getChainId());
221
+ tx.v = (0, util_1.bufferToHex)(tx.getChainId());
243
222
  // @ts-expect-error tx.r should be a Buffer, but we are assigning a string
244
223
  tx.r = '0x00';
245
224
  // @ts-expect-error tx.s should be a Buffer, but we are assigning a string
@@ -271,9 +250,9 @@ class LedgerKeyring extends events_1.EventEmitter {
271
250
  // The fromTxData utility expects a type to support transactions with a type other than 0
272
251
  txData.type = tx.type;
273
252
  // The fromTxData utility expects v,r and s to be hex prefixed
274
- txData.v = ethUtil.addHexPrefix(payload.v);
275
- txData.r = ethUtil.addHexPrefix(payload.r);
276
- txData.s = ethUtil.addHexPrefix(payload.s);
253
+ txData.v = (0, utils_1.add0x)(payload.v);
254
+ txData.r = (0, utils_1.add0x)(payload.r);
255
+ txData.s = (0, utils_1.add0x)(payload.s);
277
256
  // Adopt the 'common' option from the original transaction and set the
278
257
  // returned object to be frozen if the original is frozen.
279
258
  return tx_1.TransactionFactory.fromTxData(txData, {
@@ -295,7 +274,7 @@ class LedgerKeyring extends events_1.EventEmitter {
295
274
  try {
296
275
  payload = await this.bridge.deviceSignMessage({
297
276
  hdPath,
298
- message: ethUtil.stripHexPrefix(message),
277
+ message: (0, utils_1.remove0x)(message),
299
278
  });
300
279
  }
301
280
  catch (error) {
@@ -312,14 +291,14 @@ class LedgerKeyring extends events_1.EventEmitter {
312
291
  data: message,
313
292
  signature,
314
293
  });
315
- if (ethUtil.toChecksumAddress(addressSignedWith) !==
316
- ethUtil.toChecksumAddress(withAccount)) {
294
+ if (__classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, addressSignedWith) !==
295
+ __classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, withAccount)) {
317
296
  throw new Error('Ledger: The signature doesnt match the right address');
318
297
  }
319
298
  return signature;
320
299
  }
321
300
  async unlockAccountByAddress(address) {
322
- const checksummedAddress = ethUtil.toChecksumAddress(address);
301
+ const checksummedAddress = __classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, address);
323
302
  const accountDetails = this.accountDetails[checksummedAddress];
324
303
  if (!accountDetails) {
325
304
  throw new Error(`Ledger: Account for address '${checksummedAddress}' not found`);
@@ -376,15 +355,12 @@ class LedgerKeyring extends events_1.EventEmitter {
376
355
  signature,
377
356
  version: eth_sig_util_1.SignTypedDataVersion.V4,
378
357
  });
379
- if (ethUtil.toChecksumAddress(addressSignedWith) !==
380
- ethUtil.toChecksumAddress(withAccount)) {
358
+ if (__classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, addressSignedWith) !==
359
+ __classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, withAccount)) {
381
360
  throw new Error('Ledger: The signature doesnt match the right address');
382
361
  }
383
362
  return signature;
384
363
  }
385
- exportAccount() {
386
- throw new Error('Not supported on this device');
387
- }
388
364
  forgetDevice() {
389
365
  this.deviceId = '';
390
366
  this.accounts = [];
@@ -409,7 +385,7 @@ _LedgerKeyring_instances = new WeakSet(), _LedgerKeyring_migrateAccountDetails =
409
385
  // try to migrate non-LedgerLive accounts too
410
386
  if (!__classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_isLedgerLiveHdPath).call(this)) {
411
387
  this.accounts.forEach((account) => {
412
- const key = ethUtil.toChecksumAddress(account);
388
+ const key = __classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, account);
413
389
  if (!keys.has(key)) {
414
390
  this.accountDetails[key] = {
415
391
  bip44: false,
@@ -498,17 +474,15 @@ async function _LedgerKeyring_getPage(increment) {
498
474
  balance: null,
499
475
  index: i,
500
476
  });
501
- this.paths[ethUtil.toChecksumAddress(address)] = i;
477
+ this.paths[__classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, address)] = i;
502
478
  }
503
479
  return accounts;
504
480
  }, _LedgerKeyring_addressFromIndex = function _LedgerKeyring_addressFromIndex(basePath, i) {
505
481
  const dkey = this.hdk.derive(`${basePath}/${i}`);
506
- const address = ethUtil
507
- .publicToAddress(dkey.publicKey, true)
508
- .toString('hex');
509
- return ethUtil.toChecksumAddress(`0x${address}`);
482
+ const address = (0, util_1.publicToAddress)(dkey.publicKey, true).toString('hex');
483
+ return __classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, (0, utils_1.add0x)(address));
510
484
  }, _LedgerKeyring_pathFromAddress = function _LedgerKeyring_pathFromAddress(address) {
511
- const checksummedAddress = ethUtil.toChecksumAddress(address);
485
+ const checksummedAddress = __classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, address);
512
486
  let index = this.paths[checksummedAddress];
513
487
  if (typeof index === 'undefined') {
514
488
  for (let i = 0; i < MAX_INDEX; i++) {
@@ -538,6 +512,8 @@ async function _LedgerKeyring_getPage(increment) {
538
512
  return parsedResponse.status !== '0' && parsedResponse.result.length > 0;
539
513
  }, _LedgerKeyring_getApiUrl = function _LedgerKeyring_getApiUrl() {
540
514
  return this.network;
515
+ }, _LedgerKeyring_getChecksumHexAddress = function _LedgerKeyring_getChecksumHexAddress(address) {
516
+ return (0, utils_1.getChecksumAddress)((0, utils_1.add0x)(address));
541
517
  };
542
518
  LedgerKeyring.type = keyringType;
543
519
  //# sourceMappingURL=ledger-keyring.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ledger-keyring.cjs","sourceRoot":"","sources":["../src/ledger-keyring.ts"],"names":[],"mappings":"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","sourcesContent":["import { RLP } from '@ethereumjs/rlp';\nimport { TransactionFactory, TxData, TypedTransaction } from '@ethereumjs/tx';\nimport * as ethUtil from '@ethereumjs/util';\nimport type { MessageTypes, TypedMessage } from '@metamask/eth-sig-util';\nimport {\n recoverPersonalSignature,\n recoverTypedSignature,\n SignTypedDataVersion,\n TypedDataUtils,\n} from '@metamask/eth-sig-util';\nimport { Buffer } from 'buffer';\nimport type OldEthJsTransaction from 'ethereumjs-tx';\nimport { EventEmitter } from 'events';\nimport HDKey from 'hdkey';\n\nimport { LedgerBridge, LedgerBridgeOptions } from './ledger-bridge';\nimport { LedgerIframeBridgeOptions } from './ledger-iframe-bridge';\n\nconst pathBase = 'm';\nconst hdPathString = `${pathBase}/44'/60'/0'`;\nconst keyringType = 'Ledger Hardware';\n\n// This number causes one of our failing tests to run very slowly, as the for loop needs to iterate 1000 times.\nconst MAX_INDEX = 1000;\n\nenum NetworkApiUrls {\n Ropsten = 'https://api-ropsten.etherscan.io',\n Kovan = 'https://api-kovan.etherscan.io',\n Rinkeby = 'https://api-rinkeby.etherscan.io',\n Mainnet = `https://api.etherscan.io`,\n}\n\ntype SignTransactionPayload = Awaited<\n ReturnType<LedgerBridge<LedgerIframeBridgeOptions>['deviceSignTransaction']>\n>;\n\nexport type AccountPageEntry = {\n address: string;\n balance: number | null;\n index: number;\n};\n\nexport type AccountPage = AccountPageEntry[];\n\nexport type AccountDetails = {\n index?: number;\n bip44?: boolean;\n hdPath?: string;\n};\n\nexport type LedgerBridgeKeyringOptions = {\n hdPath: string;\n accounts: readonly string[];\n deviceId: string;\n accountDetails: Readonly<Record<string, AccountDetails>>;\n accountIndexes: Readonly<Record<string, number>>;\n implementFullBIP44: boolean;\n};\n\n/**\n * Check if the given transaction is made with ethereumjs-tx or @ethereumjs/tx\n *\n * Transactions built with older versions of ethereumjs-tx have a\n * getChainId method that newer versions do not.\n * Older versions are mutable\n * while newer versions default to being immutable.\n * Expected shape and type\n * of data for v, r and s differ (Buffer (old) vs BN (new)).\n *\n * @param tx - Transaction to check, instance of either ethereumjs-tx or @ethereumjs/tx.\n * @returns Returns `true` if tx is an old-style ethereumjs-tx transaction.\n */\nfunction isOldStyleEthereumjsTx(\n tx: TypedTransaction | OldEthJsTransaction,\n): tx is OldEthJsTransaction {\n return 'getChainId' in tx && typeof tx.getChainId === 'function';\n}\n\nexport class LedgerKeyring extends EventEmitter {\n static type: string = keyringType;\n\n deviceId = '';\n\n readonly type: string = keyringType;\n\n page = 0;\n\n perPage = 5;\n\n unlockedAccount = 0;\n\n accounts: readonly string[] = [];\n\n accountDetails: Record<string, AccountDetails> = {};\n\n hdk = new HDKey();\n\n hdPath = hdPathString;\n\n paths: Record<string, number> = {};\n\n network: NetworkApiUrls = NetworkApiUrls.Mainnet;\n\n implementFullBIP44 = false;\n\n bridge: LedgerBridge<LedgerBridgeOptions>;\n\n constructor({ bridge }: { bridge: LedgerBridge<LedgerBridgeOptions> }) {\n super();\n\n if (!bridge) {\n throw new Error('Bridge is a required dependency for the keyring');\n }\n\n this.bridge = bridge;\n }\n\n async init(): Promise<void> {\n return this.bridge.init();\n }\n\n async destroy(): Promise<void> {\n return this.bridge.destroy();\n }\n\n async serialize(): Promise<\n Partial<LedgerBridgeKeyringOptions> // Maybe we should have a proper \"state\" type here instead of using this \"options\" type.\n > {\n return {\n hdPath: this.hdPath,\n accounts: this.accounts,\n deviceId: this.deviceId,\n accountDetails: this.accountDetails,\n implementFullBIP44: false,\n };\n }\n\n async deserialize(\n opts: Partial<LedgerBridgeKeyringOptions> = {}, // Same question here?\n ): Promise<void> {\n this.hdPath = opts.hdPath ?? hdPathString;\n this.accounts = opts.accounts ?? [];\n this.deviceId = opts.deviceId ?? '';\n this.accountDetails = opts.accountDetails ?? {};\n\n if (!opts.accountDetails) {\n this.#migrateAccountDetails(opts);\n }\n\n this.implementFullBIP44 = opts.implementFullBIP44 ?? false;\n\n const keys = new Set<string>(Object.keys(this.accountDetails));\n // Remove accounts that don't have corresponding account details\n this.accounts = this.accounts.filter((account) =>\n keys.has(ethUtil.toChecksumAddress(account)),\n );\n\n return Promise.resolve();\n }\n\n public setDeviceId(deviceId: string): void {\n this.deviceId = deviceId;\n }\n\n public getDeviceId(): string {\n return this.deviceId;\n }\n\n #migrateAccountDetails(opts: Partial<LedgerBridgeKeyringOptions>): void {\n if (this.#isLedgerLiveHdPath() && opts.accountIndexes) {\n for (const [account, index] of Object.entries(opts.accountIndexes)) {\n this.accountDetails[account] = {\n bip44: true,\n hdPath: this.#getPathForIndex(index),\n };\n }\n }\n const keys = new Set<string>(Object.keys(this.accountDetails));\n // try to migrate non-LedgerLive accounts too\n if (!this.#isLedgerLiveHdPath()) {\n this.accounts.forEach((account) => {\n const key = ethUtil.toChecksumAddress(account);\n\n if (!keys.has(key)) {\n this.accountDetails[key] = {\n bip44: false,\n hdPath: this.#pathFromAddress(account),\n };\n }\n });\n }\n }\n\n isUnlocked(): boolean {\n return Boolean(this.hdk.publicKey);\n }\n\n isConnected(): boolean {\n return this.bridge.isDeviceConnected;\n }\n\n setAccountToUnlock(index: number): void {\n this.unlockedAccount = index;\n }\n\n setHdPath(hdPath: string): void {\n // Reset HDKey if the path changes\n if (this.hdPath !== hdPath) {\n this.hdk = new HDKey();\n }\n this.hdPath = hdPath;\n }\n\n async unlock(hdPath?: string, updateHdk = true): Promise<string> {\n if (this.isUnlocked() && !hdPath) {\n return 'already unlocked';\n }\n const path = hdPath ? this.#toLedgerPath(hdPath) : this.hdPath;\n\n let payload;\n try {\n payload = await this.bridge.getPublicKey({\n hdPath: path,\n });\n } catch (error) {\n throw error instanceof Error\n ? error\n : new Error('Ledger Ethereum app closed. Open it to unlock.');\n }\n\n if (updateHdk && payload.chainCode) {\n this.hdk.publicKey = Buffer.from(payload.publicKey, 'hex');\n this.hdk.chainCode = Buffer.from(payload.chainCode, 'hex');\n }\n\n return payload.address;\n }\n\n async addAccounts(amount = 1): Promise<string[]> {\n return new Promise((resolve, reject) => {\n this.unlock()\n .then(async (_) => {\n const from = this.unlockedAccount;\n const to = from + amount;\n const newAccounts: string[] = [];\n for (let i = from; i < to; i++) {\n const path = this.#getPathForIndex(i);\n let address;\n if (this.#isLedgerLiveHdPath()) {\n address = await this.unlock(path);\n } else {\n address = this.#addressFromIndex(pathBase, i);\n }\n\n this.accountDetails[ethUtil.toChecksumAddress(address)] = {\n // TODO: consider renaming this property, as the current name is misleading\n // It's currently used to represent whether an account uses the Ledger Live path.\n bip44: this.#isLedgerLiveHdPath(),\n hdPath: path,\n };\n\n if (!this.accounts.includes(address)) {\n this.accounts = [...this.accounts, address];\n newAccounts.push(address);\n }\n this.page = 0;\n }\n resolve(newAccounts);\n })\n .catch(reject);\n });\n }\n\n getName(): string {\n return keyringType;\n }\n\n async getFirstPage(): Promise<AccountPage> {\n this.page = 0;\n return this.#getPage(1);\n }\n\n async getNextPage(): Promise<AccountPage> {\n return this.#getPage(1);\n }\n\n async getPreviousPage(): Promise<AccountPage> {\n return this.#getPage(-1);\n }\n\n async getAccounts(): Promise<string[]> {\n return Promise.resolve(this.accounts.slice());\n }\n\n removeAccount(address: string): void {\n const filteredAccounts = this.accounts.filter(\n (a) => a.toLowerCase() !== address.toLowerCase(),\n );\n\n if (filteredAccounts.length === this.accounts.length) {\n throw new Error(`Address ${address} not found in this keyring`);\n }\n\n this.accounts = filteredAccounts;\n delete this.accountDetails[ethUtil.toChecksumAddress(address)];\n }\n\n async attemptMakeApp(): Promise<boolean> {\n return this.bridge.attemptMakeApp();\n }\n\n async updateTransportMethod(transportType: string): Promise<boolean> {\n return this.bridge.updateTransportMethod(transportType);\n }\n\n // tx is an instance of the ethereumjs-transaction class.\n async signTransaction(\n address: string,\n tx: TypedTransaction | OldEthJsTransaction,\n ): Promise<TypedTransaction | OldEthJsTransaction> {\n let rawTxHex;\n // transactions built with older versions of ethereumjs-tx have a\n // getChainId method that newer versions do not. Older versions are mutable\n // while newer versions default to being immutable. Expected shape and type\n // of data for v, r and s differ (Buffer (old) vs BN (new))\n if (isOldStyleEthereumjsTx(tx)) {\n // In this version of ethereumjs-tx we must add the chainId in hex format\n // to the initial v value. The chainId must be included in the serialized\n // transaction which is only communicated to ethereumjs-tx in this\n // value. In newer versions the chainId is communicated via the 'Common'\n // object.\n // @ts-expect-error tx.v should be a Buffer, but we are assigning a string\n tx.v = ethUtil.bufferToHex(tx.getChainId());\n // @ts-expect-error tx.r should be a Buffer, but we are assigning a string\n tx.r = '0x00';\n // @ts-expect-error tx.s should be a Buffer, but we are assigning a string\n tx.s = '0x00';\n\n rawTxHex = tx.serialize().toString('hex');\n\n return this.#signTransaction(address, rawTxHex, (payload) => {\n tx.v = Buffer.from(payload.v, 'hex');\n tx.r = Buffer.from(payload.r, 'hex');\n tx.s = Buffer.from(payload.s, 'hex');\n return tx;\n });\n }\n\n // The below `encode` call is only necessary for legacy transactions, as `getMessageToSign`\n // calls `rlp.encode` internally for non-legacy transactions. As per the \"Transaction Execution\"\n // section of the ethereum yellow paper, transactions need to be \"well-formed RLP, with no additional\n // trailing bytes\".\n\n // Note also that `getMessageToSign` will return valid RLP for all transaction types, whereas the\n // `serialize` method will not for any transaction type except legacy. This is because `serialize` includes\n // empty r, s and v values in the encoded rlp. This is why we use `getMessageToSign` here instead of `serialize`.\n const messageToSign = tx.getMessageToSign(false);\n\n rawTxHex = Buffer.isBuffer(messageToSign)\n ? messageToSign.toString('hex')\n : Buffer.from(RLP.encode(messageToSign)).toString('hex');\n\n return this.#signTransaction(address, rawTxHex, (payload) => {\n // Because tx will be immutable, first get a plain javascript object that\n // represents the transaction. Using txData here as it aligns with the\n // nomenclature of ethereumjs/tx.\n const txData: TxData = tx.toJSON();\n // The fromTxData utility expects a type to support transactions with a type other than 0\n txData.type = tx.type;\n // The fromTxData utility expects v,r and s to be hex prefixed\n txData.v = ethUtil.addHexPrefix(payload.v);\n txData.r = ethUtil.addHexPrefix(payload.r);\n txData.s = ethUtil.addHexPrefix(payload.s);\n // Adopt the 'common' option from the original transaction and set the\n // returned object to be frozen if the original is frozen.\n return TransactionFactory.fromTxData(txData, {\n common: tx.common,\n freeze: Object.isFrozen(tx),\n });\n });\n }\n\n async #signTransaction(\n address: string,\n rawTxHex: string,\n handleSigning: (\n payload: SignTransactionPayload,\n ) => TypedTransaction | OldEthJsTransaction,\n ): Promise<TypedTransaction | OldEthJsTransaction> {\n const hdPath = await this.unlockAccountByAddress(address);\n\n if (!hdPath) {\n throw new Error('Ledger: Unknown error while signing transaction');\n }\n\n let payload;\n try {\n payload = await this.bridge.deviceSignTransaction({\n tx: rawTxHex,\n hdPath,\n });\n } catch (error) {\n throw error instanceof Error\n ? error\n : new Error('Ledger: Unknown error while signing transaction');\n }\n\n const newOrMutatedTx = handleSigning(payload);\n const valid = newOrMutatedTx.verifySignature();\n if (valid) {\n return newOrMutatedTx;\n }\n throw new Error('Ledger: The transaction signature is not valid');\n }\n\n async signMessage(withAccount: string, data: string): Promise<string> {\n return this.signPersonalMessage(withAccount, data);\n }\n\n // For personal_sign, we need to prefix the message:\n async signPersonalMessage(\n withAccount: string,\n message: string,\n ): Promise<string> {\n const hdPath = await this.unlockAccountByAddress(withAccount);\n\n if (!hdPath) {\n throw new Error('Ledger: Unknown error while signing message');\n }\n\n let payload;\n try {\n payload = await this.bridge.deviceSignMessage({\n hdPath,\n message: ethUtil.stripHexPrefix(message),\n });\n } catch (error) {\n throw error instanceof Error\n ? error\n : new Error('Ledger: Unknown error while signing message');\n }\n\n let modifiedV = parseInt(String(payload.v), 10).toString(16);\n if (modifiedV.length < 2) {\n modifiedV = `0${modifiedV}`;\n }\n\n const signature = `0x${payload.r}${payload.s}${modifiedV}`;\n const addressSignedWith = recoverPersonalSignature({\n data: message,\n signature,\n });\n if (\n ethUtil.toChecksumAddress(addressSignedWith) !==\n ethUtil.toChecksumAddress(withAccount)\n ) {\n throw new Error('Ledger: The signature doesnt match the right address');\n }\n return signature;\n }\n\n async unlockAccountByAddress(address: string): Promise<string | undefined> {\n const checksummedAddress = ethUtil.toChecksumAddress(address);\n const accountDetails = this.accountDetails[checksummedAddress];\n if (!accountDetails) {\n throw new Error(\n `Ledger: Account for address '${checksummedAddress}' not found`,\n );\n }\n const { hdPath } = accountDetails;\n const unlockedAddress = await this.unlock(hdPath, false);\n\n // unlock resolves to the address for the given hdPath as reported by the ledger device\n // if that address is not the requested address, then this account belongs to a different device or seed\n if (unlockedAddress.toLowerCase() !== address.toLowerCase()) {\n throw new Error(\n `Ledger: Account ${address} does not belong to the connected device`,\n );\n }\n return hdPath;\n }\n\n async signTypedData<T extends MessageTypes>(\n withAccount: string,\n data: TypedMessage<T>,\n options: { version?: string } = {},\n ): Promise<string> {\n const isV4 = options.version === 'V4';\n if (!isV4) {\n throw new Error(\n 'Ledger: Only version 4 of typed data signing is supported',\n );\n }\n\n const { domain, types, primaryType, message } =\n TypedDataUtils.sanitizeData(data);\n\n const hdPath = await this.unlockAccountByAddress(withAccount);\n\n if (!hdPath) {\n throw new Error('Ledger: Unknown error while signing message');\n }\n\n let payload;\n try {\n payload = await this.bridge.deviceSignTypedData({\n hdPath,\n message: {\n domain: {\n name: domain.name,\n chainId: domain.chainId,\n version: domain.version,\n verifyingContract: domain.verifyingContract,\n salt: this.#convertSaltIfAny(domain.salt),\n },\n types,\n primaryType: primaryType.toString(),\n message,\n },\n });\n } catch (error) {\n throw error instanceof Error\n ? error\n : new Error('Ledger: Unknown error while signing message');\n }\n\n let recoveryId = parseInt(String(payload.v), 10).toString(16);\n if (recoveryId.length < 2) {\n recoveryId = `0${recoveryId}`;\n }\n const signature = `0x${payload.r}${payload.s}${recoveryId}`;\n const addressSignedWith = recoverTypedSignature({\n data,\n signature,\n version: SignTypedDataVersion.V4,\n });\n\n if (\n ethUtil.toChecksumAddress(addressSignedWith) !==\n ethUtil.toChecksumAddress(withAccount)\n ) {\n throw new Error('Ledger: The signature doesnt match the right address');\n }\n return signature;\n }\n\n exportAccount(): void {\n throw new Error('Not supported on this device');\n }\n\n forgetDevice(): void {\n this.deviceId = '';\n this.accounts = [];\n this.page = 0;\n this.unlockedAccount = 0;\n this.paths = {};\n this.accountDetails = {};\n this.hdk = new HDKey();\n }\n\n #convertSaltIfAny(salt: ArrayBuffer | undefined): string | undefined {\n if (!salt) {\n return undefined;\n }\n\n // We convert this to a plain string to avoid encoding issue on the\n // mobile side (to avoid using `TextDecoder`).\n const saltBytes = new Uint8Array(salt);\n return String.fromCharCode(...saltBytes);\n }\n\n /* PRIVATE METHODS */\n async #getPage(increment: number): Promise<AccountPage> {\n this.page += increment;\n\n if (this.page <= 0) {\n this.page = 1;\n }\n const from = (this.page - 1) * this.perPage;\n const to = from + this.perPage;\n\n await this.unlock();\n let accounts;\n if (this.#isLedgerLiveHdPath()) {\n accounts = await this.#getAccountsBIP44(from, to);\n } else {\n accounts = this.#getAccountsLegacy(from, to);\n }\n return accounts;\n }\n\n async #getAccountsBIP44(from: number, to: number): Promise<AccountPage> {\n const accounts: AccountPage = [];\n\n for (let i = from; i < to; i++) {\n const path = this.#getPathForIndex(i);\n const address = await this.unlock(path);\n const valid = this.implementFullBIP44\n ? await this.#hasPreviousTransactions(address)\n : true;\n accounts.push({\n address,\n balance: null,\n index: i,\n });\n\n // PER BIP44\n // \"Software should prevent a creation of an account if\n // a previous account does not have a transaction history\n // (meaning none of its addresses have been used before).\"\n if (!valid) {\n break;\n }\n }\n return accounts;\n }\n\n #getAccountsLegacy(from: number, to: number): AccountPage {\n const accounts: AccountPage = [];\n\n for (let i = from; i < to; i++) {\n const address = this.#addressFromIndex(pathBase, i);\n accounts.push({\n address,\n balance: null,\n index: i,\n });\n this.paths[ethUtil.toChecksumAddress(address)] = i;\n }\n return accounts;\n }\n\n #addressFromIndex(basePath: string, i: number): string {\n const dkey = this.hdk.derive(`${basePath}/${i}`);\n const address = ethUtil\n .publicToAddress(dkey.publicKey, true)\n .toString('hex');\n return ethUtil.toChecksumAddress(`0x${address}`);\n }\n\n #pathFromAddress(address: string): string {\n const checksummedAddress = ethUtil.toChecksumAddress(address);\n let index = this.paths[checksummedAddress];\n if (typeof index === 'undefined') {\n for (let i = 0; i < MAX_INDEX; i++) {\n if (checksummedAddress === this.#addressFromIndex(pathBase, i)) {\n index = i;\n break;\n }\n }\n }\n\n if (typeof index === 'undefined') {\n throw new Error('Unknown address');\n }\n return this.#getPathForIndex(index);\n }\n\n #getPathForIndex(index: number): string {\n // Check if the path is BIP 44 (Ledger Live)\n return this.#isLedgerLiveHdPath()\n ? `m/44'/60'/${index}'/0/0`\n : `${this.hdPath}/${index}`;\n }\n\n #isLedgerLiveHdPath(): boolean {\n return this.hdPath === `m/44'/60'/0'/0/0`;\n }\n\n #toLedgerPath(path: string): string {\n return path.toString().replace('m/', '');\n }\n\n async #hasPreviousTransactions(address: string): Promise<boolean> {\n const apiUrl = this.#getApiUrl();\n const response = await window.fetch(\n `${apiUrl}/api?module=account&action=txlist&address=${address}&tag=latest&page=1&offset=1`,\n );\n const parsedResponse = await response.json();\n return parsedResponse.status !== '0' && parsedResponse.result.length > 0;\n }\n\n #getApiUrl(): NetworkApiUrls {\n return this.network;\n }\n}\n"]}
1
+ {"version":3,"file":"ledger-keyring.cjs","sourceRoot":"","sources":["../src/ledger-keyring.ts"],"names":[],"mappings":"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","sourcesContent":["import { RLP } from '@ethereumjs/rlp';\nimport { TransactionFactory, TxData, TypedTransaction } from '@ethereumjs/tx';\nimport { bufferToHex, publicToAddress } from '@ethereumjs/util';\nimport type { MessageTypes, TypedMessage } from '@metamask/eth-sig-util';\nimport {\n recoverPersonalSignature,\n recoverTypedSignature,\n SignTypedDataVersion,\n TypedDataUtils,\n} from '@metamask/eth-sig-util';\nimport type { Keyring } from '@metamask/keyring-utils';\nimport { add0x, getChecksumAddress, Hex, remove0x } from '@metamask/utils';\nimport { Buffer } from 'buffer';\nimport type OldEthJsTransaction from 'ethereumjs-tx';\nimport HDKey from 'hdkey';\n\nimport { LedgerBridge, LedgerBridgeOptions } from './ledger-bridge';\nimport { LedgerIframeBridgeOptions } from './ledger-iframe-bridge';\n\nconst pathBase = 'm';\nconst hdPathString = `${pathBase}/44'/60'/0'`;\nconst keyringType = 'Ledger Hardware';\n\n// This number causes one of our failing tests to run very slowly, as the for loop needs to iterate 1000 times.\nconst MAX_INDEX = 1000;\n\nenum NetworkApiUrls {\n Ropsten = 'https://api-ropsten.etherscan.io',\n Kovan = 'https://api-kovan.etherscan.io',\n Rinkeby = 'https://api-rinkeby.etherscan.io',\n Mainnet = `https://api.etherscan.io`,\n}\n\ntype SignTransactionPayload = Awaited<\n ReturnType<LedgerBridge<LedgerIframeBridgeOptions>['deviceSignTransaction']>\n>;\n\nexport type AccountPageEntry = {\n address: string;\n balance: number | null;\n index: number;\n};\n\nexport type AccountPage = AccountPageEntry[];\n\nexport type AccountDetails = {\n index?: number;\n bip44?: boolean;\n hdPath?: string;\n};\n\nexport type LedgerBridgeKeyringOptions = {\n hdPath: string;\n accounts: Hex[];\n deviceId: string;\n accountDetails: Readonly<Record<Hex, AccountDetails>>;\n accountIndexes: Readonly<Record<Hex, number>>;\n implementFullBIP44: boolean;\n};\n\nexport type LedgerKeyringSerializedState = Partial<LedgerBridgeKeyringOptions>;\n\n/**\n * Check if the given transaction is made with ethereumjs-tx or @ethereumjs/tx\n *\n * Transactions built with older versions of ethereumjs-tx have a\n * getChainId method that newer versions do not.\n * Older versions are mutable\n * while newer versions default to being immutable.\n * Expected shape and type\n * of data for v, r and s differ (Buffer (old) vs BN (new)).\n *\n * @param tx - Transaction to check, instance of either ethereumjs-tx or @ethereumjs/tx.\n * @returns Returns `true` if tx is an old-style ethereumjs-tx transaction.\n */\nfunction isOldStyleEthereumjsTx(\n tx: TypedTransaction | OldEthJsTransaction,\n): tx is OldEthJsTransaction {\n return 'getChainId' in tx && typeof tx.getChainId === 'function';\n}\n\nexport class LedgerKeyring implements Keyring {\n static type: string = keyringType;\n\n deviceId = '';\n\n readonly type: string = keyringType;\n\n page = 0;\n\n perPage = 5;\n\n unlockedAccount = 0;\n\n accounts: readonly Hex[] = [];\n\n accountDetails: Record<string, AccountDetails> = {};\n\n hdk = new HDKey();\n\n hdPath = hdPathString;\n\n paths: Record<string, number> = {};\n\n network: NetworkApiUrls = NetworkApiUrls.Mainnet;\n\n implementFullBIP44 = false;\n\n bridge: LedgerBridge<LedgerBridgeOptions>;\n\n constructor({ bridge }: { bridge: LedgerBridge<LedgerBridgeOptions> }) {\n if (!bridge) {\n throw new Error('Bridge is a required dependency for the keyring');\n }\n\n this.bridge = bridge;\n }\n\n async init(): Promise<void> {\n return this.bridge.init();\n }\n\n async destroy(): Promise<void> {\n return this.bridge.destroy();\n }\n\n async serialize(): Promise<\n Omit<LedgerKeyringSerializedState, 'accountIndexes'>\n > {\n return {\n hdPath: this.hdPath,\n accounts: this.accounts.slice(),\n deviceId: this.deviceId,\n accountDetails: this.accountDetails,\n implementFullBIP44: false,\n };\n }\n\n async deserialize(opts: LedgerKeyringSerializedState): Promise<void> {\n this.hdPath = opts.hdPath ?? hdPathString;\n this.accounts = opts.accounts ?? [];\n this.deviceId = opts.deviceId ?? '';\n this.accountDetails = opts.accountDetails ?? {};\n\n if (!opts.accountDetails) {\n this.#migrateAccountDetails(opts);\n }\n\n this.implementFullBIP44 = opts.implementFullBIP44 ?? false;\n\n const keys = new Set<string>(Object.keys(this.accountDetails));\n // Remove accounts that don't have corresponding account details\n this.accounts = this.accounts.filter((account) =>\n keys.has(this.#getChecksumHexAddress(account)),\n );\n\n return Promise.resolve();\n }\n\n public setDeviceId(deviceId: string): void {\n this.deviceId = deviceId;\n }\n\n public getDeviceId(): string {\n return this.deviceId;\n }\n\n #migrateAccountDetails(opts: Partial<LedgerBridgeKeyringOptions>): void {\n if (this.#isLedgerLiveHdPath() && opts.accountIndexes) {\n for (const [account, index] of Object.entries(opts.accountIndexes)) {\n this.accountDetails[account] = {\n bip44: true,\n hdPath: this.#getPathForIndex(index),\n };\n }\n }\n const keys = new Set<string>(Object.keys(this.accountDetails));\n // try to migrate non-LedgerLive accounts too\n if (!this.#isLedgerLiveHdPath()) {\n this.accounts.forEach((account) => {\n const key = this.#getChecksumHexAddress(account);\n\n if (!keys.has(key)) {\n this.accountDetails[key] = {\n bip44: false,\n hdPath: this.#pathFromAddress(account),\n };\n }\n });\n }\n }\n\n isUnlocked(): boolean {\n return Boolean(this.hdk.publicKey);\n }\n\n isConnected(): boolean {\n return this.bridge.isDeviceConnected;\n }\n\n setAccountToUnlock(index: number): void {\n this.unlockedAccount = index;\n }\n\n setHdPath(hdPath: string): void {\n // Reset HDKey if the path changes\n if (this.hdPath !== hdPath) {\n this.hdk = new HDKey();\n }\n this.hdPath = hdPath;\n }\n\n async unlock(hdPath?: string, updateHdk = true): Promise<Hex> {\n if (this.isUnlocked() && !hdPath) {\n // if the device is already unlocked and no path is provided,\n // we return the checksummed address of the public key stored in\n // `this.hdk`, which is the root address of the last unlocked path.\n return this.#getChecksumHexAddress(\n publicToAddress(this.hdk.publicKey, true).toString('hex'),\n );\n }\n const path = hdPath ? this.#toLedgerPath(hdPath) : this.hdPath;\n\n let payload;\n try {\n payload = await this.bridge.getPublicKey({\n hdPath: path,\n });\n } catch (error) {\n throw error instanceof Error\n ? error\n : new Error('Ledger Ethereum app closed. Open it to unlock.');\n }\n\n if (updateHdk && payload.chainCode) {\n this.hdk.publicKey = Buffer.from(payload.publicKey, 'hex');\n this.hdk.chainCode = Buffer.from(payload.chainCode, 'hex');\n }\n\n return add0x(payload.address);\n }\n\n async addAccounts(amount: number): Promise<Hex[]> {\n return new Promise((resolve, reject) => {\n this.unlock()\n .then(async (_) => {\n const from = this.unlockedAccount;\n const to = from + amount;\n const newAccounts: Hex[] = [];\n for (let i = from; i < to; i++) {\n const path = this.#getPathForIndex(i);\n let address: Hex;\n if (this.#isLedgerLiveHdPath()) {\n address = await this.unlock(path);\n } else {\n address = this.#addressFromIndex(pathBase, i);\n }\n\n this.accountDetails[this.#getChecksumHexAddress(address)] = {\n // TODO: consider renaming this property, as the current name is misleading\n // It's currently used to represent whether an account uses the Ledger Live path.\n bip44: this.#isLedgerLiveHdPath(),\n hdPath: path,\n };\n\n if (!this.accounts.includes(address)) {\n this.accounts = [...this.accounts, address];\n newAccounts.push(address);\n }\n this.page = 0;\n }\n resolve(newAccounts);\n })\n .catch(reject);\n });\n }\n\n getName(): string {\n return keyringType;\n }\n\n async getFirstPage(): Promise<AccountPage> {\n this.page = 0;\n return this.#getPage(1);\n }\n\n async getNextPage(): Promise<AccountPage> {\n return this.#getPage(1);\n }\n\n async getPreviousPage(): Promise<AccountPage> {\n return this.#getPage(-1);\n }\n\n async getAccounts(): Promise<Hex[]> {\n return Promise.resolve(this.accounts.slice());\n }\n\n removeAccount(address: string): void {\n const filteredAccounts = this.accounts.filter(\n (a) => a.toLowerCase() !== address.toLowerCase(),\n );\n\n if (filteredAccounts.length === this.accounts.length) {\n throw new Error(`Address ${address} not found in this keyring`);\n }\n\n this.accounts = filteredAccounts;\n delete this.accountDetails[this.#getChecksumHexAddress(address)];\n }\n\n async attemptMakeApp(): Promise<boolean> {\n return this.bridge.attemptMakeApp();\n }\n\n async updateTransportMethod(transportType: string): Promise<boolean> {\n return this.bridge.updateTransportMethod(transportType);\n }\n\n // tx is an instance of the ethereumjs-transaction class.\n async signTransaction(\n address: Hex,\n tx: TypedTransaction | OldEthJsTransaction,\n ): Promise<TypedTransaction | OldEthJsTransaction> {\n let rawTxHex;\n // transactions built with older versions of ethereumjs-tx have a\n // getChainId method that newer versions do not. Older versions are mutable\n // while newer versions default to being immutable. Expected shape and type\n // of data for v, r and s differ (Buffer (old) vs BN (new))\n if (isOldStyleEthereumjsTx(tx)) {\n // In this version of ethereumjs-tx we must add the chainId in hex format\n // to the initial v value. The chainId must be included in the serialized\n // transaction which is only communicated to ethereumjs-tx in this\n // value. In newer versions the chainId is communicated via the 'Common'\n // object.\n // @ts-expect-error tx.v should be a Buffer, but we are assigning a string\n tx.v = bufferToHex(tx.getChainId());\n // @ts-expect-error tx.r should be a Buffer, but we are assigning a string\n tx.r = '0x00';\n // @ts-expect-error tx.s should be a Buffer, but we are assigning a string\n tx.s = '0x00';\n\n rawTxHex = tx.serialize().toString('hex');\n\n return this.#signTransaction(address, rawTxHex, (payload) => {\n tx.v = Buffer.from(payload.v, 'hex');\n tx.r = Buffer.from(payload.r, 'hex');\n tx.s = Buffer.from(payload.s, 'hex');\n return tx;\n });\n }\n\n // The below `encode` call is only necessary for legacy transactions, as `getMessageToSign`\n // calls `rlp.encode` internally for non-legacy transactions. As per the \"Transaction Execution\"\n // section of the ethereum yellow paper, transactions need to be \"well-formed RLP, with no additional\n // trailing bytes\".\n\n // Note also that `getMessageToSign` will return valid RLP for all transaction types, whereas the\n // `serialize` method will not for any transaction type except legacy. This is because `serialize` includes\n // empty r, s and v values in the encoded rlp. This is why we use `getMessageToSign` here instead of `serialize`.\n const messageToSign = tx.getMessageToSign(false);\n\n rawTxHex = Buffer.isBuffer(messageToSign)\n ? messageToSign.toString('hex')\n : Buffer.from(RLP.encode(messageToSign)).toString('hex');\n\n return this.#signTransaction(address, rawTxHex, (payload) => {\n // Because tx will be immutable, first get a plain javascript object that\n // represents the transaction. Using txData here as it aligns with the\n // nomenclature of ethereumjs/tx.\n const txData: TxData = tx.toJSON();\n // The fromTxData utility expects a type to support transactions with a type other than 0\n txData.type = tx.type;\n // The fromTxData utility expects v,r and s to be hex prefixed\n txData.v = add0x(payload.v);\n txData.r = add0x(payload.r);\n txData.s = add0x(payload.s);\n // Adopt the 'common' option from the original transaction and set the\n // returned object to be frozen if the original is frozen.\n return TransactionFactory.fromTxData(txData, {\n common: tx.common,\n freeze: Object.isFrozen(tx),\n });\n });\n }\n\n async #signTransaction(\n address: Hex,\n rawTxHex: string,\n handleSigning: (\n payload: SignTransactionPayload,\n ) => TypedTransaction | OldEthJsTransaction,\n ): Promise<TypedTransaction | OldEthJsTransaction> {\n const hdPath = await this.unlockAccountByAddress(address);\n\n if (!hdPath) {\n throw new Error('Ledger: Unknown error while signing transaction');\n }\n\n let payload;\n try {\n payload = await this.bridge.deviceSignTransaction({\n tx: rawTxHex,\n hdPath,\n });\n } catch (error) {\n throw error instanceof Error\n ? error\n : new Error('Ledger: Unknown error while signing transaction');\n }\n\n const newOrMutatedTx = handleSigning(payload);\n const valid = newOrMutatedTx.verifySignature();\n if (valid) {\n return newOrMutatedTx;\n }\n throw new Error('Ledger: The transaction signature is not valid');\n }\n\n async signMessage(withAccount: Hex, data: string): Promise<string> {\n return this.signPersonalMessage(withAccount, data);\n }\n\n // For personal_sign, we need to prefix the message:\n async signPersonalMessage(\n withAccount: Hex,\n message: string,\n ): Promise<string> {\n const hdPath = await this.unlockAccountByAddress(withAccount);\n\n if (!hdPath) {\n throw new Error('Ledger: Unknown error while signing message');\n }\n\n let payload;\n try {\n payload = await this.bridge.deviceSignMessage({\n hdPath,\n message: remove0x(message),\n });\n } catch (error) {\n throw error instanceof Error\n ? error\n : new Error('Ledger: Unknown error while signing message');\n }\n\n let modifiedV = parseInt(String(payload.v), 10).toString(16);\n if (modifiedV.length < 2) {\n modifiedV = `0${modifiedV}`;\n }\n\n const signature = `0x${payload.r}${payload.s}${modifiedV}`;\n const addressSignedWith = recoverPersonalSignature({\n data: message,\n signature,\n });\n if (\n this.#getChecksumHexAddress(addressSignedWith) !==\n this.#getChecksumHexAddress(withAccount)\n ) {\n throw new Error('Ledger: The signature doesnt match the right address');\n }\n return signature;\n }\n\n async unlockAccountByAddress(address: Hex): Promise<string | undefined> {\n const checksummedAddress = this.#getChecksumHexAddress(address);\n const accountDetails = this.accountDetails[checksummedAddress];\n if (!accountDetails) {\n throw new Error(\n `Ledger: Account for address '${checksummedAddress}' not found`,\n );\n }\n const { hdPath } = accountDetails;\n const unlockedAddress = await this.unlock(hdPath, false);\n\n // unlock resolves to the address for the given hdPath as reported by the ledger device\n // if that address is not the requested address, then this account belongs to a different device or seed\n if (unlockedAddress.toLowerCase() !== address.toLowerCase()) {\n throw new Error(\n `Ledger: Account ${address} does not belong to the connected device`,\n );\n }\n return hdPath;\n }\n\n async signTypedData<T extends MessageTypes>(\n withAccount: Hex,\n data: TypedMessage<T>,\n options: { version?: string } = {},\n ): Promise<string> {\n const isV4 = options.version === 'V4';\n if (!isV4) {\n throw new Error(\n 'Ledger: Only version 4 of typed data signing is supported',\n );\n }\n\n const { domain, types, primaryType, message } =\n TypedDataUtils.sanitizeData(data);\n\n const hdPath = await this.unlockAccountByAddress(withAccount);\n\n if (!hdPath) {\n throw new Error('Ledger: Unknown error while signing message');\n }\n\n let payload;\n try {\n payload = await this.bridge.deviceSignTypedData({\n hdPath,\n message: {\n domain: {\n name: domain.name,\n chainId: domain.chainId,\n version: domain.version,\n verifyingContract: domain.verifyingContract,\n salt: this.#convertSaltIfAny(domain.salt),\n },\n types,\n primaryType: primaryType.toString(),\n message,\n },\n });\n } catch (error) {\n throw error instanceof Error\n ? error\n : new Error('Ledger: Unknown error while signing message');\n }\n\n let recoveryId = parseInt(String(payload.v), 10).toString(16);\n if (recoveryId.length < 2) {\n recoveryId = `0${recoveryId}`;\n }\n const signature = `0x${payload.r}${payload.s}${recoveryId}`;\n const addressSignedWith = recoverTypedSignature({\n data,\n signature,\n version: SignTypedDataVersion.V4,\n });\n\n if (\n this.#getChecksumHexAddress(addressSignedWith) !==\n this.#getChecksumHexAddress(withAccount)\n ) {\n throw new Error('Ledger: The signature doesnt match the right address');\n }\n return signature;\n }\n\n forgetDevice(): void {\n this.deviceId = '';\n this.accounts = [];\n this.page = 0;\n this.unlockedAccount = 0;\n this.paths = {};\n this.accountDetails = {};\n this.hdk = new HDKey();\n }\n\n #convertSaltIfAny(salt: ArrayBuffer | undefined): string | undefined {\n if (!salt) {\n return undefined;\n }\n\n // We convert this to a plain string to avoid encoding issue on the\n // mobile side (to avoid using `TextDecoder`).\n const saltBytes = new Uint8Array(salt);\n return String.fromCharCode(...saltBytes);\n }\n\n /* PRIVATE METHODS */\n async #getPage(increment: number): Promise<AccountPage> {\n this.page += increment;\n\n if (this.page <= 0) {\n this.page = 1;\n }\n const from = (this.page - 1) * this.perPage;\n const to = from + this.perPage;\n\n await this.unlock();\n let accounts;\n if (this.#isLedgerLiveHdPath()) {\n accounts = await this.#getAccountsBIP44(from, to);\n } else {\n accounts = this.#getAccountsLegacy(from, to);\n }\n return accounts;\n }\n\n async #getAccountsBIP44(from: number, to: number): Promise<AccountPage> {\n const accounts: AccountPage = [];\n\n for (let i = from; i < to; i++) {\n const path = this.#getPathForIndex(i);\n const address = await this.unlock(path);\n const valid = this.implementFullBIP44\n ? await this.#hasPreviousTransactions(address)\n : true;\n accounts.push({\n address,\n balance: null,\n index: i,\n });\n\n // PER BIP44\n // \"Software should prevent a creation of an account if\n // a previous account does not have a transaction history\n // (meaning none of its addresses have been used before).\"\n if (!valid) {\n break;\n }\n }\n return accounts;\n }\n\n #getAccountsLegacy(from: number, to: number): AccountPage {\n const accounts: AccountPage = [];\n\n for (let i = from; i < to; i++) {\n const address = this.#addressFromIndex(pathBase, i);\n accounts.push({\n address,\n balance: null,\n index: i,\n });\n this.paths[this.#getChecksumHexAddress(address)] = i;\n }\n return accounts;\n }\n\n #addressFromIndex(basePath: string, i: number): Hex {\n const dkey = this.hdk.derive(`${basePath}/${i}`);\n const address = publicToAddress(dkey.publicKey, true).toString('hex');\n return this.#getChecksumHexAddress(add0x(address));\n }\n\n #pathFromAddress(address: string): string {\n const checksummedAddress = this.#getChecksumHexAddress(address);\n let index = this.paths[checksummedAddress];\n if (typeof index === 'undefined') {\n for (let i = 0; i < MAX_INDEX; i++) {\n if (checksummedAddress === this.#addressFromIndex(pathBase, i)) {\n index = i;\n break;\n }\n }\n }\n\n if (typeof index === 'undefined') {\n throw new Error('Unknown address');\n }\n return this.#getPathForIndex(index);\n }\n\n #getPathForIndex(index: number): string {\n // Check if the path is BIP 44 (Ledger Live)\n return this.#isLedgerLiveHdPath()\n ? `m/44'/60'/${index}'/0/0`\n : `${this.hdPath}/${index}`;\n }\n\n #isLedgerLiveHdPath(): boolean {\n return this.hdPath === `m/44'/60'/0'/0/0`;\n }\n\n #toLedgerPath(path: string): string {\n return path.toString().replace('m/', '');\n }\n\n async #hasPreviousTransactions(address: string): Promise<boolean> {\n const apiUrl = this.#getApiUrl();\n const response = await window.fetch(\n `${apiUrl}/api?module=account&action=txlist&address=${address}&tag=latest&page=1&offset=1`,\n );\n const parsedResponse = await response.json();\n return parsedResponse.status !== '0' && parsedResponse.result.length > 0;\n }\n\n #getApiUrl(): NetworkApiUrls {\n return this.network;\n }\n\n #getChecksumHexAddress(address: string): Hex {\n return getChecksumAddress(add0x(address));\n }\n}\n"]}
@@ -1,7 +1,8 @@
1
1
  import { TypedTransaction } from "@ethereumjs/tx";
2
2
  import type { MessageTypes, TypedMessage } from "@metamask/eth-sig-util";
3
+ import type { Keyring } from "@metamask/keyring-utils";
4
+ import { Hex } from "@metamask/utils";
3
5
  import type OldEthJsTransaction from "ethereumjs-tx";
4
- import { EventEmitter } from "events";
5
6
  import HDKey from "hdkey";
6
7
  import { LedgerBridge, LedgerBridgeOptions } from "./ledger-bridge.cjs";
7
8
  declare enum NetworkApiUrls {
@@ -23,13 +24,14 @@ export type AccountDetails = {
23
24
  };
24
25
  export type LedgerBridgeKeyringOptions = {
25
26
  hdPath: string;
26
- accounts: readonly string[];
27
+ accounts: Hex[];
27
28
  deviceId: string;
28
- accountDetails: Readonly<Record<string, AccountDetails>>;
29
- accountIndexes: Readonly<Record<string, number>>;
29
+ accountDetails: Readonly<Record<Hex, AccountDetails>>;
30
+ accountIndexes: Readonly<Record<Hex, number>>;
30
31
  implementFullBIP44: boolean;
31
32
  };
32
- export declare class LedgerKeyring extends EventEmitter {
33
+ export type LedgerKeyringSerializedState = Partial<LedgerBridgeKeyringOptions>;
34
+ export declare class LedgerKeyring implements Keyring {
33
35
  #private;
34
36
  static type: string;
35
37
  deviceId: string;
@@ -37,7 +39,7 @@ export declare class LedgerKeyring extends EventEmitter {
37
39
  page: number;
38
40
  perPage: number;
39
41
  unlockedAccount: number;
40
- accounts: readonly string[];
42
+ accounts: readonly Hex[];
41
43
  accountDetails: Record<string, AccountDetails>;
42
44
  hdk: HDKey;
43
45
  hdPath: string;
@@ -50,32 +52,31 @@ export declare class LedgerKeyring extends EventEmitter {
50
52
  });
51
53
  init(): Promise<void>;
52
54
  destroy(): Promise<void>;
53
- serialize(): Promise<Partial<LedgerBridgeKeyringOptions>>;
54
- deserialize(opts?: Partial<LedgerBridgeKeyringOptions>): Promise<void>;
55
+ serialize(): Promise<Omit<LedgerKeyringSerializedState, 'accountIndexes'>>;
56
+ deserialize(opts: LedgerKeyringSerializedState): Promise<void>;
55
57
  setDeviceId(deviceId: string): void;
56
58
  getDeviceId(): string;
57
59
  isUnlocked(): boolean;
58
60
  isConnected(): boolean;
59
61
  setAccountToUnlock(index: number): void;
60
62
  setHdPath(hdPath: string): void;
61
- unlock(hdPath?: string, updateHdk?: boolean): Promise<string>;
62
- addAccounts(amount?: number): Promise<string[]>;
63
+ unlock(hdPath?: string, updateHdk?: boolean): Promise<Hex>;
64
+ addAccounts(amount: number): Promise<Hex[]>;
63
65
  getName(): string;
64
66
  getFirstPage(): Promise<AccountPage>;
65
67
  getNextPage(): Promise<AccountPage>;
66
68
  getPreviousPage(): Promise<AccountPage>;
67
- getAccounts(): Promise<string[]>;
69
+ getAccounts(): Promise<Hex[]>;
68
70
  removeAccount(address: string): void;
69
71
  attemptMakeApp(): Promise<boolean>;
70
72
  updateTransportMethod(transportType: string): Promise<boolean>;
71
- signTransaction(address: string, tx: TypedTransaction | OldEthJsTransaction): Promise<TypedTransaction | OldEthJsTransaction>;
72
- signMessage(withAccount: string, data: string): Promise<string>;
73
- signPersonalMessage(withAccount: string, message: string): Promise<string>;
74
- unlockAccountByAddress(address: string): Promise<string | undefined>;
75
- signTypedData<T extends MessageTypes>(withAccount: string, data: TypedMessage<T>, options?: {
73
+ signTransaction(address: Hex, tx: TypedTransaction | OldEthJsTransaction): Promise<TypedTransaction | OldEthJsTransaction>;
74
+ signMessage(withAccount: Hex, data: string): Promise<string>;
75
+ signPersonalMessage(withAccount: Hex, message: string): Promise<string>;
76
+ unlockAccountByAddress(address: Hex): Promise<string | undefined>;
77
+ signTypedData<T extends MessageTypes>(withAccount: Hex, data: TypedMessage<T>, options?: {
76
78
  version?: string;
77
79
  }): Promise<string>;
78
- exportAccount(): void;
79
80
  forgetDevice(): void;
80
81
  }
81
82
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"ledger-keyring.d.cts","sourceRoot":"","sources":["../src/ledger-keyring.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ledger-keyring.d.cts","sourceRoot":"","sources":["../src/ledger-keyring.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,8 @@
1
1
  import { TypedTransaction } from "@ethereumjs/tx";
2
2
  import type { MessageTypes, TypedMessage } from "@metamask/eth-sig-util";
3
+ import type { Keyring } from "@metamask/keyring-utils";
4
+ import { Hex } from "@metamask/utils";
3
5
  import type OldEthJsTransaction from "ethereumjs-tx";
4
- import { EventEmitter } from "events";
5
6
  import HDKey from "hdkey";
6
7
  import { LedgerBridge, LedgerBridgeOptions } from "./ledger-bridge.mjs";
7
8
  declare enum NetworkApiUrls {
@@ -23,13 +24,14 @@ export type AccountDetails = {
23
24
  };
24
25
  export type LedgerBridgeKeyringOptions = {
25
26
  hdPath: string;
26
- accounts: readonly string[];
27
+ accounts: Hex[];
27
28
  deviceId: string;
28
- accountDetails: Readonly<Record<string, AccountDetails>>;
29
- accountIndexes: Readonly<Record<string, number>>;
29
+ accountDetails: Readonly<Record<Hex, AccountDetails>>;
30
+ accountIndexes: Readonly<Record<Hex, number>>;
30
31
  implementFullBIP44: boolean;
31
32
  };
32
- export declare class LedgerKeyring extends EventEmitter {
33
+ export type LedgerKeyringSerializedState = Partial<LedgerBridgeKeyringOptions>;
34
+ export declare class LedgerKeyring implements Keyring {
33
35
  #private;
34
36
  static type: string;
35
37
  deviceId: string;
@@ -37,7 +39,7 @@ export declare class LedgerKeyring extends EventEmitter {
37
39
  page: number;
38
40
  perPage: number;
39
41
  unlockedAccount: number;
40
- accounts: readonly string[];
42
+ accounts: readonly Hex[];
41
43
  accountDetails: Record<string, AccountDetails>;
42
44
  hdk: HDKey;
43
45
  hdPath: string;
@@ -50,32 +52,31 @@ export declare class LedgerKeyring extends EventEmitter {
50
52
  });
51
53
  init(): Promise<void>;
52
54
  destroy(): Promise<void>;
53
- serialize(): Promise<Partial<LedgerBridgeKeyringOptions>>;
54
- deserialize(opts?: Partial<LedgerBridgeKeyringOptions>): Promise<void>;
55
+ serialize(): Promise<Omit<LedgerKeyringSerializedState, 'accountIndexes'>>;
56
+ deserialize(opts: LedgerKeyringSerializedState): Promise<void>;
55
57
  setDeviceId(deviceId: string): void;
56
58
  getDeviceId(): string;
57
59
  isUnlocked(): boolean;
58
60
  isConnected(): boolean;
59
61
  setAccountToUnlock(index: number): void;
60
62
  setHdPath(hdPath: string): void;
61
- unlock(hdPath?: string, updateHdk?: boolean): Promise<string>;
62
- addAccounts(amount?: number): Promise<string[]>;
63
+ unlock(hdPath?: string, updateHdk?: boolean): Promise<Hex>;
64
+ addAccounts(amount: number): Promise<Hex[]>;
63
65
  getName(): string;
64
66
  getFirstPage(): Promise<AccountPage>;
65
67
  getNextPage(): Promise<AccountPage>;
66
68
  getPreviousPage(): Promise<AccountPage>;
67
- getAccounts(): Promise<string[]>;
69
+ getAccounts(): Promise<Hex[]>;
68
70
  removeAccount(address: string): void;
69
71
  attemptMakeApp(): Promise<boolean>;
70
72
  updateTransportMethod(transportType: string): Promise<boolean>;
71
- signTransaction(address: string, tx: TypedTransaction | OldEthJsTransaction): Promise<TypedTransaction | OldEthJsTransaction>;
72
- signMessage(withAccount: string, data: string): Promise<string>;
73
- signPersonalMessage(withAccount: string, message: string): Promise<string>;
74
- unlockAccountByAddress(address: string): Promise<string | undefined>;
75
- signTypedData<T extends MessageTypes>(withAccount: string, data: TypedMessage<T>, options?: {
73
+ signTransaction(address: Hex, tx: TypedTransaction | OldEthJsTransaction): Promise<TypedTransaction | OldEthJsTransaction>;
74
+ signMessage(withAccount: Hex, data: string): Promise<string>;
75
+ signPersonalMessage(withAccount: Hex, message: string): Promise<string>;
76
+ unlockAccountByAddress(address: Hex): Promise<string | undefined>;
77
+ signTypedData<T extends MessageTypes>(withAccount: Hex, data: TypedMessage<T>, options?: {
76
78
  version?: string;
77
79
  }): Promise<string>;
78
- exportAccount(): void;
79
80
  forgetDevice(): void;
80
81
  }
81
82
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"ledger-keyring.d.mts","sourceRoot":"","sources":["../src/ledger-keyring.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ledger-keyring.d.mts","sourceRoot":"","sources":["../src/ledger-keyring.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
3
3
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
4
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
5
  };
6
- var _LedgerKeyring_instances, _LedgerKeyring_migrateAccountDetails, _LedgerKeyring_signTransaction, _LedgerKeyring_convertSaltIfAny, _LedgerKeyring_getPage, _LedgerKeyring_getAccountsBIP44, _LedgerKeyring_getAccountsLegacy, _LedgerKeyring_addressFromIndex, _LedgerKeyring_pathFromAddress, _LedgerKeyring_getPathForIndex, _LedgerKeyring_isLedgerLiveHdPath, _LedgerKeyring_toLedgerPath, _LedgerKeyring_hasPreviousTransactions, _LedgerKeyring_getApiUrl;
6
+ var _LedgerKeyring_instances, _LedgerKeyring_migrateAccountDetails, _LedgerKeyring_signTransaction, _LedgerKeyring_convertSaltIfAny, _LedgerKeyring_getPage, _LedgerKeyring_getAccountsBIP44, _LedgerKeyring_getAccountsLegacy, _LedgerKeyring_addressFromIndex, _LedgerKeyring_pathFromAddress, _LedgerKeyring_getPathForIndex, _LedgerKeyring_isLedgerLiveHdPath, _LedgerKeyring_toLedgerPath, _LedgerKeyring_hasPreviousTransactions, _LedgerKeyring_getApiUrl, _LedgerKeyring_getChecksumHexAddress;
7
7
  function $importDefault(module) {
8
8
  if (module?.__esModule) {
9
9
  return module.default;
@@ -12,10 +12,10 @@ function $importDefault(module) {
12
12
  }
13
13
  import { RLP } from "@ethereumjs/rlp";
14
14
  import { TransactionFactory } from "@ethereumjs/tx";
15
- import * as ethUtil from "@ethereumjs/util";
15
+ import { bufferToHex, publicToAddress } from "@ethereumjs/util";
16
16
  import { recoverPersonalSignature, recoverTypedSignature, SignTypedDataVersion, TypedDataUtils } from "@metamask/eth-sig-util";
17
+ import { add0x, getChecksumAddress, remove0x } from "@metamask/utils";
17
18
  import { Buffer } from "buffer";
18
- import { EventEmitter } from "events";
19
19
  import $HDKey from "hdkey";
20
20
  const HDKey = $importDefault($HDKey);
21
21
  const pathBase = 'm';
@@ -46,9 +46,8 @@ var NetworkApiUrls;
46
46
  function isOldStyleEthereumjsTx(tx) {
47
47
  return 'getChainId' in tx && typeof tx.getChainId === 'function';
48
48
  }
49
- export class LedgerKeyring extends EventEmitter {
49
+ export class LedgerKeyring {
50
50
  constructor({ bridge }) {
51
- super();
52
51
  _LedgerKeyring_instances.add(this);
53
52
  this.deviceId = '';
54
53
  this.type = keyringType;
@@ -76,13 +75,13 @@ export class LedgerKeyring extends EventEmitter {
76
75
  async serialize() {
77
76
  return {
78
77
  hdPath: this.hdPath,
79
- accounts: this.accounts,
78
+ accounts: this.accounts.slice(),
80
79
  deviceId: this.deviceId,
81
80
  accountDetails: this.accountDetails,
82
81
  implementFullBIP44: false,
83
82
  };
84
83
  }
85
- async deserialize(opts = {}) {
84
+ async deserialize(opts) {
86
85
  this.hdPath = opts.hdPath ?? hdPathString;
87
86
  this.accounts = opts.accounts ?? [];
88
87
  this.deviceId = opts.deviceId ?? '';
@@ -93,7 +92,7 @@ export class LedgerKeyring extends EventEmitter {
93
92
  this.implementFullBIP44 = opts.implementFullBIP44 ?? false;
94
93
  const keys = new Set(Object.keys(this.accountDetails));
95
94
  // Remove accounts that don't have corresponding account details
96
- this.accounts = this.accounts.filter((account) => keys.has(ethUtil.toChecksumAddress(account)));
95
+ this.accounts = this.accounts.filter((account) => keys.has(__classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, account)));
97
96
  return Promise.resolve();
98
97
  }
99
98
  setDeviceId(deviceId) {
@@ -120,7 +119,10 @@ export class LedgerKeyring extends EventEmitter {
120
119
  }
121
120
  async unlock(hdPath, updateHdk = true) {
122
121
  if (this.isUnlocked() && !hdPath) {
123
- return 'already unlocked';
122
+ // if the device is already unlocked and no path is provided,
123
+ // we return the checksummed address of the public key stored in
124
+ // `this.hdk`, which is the root address of the last unlocked path.
125
+ return __classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, publicToAddress(this.hdk.publicKey, true).toString('hex'));
124
126
  }
125
127
  const path = hdPath ? __classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_toLedgerPath).call(this, hdPath) : this.hdPath;
126
128
  let payload;
@@ -138,9 +140,9 @@ export class LedgerKeyring extends EventEmitter {
138
140
  this.hdk.publicKey = Buffer.from(payload.publicKey, 'hex');
139
141
  this.hdk.chainCode = Buffer.from(payload.chainCode, 'hex');
140
142
  }
141
- return payload.address;
143
+ return add0x(payload.address);
142
144
  }
143
- async addAccounts(amount = 1) {
145
+ async addAccounts(amount) {
144
146
  return new Promise((resolve, reject) => {
145
147
  this.unlock()
146
148
  .then(async (_) => {
@@ -156,7 +158,7 @@ export class LedgerKeyring extends EventEmitter {
156
158
  else {
157
159
  address = __classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_addressFromIndex).call(this, pathBase, i);
158
160
  }
159
- this.accountDetails[ethUtil.toChecksumAddress(address)] = {
161
+ this.accountDetails[__classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, address)] = {
160
162
  // TODO: consider renaming this property, as the current name is misleading
161
163
  // It's currently used to represent whether an account uses the Ledger Live path.
162
164
  bip44: __classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_isLedgerLiveHdPath).call(this),
@@ -195,7 +197,7 @@ export class LedgerKeyring extends EventEmitter {
195
197
  throw new Error(`Address ${address} not found in this keyring`);
196
198
  }
197
199
  this.accounts = filteredAccounts;
198
- delete this.accountDetails[ethUtil.toChecksumAddress(address)];
200
+ delete this.accountDetails[__classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, address)];
199
201
  }
200
202
  async attemptMakeApp() {
201
203
  return this.bridge.attemptMakeApp();
@@ -217,7 +219,7 @@ export class LedgerKeyring extends EventEmitter {
217
219
  // value. In newer versions the chainId is communicated via the 'Common'
218
220
  // object.
219
221
  // @ts-expect-error tx.v should be a Buffer, but we are assigning a string
220
- tx.v = ethUtil.bufferToHex(tx.getChainId());
222
+ tx.v = bufferToHex(tx.getChainId());
221
223
  // @ts-expect-error tx.r should be a Buffer, but we are assigning a string
222
224
  tx.r = '0x00';
223
225
  // @ts-expect-error tx.s should be a Buffer, but we are assigning a string
@@ -249,9 +251,9 @@ export class LedgerKeyring extends EventEmitter {
249
251
  // The fromTxData utility expects a type to support transactions with a type other than 0
250
252
  txData.type = tx.type;
251
253
  // The fromTxData utility expects v,r and s to be hex prefixed
252
- txData.v = ethUtil.addHexPrefix(payload.v);
253
- txData.r = ethUtil.addHexPrefix(payload.r);
254
- txData.s = ethUtil.addHexPrefix(payload.s);
254
+ txData.v = add0x(payload.v);
255
+ txData.r = add0x(payload.r);
256
+ txData.s = add0x(payload.s);
255
257
  // Adopt the 'common' option from the original transaction and set the
256
258
  // returned object to be frozen if the original is frozen.
257
259
  return TransactionFactory.fromTxData(txData, {
@@ -273,7 +275,7 @@ export class LedgerKeyring extends EventEmitter {
273
275
  try {
274
276
  payload = await this.bridge.deviceSignMessage({
275
277
  hdPath,
276
- message: ethUtil.stripHexPrefix(message),
278
+ message: remove0x(message),
277
279
  });
278
280
  }
279
281
  catch (error) {
@@ -290,14 +292,14 @@ export class LedgerKeyring extends EventEmitter {
290
292
  data: message,
291
293
  signature,
292
294
  });
293
- if (ethUtil.toChecksumAddress(addressSignedWith) !==
294
- ethUtil.toChecksumAddress(withAccount)) {
295
+ if (__classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, addressSignedWith) !==
296
+ __classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, withAccount)) {
295
297
  throw new Error('Ledger: The signature doesnt match the right address');
296
298
  }
297
299
  return signature;
298
300
  }
299
301
  async unlockAccountByAddress(address) {
300
- const checksummedAddress = ethUtil.toChecksumAddress(address);
302
+ const checksummedAddress = __classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, address);
301
303
  const accountDetails = this.accountDetails[checksummedAddress];
302
304
  if (!accountDetails) {
303
305
  throw new Error(`Ledger: Account for address '${checksummedAddress}' not found`);
@@ -354,15 +356,12 @@ export class LedgerKeyring extends EventEmitter {
354
356
  signature,
355
357
  version: SignTypedDataVersion.V4,
356
358
  });
357
- if (ethUtil.toChecksumAddress(addressSignedWith) !==
358
- ethUtil.toChecksumAddress(withAccount)) {
359
+ if (__classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, addressSignedWith) !==
360
+ __classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, withAccount)) {
359
361
  throw new Error('Ledger: The signature doesnt match the right address');
360
362
  }
361
363
  return signature;
362
364
  }
363
- exportAccount() {
364
- throw new Error('Not supported on this device');
365
- }
366
365
  forgetDevice() {
367
366
  this.deviceId = '';
368
367
  this.accounts = [];
@@ -386,7 +385,7 @@ _LedgerKeyring_instances = new WeakSet(), _LedgerKeyring_migrateAccountDetails =
386
385
  // try to migrate non-LedgerLive accounts too
387
386
  if (!__classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_isLedgerLiveHdPath).call(this)) {
388
387
  this.accounts.forEach((account) => {
389
- const key = ethUtil.toChecksumAddress(account);
388
+ const key = __classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, account);
390
389
  if (!keys.has(key)) {
391
390
  this.accountDetails[key] = {
392
391
  bip44: false,
@@ -475,17 +474,15 @@ async function _LedgerKeyring_getPage(increment) {
475
474
  balance: null,
476
475
  index: i,
477
476
  });
478
- this.paths[ethUtil.toChecksumAddress(address)] = i;
477
+ this.paths[__classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, address)] = i;
479
478
  }
480
479
  return accounts;
481
480
  }, _LedgerKeyring_addressFromIndex = function _LedgerKeyring_addressFromIndex(basePath, i) {
482
481
  const dkey = this.hdk.derive(`${basePath}/${i}`);
483
- const address = ethUtil
484
- .publicToAddress(dkey.publicKey, true)
485
- .toString('hex');
486
- return ethUtil.toChecksumAddress(`0x${address}`);
482
+ const address = publicToAddress(dkey.publicKey, true).toString('hex');
483
+ return __classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, add0x(address));
487
484
  }, _LedgerKeyring_pathFromAddress = function _LedgerKeyring_pathFromAddress(address) {
488
- const checksummedAddress = ethUtil.toChecksumAddress(address);
485
+ const checksummedAddress = __classPrivateFieldGet(this, _LedgerKeyring_instances, "m", _LedgerKeyring_getChecksumHexAddress).call(this, address);
489
486
  let index = this.paths[checksummedAddress];
490
487
  if (typeof index === 'undefined') {
491
488
  for (let i = 0; i < MAX_INDEX; i++) {
@@ -515,6 +512,8 @@ async function _LedgerKeyring_getPage(increment) {
515
512
  return parsedResponse.status !== '0' && parsedResponse.result.length > 0;
516
513
  }, _LedgerKeyring_getApiUrl = function _LedgerKeyring_getApiUrl() {
517
514
  return this.network;
515
+ }, _LedgerKeyring_getChecksumHexAddress = function _LedgerKeyring_getChecksumHexAddress(address) {
516
+ return getChecksumAddress(add0x(address));
518
517
  };
519
518
  LedgerKeyring.type = keyringType;
520
519
  //# sourceMappingURL=ledger-keyring.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ledger-keyring.mjs","sourceRoot":"","sources":["../src/ledger-keyring.ts"],"names":[],"mappings":"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","sourcesContent":["import { RLP } from '@ethereumjs/rlp';\nimport { TransactionFactory, TxData, TypedTransaction } from '@ethereumjs/tx';\nimport * as ethUtil from '@ethereumjs/util';\nimport type { MessageTypes, TypedMessage } from '@metamask/eth-sig-util';\nimport {\n recoverPersonalSignature,\n recoverTypedSignature,\n SignTypedDataVersion,\n TypedDataUtils,\n} from '@metamask/eth-sig-util';\nimport { Buffer } from 'buffer';\nimport type OldEthJsTransaction from 'ethereumjs-tx';\nimport { EventEmitter } from 'events';\nimport HDKey from 'hdkey';\n\nimport { LedgerBridge, LedgerBridgeOptions } from './ledger-bridge';\nimport { LedgerIframeBridgeOptions } from './ledger-iframe-bridge';\n\nconst pathBase = 'm';\nconst hdPathString = `${pathBase}/44'/60'/0'`;\nconst keyringType = 'Ledger Hardware';\n\n// This number causes one of our failing tests to run very slowly, as the for loop needs to iterate 1000 times.\nconst MAX_INDEX = 1000;\n\nenum NetworkApiUrls {\n Ropsten = 'https://api-ropsten.etherscan.io',\n Kovan = 'https://api-kovan.etherscan.io',\n Rinkeby = 'https://api-rinkeby.etherscan.io',\n Mainnet = `https://api.etherscan.io`,\n}\n\ntype SignTransactionPayload = Awaited<\n ReturnType<LedgerBridge<LedgerIframeBridgeOptions>['deviceSignTransaction']>\n>;\n\nexport type AccountPageEntry = {\n address: string;\n balance: number | null;\n index: number;\n};\n\nexport type AccountPage = AccountPageEntry[];\n\nexport type AccountDetails = {\n index?: number;\n bip44?: boolean;\n hdPath?: string;\n};\n\nexport type LedgerBridgeKeyringOptions = {\n hdPath: string;\n accounts: readonly string[];\n deviceId: string;\n accountDetails: Readonly<Record<string, AccountDetails>>;\n accountIndexes: Readonly<Record<string, number>>;\n implementFullBIP44: boolean;\n};\n\n/**\n * Check if the given transaction is made with ethereumjs-tx or @ethereumjs/tx\n *\n * Transactions built with older versions of ethereumjs-tx have a\n * getChainId method that newer versions do not.\n * Older versions are mutable\n * while newer versions default to being immutable.\n * Expected shape and type\n * of data for v, r and s differ (Buffer (old) vs BN (new)).\n *\n * @param tx - Transaction to check, instance of either ethereumjs-tx or @ethereumjs/tx.\n * @returns Returns `true` if tx is an old-style ethereumjs-tx transaction.\n */\nfunction isOldStyleEthereumjsTx(\n tx: TypedTransaction | OldEthJsTransaction,\n): tx is OldEthJsTransaction {\n return 'getChainId' in tx && typeof tx.getChainId === 'function';\n}\n\nexport class LedgerKeyring extends EventEmitter {\n static type: string = keyringType;\n\n deviceId = '';\n\n readonly type: string = keyringType;\n\n page = 0;\n\n perPage = 5;\n\n unlockedAccount = 0;\n\n accounts: readonly string[] = [];\n\n accountDetails: Record<string, AccountDetails> = {};\n\n hdk = new HDKey();\n\n hdPath = hdPathString;\n\n paths: Record<string, number> = {};\n\n network: NetworkApiUrls = NetworkApiUrls.Mainnet;\n\n implementFullBIP44 = false;\n\n bridge: LedgerBridge<LedgerBridgeOptions>;\n\n constructor({ bridge }: { bridge: LedgerBridge<LedgerBridgeOptions> }) {\n super();\n\n if (!bridge) {\n throw new Error('Bridge is a required dependency for the keyring');\n }\n\n this.bridge = bridge;\n }\n\n async init(): Promise<void> {\n return this.bridge.init();\n }\n\n async destroy(): Promise<void> {\n return this.bridge.destroy();\n }\n\n async serialize(): Promise<\n Partial<LedgerBridgeKeyringOptions> // Maybe we should have a proper \"state\" type here instead of using this \"options\" type.\n > {\n return {\n hdPath: this.hdPath,\n accounts: this.accounts,\n deviceId: this.deviceId,\n accountDetails: this.accountDetails,\n implementFullBIP44: false,\n };\n }\n\n async deserialize(\n opts: Partial<LedgerBridgeKeyringOptions> = {}, // Same question here?\n ): Promise<void> {\n this.hdPath = opts.hdPath ?? hdPathString;\n this.accounts = opts.accounts ?? [];\n this.deviceId = opts.deviceId ?? '';\n this.accountDetails = opts.accountDetails ?? {};\n\n if (!opts.accountDetails) {\n this.#migrateAccountDetails(opts);\n }\n\n this.implementFullBIP44 = opts.implementFullBIP44 ?? false;\n\n const keys = new Set<string>(Object.keys(this.accountDetails));\n // Remove accounts that don't have corresponding account details\n this.accounts = this.accounts.filter((account) =>\n keys.has(ethUtil.toChecksumAddress(account)),\n );\n\n return Promise.resolve();\n }\n\n public setDeviceId(deviceId: string): void {\n this.deviceId = deviceId;\n }\n\n public getDeviceId(): string {\n return this.deviceId;\n }\n\n #migrateAccountDetails(opts: Partial<LedgerBridgeKeyringOptions>): void {\n if (this.#isLedgerLiveHdPath() && opts.accountIndexes) {\n for (const [account, index] of Object.entries(opts.accountIndexes)) {\n this.accountDetails[account] = {\n bip44: true,\n hdPath: this.#getPathForIndex(index),\n };\n }\n }\n const keys = new Set<string>(Object.keys(this.accountDetails));\n // try to migrate non-LedgerLive accounts too\n if (!this.#isLedgerLiveHdPath()) {\n this.accounts.forEach((account) => {\n const key = ethUtil.toChecksumAddress(account);\n\n if (!keys.has(key)) {\n this.accountDetails[key] = {\n bip44: false,\n hdPath: this.#pathFromAddress(account),\n };\n }\n });\n }\n }\n\n isUnlocked(): boolean {\n return Boolean(this.hdk.publicKey);\n }\n\n isConnected(): boolean {\n return this.bridge.isDeviceConnected;\n }\n\n setAccountToUnlock(index: number): void {\n this.unlockedAccount = index;\n }\n\n setHdPath(hdPath: string): void {\n // Reset HDKey if the path changes\n if (this.hdPath !== hdPath) {\n this.hdk = new HDKey();\n }\n this.hdPath = hdPath;\n }\n\n async unlock(hdPath?: string, updateHdk = true): Promise<string> {\n if (this.isUnlocked() && !hdPath) {\n return 'already unlocked';\n }\n const path = hdPath ? this.#toLedgerPath(hdPath) : this.hdPath;\n\n let payload;\n try {\n payload = await this.bridge.getPublicKey({\n hdPath: path,\n });\n } catch (error) {\n throw error instanceof Error\n ? error\n : new Error('Ledger Ethereum app closed. Open it to unlock.');\n }\n\n if (updateHdk && payload.chainCode) {\n this.hdk.publicKey = Buffer.from(payload.publicKey, 'hex');\n this.hdk.chainCode = Buffer.from(payload.chainCode, 'hex');\n }\n\n return payload.address;\n }\n\n async addAccounts(amount = 1): Promise<string[]> {\n return new Promise((resolve, reject) => {\n this.unlock()\n .then(async (_) => {\n const from = this.unlockedAccount;\n const to = from + amount;\n const newAccounts: string[] = [];\n for (let i = from; i < to; i++) {\n const path = this.#getPathForIndex(i);\n let address;\n if (this.#isLedgerLiveHdPath()) {\n address = await this.unlock(path);\n } else {\n address = this.#addressFromIndex(pathBase, i);\n }\n\n this.accountDetails[ethUtil.toChecksumAddress(address)] = {\n // TODO: consider renaming this property, as the current name is misleading\n // It's currently used to represent whether an account uses the Ledger Live path.\n bip44: this.#isLedgerLiveHdPath(),\n hdPath: path,\n };\n\n if (!this.accounts.includes(address)) {\n this.accounts = [...this.accounts, address];\n newAccounts.push(address);\n }\n this.page = 0;\n }\n resolve(newAccounts);\n })\n .catch(reject);\n });\n }\n\n getName(): string {\n return keyringType;\n }\n\n async getFirstPage(): Promise<AccountPage> {\n this.page = 0;\n return this.#getPage(1);\n }\n\n async getNextPage(): Promise<AccountPage> {\n return this.#getPage(1);\n }\n\n async getPreviousPage(): Promise<AccountPage> {\n return this.#getPage(-1);\n }\n\n async getAccounts(): Promise<string[]> {\n return Promise.resolve(this.accounts.slice());\n }\n\n removeAccount(address: string): void {\n const filteredAccounts = this.accounts.filter(\n (a) => a.toLowerCase() !== address.toLowerCase(),\n );\n\n if (filteredAccounts.length === this.accounts.length) {\n throw new Error(`Address ${address} not found in this keyring`);\n }\n\n this.accounts = filteredAccounts;\n delete this.accountDetails[ethUtil.toChecksumAddress(address)];\n }\n\n async attemptMakeApp(): Promise<boolean> {\n return this.bridge.attemptMakeApp();\n }\n\n async updateTransportMethod(transportType: string): Promise<boolean> {\n return this.bridge.updateTransportMethod(transportType);\n }\n\n // tx is an instance of the ethereumjs-transaction class.\n async signTransaction(\n address: string,\n tx: TypedTransaction | OldEthJsTransaction,\n ): Promise<TypedTransaction | OldEthJsTransaction> {\n let rawTxHex;\n // transactions built with older versions of ethereumjs-tx have a\n // getChainId method that newer versions do not. Older versions are mutable\n // while newer versions default to being immutable. Expected shape and type\n // of data for v, r and s differ (Buffer (old) vs BN (new))\n if (isOldStyleEthereumjsTx(tx)) {\n // In this version of ethereumjs-tx we must add the chainId in hex format\n // to the initial v value. The chainId must be included in the serialized\n // transaction which is only communicated to ethereumjs-tx in this\n // value. In newer versions the chainId is communicated via the 'Common'\n // object.\n // @ts-expect-error tx.v should be a Buffer, but we are assigning a string\n tx.v = ethUtil.bufferToHex(tx.getChainId());\n // @ts-expect-error tx.r should be a Buffer, but we are assigning a string\n tx.r = '0x00';\n // @ts-expect-error tx.s should be a Buffer, but we are assigning a string\n tx.s = '0x00';\n\n rawTxHex = tx.serialize().toString('hex');\n\n return this.#signTransaction(address, rawTxHex, (payload) => {\n tx.v = Buffer.from(payload.v, 'hex');\n tx.r = Buffer.from(payload.r, 'hex');\n tx.s = Buffer.from(payload.s, 'hex');\n return tx;\n });\n }\n\n // The below `encode` call is only necessary for legacy transactions, as `getMessageToSign`\n // calls `rlp.encode` internally for non-legacy transactions. As per the \"Transaction Execution\"\n // section of the ethereum yellow paper, transactions need to be \"well-formed RLP, with no additional\n // trailing bytes\".\n\n // Note also that `getMessageToSign` will return valid RLP for all transaction types, whereas the\n // `serialize` method will not for any transaction type except legacy. This is because `serialize` includes\n // empty r, s and v values in the encoded rlp. This is why we use `getMessageToSign` here instead of `serialize`.\n const messageToSign = tx.getMessageToSign(false);\n\n rawTxHex = Buffer.isBuffer(messageToSign)\n ? messageToSign.toString('hex')\n : Buffer.from(RLP.encode(messageToSign)).toString('hex');\n\n return this.#signTransaction(address, rawTxHex, (payload) => {\n // Because tx will be immutable, first get a plain javascript object that\n // represents the transaction. Using txData here as it aligns with the\n // nomenclature of ethereumjs/tx.\n const txData: TxData = tx.toJSON();\n // The fromTxData utility expects a type to support transactions with a type other than 0\n txData.type = tx.type;\n // The fromTxData utility expects v,r and s to be hex prefixed\n txData.v = ethUtil.addHexPrefix(payload.v);\n txData.r = ethUtil.addHexPrefix(payload.r);\n txData.s = ethUtil.addHexPrefix(payload.s);\n // Adopt the 'common' option from the original transaction and set the\n // returned object to be frozen if the original is frozen.\n return TransactionFactory.fromTxData(txData, {\n common: tx.common,\n freeze: Object.isFrozen(tx),\n });\n });\n }\n\n async #signTransaction(\n address: string,\n rawTxHex: string,\n handleSigning: (\n payload: SignTransactionPayload,\n ) => TypedTransaction | OldEthJsTransaction,\n ): Promise<TypedTransaction | OldEthJsTransaction> {\n const hdPath = await this.unlockAccountByAddress(address);\n\n if (!hdPath) {\n throw new Error('Ledger: Unknown error while signing transaction');\n }\n\n let payload;\n try {\n payload = await this.bridge.deviceSignTransaction({\n tx: rawTxHex,\n hdPath,\n });\n } catch (error) {\n throw error instanceof Error\n ? error\n : new Error('Ledger: Unknown error while signing transaction');\n }\n\n const newOrMutatedTx = handleSigning(payload);\n const valid = newOrMutatedTx.verifySignature();\n if (valid) {\n return newOrMutatedTx;\n }\n throw new Error('Ledger: The transaction signature is not valid');\n }\n\n async signMessage(withAccount: string, data: string): Promise<string> {\n return this.signPersonalMessage(withAccount, data);\n }\n\n // For personal_sign, we need to prefix the message:\n async signPersonalMessage(\n withAccount: string,\n message: string,\n ): Promise<string> {\n const hdPath = await this.unlockAccountByAddress(withAccount);\n\n if (!hdPath) {\n throw new Error('Ledger: Unknown error while signing message');\n }\n\n let payload;\n try {\n payload = await this.bridge.deviceSignMessage({\n hdPath,\n message: ethUtil.stripHexPrefix(message),\n });\n } catch (error) {\n throw error instanceof Error\n ? error\n : new Error('Ledger: Unknown error while signing message');\n }\n\n let modifiedV = parseInt(String(payload.v), 10).toString(16);\n if (modifiedV.length < 2) {\n modifiedV = `0${modifiedV}`;\n }\n\n const signature = `0x${payload.r}${payload.s}${modifiedV}`;\n const addressSignedWith = recoverPersonalSignature({\n data: message,\n signature,\n });\n if (\n ethUtil.toChecksumAddress(addressSignedWith) !==\n ethUtil.toChecksumAddress(withAccount)\n ) {\n throw new Error('Ledger: The signature doesnt match the right address');\n }\n return signature;\n }\n\n async unlockAccountByAddress(address: string): Promise<string | undefined> {\n const checksummedAddress = ethUtil.toChecksumAddress(address);\n const accountDetails = this.accountDetails[checksummedAddress];\n if (!accountDetails) {\n throw new Error(\n `Ledger: Account for address '${checksummedAddress}' not found`,\n );\n }\n const { hdPath } = accountDetails;\n const unlockedAddress = await this.unlock(hdPath, false);\n\n // unlock resolves to the address for the given hdPath as reported by the ledger device\n // if that address is not the requested address, then this account belongs to a different device or seed\n if (unlockedAddress.toLowerCase() !== address.toLowerCase()) {\n throw new Error(\n `Ledger: Account ${address} does not belong to the connected device`,\n );\n }\n return hdPath;\n }\n\n async signTypedData<T extends MessageTypes>(\n withAccount: string,\n data: TypedMessage<T>,\n options: { version?: string } = {},\n ): Promise<string> {\n const isV4 = options.version === 'V4';\n if (!isV4) {\n throw new Error(\n 'Ledger: Only version 4 of typed data signing is supported',\n );\n }\n\n const { domain, types, primaryType, message } =\n TypedDataUtils.sanitizeData(data);\n\n const hdPath = await this.unlockAccountByAddress(withAccount);\n\n if (!hdPath) {\n throw new Error('Ledger: Unknown error while signing message');\n }\n\n let payload;\n try {\n payload = await this.bridge.deviceSignTypedData({\n hdPath,\n message: {\n domain: {\n name: domain.name,\n chainId: domain.chainId,\n version: domain.version,\n verifyingContract: domain.verifyingContract,\n salt: this.#convertSaltIfAny(domain.salt),\n },\n types,\n primaryType: primaryType.toString(),\n message,\n },\n });\n } catch (error) {\n throw error instanceof Error\n ? error\n : new Error('Ledger: Unknown error while signing message');\n }\n\n let recoveryId = parseInt(String(payload.v), 10).toString(16);\n if (recoveryId.length < 2) {\n recoveryId = `0${recoveryId}`;\n }\n const signature = `0x${payload.r}${payload.s}${recoveryId}`;\n const addressSignedWith = recoverTypedSignature({\n data,\n signature,\n version: SignTypedDataVersion.V4,\n });\n\n if (\n ethUtil.toChecksumAddress(addressSignedWith) !==\n ethUtil.toChecksumAddress(withAccount)\n ) {\n throw new Error('Ledger: The signature doesnt match the right address');\n }\n return signature;\n }\n\n exportAccount(): void {\n throw new Error('Not supported on this device');\n }\n\n forgetDevice(): void {\n this.deviceId = '';\n this.accounts = [];\n this.page = 0;\n this.unlockedAccount = 0;\n this.paths = {};\n this.accountDetails = {};\n this.hdk = new HDKey();\n }\n\n #convertSaltIfAny(salt: ArrayBuffer | undefined): string | undefined {\n if (!salt) {\n return undefined;\n }\n\n // We convert this to a plain string to avoid encoding issue on the\n // mobile side (to avoid using `TextDecoder`).\n const saltBytes = new Uint8Array(salt);\n return String.fromCharCode(...saltBytes);\n }\n\n /* PRIVATE METHODS */\n async #getPage(increment: number): Promise<AccountPage> {\n this.page += increment;\n\n if (this.page <= 0) {\n this.page = 1;\n }\n const from = (this.page - 1) * this.perPage;\n const to = from + this.perPage;\n\n await this.unlock();\n let accounts;\n if (this.#isLedgerLiveHdPath()) {\n accounts = await this.#getAccountsBIP44(from, to);\n } else {\n accounts = this.#getAccountsLegacy(from, to);\n }\n return accounts;\n }\n\n async #getAccountsBIP44(from: number, to: number): Promise<AccountPage> {\n const accounts: AccountPage = [];\n\n for (let i = from; i < to; i++) {\n const path = this.#getPathForIndex(i);\n const address = await this.unlock(path);\n const valid = this.implementFullBIP44\n ? await this.#hasPreviousTransactions(address)\n : true;\n accounts.push({\n address,\n balance: null,\n index: i,\n });\n\n // PER BIP44\n // \"Software should prevent a creation of an account if\n // a previous account does not have a transaction history\n // (meaning none of its addresses have been used before).\"\n if (!valid) {\n break;\n }\n }\n return accounts;\n }\n\n #getAccountsLegacy(from: number, to: number): AccountPage {\n const accounts: AccountPage = [];\n\n for (let i = from; i < to; i++) {\n const address = this.#addressFromIndex(pathBase, i);\n accounts.push({\n address,\n balance: null,\n index: i,\n });\n this.paths[ethUtil.toChecksumAddress(address)] = i;\n }\n return accounts;\n }\n\n #addressFromIndex(basePath: string, i: number): string {\n const dkey = this.hdk.derive(`${basePath}/${i}`);\n const address = ethUtil\n .publicToAddress(dkey.publicKey, true)\n .toString('hex');\n return ethUtil.toChecksumAddress(`0x${address}`);\n }\n\n #pathFromAddress(address: string): string {\n const checksummedAddress = ethUtil.toChecksumAddress(address);\n let index = this.paths[checksummedAddress];\n if (typeof index === 'undefined') {\n for (let i = 0; i < MAX_INDEX; i++) {\n if (checksummedAddress === this.#addressFromIndex(pathBase, i)) {\n index = i;\n break;\n }\n }\n }\n\n if (typeof index === 'undefined') {\n throw new Error('Unknown address');\n }\n return this.#getPathForIndex(index);\n }\n\n #getPathForIndex(index: number): string {\n // Check if the path is BIP 44 (Ledger Live)\n return this.#isLedgerLiveHdPath()\n ? `m/44'/60'/${index}'/0/0`\n : `${this.hdPath}/${index}`;\n }\n\n #isLedgerLiveHdPath(): boolean {\n return this.hdPath === `m/44'/60'/0'/0/0`;\n }\n\n #toLedgerPath(path: string): string {\n return path.toString().replace('m/', '');\n }\n\n async #hasPreviousTransactions(address: string): Promise<boolean> {\n const apiUrl = this.#getApiUrl();\n const response = await window.fetch(\n `${apiUrl}/api?module=account&action=txlist&address=${address}&tag=latest&page=1&offset=1`,\n );\n const parsedResponse = await response.json();\n return parsedResponse.status !== '0' && parsedResponse.result.length > 0;\n }\n\n #getApiUrl(): NetworkApiUrls {\n return this.network;\n }\n}\n"]}
1
+ {"version":3,"file":"ledger-keyring.mjs","sourceRoot":"","sources":["../src/ledger-keyring.ts"],"names":[],"mappings":"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","sourcesContent":["import { RLP } from '@ethereumjs/rlp';\nimport { TransactionFactory, TxData, TypedTransaction } from '@ethereumjs/tx';\nimport { bufferToHex, publicToAddress } from '@ethereumjs/util';\nimport type { MessageTypes, TypedMessage } from '@metamask/eth-sig-util';\nimport {\n recoverPersonalSignature,\n recoverTypedSignature,\n SignTypedDataVersion,\n TypedDataUtils,\n} from '@metamask/eth-sig-util';\nimport type { Keyring } from '@metamask/keyring-utils';\nimport { add0x, getChecksumAddress, Hex, remove0x } from '@metamask/utils';\nimport { Buffer } from 'buffer';\nimport type OldEthJsTransaction from 'ethereumjs-tx';\nimport HDKey from 'hdkey';\n\nimport { LedgerBridge, LedgerBridgeOptions } from './ledger-bridge';\nimport { LedgerIframeBridgeOptions } from './ledger-iframe-bridge';\n\nconst pathBase = 'm';\nconst hdPathString = `${pathBase}/44'/60'/0'`;\nconst keyringType = 'Ledger Hardware';\n\n// This number causes one of our failing tests to run very slowly, as the for loop needs to iterate 1000 times.\nconst MAX_INDEX = 1000;\n\nenum NetworkApiUrls {\n Ropsten = 'https://api-ropsten.etherscan.io',\n Kovan = 'https://api-kovan.etherscan.io',\n Rinkeby = 'https://api-rinkeby.etherscan.io',\n Mainnet = `https://api.etherscan.io`,\n}\n\ntype SignTransactionPayload = Awaited<\n ReturnType<LedgerBridge<LedgerIframeBridgeOptions>['deviceSignTransaction']>\n>;\n\nexport type AccountPageEntry = {\n address: string;\n balance: number | null;\n index: number;\n};\n\nexport type AccountPage = AccountPageEntry[];\n\nexport type AccountDetails = {\n index?: number;\n bip44?: boolean;\n hdPath?: string;\n};\n\nexport type LedgerBridgeKeyringOptions = {\n hdPath: string;\n accounts: Hex[];\n deviceId: string;\n accountDetails: Readonly<Record<Hex, AccountDetails>>;\n accountIndexes: Readonly<Record<Hex, number>>;\n implementFullBIP44: boolean;\n};\n\nexport type LedgerKeyringSerializedState = Partial<LedgerBridgeKeyringOptions>;\n\n/**\n * Check if the given transaction is made with ethereumjs-tx or @ethereumjs/tx\n *\n * Transactions built with older versions of ethereumjs-tx have a\n * getChainId method that newer versions do not.\n * Older versions are mutable\n * while newer versions default to being immutable.\n * Expected shape and type\n * of data for v, r and s differ (Buffer (old) vs BN (new)).\n *\n * @param tx - Transaction to check, instance of either ethereumjs-tx or @ethereumjs/tx.\n * @returns Returns `true` if tx is an old-style ethereumjs-tx transaction.\n */\nfunction isOldStyleEthereumjsTx(\n tx: TypedTransaction | OldEthJsTransaction,\n): tx is OldEthJsTransaction {\n return 'getChainId' in tx && typeof tx.getChainId === 'function';\n}\n\nexport class LedgerKeyring implements Keyring {\n static type: string = keyringType;\n\n deviceId = '';\n\n readonly type: string = keyringType;\n\n page = 0;\n\n perPage = 5;\n\n unlockedAccount = 0;\n\n accounts: readonly Hex[] = [];\n\n accountDetails: Record<string, AccountDetails> = {};\n\n hdk = new HDKey();\n\n hdPath = hdPathString;\n\n paths: Record<string, number> = {};\n\n network: NetworkApiUrls = NetworkApiUrls.Mainnet;\n\n implementFullBIP44 = false;\n\n bridge: LedgerBridge<LedgerBridgeOptions>;\n\n constructor({ bridge }: { bridge: LedgerBridge<LedgerBridgeOptions> }) {\n if (!bridge) {\n throw new Error('Bridge is a required dependency for the keyring');\n }\n\n this.bridge = bridge;\n }\n\n async init(): Promise<void> {\n return this.bridge.init();\n }\n\n async destroy(): Promise<void> {\n return this.bridge.destroy();\n }\n\n async serialize(): Promise<\n Omit<LedgerKeyringSerializedState, 'accountIndexes'>\n > {\n return {\n hdPath: this.hdPath,\n accounts: this.accounts.slice(),\n deviceId: this.deviceId,\n accountDetails: this.accountDetails,\n implementFullBIP44: false,\n };\n }\n\n async deserialize(opts: LedgerKeyringSerializedState): Promise<void> {\n this.hdPath = opts.hdPath ?? hdPathString;\n this.accounts = opts.accounts ?? [];\n this.deviceId = opts.deviceId ?? '';\n this.accountDetails = opts.accountDetails ?? {};\n\n if (!opts.accountDetails) {\n this.#migrateAccountDetails(opts);\n }\n\n this.implementFullBIP44 = opts.implementFullBIP44 ?? false;\n\n const keys = new Set<string>(Object.keys(this.accountDetails));\n // Remove accounts that don't have corresponding account details\n this.accounts = this.accounts.filter((account) =>\n keys.has(this.#getChecksumHexAddress(account)),\n );\n\n return Promise.resolve();\n }\n\n public setDeviceId(deviceId: string): void {\n this.deviceId = deviceId;\n }\n\n public getDeviceId(): string {\n return this.deviceId;\n }\n\n #migrateAccountDetails(opts: Partial<LedgerBridgeKeyringOptions>): void {\n if (this.#isLedgerLiveHdPath() && opts.accountIndexes) {\n for (const [account, index] of Object.entries(opts.accountIndexes)) {\n this.accountDetails[account] = {\n bip44: true,\n hdPath: this.#getPathForIndex(index),\n };\n }\n }\n const keys = new Set<string>(Object.keys(this.accountDetails));\n // try to migrate non-LedgerLive accounts too\n if (!this.#isLedgerLiveHdPath()) {\n this.accounts.forEach((account) => {\n const key = this.#getChecksumHexAddress(account);\n\n if (!keys.has(key)) {\n this.accountDetails[key] = {\n bip44: false,\n hdPath: this.#pathFromAddress(account),\n };\n }\n });\n }\n }\n\n isUnlocked(): boolean {\n return Boolean(this.hdk.publicKey);\n }\n\n isConnected(): boolean {\n return this.bridge.isDeviceConnected;\n }\n\n setAccountToUnlock(index: number): void {\n this.unlockedAccount = index;\n }\n\n setHdPath(hdPath: string): void {\n // Reset HDKey if the path changes\n if (this.hdPath !== hdPath) {\n this.hdk = new HDKey();\n }\n this.hdPath = hdPath;\n }\n\n async unlock(hdPath?: string, updateHdk = true): Promise<Hex> {\n if (this.isUnlocked() && !hdPath) {\n // if the device is already unlocked and no path is provided,\n // we return the checksummed address of the public key stored in\n // `this.hdk`, which is the root address of the last unlocked path.\n return this.#getChecksumHexAddress(\n publicToAddress(this.hdk.publicKey, true).toString('hex'),\n );\n }\n const path = hdPath ? this.#toLedgerPath(hdPath) : this.hdPath;\n\n let payload;\n try {\n payload = await this.bridge.getPublicKey({\n hdPath: path,\n });\n } catch (error) {\n throw error instanceof Error\n ? error\n : new Error('Ledger Ethereum app closed. Open it to unlock.');\n }\n\n if (updateHdk && payload.chainCode) {\n this.hdk.publicKey = Buffer.from(payload.publicKey, 'hex');\n this.hdk.chainCode = Buffer.from(payload.chainCode, 'hex');\n }\n\n return add0x(payload.address);\n }\n\n async addAccounts(amount: number): Promise<Hex[]> {\n return new Promise((resolve, reject) => {\n this.unlock()\n .then(async (_) => {\n const from = this.unlockedAccount;\n const to = from + amount;\n const newAccounts: Hex[] = [];\n for (let i = from; i < to; i++) {\n const path = this.#getPathForIndex(i);\n let address: Hex;\n if (this.#isLedgerLiveHdPath()) {\n address = await this.unlock(path);\n } else {\n address = this.#addressFromIndex(pathBase, i);\n }\n\n this.accountDetails[this.#getChecksumHexAddress(address)] = {\n // TODO: consider renaming this property, as the current name is misleading\n // It's currently used to represent whether an account uses the Ledger Live path.\n bip44: this.#isLedgerLiveHdPath(),\n hdPath: path,\n };\n\n if (!this.accounts.includes(address)) {\n this.accounts = [...this.accounts, address];\n newAccounts.push(address);\n }\n this.page = 0;\n }\n resolve(newAccounts);\n })\n .catch(reject);\n });\n }\n\n getName(): string {\n return keyringType;\n }\n\n async getFirstPage(): Promise<AccountPage> {\n this.page = 0;\n return this.#getPage(1);\n }\n\n async getNextPage(): Promise<AccountPage> {\n return this.#getPage(1);\n }\n\n async getPreviousPage(): Promise<AccountPage> {\n return this.#getPage(-1);\n }\n\n async getAccounts(): Promise<Hex[]> {\n return Promise.resolve(this.accounts.slice());\n }\n\n removeAccount(address: string): void {\n const filteredAccounts = this.accounts.filter(\n (a) => a.toLowerCase() !== address.toLowerCase(),\n );\n\n if (filteredAccounts.length === this.accounts.length) {\n throw new Error(`Address ${address} not found in this keyring`);\n }\n\n this.accounts = filteredAccounts;\n delete this.accountDetails[this.#getChecksumHexAddress(address)];\n }\n\n async attemptMakeApp(): Promise<boolean> {\n return this.bridge.attemptMakeApp();\n }\n\n async updateTransportMethod(transportType: string): Promise<boolean> {\n return this.bridge.updateTransportMethod(transportType);\n }\n\n // tx is an instance of the ethereumjs-transaction class.\n async signTransaction(\n address: Hex,\n tx: TypedTransaction | OldEthJsTransaction,\n ): Promise<TypedTransaction | OldEthJsTransaction> {\n let rawTxHex;\n // transactions built with older versions of ethereumjs-tx have a\n // getChainId method that newer versions do not. Older versions are mutable\n // while newer versions default to being immutable. Expected shape and type\n // of data for v, r and s differ (Buffer (old) vs BN (new))\n if (isOldStyleEthereumjsTx(tx)) {\n // In this version of ethereumjs-tx we must add the chainId in hex format\n // to the initial v value. The chainId must be included in the serialized\n // transaction which is only communicated to ethereumjs-tx in this\n // value. In newer versions the chainId is communicated via the 'Common'\n // object.\n // @ts-expect-error tx.v should be a Buffer, but we are assigning a string\n tx.v = bufferToHex(tx.getChainId());\n // @ts-expect-error tx.r should be a Buffer, but we are assigning a string\n tx.r = '0x00';\n // @ts-expect-error tx.s should be a Buffer, but we are assigning a string\n tx.s = '0x00';\n\n rawTxHex = tx.serialize().toString('hex');\n\n return this.#signTransaction(address, rawTxHex, (payload) => {\n tx.v = Buffer.from(payload.v, 'hex');\n tx.r = Buffer.from(payload.r, 'hex');\n tx.s = Buffer.from(payload.s, 'hex');\n return tx;\n });\n }\n\n // The below `encode` call is only necessary for legacy transactions, as `getMessageToSign`\n // calls `rlp.encode` internally for non-legacy transactions. As per the \"Transaction Execution\"\n // section of the ethereum yellow paper, transactions need to be \"well-formed RLP, with no additional\n // trailing bytes\".\n\n // Note also that `getMessageToSign` will return valid RLP for all transaction types, whereas the\n // `serialize` method will not for any transaction type except legacy. This is because `serialize` includes\n // empty r, s and v values in the encoded rlp. This is why we use `getMessageToSign` here instead of `serialize`.\n const messageToSign = tx.getMessageToSign(false);\n\n rawTxHex = Buffer.isBuffer(messageToSign)\n ? messageToSign.toString('hex')\n : Buffer.from(RLP.encode(messageToSign)).toString('hex');\n\n return this.#signTransaction(address, rawTxHex, (payload) => {\n // Because tx will be immutable, first get a plain javascript object that\n // represents the transaction. Using txData here as it aligns with the\n // nomenclature of ethereumjs/tx.\n const txData: TxData = tx.toJSON();\n // The fromTxData utility expects a type to support transactions with a type other than 0\n txData.type = tx.type;\n // The fromTxData utility expects v,r and s to be hex prefixed\n txData.v = add0x(payload.v);\n txData.r = add0x(payload.r);\n txData.s = add0x(payload.s);\n // Adopt the 'common' option from the original transaction and set the\n // returned object to be frozen if the original is frozen.\n return TransactionFactory.fromTxData(txData, {\n common: tx.common,\n freeze: Object.isFrozen(tx),\n });\n });\n }\n\n async #signTransaction(\n address: Hex,\n rawTxHex: string,\n handleSigning: (\n payload: SignTransactionPayload,\n ) => TypedTransaction | OldEthJsTransaction,\n ): Promise<TypedTransaction | OldEthJsTransaction> {\n const hdPath = await this.unlockAccountByAddress(address);\n\n if (!hdPath) {\n throw new Error('Ledger: Unknown error while signing transaction');\n }\n\n let payload;\n try {\n payload = await this.bridge.deviceSignTransaction({\n tx: rawTxHex,\n hdPath,\n });\n } catch (error) {\n throw error instanceof Error\n ? error\n : new Error('Ledger: Unknown error while signing transaction');\n }\n\n const newOrMutatedTx = handleSigning(payload);\n const valid = newOrMutatedTx.verifySignature();\n if (valid) {\n return newOrMutatedTx;\n }\n throw new Error('Ledger: The transaction signature is not valid');\n }\n\n async signMessage(withAccount: Hex, data: string): Promise<string> {\n return this.signPersonalMessage(withAccount, data);\n }\n\n // For personal_sign, we need to prefix the message:\n async signPersonalMessage(\n withAccount: Hex,\n message: string,\n ): Promise<string> {\n const hdPath = await this.unlockAccountByAddress(withAccount);\n\n if (!hdPath) {\n throw new Error('Ledger: Unknown error while signing message');\n }\n\n let payload;\n try {\n payload = await this.bridge.deviceSignMessage({\n hdPath,\n message: remove0x(message),\n });\n } catch (error) {\n throw error instanceof Error\n ? error\n : new Error('Ledger: Unknown error while signing message');\n }\n\n let modifiedV = parseInt(String(payload.v), 10).toString(16);\n if (modifiedV.length < 2) {\n modifiedV = `0${modifiedV}`;\n }\n\n const signature = `0x${payload.r}${payload.s}${modifiedV}`;\n const addressSignedWith = recoverPersonalSignature({\n data: message,\n signature,\n });\n if (\n this.#getChecksumHexAddress(addressSignedWith) !==\n this.#getChecksumHexAddress(withAccount)\n ) {\n throw new Error('Ledger: The signature doesnt match the right address');\n }\n return signature;\n }\n\n async unlockAccountByAddress(address: Hex): Promise<string | undefined> {\n const checksummedAddress = this.#getChecksumHexAddress(address);\n const accountDetails = this.accountDetails[checksummedAddress];\n if (!accountDetails) {\n throw new Error(\n `Ledger: Account for address '${checksummedAddress}' not found`,\n );\n }\n const { hdPath } = accountDetails;\n const unlockedAddress = await this.unlock(hdPath, false);\n\n // unlock resolves to the address for the given hdPath as reported by the ledger device\n // if that address is not the requested address, then this account belongs to a different device or seed\n if (unlockedAddress.toLowerCase() !== address.toLowerCase()) {\n throw new Error(\n `Ledger: Account ${address} does not belong to the connected device`,\n );\n }\n return hdPath;\n }\n\n async signTypedData<T extends MessageTypes>(\n withAccount: Hex,\n data: TypedMessage<T>,\n options: { version?: string } = {},\n ): Promise<string> {\n const isV4 = options.version === 'V4';\n if (!isV4) {\n throw new Error(\n 'Ledger: Only version 4 of typed data signing is supported',\n );\n }\n\n const { domain, types, primaryType, message } =\n TypedDataUtils.sanitizeData(data);\n\n const hdPath = await this.unlockAccountByAddress(withAccount);\n\n if (!hdPath) {\n throw new Error('Ledger: Unknown error while signing message');\n }\n\n let payload;\n try {\n payload = await this.bridge.deviceSignTypedData({\n hdPath,\n message: {\n domain: {\n name: domain.name,\n chainId: domain.chainId,\n version: domain.version,\n verifyingContract: domain.verifyingContract,\n salt: this.#convertSaltIfAny(domain.salt),\n },\n types,\n primaryType: primaryType.toString(),\n message,\n },\n });\n } catch (error) {\n throw error instanceof Error\n ? error\n : new Error('Ledger: Unknown error while signing message');\n }\n\n let recoveryId = parseInt(String(payload.v), 10).toString(16);\n if (recoveryId.length < 2) {\n recoveryId = `0${recoveryId}`;\n }\n const signature = `0x${payload.r}${payload.s}${recoveryId}`;\n const addressSignedWith = recoverTypedSignature({\n data,\n signature,\n version: SignTypedDataVersion.V4,\n });\n\n if (\n this.#getChecksumHexAddress(addressSignedWith) !==\n this.#getChecksumHexAddress(withAccount)\n ) {\n throw new Error('Ledger: The signature doesnt match the right address');\n }\n return signature;\n }\n\n forgetDevice(): void {\n this.deviceId = '';\n this.accounts = [];\n this.page = 0;\n this.unlockedAccount = 0;\n this.paths = {};\n this.accountDetails = {};\n this.hdk = new HDKey();\n }\n\n #convertSaltIfAny(salt: ArrayBuffer | undefined): string | undefined {\n if (!salt) {\n return undefined;\n }\n\n // We convert this to a plain string to avoid encoding issue on the\n // mobile side (to avoid using `TextDecoder`).\n const saltBytes = new Uint8Array(salt);\n return String.fromCharCode(...saltBytes);\n }\n\n /* PRIVATE METHODS */\n async #getPage(increment: number): Promise<AccountPage> {\n this.page += increment;\n\n if (this.page <= 0) {\n this.page = 1;\n }\n const from = (this.page - 1) * this.perPage;\n const to = from + this.perPage;\n\n await this.unlock();\n let accounts;\n if (this.#isLedgerLiveHdPath()) {\n accounts = await this.#getAccountsBIP44(from, to);\n } else {\n accounts = this.#getAccountsLegacy(from, to);\n }\n return accounts;\n }\n\n async #getAccountsBIP44(from: number, to: number): Promise<AccountPage> {\n const accounts: AccountPage = [];\n\n for (let i = from; i < to; i++) {\n const path = this.#getPathForIndex(i);\n const address = await this.unlock(path);\n const valid = this.implementFullBIP44\n ? await this.#hasPreviousTransactions(address)\n : true;\n accounts.push({\n address,\n balance: null,\n index: i,\n });\n\n // PER BIP44\n // \"Software should prevent a creation of an account if\n // a previous account does not have a transaction history\n // (meaning none of its addresses have been used before).\"\n if (!valid) {\n break;\n }\n }\n return accounts;\n }\n\n #getAccountsLegacy(from: number, to: number): AccountPage {\n const accounts: AccountPage = [];\n\n for (let i = from; i < to; i++) {\n const address = this.#addressFromIndex(pathBase, i);\n accounts.push({\n address,\n balance: null,\n index: i,\n });\n this.paths[this.#getChecksumHexAddress(address)] = i;\n }\n return accounts;\n }\n\n #addressFromIndex(basePath: string, i: number): Hex {\n const dkey = this.hdk.derive(`${basePath}/${i}`);\n const address = publicToAddress(dkey.publicKey, true).toString('hex');\n return this.#getChecksumHexAddress(add0x(address));\n }\n\n #pathFromAddress(address: string): string {\n const checksummedAddress = this.#getChecksumHexAddress(address);\n let index = this.paths[checksummedAddress];\n if (typeof index === 'undefined') {\n for (let i = 0; i < MAX_INDEX; i++) {\n if (checksummedAddress === this.#addressFromIndex(pathBase, i)) {\n index = i;\n break;\n }\n }\n }\n\n if (typeof index === 'undefined') {\n throw new Error('Unknown address');\n }\n return this.#getPathForIndex(index);\n }\n\n #getPathForIndex(index: number): string {\n // Check if the path is BIP 44 (Ledger Live)\n return this.#isLedgerLiveHdPath()\n ? `m/44'/60'/${index}'/0/0`\n : `${this.hdPath}/${index}`;\n }\n\n #isLedgerLiveHdPath(): boolean {\n return this.hdPath === `m/44'/60'/0'/0/0`;\n }\n\n #toLedgerPath(path: string): string {\n return path.toString().replace('m/', '');\n }\n\n async #hasPreviousTransactions(address: string): Promise<boolean> {\n const apiUrl = this.#getApiUrl();\n const response = await window.fetch(\n `${apiUrl}/api?module=account&action=txlist&address=${address}&tag=latest&page=1&offset=1`,\n );\n const parsedResponse = await response.json();\n return parsedResponse.status !== '0' && parsedResponse.result.length > 0;\n }\n\n #getApiUrl(): NetworkApiUrls {\n return this.network;\n }\n\n #getChecksumHexAddress(address: string): Hex {\n return getChecksumAddress(add0x(address));\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask/eth-ledger-bridge-keyring",
3
- "version": "8.0.5",
3
+ "version": "9.0.0",
4
4
  "description": "A MetaMask compatible keyring, for ledger hardware wallets",
5
5
  "keywords": [
6
6
  "ethereum",
@@ -62,6 +62,7 @@
62
62
  "@ledgerhq/types-devices": "^6.25.3",
63
63
  "@ledgerhq/types-live": "^6.52.0",
64
64
  "@metamask/auto-changelog": "^3.4.4",
65
+ "@metamask/keyring-utils": "^2.3.1",
65
66
  "@metamask/utils": "^11.1.0",
66
67
  "@ts-bridge/cli": "^0.6.3",
67
68
  "@types/ethereumjs-tx": "^1.0.1",