@rabby-wallet/eth-hd-keyring 3.6.11 → 4.0.0-alpha
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/dist/index.js +31 -9
- package/index.ts +50 -12
- package/package.json +5 -5
- package/test/index.js +11 -9
package/dist/index.js
CHANGED
|
@@ -31,10 +31,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
31
31
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
32
32
|
};
|
|
33
33
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
-
|
|
34
|
+
// import Wallet, { hdkey } from 'ethereumjs-wallet';
|
|
35
|
+
const hdkey_1 = require("ethereum-cryptography/hdkey");
|
|
35
36
|
const eth_simple_keyring_1 = __importDefault(require("@rabby-wallet/eth-simple-keyring"));
|
|
36
|
-
const bip39 = __importStar(require("bip39"));
|
|
37
|
+
const bip39 = __importStar(require("@scure/bip39"));
|
|
38
|
+
const english_1 = require("@scure/bip39/wordlists/english");
|
|
37
39
|
const sigUtil = __importStar(require("eth-sig-util"));
|
|
40
|
+
const util_1 = require("@ethereumjs/util");
|
|
38
41
|
// Options:
|
|
39
42
|
const hdPathString = "m/44'/60'/0'/0";
|
|
40
43
|
const type = 'HD Key Tree';
|
|
@@ -53,6 +56,7 @@ class HdKeyring extends eth_simple_keyring_1.default {
|
|
|
53
56
|
this.page = 0;
|
|
54
57
|
this.perPage = 5;
|
|
55
58
|
this.byImport = false;
|
|
59
|
+
this.publicKey = '';
|
|
56
60
|
this.deserialize(opts);
|
|
57
61
|
}
|
|
58
62
|
serialize() {
|
|
@@ -62,6 +66,7 @@ class HdKeyring extends eth_simple_keyring_1.default {
|
|
|
62
66
|
hdPath: this.hdPath,
|
|
63
67
|
byImport: this.byImport,
|
|
64
68
|
index: this.index,
|
|
69
|
+
publicKey: this.publicKey,
|
|
65
70
|
});
|
|
66
71
|
}
|
|
67
72
|
deserialize(opts = {}) {
|
|
@@ -71,6 +76,7 @@ class HdKeyring extends eth_simple_keyring_1.default {
|
|
|
71
76
|
this.hdPath = opts.hdPath || hdPathString;
|
|
72
77
|
this.byImport = !!opts.byImport;
|
|
73
78
|
this.index = opts.index || 0;
|
|
79
|
+
this.publicKey = opts.publicKey || '';
|
|
74
80
|
if (opts.mnemonic) {
|
|
75
81
|
this.initFromMnemonic(opts.mnemonic);
|
|
76
82
|
}
|
|
@@ -79,16 +85,26 @@ class HdKeyring extends eth_simple_keyring_1.default {
|
|
|
79
85
|
}
|
|
80
86
|
return Promise.resolve([]);
|
|
81
87
|
}
|
|
88
|
+
initPublicKey() {
|
|
89
|
+
this.root = this.hdWallet.derive(this.hdPath);
|
|
90
|
+
this.publicKey = (0, util_1.bytesToHex)(this.root.publicKey);
|
|
91
|
+
}
|
|
92
|
+
getPublicKey() {
|
|
93
|
+
return this.publicKey;
|
|
94
|
+
}
|
|
82
95
|
initFromMnemonic(mnemonic) {
|
|
83
96
|
this.mnemonic = mnemonic;
|
|
84
97
|
this._index2wallet = {};
|
|
85
98
|
const seed = bip39.mnemonicToSeedSync(mnemonic);
|
|
86
|
-
this.hdWallet =
|
|
87
|
-
this.root = this.hdWallet.
|
|
99
|
+
this.hdWallet = hdkey_1.HDKey.fromMasterSeed(seed);
|
|
100
|
+
this.root = this.hdWallet.derive(this.hdPath);
|
|
101
|
+
if (!this.publicKey) {
|
|
102
|
+
this.initPublicKey();
|
|
103
|
+
}
|
|
88
104
|
}
|
|
89
105
|
addAccounts(numberOfAccounts = 1) {
|
|
90
106
|
if (!this.root) {
|
|
91
|
-
this.initFromMnemonic(bip39.generateMnemonic());
|
|
107
|
+
this.initFromMnemonic(bip39.generateMnemonic(english_1.wordlist));
|
|
92
108
|
}
|
|
93
109
|
let count = numberOfAccounts;
|
|
94
110
|
let currentIdx = 0;
|
|
@@ -106,7 +122,7 @@ class HdKeyring extends eth_simple_keyring_1.default {
|
|
|
106
122
|
}
|
|
107
123
|
}
|
|
108
124
|
const hexWallets = newWallets.map((w) => {
|
|
109
|
-
return sigUtil.normalize(
|
|
125
|
+
return sigUtil.normalize(this._addressfromPublicKey(w.publicKey));
|
|
110
126
|
});
|
|
111
127
|
return Promise.resolve(hexWallets);
|
|
112
128
|
}
|
|
@@ -169,7 +185,7 @@ class HdKeyring extends eth_simple_keyring_1.default {
|
|
|
169
185
|
}
|
|
170
186
|
getAccounts() {
|
|
171
187
|
return Promise.resolve(this.wallets.map((w) => {
|
|
172
|
-
return sigUtil.normalize(
|
|
188
|
+
return sigUtil.normalize(this._addressfromPublicKey(w.publicKey));
|
|
173
189
|
}));
|
|
174
190
|
}
|
|
175
191
|
getIndexByAddress(address) {
|
|
@@ -184,12 +200,18 @@ class HdKeyring extends eth_simple_keyring_1.default {
|
|
|
184
200
|
_addressFromIndex(i) {
|
|
185
201
|
if (!this._index2wallet[i]) {
|
|
186
202
|
const child = this.root.deriveChild(i);
|
|
187
|
-
const wallet =
|
|
188
|
-
|
|
203
|
+
const wallet = {
|
|
204
|
+
publicKey: (0, util_1.privateToPublic)(child.privateKey),
|
|
205
|
+
privateKey: child.privateKey,
|
|
206
|
+
};
|
|
207
|
+
const address = sigUtil.normalize(this._addressfromPublicKey(wallet.publicKey));
|
|
189
208
|
this._index2wallet[i] = [address, wallet];
|
|
190
209
|
}
|
|
191
210
|
return this._index2wallet[i];
|
|
192
211
|
}
|
|
212
|
+
_addressfromPublicKey(publicKey) {
|
|
213
|
+
return (0, util_1.bytesToHex)((0, util_1.publicToAddress)(publicKey, true)).toLowerCase();
|
|
214
|
+
}
|
|
193
215
|
}
|
|
194
216
|
HdKeyring.type = type;
|
|
195
217
|
exports.default = HdKeyring;
|
package/index.ts
CHANGED
|
@@ -1,18 +1,31 @@
|
|
|
1
|
-
import Wallet, { hdkey } from 'ethereumjs-wallet';
|
|
1
|
+
// import Wallet, { hdkey } from 'ethereumjs-wallet';
|
|
2
|
+
import { HDKey } from 'ethereum-cryptography/hdkey';
|
|
2
3
|
import SimpleKeyring from '@rabby-wallet/eth-simple-keyring';
|
|
3
|
-
import * as bip39 from 'bip39';
|
|
4
|
+
import * as bip39 from '@scure/bip39';
|
|
5
|
+
import { wordlist } from '@scure/bip39/wordlists/english';
|
|
4
6
|
import * as sigUtil from 'eth-sig-util';
|
|
7
|
+
import {
|
|
8
|
+
bytesToHex,
|
|
9
|
+
publicToAddress,
|
|
10
|
+
privateToPublic,
|
|
11
|
+
} from '@ethereumjs/util';
|
|
5
12
|
|
|
6
13
|
// Options:
|
|
7
14
|
const hdPathString = "m/44'/60'/0'/0";
|
|
8
15
|
const type = 'HD Key Tree';
|
|
9
16
|
|
|
17
|
+
interface Wallet {
|
|
18
|
+
publicKey: Uint8Array;
|
|
19
|
+
privateKey: Uint8Array;
|
|
20
|
+
}
|
|
21
|
+
|
|
10
22
|
interface DeserializeOption {
|
|
11
23
|
hdPath?: string;
|
|
12
24
|
mnemonic?: string;
|
|
13
25
|
activeIndexes?: number[];
|
|
14
26
|
byImport?: boolean;
|
|
15
27
|
index?: number;
|
|
28
|
+
publicKey?: string;
|
|
16
29
|
}
|
|
17
30
|
|
|
18
31
|
class HdKeyring extends SimpleKeyring {
|
|
@@ -21,8 +34,8 @@ class HdKeyring extends SimpleKeyring {
|
|
|
21
34
|
type = type;
|
|
22
35
|
mnemonic: string | null = null;
|
|
23
36
|
hdPath = hdPathString;
|
|
24
|
-
hdWallet?:
|
|
25
|
-
root:
|
|
37
|
+
hdWallet?: HDKey;
|
|
38
|
+
root: HDKey | null = null;
|
|
26
39
|
wallets: Wallet[] = [];
|
|
27
40
|
_index2wallet: Record<number, [string, Wallet]> = {};
|
|
28
41
|
activeIndexes: number[] = [];
|
|
@@ -30,6 +43,7 @@ class HdKeyring extends SimpleKeyring {
|
|
|
30
43
|
page = 0;
|
|
31
44
|
perPage = 5;
|
|
32
45
|
byImport = false;
|
|
46
|
+
publicKey: string = '';
|
|
33
47
|
|
|
34
48
|
/* PUBLIC METHODS */
|
|
35
49
|
constructor(opts = {}) {
|
|
@@ -44,6 +58,7 @@ class HdKeyring extends SimpleKeyring {
|
|
|
44
58
|
hdPath: this.hdPath,
|
|
45
59
|
byImport: this.byImport,
|
|
46
60
|
index: this.index,
|
|
61
|
+
publicKey: this.publicKey,
|
|
47
62
|
});
|
|
48
63
|
}
|
|
49
64
|
|
|
@@ -54,6 +69,7 @@ class HdKeyring extends SimpleKeyring {
|
|
|
54
69
|
this.hdPath = opts.hdPath || hdPathString;
|
|
55
70
|
this.byImport = !!opts.byImport;
|
|
56
71
|
this.index = opts.index || 0;
|
|
72
|
+
this.publicKey = opts.publicKey || '';
|
|
57
73
|
|
|
58
74
|
if (opts.mnemonic) {
|
|
59
75
|
this.initFromMnemonic(opts.mnemonic);
|
|
@@ -66,23 +82,36 @@ class HdKeyring extends SimpleKeyring {
|
|
|
66
82
|
return Promise.resolve([]);
|
|
67
83
|
}
|
|
68
84
|
|
|
85
|
+
private initPublicKey() {
|
|
86
|
+
this.root = this.hdWallet!.derive(this.hdPath);
|
|
87
|
+
this.publicKey = bytesToHex(this.root.publicKey);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
getPublicKey() {
|
|
91
|
+
return this.publicKey;
|
|
92
|
+
}
|
|
93
|
+
|
|
69
94
|
initFromMnemonic(mnemonic) {
|
|
70
95
|
this.mnemonic = mnemonic;
|
|
71
96
|
this._index2wallet = {};
|
|
72
97
|
const seed = bip39.mnemonicToSeedSync(mnemonic);
|
|
73
|
-
this.hdWallet =
|
|
74
|
-
this.root = this.hdWallet!.
|
|
98
|
+
this.hdWallet = HDKey.fromMasterSeed(seed);
|
|
99
|
+
this.root = this.hdWallet!.derive(this.hdPath);
|
|
100
|
+
|
|
101
|
+
if (!this.publicKey) {
|
|
102
|
+
this.initPublicKey();
|
|
103
|
+
}
|
|
75
104
|
}
|
|
76
105
|
|
|
77
106
|
addAccounts(numberOfAccounts = 1) {
|
|
78
107
|
if (!this.root) {
|
|
79
|
-
this.initFromMnemonic(bip39.generateMnemonic());
|
|
108
|
+
this.initFromMnemonic(bip39.generateMnemonic(wordlist));
|
|
80
109
|
}
|
|
81
110
|
|
|
82
111
|
let count = numberOfAccounts;
|
|
83
112
|
let currentIdx = 0;
|
|
84
113
|
const newWallets: Wallet[] = [];
|
|
85
|
-
|
|
114
|
+
|
|
86
115
|
while (count) {
|
|
87
116
|
const [, wallet] = this._addressFromIndex(currentIdx);
|
|
88
117
|
if (this.wallets.includes(wallet)) {
|
|
@@ -96,7 +125,7 @@ class HdKeyring extends SimpleKeyring {
|
|
|
96
125
|
}
|
|
97
126
|
|
|
98
127
|
const hexWallets = newWallets.map((w) => {
|
|
99
|
-
return sigUtil.normalize(
|
|
128
|
+
return sigUtil.normalize(this._addressfromPublicKey(w.publicKey));
|
|
100
129
|
});
|
|
101
130
|
|
|
102
131
|
return Promise.resolve(hexWallets);
|
|
@@ -178,7 +207,7 @@ class HdKeyring extends SimpleKeyring {
|
|
|
178
207
|
getAccounts() {
|
|
179
208
|
return Promise.resolve(
|
|
180
209
|
this.wallets.map((w) => {
|
|
181
|
-
return sigUtil.normalize(
|
|
210
|
+
return sigUtil.normalize(this._addressfromPublicKey(w.publicKey));
|
|
182
211
|
}),
|
|
183
212
|
);
|
|
184
213
|
}
|
|
@@ -197,13 +226,22 @@ class HdKeyring extends SimpleKeyring {
|
|
|
197
226
|
_addressFromIndex(i: number): [string, Wallet] {
|
|
198
227
|
if (!this._index2wallet[i]) {
|
|
199
228
|
const child = this.root!.deriveChild(i);
|
|
200
|
-
const wallet =
|
|
201
|
-
|
|
229
|
+
const wallet = {
|
|
230
|
+
publicKey: privateToPublic(child.privateKey),
|
|
231
|
+
privateKey: child.privateKey,
|
|
232
|
+
};
|
|
233
|
+
const address = sigUtil.normalize(
|
|
234
|
+
this._addressfromPublicKey(wallet.publicKey),
|
|
235
|
+
);
|
|
202
236
|
this._index2wallet[i] = [address, wallet];
|
|
203
237
|
}
|
|
204
238
|
|
|
205
239
|
return this._index2wallet[i];
|
|
206
240
|
}
|
|
241
|
+
|
|
242
|
+
_addressfromPublicKey(publicKey: Uint8Array) {
|
|
243
|
+
return bytesToHex(publicToAddress(publicKey, true)).toLowerCase();
|
|
244
|
+
}
|
|
207
245
|
}
|
|
208
246
|
|
|
209
247
|
export default HdKeyring;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rabby-wallet/eth-hd-keyring",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-alpha",
|
|
4
4
|
"description": "A simple standard interface for a seed phrase generated set of Ethereum accounts.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ethereum",
|
|
@@ -27,12 +27,12 @@
|
|
|
27
27
|
"test": "mocha"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
+
"@ethereumjs/util": "^9.0.0",
|
|
30
31
|
"@metamask/eth-sig-util": "^4.0.0",
|
|
31
|
-
"@rabby-wallet/eth-simple-keyring": "
|
|
32
|
-
"bip39": "^
|
|
32
|
+
"@rabby-wallet/eth-simple-keyring": "5.0.0-alpha",
|
|
33
|
+
"@scure/bip39": "^1.2.1",
|
|
33
34
|
"eth-sig-util": "^3.0.1",
|
|
34
|
-
"
|
|
35
|
-
"ethereumjs-wallet": "^1.0.1"
|
|
35
|
+
"ethereum-cryptography": "^2.1.2"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@lavamoat/allow-scripts": "^1.0.6",
|
package/test/index.js
CHANGED
|
@@ -8,6 +8,7 @@ const {
|
|
|
8
8
|
SignTypedDataVersion,
|
|
9
9
|
} = require('@metamask/eth-sig-util');
|
|
10
10
|
const ethUtil = require('ethereumjs-util');
|
|
11
|
+
const newEthUtil = require('@ethereumjs/util');
|
|
11
12
|
const HdKeyring = require('..').default;
|
|
12
13
|
// Sample account:
|
|
13
14
|
const privKeyHex =
|
|
@@ -109,19 +110,20 @@ describe('hd-keyring', function () {
|
|
|
109
110
|
describe('#getAccounts', function () {
|
|
110
111
|
it('calls getAddress on each wallet', function (done) {
|
|
111
112
|
// Push a mock wallet
|
|
112
|
-
const desiredOutput = '
|
|
113
|
+
const desiredOutput = '0x410264A247892c3b2912AeE58236036A82CA209e';
|
|
113
114
|
keyring.wallets.push({
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
115
|
+
publicKey: newEthUtil.importPublic(
|
|
116
|
+
newEthUtil.hexToBytes(
|
|
117
|
+
'0x0220381189b226eae955cf7331b649be61b6ec55ea678cb30c7371e9e07dc200bd',
|
|
118
|
+
),
|
|
119
|
+
),
|
|
120
|
+
privateKey: newEthUtil.hexToBytes(
|
|
121
|
+
'0x504560704904af362cab963188f571bccb1498f6ab5113b6bd8d76b6c53a963e',
|
|
122
|
+
),
|
|
121
123
|
});
|
|
122
124
|
|
|
123
125
|
keyring.getAccounts().then((output) => {
|
|
124
|
-
assert.equal(output[0],
|
|
126
|
+
assert.equal(output[0].toLowerCase(), desiredOutput.toLowerCase());
|
|
125
127
|
assert.equal(output.length, 1);
|
|
126
128
|
done();
|
|
127
129
|
});
|