@metamask/eth-hd-keyring 4.0.2 → 6.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/.eslintrc.js CHANGED
@@ -7,6 +7,9 @@ module.exports = {
7
7
  {
8
8
  files: ['test/**/*.js'],
9
9
  extends: ['@metamask/eslint-config-jest'],
10
+ rules: {
11
+ 'node/no-unpublished-require': 0,
12
+ },
10
13
  },
11
14
  ],
12
15
 
@@ -0,0 +1,9 @@
1
+ /* eslint-disable */
2
+ //prettier-ignore
3
+ module.exports = {
4
+ name: "@yarnpkg/plugin-allow-scripts",
5
+ factory: function (require) {
6
+ var plugin=(()=>{var a=Object.create,l=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var s=Object.getOwnPropertyNames;var p=Object.getPrototypeOf,c=Object.prototype.hasOwnProperty;var u=e=>l(e,"__esModule",{value:!0});var f=e=>{if(typeof require!="undefined")return require(e);throw new Error('Dynamic require of "'+e+'" is not supported')};var g=(e,o)=>{for(var r in o)l(e,r,{get:o[r],enumerable:!0})},m=(e,o,r)=>{if(o&&typeof o=="object"||typeof o=="function")for(let t of s(o))!c.call(e,t)&&t!=="default"&&l(e,t,{get:()=>o[t],enumerable:!(r=i(o,t))||r.enumerable});return e},x=e=>m(u(l(e!=null?a(p(e)):{},"default",e&&e.__esModule&&"default"in e?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e);var k={};g(k,{default:()=>d});var n=x(f("@yarnpkg/shell")),y={hooks:{afterAllInstalled:async()=>{let e=await(0,n.execute)("yarn run allow-scripts");e!==0&&process.exit(e)}}},d=y;return k;})();
7
+ return plugin;
8
+ }
9
+ };
package/CHANGELOG.md CHANGED
@@ -6,6 +6,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [6.0.0]
10
+ ### Changed
11
+ - Revert mnemonic serialization format from `Record<number, number>` (i.e. a stringified `Uint8Array`) which was introduced in v5.0.0 back to an untyped array of utf8 encoded bytes, which was the format prior to v5.0.0 ([#81](https://github.com/MetaMask/eth-hd-keyring/pull/81))
12
+
13
+ ## [5.0.1] [DEPRECATED]
14
+ ### Removed
15
+ - Remove prepack script and references in order to fix publish release flow ([#77](https://github.com/MetaMask/eth-hd-keyring/pull/77))
16
+
17
+ ## [5.0.0] [DEPRECATED]
18
+ ### Changed
19
+ - **BREAKING**: Update minimum Node.js version from v12 to v14 ([#67](https://github.com/MetaMask/eth-hd-keyring/pull/67))
20
+ - **BREAKING:** Makes version-specific `signTypedData` methods private ([#71](https://github.com/MetaMask/eth-hd-keyring/pull/71))
21
+ - Consumers should use the generic `signTypedData` method and pass the version they'd like as a property in the options argument.
22
+ - **BREAKING:** Makes the `wallets` property private ([#71](https://github.com/MetaMask/eth-hd-keyring/pull/71))
23
+ - Consumers should not use this property as it is intended for internal use only.
24
+ - **BREAKING:** Makes `getPrivateKeyFor` a private method ([#71](https://github.com/MetaMask/eth-hd-keyring/pull/71))
25
+ - Consumers who wish to get the private key for a given account should use the `exportAccount` method.
26
+ - **BREAKING:** Bumps browser requirements to those with ES2020 support or greater ([#70](https://github.com/MetaMask/eth-hd-keyring/pull/70))
27
+ - This change is introduced in update of `@metamask/eth-sig-util` to v5 and new direct dependency on `ethereumjs/util` v8.0.2
28
+ - Replaces use of `ethereumjs-wallet` implementation of hdkey with one from `ethereum-cryptography` and adapts accordingly. ([#69](https://github.com/MetaMask/eth-hd-keyring/pull/69))
29
+ - Replaces `@metamask/bip39` with `@metamask/scure-bip39` ([#67](https://github.com/MetaMask/eth-hd-keyring/pull/67))
30
+
31
+ ### Removed
32
+ - **BREAKING:** Remove redundant `newGethSignMessage` method ([#71](https://github.com/MetaMask/eth-hd-keyring/pull/71))
33
+ - Consumers can use `signPersonalMessage` method as a replacement for newGethSignMessage.
34
+ - **BREAKING:** `HDKeyring` no longer extends `EventEmitter`, so no `EventEmitter` methods are available on this class ([#70](https://github.com/MetaMask/eth-hd-keyring/pull/70))
35
+ - Removes `ethereumjs-util` dependency. ([#67](https://github.com/MetaMask/eth-hd-keyring/pull/67))
36
+
9
37
  ## [4.0.2]
10
38
  ### Added
11
39
  - Add parameter validation for constructor / `deserialize` method ([#65](https://github.com/MetaMask/eth-hd-keyring/pull/65))
@@ -30,7 +58,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
30
58
  - Deserialize method (and `HdKeyring` constructor by extension) can no longer be passed an options object containing a value for `numberOfAccounts` if it is not also containing a value for `mnemonic`.
31
59
  - Package name changed from `eth-hd-keyring` to `@metamask/eth-hd-keyring`.
32
60
 
33
- [Unreleased]: https://github.com/MetaMask/eth-hd-keyring/compare/v4.0.2...HEAD
61
+ [Unreleased]: https://github.com/MetaMask/eth-hd-keyring/compare/v6.0.0...HEAD
62
+ [6.0.0]: https://github.com/MetaMask/eth-hd-keyring/compare/v5.0.1...v6.0.0
63
+ [5.0.1]: https://github.com/MetaMask/eth-hd-keyring/compare/v5.0.0...v5.0.1
64
+ [5.0.0]: https://github.com/MetaMask/eth-hd-keyring/compare/v4.0.2...v5.0.0
34
65
  [4.0.2]: https://github.com/MetaMask/eth-hd-keyring/compare/v4.0.1...v4.0.2
35
66
  [4.0.1]: https://github.com/MetaMask/eth-hd-keyring/compare/v4.0.0...v4.0.1
36
67
  [4.0.0]: https://github.com/MetaMask/eth-hd-keyring/releases/tag/v4.0.0
package/README.md CHANGED
@@ -79,9 +79,8 @@ Exports the specified account as a private key hex string.
79
79
 
80
80
  - Install [Node.js](https://nodejs.org) version 12
81
81
  - If you are using [nvm](https://github.com/creationix/nvm#installation) (recommended) running `nvm use` will automatically choose the right node version for you.
82
- - Install [Yarn v1](https://yarnpkg.com/en/docs/install)
83
- - Run `yarn setup` to install dependencies and run any requried post-install scripts
84
- - **Warning:** Do not use the `yarn` / `yarn install` command directly. Use `yarn setup` instead. The normal install command will skip required post-install scripts, leaving your development environment in an invalid state.
82
+ - Install [Yarn v3](https://yarnpkg.com/getting-started/install)
83
+ - Run `yarn install` to install dependencies and run any required post-install scripts
85
84
 
86
85
  ### Testing and Linting
87
86
 
package/index.js CHANGED
@@ -1,33 +1,93 @@
1
- const { hdkey } = require('ethereumjs-wallet');
2
- const SimpleKeyring = require('eth-simple-keyring');
3
- const bip39 = require('@metamask/bip39');
4
- const { normalize } = require('@metamask/eth-sig-util');
1
+ const { HDKey } = require('ethereum-cryptography/hdkey');
2
+ const { keccak256 } = require('ethereum-cryptography/keccak');
3
+ const { bytesToHex } = require('ethereum-cryptography/utils');
4
+ const {
5
+ stripHexPrefix,
6
+ privateToPublic,
7
+ publicToAddress,
8
+ ecsign,
9
+ arrToBufArr,
10
+ bufferToHex,
11
+ } = require('@ethereumjs/util');
12
+ const bip39 = require('@metamask/scure-bip39');
13
+ const { wordlist } = require('@metamask/scure-bip39/dist/wordlists/english');
14
+ const {
15
+ concatSig,
16
+ decrypt,
17
+ getEncryptionPublicKey,
18
+ normalize,
19
+ personalSign,
20
+ signTypedData,
21
+ SignTypedDataVersion,
22
+ } = require('@metamask/eth-sig-util');
5
23
 
6
24
  // Options:
7
25
  const hdPathString = `m/44'/60'/0'/0`;
8
26
  const type = 'HD Key Tree';
9
27
 
10
- class HdKeyring extends SimpleKeyring {
28
+ class HdKeyring {
11
29
  /* PUBLIC METHODS */
12
30
  constructor(opts = {}) {
13
- super();
14
31
  this.type = type;
32
+ this._wallets = [];
15
33
  this.deserialize(opts);
16
34
  }
17
35
 
18
36
  generateRandomMnemonic() {
19
- this._initFromMnemonic(bip39.generateMnemonic());
37
+ this._initFromMnemonic(bip39.generateMnemonic(wordlist));
38
+ }
39
+
40
+ _uint8ArrayToString(mnemonic) {
41
+ const recoveredIndices = Array.from(
42
+ new Uint16Array(new Uint8Array(mnemonic).buffer),
43
+ );
44
+ return recoveredIndices.map((i) => wordlist[i]).join(' ');
45
+ }
46
+
47
+ _stringToUint8Array(mnemonic) {
48
+ const indices = mnemonic.split(' ').map((word) => wordlist.indexOf(word));
49
+ return new Uint8Array(new Uint16Array(indices).buffer);
50
+ }
51
+
52
+ _mnemonicToUint8Array(mnemonic) {
53
+ let mnemonicData = mnemonic;
54
+ // when encrypted/decrypted, buffers get cast into js object with a property type set to buffer
55
+ if (mnemonic && mnemonic.type && mnemonic.type === 'Buffer') {
56
+ mnemonicData = mnemonic.data;
57
+ }
58
+
59
+ if (
60
+ // this block is for backwards compatibility with vaults that were previously stored as buffers, number arrays or plain text strings
61
+ typeof mnemonicData === 'string' ||
62
+ Buffer.isBuffer(mnemonicData) ||
63
+ Array.isArray(mnemonicData)
64
+ ) {
65
+ let mnemonicAsString = mnemonicData;
66
+ if (Array.isArray(mnemonicData)) {
67
+ mnemonicAsString = Buffer.from(mnemonicData).toString();
68
+ } else if (Buffer.isBuffer(mnemonicData)) {
69
+ mnemonicAsString = mnemonicData.toString();
70
+ }
71
+ return this._stringToUint8Array(mnemonicAsString);
72
+ } else if (
73
+ mnemonicData instanceof Object &&
74
+ !(mnemonicData instanceof Uint8Array)
75
+ ) {
76
+ // when encrypted/decrypted the Uint8Array becomes a js object we need to cast back to a Uint8Array
77
+ return Uint8Array.from(Object.values(mnemonicData));
78
+ }
79
+ return mnemonicData;
20
80
  }
21
81
 
22
82
  serialize() {
23
- const mnemonicAsBuffer =
24
- typeof this.mnemonic === 'string'
25
- ? Buffer.from(this.mnemonic, 'utf8')
26
- : this.mnemonic;
83
+ const mnemonicAsString = this._uint8ArrayToString(this.mnemonic);
84
+ const uint8ArrayMnemonic = new TextEncoder('utf-8').encode(
85
+ mnemonicAsString,
86
+ );
27
87
 
28
88
  return Promise.resolve({
29
- mnemonic: Array.from(mnemonicAsBuffer.values()),
30
- numberOfAccounts: this.wallets.length,
89
+ mnemonic: Array.from(uint8ArrayMnemonic),
90
+ numberOfAccounts: this._wallets.length,
31
91
  hdPath: this.hdPath,
32
92
  });
33
93
  }
@@ -45,7 +105,7 @@ class HdKeyring extends SimpleKeyring {
45
105
  );
46
106
  }
47
107
  this.opts = opts;
48
- this.wallets = [];
108
+ this._wallets = [];
49
109
  this.mnemonic = null;
50
110
  this.root = null;
51
111
  this.hdPath = opts.hdPath || hdPathString;
@@ -66,29 +126,147 @@ class HdKeyring extends SimpleKeyring {
66
126
  throw new Error('Eth-Hd-Keyring: No secret recovery phrase provided');
67
127
  }
68
128
 
69
- const oldLen = this.wallets.length;
129
+ const oldLen = this._wallets.length;
70
130
  const newWallets = [];
71
131
  for (let i = oldLen; i < numberOfAccounts + oldLen; i++) {
72
- const child = this.root.deriveChild(i);
73
- const wallet = child.getWallet();
132
+ const wallet = this.root.deriveChild(i);
74
133
  newWallets.push(wallet);
75
- this.wallets.push(wallet);
134
+ this._wallets.push(wallet);
76
135
  }
77
136
  const hexWallets = newWallets.map((w) => {
78
- return normalize(w.getAddress().toString('hex'));
137
+ return this._addressfromPublicKey(w.publicKey);
79
138
  });
80
139
  return Promise.resolve(hexWallets);
81
140
  }
82
141
 
83
142
  getAccounts() {
84
- return Promise.resolve(
85
- this.wallets.map((w) => {
86
- return normalize(w.getAddress().toString('hex'));
87
- }),
143
+ return this._wallets.map((w) => this._addressfromPublicKey(w.publicKey));
144
+ }
145
+
146
+ /* BASE KEYRING METHODS */
147
+
148
+ // returns an address specific to an app
149
+ async getAppKeyAddress(address, origin) {
150
+ if (!origin || typeof origin !== 'string') {
151
+ throw new Error(`'origin' must be a non-empty string`);
152
+ }
153
+ const wallet = this._getWalletForAccount(address, {
154
+ withAppKeyOrigin: origin,
155
+ });
156
+ const appKeyAddress = normalize(
157
+ publicToAddress(wallet.publicKey).toString('hex'),
88
158
  );
159
+
160
+ return appKeyAddress;
161
+ }
162
+
163
+ // exportAccount should return a hex-encoded private key:
164
+ async exportAccount(address, opts = {}) {
165
+ const wallet = this._getWalletForAccount(address, opts);
166
+ return bytesToHex(wallet.privateKey);
167
+ }
168
+
169
+ // tx is an instance of the ethereumjs-transaction class.
170
+ async signTransaction(address, tx, opts = {}) {
171
+ const privKey = this._getPrivateKeyFor(address, opts);
172
+ const signedTx = tx.sign(privKey);
173
+ // Newer versions of Ethereumjs-tx are immutable and return a new tx object
174
+ return signedTx === undefined ? tx : signedTx;
175
+ }
176
+
177
+ // For eth_sign, we need to sign arbitrary data:
178
+ async signMessage(address, data, opts = {}) {
179
+ const message = stripHexPrefix(data);
180
+ const privKey = this._getPrivateKeyFor(address, opts);
181
+ const msgSig = ecsign(Buffer.from(message, 'hex'), privKey);
182
+ const rawMsgSig = concatSig(msgSig.v, msgSig.r, msgSig.s);
183
+ return rawMsgSig;
184
+ }
185
+
186
+ // For personal_sign, we need to prefix the message:
187
+ async signPersonalMessage(address, msgHex, opts = {}) {
188
+ const privKey = this._getPrivateKeyFor(address, opts);
189
+ const privateKey = Buffer.from(privKey, 'hex');
190
+ const sig = personalSign({ privateKey, data: msgHex });
191
+ return sig;
192
+ }
193
+
194
+ // For eth_decryptMessage:
195
+ async decryptMessage(withAccount, encryptedData) {
196
+ const wallet = this._getWalletForAccount(withAccount);
197
+ const { privateKey: privateKeyAsUint8Array } = wallet;
198
+ const privateKeyAsHex = Buffer.from(privateKeyAsUint8Array).toString('hex');
199
+ const sig = decrypt({ privateKey: privateKeyAsHex, encryptedData });
200
+ return sig;
89
201
  }
90
202
 
91
- /* PRIVATE METHODS */
203
+ // personal_signTypedData, signs data along with the schema
204
+ async signTypedData(
205
+ withAccount,
206
+ typedData,
207
+ opts = { version: SignTypedDataVersion.V1 },
208
+ ) {
209
+ // Treat invalid versions as "V1"
210
+ const version = Object.keys(SignTypedDataVersion).includes(opts.version)
211
+ ? opts.version
212
+ : SignTypedDataVersion.V1;
213
+
214
+ const privateKey = this._getPrivateKeyFor(withAccount, opts);
215
+ return signTypedData({ privateKey, data: typedData, version });
216
+ }
217
+
218
+ removeAccount(account) {
219
+ const address = normalize(account);
220
+ if (
221
+ !this._wallets
222
+ .map(({ publicKey }) => this._addressfromPublicKey(publicKey))
223
+ .includes(address)
224
+ ) {
225
+ throw new Error(`Address ${address} not found in this keyring`);
226
+ }
227
+
228
+ this._wallets = this._wallets.filter(
229
+ ({ publicKey }) => this._addressfromPublicKey(publicKey) !== address,
230
+ );
231
+ }
232
+
233
+ // get public key for nacl
234
+ async getEncryptionPublicKey(withAccount, opts = {}) {
235
+ const privKey = this._getPrivateKeyFor(withAccount, opts);
236
+ const publicKey = getEncryptionPublicKey(privKey);
237
+ return publicKey;
238
+ }
239
+
240
+ _getPrivateKeyFor(address, opts = {}) {
241
+ if (!address) {
242
+ throw new Error('Must specify address.');
243
+ }
244
+ const wallet = this._getWalletForAccount(address, opts);
245
+ return wallet.privateKey;
246
+ }
247
+
248
+ _getWalletForAccount(account, opts = {}) {
249
+ const address = normalize(account);
250
+ let wallet = this._wallets.find(({ publicKey }) => {
251
+ return this._addressfromPublicKey(publicKey) === address;
252
+ });
253
+ if (!wallet) {
254
+ throw new Error('HD Keyring - Unable to find matching address.');
255
+ }
256
+
257
+ if (opts.withAppKeyOrigin) {
258
+ const { privateKey } = wallet;
259
+ const appKeyOriginBuffer = Buffer.from(opts.withAppKeyOrigin, 'utf8');
260
+ const appKeyBuffer = Buffer.concat([privateKey, appKeyOriginBuffer]);
261
+ const appKeyPrivateKey = arrToBufArr(keccak256(appKeyBuffer, 256));
262
+ const appKeyPublicKey = privateToPublic(appKeyPrivateKey);
263
+ wallet = { privateKey: appKeyPrivateKey, publicKey: appKeyPublicKey };
264
+ }
265
+
266
+ return wallet;
267
+ }
268
+
269
+ /* PRIVATE / UTILITY METHODS */
92
270
 
93
271
  /**
94
272
  * Sets appropriate properties for the keyring based on the given
@@ -104,26 +282,28 @@ class HdKeyring extends SimpleKeyring {
104
282
  'Eth-Hd-Keyring: Secret recovery phrase already provided',
105
283
  );
106
284
  }
285
+
286
+ this.mnemonic = this._mnemonicToUint8Array(mnemonic);
287
+
107
288
  // validate before initializing
108
- const isValid = bip39.validateMnemonic(mnemonic);
289
+ const isValid = bip39.validateMnemonic(this.mnemonic, wordlist);
109
290
  if (!isValid) {
110
291
  throw new Error(
111
292
  'Eth-Hd-Keyring: Invalid secret recovery phrase provided',
112
293
  );
113
294
  }
114
295
 
115
- if (typeof mnemonic === 'string') {
116
- this.mnemonic = Buffer.from(mnemonic, 'utf8');
117
- } else if (Array.isArray(mnemonic)) {
118
- this.mnemonic = Buffer.from(mnemonic);
119
- } else {
120
- this.mnemonic = mnemonic;
121
- }
122
-
123
296
  // eslint-disable-next-line node/no-sync
124
- const seed = bip39.mnemonicToSeedSync(this.mnemonic);
125
- this.hdWallet = hdkey.fromMasterSeed(seed);
126
- this.root = this.hdWallet.derivePath(this.hdPath);
297
+ const seed = bip39.mnemonicToSeedSync(this.mnemonic, wordlist);
298
+ this.hdWallet = HDKey.fromMasterSeed(seed);
299
+ this.root = this.hdWallet.derive(this.hdPath);
300
+ }
301
+
302
+ // small helper function to convert publicKey in Uint8Array form to a publicAddress as a hex
303
+ _addressfromPublicKey(publicKey) {
304
+ return bufferToHex(
305
+ publicToAddress(Buffer.from(publicKey), true),
306
+ ).toLowerCase();
127
307
  }
128
308
  }
129
309
 
package/jest.config.js CHANGED
@@ -5,8 +5,8 @@ module.exports = {
5
5
  global: {
6
6
  branches: 84,
7
7
  functions: 100,
8
- lines: 96,
9
- statements: 96,
8
+ lines: 95,
9
+ statements: 95,
10
10
  },
11
11
  },
12
12
  moduleFileExtensions: ['js', 'json', 'jsx', 'ts', 'tsx', 'node'],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask/eth-hd-keyring",
3
- "version": "4.0.2",
3
+ "version": "6.0.0",
4
4
  "description": "A simple standard interface for a seed phrase generated set of Ethereum accounts.",
5
5
  "keywords": [
6
6
  "ethereum",
@@ -18,26 +18,27 @@
18
18
  "author": "Dan Finlay",
19
19
  "main": "index.js",
20
20
  "scripts": {
21
- "setup": "yarn install && yarn allow-scripts",
22
- "lint:eslint": "eslint . --cache --ext js,ts",
23
- "lint:misc": "prettier '**/*.json' '**/*.md' '!CHANGELOG.md' '**/*.yml' --ignore-path .gitignore",
24
21
  "lint": "yarn lint:eslint && yarn lint:misc --check",
22
+ "lint:eslint": "eslint . --cache --ext js,ts",
25
23
  "lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write",
24
+ "lint:misc": "prettier '**/*.json' '**/*.md' '!CHANGELOG.md' '**/*.yml' '!.yarnrc.yml' --ignore-path .gitignore --no-error-on-unmatched-pattern",
26
25
  "test": "jest"
27
26
  },
28
27
  "dependencies": {
29
- "@metamask/bip39": "^4.0.0",
30
- "@metamask/eth-sig-util": "^4.0.0",
31
- "eth-simple-keyring": "^4.2.0",
32
- "ethereumjs-util": "^7.0.9",
33
- "ethereumjs-wallet": "^1.0.1"
28
+ "@ethereumjs/util": "^8.0.2",
29
+ "@metamask/eth-sig-util": "^5.0.2",
30
+ "@metamask/scure-bip39": "^2.0.3",
31
+ "ethereum-cryptography": "^1.1.2"
34
32
  },
35
33
  "devDependencies": {
36
- "@lavamoat/allow-scripts": "^1.0.6",
34
+ "@ethereumjs/tx": "^4.0.1",
35
+ "@lavamoat/allow-scripts": "^2.1.0",
37
36
  "@metamask/auto-changelog": "^2.5.0",
37
+ "@metamask/bip39": "^4.0.0",
38
38
  "@metamask/eslint-config": "^8.0.0",
39
39
  "@metamask/eslint-config-jest": "^9.0.0",
40
40
  "@metamask/eslint-config-nodejs": "^8.0.0",
41
+ "@metamask/eth-hd-keyring": "4.0.1",
41
42
  "@types/jest": "^27.4.1",
42
43
  "eslint": "^7.32.0",
43
44
  "eslint-config-prettier": "^8.3.0",
@@ -49,8 +50,9 @@
49
50
  "prettier": "^2.4.1",
50
51
  "prettier-plugin-packagejson": "^2.2.12"
51
52
  },
53
+ "packageManager": "yarn@3.3.0",
52
54
  "engines": {
53
- "node": ">= 12.0.0"
55
+ "node": ">= 14.0.0"
54
56
  },
55
57
  "publishConfig": {
56
58
  "access": "public",
@@ -59,8 +61,8 @@
59
61
  "lavamoat": {
60
62
  "allowScripts": {
61
63
  "@lavamoat/preinstall-always-fail": false,
62
- "keccak": false,
63
- "secp256k1": false
64
+ "@metamask/eth-hd-keyring>ethereumjs-util>ethereum-cryptography>keccak": false,
65
+ "@metamask/eth-hd-keyring>ethereumjs-util>ethereum-cryptography>secp256k1": false
64
66
  }
65
67
  }
66
- }
68
+ }