@rabby-wallet/eth-hd-keyring 4.2.0-beta.1 → 4.3.0-beta.1

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/index.ts CHANGED
@@ -4,7 +4,13 @@ import SimpleKeyring from '@rabby-wallet/eth-simple-keyring';
4
4
  import * as bip39 from '@scure/bip39';
5
5
  import { wordlist } from '@scure/bip39/wordlists/english';
6
6
  import * as sigUtil from 'eth-sig-util';
7
- import { bytesToHex, publicToAddress, privateToPublic } from '@ethereumjs/util';
7
+ import {
8
+ bytesToHex,
9
+ publicToAddress,
10
+ privateToPublic,
11
+ hexToBytes,
12
+ } from '@ethereumjs/util';
13
+ import slip39 from 'slip39';
8
14
 
9
15
  // Options:
10
16
  const type = 'HD Key Tree';
@@ -43,6 +49,7 @@ interface DeserializeOption {
43
49
  accounts?: string[];
44
50
  accountDetails?: Record<string, AccountDetail>;
45
51
  publicKey?: string;
52
+ isSlip39?: boolean;
46
53
  }
47
54
 
48
55
  interface AccountDetail {
@@ -70,6 +77,7 @@ class HdKeyring extends SimpleKeyring {
70
77
  accounts: string[] = [];
71
78
  accountDetails: Record<string, AccountDetail> = {};
72
79
  passphrase?: string = '';
80
+ isSlip39 = false;
73
81
 
74
82
  /* PUBLIC METHODS */
75
83
  constructor(opts: DeserializeOption = {} as any) {
@@ -91,6 +99,7 @@ class HdKeyring extends SimpleKeyring {
91
99
  accounts: this.accounts,
92
100
  accountDetails: this.accountDetails,
93
101
  publicKey: this.publicKey,
102
+ isSlip39: this.isSlip39,
94
103
  });
95
104
  }
96
105
 
@@ -105,6 +114,7 @@ class HdKeyring extends SimpleKeyring {
105
114
  this.accounts = opts.accounts || [];
106
115
  this.accountDetails = opts.accountDetails || {};
107
116
  this.publicKey = opts.publicKey || '';
117
+ this.isSlip39 = opts.isSlip39 || false;
108
118
 
109
119
  if (opts.mnemonic) {
110
120
  this.mnemonic = opts.mnemonic;
@@ -119,9 +129,9 @@ class HdKeyring extends SimpleKeyring {
119
129
  return Promise.resolve([]);
120
130
  }
121
131
 
122
- initFromMnemonic(mnemonic, passphrase?: string) {
132
+ initFromMnemonic(mnemonic: string, passphrase?: string) {
123
133
  this.mnemonic = mnemonic;
124
- const seed = bip39.mnemonicToSeedSync(mnemonic, passphrase);
134
+ const seed = this.getSeed(mnemonic, passphrase);
125
135
  this.hdWallet = HDKey.fromMasterSeed(seed);
126
136
  if (!this.publicKey) {
127
137
  this.publicKey = this.calcBasePublicKey(this.hdWallet!);
@@ -357,7 +367,7 @@ class HdKeyring extends SimpleKeyring {
357
367
  * if passphrase is correct, the publicKey will be the same as the stored one
358
368
  */
359
369
  checkPassphrase(passphrase: string) {
360
- const seed = bip39.mnemonicToSeedSync(this.mnemonic!, passphrase);
370
+ const seed = this.getSeed(this.mnemonic!, passphrase);
361
371
  const hdWallet = HDKey.fromMasterSeed(seed);
362
372
  const publicKey = this.calcBasePublicKey(hdWallet);
363
373
 
@@ -383,6 +393,43 @@ class HdKeyring extends SimpleKeyring {
383
393
  const hdPath = this.getHDPathBase(hdPathType);
384
394
  this.setHdPath(hdPath);
385
395
  }
396
+
397
+ getSeed(mnemonic: string, passphrase?: string) {
398
+ if (HdKeyring.checkMnemonicIsSlip39(mnemonic)) {
399
+ this.isSlip39 = true;
400
+ return this.slip39MnemonicToSeedSync(mnemonic, passphrase);
401
+ }
402
+ return bip39.mnemonicToSeedSync(mnemonic, passphrase);
403
+ }
404
+
405
+ slip39MnemonicToSeedSync(mnemonic: string, passphrase?: string) {
406
+ const secretShares = mnemonic.split('\n');
407
+ const secretBytes = slip39.recoverSecret(secretShares, passphrase);
408
+ const seed = hexToBytes(bytesToHex(secretBytes));
409
+
410
+ return seed;
411
+ }
412
+
413
+ static checkMnemonicIsSlip39(mnemonic: string) {
414
+ const arr = mnemonic.split('\n');
415
+ try {
416
+ HdKeyring.slip39DecodeMnemonics(arr);
417
+ return true;
418
+ } catch (e) {
419
+ return false;
420
+ }
421
+ }
422
+
423
+ static slip39DecodeMnemonics(shares: string[]) {
424
+ return slip39.decodeMnemonics(shares);
425
+ }
426
+
427
+ static validateMnemonic(mnemonic: string) {
428
+ if (this.checkMnemonicIsSlip39(mnemonic)) {
429
+ return true;
430
+ }
431
+ return bip39.validateMnemonic(mnemonic, wordlist);
432
+ }
386
433
  }
387
434
 
388
435
  export default HdKeyring;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rabby-wallet/eth-hd-keyring",
3
- "version": "4.2.0-beta.1",
3
+ "version": "4.3.0-beta.1",
4
4
  "description": "A simple standard interface for a seed phrase generated set of Ethereum accounts.",
5
5
  "keywords": [
6
6
  "ethereum",
@@ -18,7 +18,7 @@
18
18
  "author": "Dan Finlay",
19
19
  "main": "dist/index.js",
20
20
  "scripts": {
21
- "build": "tsc",
21
+ "build": "tsup index.ts",
22
22
  "setup": "yarn install && yarn allow-scripts",
23
23
  "lint:eslint": "eslint . --cache --ext js,ts",
24
24
  "lint:misc": "prettier '**/*.json' '**/*.md' '!CHANGELOG.md' '**/*.yml' --ignore-path .gitignore",
@@ -32,7 +32,8 @@
32
32
  "@rabby-wallet/eth-simple-keyring": "^5.0.1",
33
33
  "@scure/bip39": "^1.2.1",
34
34
  "eth-sig-util": "^3.0.1",
35
- "ethereum-cryptography": "^2.1.2"
35
+ "ethereum-cryptography": "^2.1.2",
36
+ "slip39": "^0.1.9"
36
37
  },
37
38
  "devDependencies": {
38
39
  "@lavamoat/allow-scripts": "^1.0.6",
@@ -47,8 +48,10 @@
47
48
  "eslint-plugin-node": "^11.1.0",
48
49
  "eslint-plugin-prettier": "^3.3.1",
49
50
  "mocha": "^8.1.3",
51
+ "patch-package": "^8.0.0",
50
52
  "prettier": "^2.4.1",
51
53
  "prettier-plugin-packagejson": "^2.2.12",
54
+ "tsup": "^8.1.0",
52
55
  "typescript": "^4.4.4"
53
56
  },
54
57
  "engines": {
@@ -64,5 +67,11 @@
64
67
  "keccak": false,
65
68
  "secp256k1": false
66
69
  }
70
+ },
71
+ "tsup": {
72
+ "dts": true,
73
+ "noExternal": [
74
+ "slip39"
75
+ ]
67
76
  }
68
77
  }
@@ -0,0 +1,45 @@
1
+ diff --git a/node_modules/slip39/src/slip39.js b/node_modules/slip39/src/slip39.js
2
+ index aff1c16..82bf498 100644
3
+ --- a/node_modules/slip39/src/slip39.js
4
+ +++ b/node_modules/slip39/src/slip39.js
5
+ @@ -180,6 +180,8 @@ class Slip39 {
6
+ return slipHelper.validateMnemonic(mnemonic);
7
+ }
8
+
9
+ + static decodeMnemonics = slipHelper.decodeMnemonics;
10
+ +
11
+ fromPath(path) {
12
+ this.validatePath(path);
13
+
14
+ diff --git a/node_modules/slip39/src/slip39_helper.js b/node_modules/slip39/src/slip39_helper.js
15
+ index 8bcb956..ed4a207 100644
16
+ --- a/node_modules/slip39/src/slip39_helper.js
17
+ +++ b/node_modules/slip39/src/slip39_helper.js
18
+ @@ -100,21 +100,6 @@ Array.prototype.slip39Generate = function (m, v = (_) => _) {
19
+ return this;
20
+ };
21
+
22
+ -Array.prototype.toHexString = function () {
23
+ - return Array.prototype.map
24
+ - .call(this, function (byte) {
25
+ - return ("0" + (byte & 0xff).toString(16)).slice(-2);
26
+ - })
27
+ - .join("");
28
+ -};
29
+ -
30
+ -Array.prototype.toByteArray = function (hexString) {
31
+ - for (let i = 0; i < hexString.length; i = i + 2) {
32
+ - this.push(parseInt(hexString.substr(i, 2), 16));
33
+ - }
34
+ - return this;
35
+ -};
36
+ -
37
+ const BIGINT_WORD_BITS = BigInt(8);
38
+
39
+ function decodeBigInt(bytes) {
40
+ @@ -1886,4 +1871,5 @@ exports = module.exports = {
41
+ crypt,
42
+ bitsToBytes,
43
+ WORD_LIST,
44
+ + decodeMnemonics,
45
+ };