@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/dist/index.d.ts +114 -0
- package/dist/index.js +2674 -298
- package/index.ts +51 -4
- package/package.json +12 -3
- package/patches/slip39+0.1.9.patch +45 -0
package/dist/index.js
CHANGED
|
@@ -1,324 +1,2700 @@
|
|
|
1
|
-
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defProps = Object.defineProperties;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
8
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
9
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
11
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
12
|
+
var __spreadValues = (a, b) => {
|
|
13
|
+
for (var prop in b || (b = {}))
|
|
14
|
+
if (__hasOwnProp.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
if (__getOwnPropSymbols)
|
|
17
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
18
|
+
if (__propIsEnum.call(b, prop))
|
|
19
|
+
__defNormalProp(a, prop, b[prop]);
|
|
20
|
+
}
|
|
21
|
+
return a;
|
|
20
22
|
};
|
|
21
|
-
var
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
25
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
26
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
27
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
28
|
-
});
|
|
23
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
24
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
25
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
29
26
|
};
|
|
30
|
-
var
|
|
31
|
-
|
|
27
|
+
var __export = (target, all) => {
|
|
28
|
+
for (var name in all)
|
|
29
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
32
30
|
};
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const util_1 = require("@ethereumjs/util");
|
|
41
|
-
// Options:
|
|
42
|
-
const type = 'HD Key Tree';
|
|
43
|
-
var HDPathType;
|
|
44
|
-
(function (HDPathType) {
|
|
45
|
-
HDPathType["LedgerLive"] = "LedgerLive";
|
|
46
|
-
HDPathType["Legacy"] = "Legacy";
|
|
47
|
-
HDPathType["BIP44"] = "BIP44";
|
|
48
|
-
})(HDPathType || (HDPathType = {}));
|
|
49
|
-
const HD_PATH_BASE = {
|
|
50
|
-
[HDPathType.BIP44]: "m/44'/60'/0'/0",
|
|
51
|
-
[HDPathType.Legacy]: "m/44'/60'/0'",
|
|
52
|
-
[HDPathType.LedgerLive]: "m/44'/60'/0'/0/0",
|
|
31
|
+
var __copyProps = (to, from, except, desc) => {
|
|
32
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
33
|
+
for (let key of __getOwnPropNames(from))
|
|
34
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
35
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
36
|
+
}
|
|
37
|
+
return to;
|
|
53
38
|
};
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
39
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
40
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
41
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
42
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
43
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
44
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
45
|
+
mod
|
|
46
|
+
));
|
|
47
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
48
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
49
|
+
var __async = (__this, __arguments, generator) => {
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
var fulfilled = (value) => {
|
|
52
|
+
try {
|
|
53
|
+
step(generator.next(value));
|
|
54
|
+
} catch (e) {
|
|
55
|
+
reject(e);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
var rejected = (value) => {
|
|
59
|
+
try {
|
|
60
|
+
step(generator.throw(value));
|
|
61
|
+
} catch (e) {
|
|
62
|
+
reject(e);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
66
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
67
|
+
});
|
|
58
68
|
};
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
69
|
+
|
|
70
|
+
// node_modules/slip39/src/slip39_helper.js
|
|
71
|
+
var require_slip39_helper = __commonJS({
|
|
72
|
+
"node_modules/slip39/src/slip39_helper.js"(exports2, module2) {
|
|
73
|
+
var crypto;
|
|
74
|
+
try {
|
|
75
|
+
crypto = require("crypto");
|
|
76
|
+
} catch (err) {
|
|
77
|
+
throw new Error("crypto support must be enabled");
|
|
78
|
+
}
|
|
79
|
+
var RADIX_BITS = 10;
|
|
80
|
+
var ID_BITS_LENGTH = 15;
|
|
81
|
+
var ITERATION_EXP_BITS_LENGTH = 4;
|
|
82
|
+
var EXTENDABLE_BACKUP_FLAG_BITS_LENGTH = 1;
|
|
83
|
+
var ITERATION_EXP_WORDS_LENGTH = parseInt(
|
|
84
|
+
(ID_BITS_LENGTH + EXTENDABLE_BACKUP_FLAG_BITS_LENGTH + ITERATION_EXP_BITS_LENGTH + RADIX_BITS - 1) / RADIX_BITS,
|
|
85
|
+
10
|
|
86
|
+
);
|
|
87
|
+
var MAX_ITERATION_EXP = Math.pow(2, ITERATION_EXP_BITS_LENGTH);
|
|
88
|
+
var MAX_SHARE_COUNT = 16;
|
|
89
|
+
var CHECKSUM_WORDS_LENGTH = 3;
|
|
90
|
+
var DIGEST_LENGTH = 4;
|
|
91
|
+
var CUSTOMIZATION_STRING_NON_EXTENDABLE = "shamir";
|
|
92
|
+
var CUSTOMIZATION_STRING_EXTENDABLE = "shamir_extendable";
|
|
93
|
+
var MIN_ENTROPY_BITS = 128;
|
|
94
|
+
var METADATA_WORDS_LENGTH = ITERATION_EXP_WORDS_LENGTH + 2 + CHECKSUM_WORDS_LENGTH;
|
|
95
|
+
var MNEMONICS_WORDS_LENGTH = parseInt(
|
|
96
|
+
METADATA_WORDS_LENGTH + (MIN_ENTROPY_BITS + RADIX_BITS - 1) / RADIX_BITS,
|
|
97
|
+
10
|
|
98
|
+
);
|
|
99
|
+
var ITERATION_COUNT = 1e4;
|
|
100
|
+
var ROUND_COUNT = 4;
|
|
101
|
+
var DIGEST_INDEX = 254;
|
|
102
|
+
var SECRET_INDEX = 255;
|
|
103
|
+
String.prototype.slip39EncodeHex = function() {
|
|
104
|
+
let bytes = [];
|
|
105
|
+
for (let i = 0; i < this.length; ++i) {
|
|
106
|
+
bytes.push(this.charCodeAt(i));
|
|
107
|
+
}
|
|
108
|
+
return bytes;
|
|
109
|
+
};
|
|
110
|
+
Array.prototype.slip39DecodeHex = function() {
|
|
111
|
+
let str = [];
|
|
112
|
+
const hex = this.toString().split(",");
|
|
113
|
+
for (let i = 0; i < hex.length; i++) {
|
|
114
|
+
str.push(String.fromCharCode(hex[i]));
|
|
115
|
+
}
|
|
116
|
+
return str.toString().replace(/,/g, "");
|
|
117
|
+
};
|
|
118
|
+
Array.prototype.slip39Generate = function(m, v = (_) => _) {
|
|
119
|
+
let n = m || this.length;
|
|
120
|
+
for (let i = 0; i < n; i++) {
|
|
121
|
+
this[i] = v(i);
|
|
122
|
+
}
|
|
123
|
+
return this;
|
|
124
|
+
};
|
|
125
|
+
var BIGINT_WORD_BITS = BigInt(8);
|
|
126
|
+
function decodeBigInt(bytes) {
|
|
127
|
+
let result = BigInt(0);
|
|
128
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
129
|
+
let b = BigInt(bytes[bytes.length - i - 1]);
|
|
130
|
+
result = result + (b << BIGINT_WORD_BITS * BigInt(i));
|
|
131
|
+
}
|
|
132
|
+
return result;
|
|
133
|
+
}
|
|
134
|
+
function encodeBigInt(number, paddedLength = 0) {
|
|
135
|
+
let num = number;
|
|
136
|
+
const BYTE_MASK = BigInt(255);
|
|
137
|
+
const BIGINT_ZERO = BigInt(0);
|
|
138
|
+
let result = new Array(0);
|
|
139
|
+
while (num > BIGINT_ZERO) {
|
|
140
|
+
let i = parseInt(num & BYTE_MASK, 10);
|
|
141
|
+
result.unshift(i);
|
|
142
|
+
num = num >> BIGINT_WORD_BITS;
|
|
143
|
+
}
|
|
144
|
+
for (let i = result.length; i < paddedLength; i++) {
|
|
145
|
+
result.unshift(0);
|
|
146
|
+
}
|
|
147
|
+
if (paddedLength !== 0 && result.length > paddedLength) {
|
|
148
|
+
throw new Error(
|
|
149
|
+
`Error in encoding BigInt value, expected less than ${paddedLength} length value, got ${result.length}`
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
154
|
+
function bitsToBytes(n) {
|
|
155
|
+
const res = (n + 7) / 8;
|
|
156
|
+
const b = parseInt(res, RADIX_BITS);
|
|
157
|
+
return b;
|
|
158
|
+
}
|
|
159
|
+
function bitsToWords(n) {
|
|
160
|
+
const res = (n + RADIX_BITS - 1) / RADIX_BITS;
|
|
161
|
+
const b = parseInt(res, RADIX_BITS);
|
|
162
|
+
return b;
|
|
163
|
+
}
|
|
164
|
+
function randomBytes(length = 32) {
|
|
165
|
+
let randoms = crypto.randomBytes(length);
|
|
166
|
+
return Array.prototype.slice.call(randoms, 0);
|
|
167
|
+
}
|
|
168
|
+
function roundFunction(round, passphrase, exp, salt, secret) {
|
|
169
|
+
const saltedSecret = salt.concat(secret);
|
|
170
|
+
const roundedPhrase = [round].concat(passphrase);
|
|
171
|
+
const count = (ITERATION_COUNT << exp) / ROUND_COUNT;
|
|
172
|
+
const key = crypto.pbkdf2Sync(
|
|
173
|
+
Buffer.from(roundedPhrase),
|
|
174
|
+
Buffer.from(saltedSecret),
|
|
175
|
+
count,
|
|
176
|
+
secret.length,
|
|
177
|
+
"sha256"
|
|
178
|
+
);
|
|
179
|
+
return Array.prototype.slice.call(key, 0);
|
|
180
|
+
}
|
|
181
|
+
function crypt(masterSecret, passphrase, iterationExponent, identifier, extendableBackupFlag, encrypt = true) {
|
|
182
|
+
if (iterationExponent < 0 || iterationExponent > MAX_ITERATION_EXP) {
|
|
183
|
+
throw Error(
|
|
184
|
+
`Invalid iteration exponent (${iterationExponent}). Expected between 0 and ${MAX_ITERATION_EXP}`
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
let IL = masterSecret.slice().slice(0, masterSecret.length / 2);
|
|
188
|
+
let IR = masterSecret.slice().slice(masterSecret.length / 2);
|
|
189
|
+
const pwd = passphrase.slip39EncodeHex();
|
|
190
|
+
const salt = getSalt(identifier, extendableBackupFlag);
|
|
191
|
+
let range = Array().slip39Generate(ROUND_COUNT);
|
|
192
|
+
range = encrypt ? range : range.reverse();
|
|
193
|
+
range.forEach((round) => {
|
|
194
|
+
const f = roundFunction(round, pwd, iterationExponent, salt, IR);
|
|
195
|
+
const t = xor(IL, f);
|
|
196
|
+
IL = IR;
|
|
197
|
+
IR = t;
|
|
198
|
+
});
|
|
199
|
+
return IR.concat(IL);
|
|
200
|
+
}
|
|
201
|
+
function createDigest(randomData, sharedSecret) {
|
|
202
|
+
const hmac = crypto.createHmac("sha256", Buffer.from(randomData));
|
|
203
|
+
hmac.update(Buffer.from(sharedSecret));
|
|
204
|
+
let result = hmac.digest();
|
|
205
|
+
result = result.slice(0, 4);
|
|
206
|
+
return Array.prototype.slice.call(result, 0);
|
|
207
|
+
}
|
|
208
|
+
function splitSecret(threshold, shareCount, sharedSecret) {
|
|
209
|
+
if (threshold <= 0) {
|
|
210
|
+
throw Error(
|
|
211
|
+
`The requested threshold (${threshold}) must be a positive integer.`
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
if (threshold > shareCount) {
|
|
215
|
+
throw Error(
|
|
216
|
+
`The requested threshold (${threshold}) must not exceed the number of shares (${shareCount}).`
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
if (shareCount > MAX_SHARE_COUNT) {
|
|
220
|
+
throw Error(
|
|
221
|
+
`The requested number of shares (${shareCount}) must not exceed ${MAX_SHARE_COUNT}.`
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
if (threshold === 1) {
|
|
225
|
+
return Array().slip39Generate(shareCount, () => sharedSecret);
|
|
226
|
+
}
|
|
227
|
+
const randomShareCount = threshold - 2;
|
|
228
|
+
const randomPart = randomBytes(sharedSecret.length - DIGEST_LENGTH);
|
|
229
|
+
const digest = createDigest(randomPart, sharedSecret);
|
|
230
|
+
let baseShares = /* @__PURE__ */ new Map();
|
|
231
|
+
let shares = [];
|
|
232
|
+
if (randomShareCount) {
|
|
233
|
+
shares = Array().slip39Generate(
|
|
234
|
+
randomShareCount,
|
|
235
|
+
() => randomBytes(sharedSecret.length)
|
|
236
|
+
);
|
|
237
|
+
shares.forEach((item, idx) => {
|
|
238
|
+
baseShares.set(idx, item);
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
baseShares.set(DIGEST_INDEX, digest.concat(randomPart));
|
|
242
|
+
baseShares.set(SECRET_INDEX, sharedSecret);
|
|
243
|
+
for (let i = randomShareCount; i < shareCount; i++) {
|
|
244
|
+
const rr = interpolate(baseShares, i);
|
|
245
|
+
shares.push(rr);
|
|
246
|
+
}
|
|
247
|
+
return shares;
|
|
248
|
+
}
|
|
249
|
+
function generateIdentifier() {
|
|
250
|
+
const byte = bitsToBytes(ID_BITS_LENGTH);
|
|
251
|
+
const bits = ID_BITS_LENGTH % 8;
|
|
252
|
+
const identifier = randomBytes(byte);
|
|
253
|
+
identifier[0] = identifier[0] & (1 << bits) - 1;
|
|
254
|
+
return identifier;
|
|
255
|
+
}
|
|
256
|
+
function xor(a, b) {
|
|
257
|
+
if (a.length !== b.length) {
|
|
258
|
+
throw new Error(
|
|
259
|
+
`Invalid padding in mnemonic or insufficient length of mnemonics (${a.length} or ${b.length})`
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
return Array().slip39Generate(a.length, (i) => a[i] ^ b[i]);
|
|
263
|
+
}
|
|
264
|
+
function getSalt(identifier, extendableBackupFlag) {
|
|
265
|
+
if (extendableBackupFlag) {
|
|
266
|
+
return [];
|
|
267
|
+
} else {
|
|
268
|
+
const salt = CUSTOMIZATION_STRING_NON_EXTENDABLE.slip39EncodeHex();
|
|
269
|
+
return salt.concat(identifier);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
function interpolate(shares, x) {
|
|
273
|
+
let xCoord = new Set(shares.keys());
|
|
274
|
+
let arr = Array.from(shares.values(), (v) => v.length);
|
|
275
|
+
let sharesValueLengths = new Set(arr);
|
|
276
|
+
if (sharesValueLengths.size !== 1) {
|
|
277
|
+
throw new Error(
|
|
278
|
+
"Invalid set of shares. All share values must have the same length."
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
if (xCoord.has(x)) {
|
|
282
|
+
shares.forEach((v, k) => {
|
|
283
|
+
if (k === x) {
|
|
284
|
+
return v;
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
let logProd = 0;
|
|
289
|
+
shares.forEach((v, k) => {
|
|
290
|
+
logProd = logProd + LOG_TABLE[k ^ x];
|
|
291
|
+
});
|
|
292
|
+
let results = Array().slip39Generate(
|
|
293
|
+
sharesValueLengths.values().next().value,
|
|
294
|
+
() => 0
|
|
295
|
+
);
|
|
296
|
+
shares.forEach((v, k) => {
|
|
297
|
+
let sum = 0;
|
|
298
|
+
shares.forEach((vv, kk) => {
|
|
299
|
+
sum = sum + LOG_TABLE[k ^ kk];
|
|
99
300
|
});
|
|
301
|
+
const basis = (logProd - LOG_TABLE[k ^ x] - sum) % 255;
|
|
302
|
+
const logBasisEval = basis < 0 ? 255 + basis : basis;
|
|
303
|
+
v.forEach((item, idx) => {
|
|
304
|
+
const shareVal = item;
|
|
305
|
+
const intermediateSum = results[idx];
|
|
306
|
+
const r = shareVal !== 0 ? EXP_TABLE[(LOG_TABLE[shareVal] + logBasisEval) % 255] : 0;
|
|
307
|
+
const res = intermediateSum ^ r;
|
|
308
|
+
results[idx] = res;
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
return results;
|
|
100
312
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
313
|
+
function rs1024Polymod(data) {
|
|
314
|
+
const GEN = [
|
|
315
|
+
14737472,
|
|
316
|
+
29474944,
|
|
317
|
+
58949888,
|
|
318
|
+
117899776,
|
|
319
|
+
235798537,
|
|
320
|
+
470557714,
|
|
321
|
+
940076068,
|
|
322
|
+
814808136,
|
|
323
|
+
565311632,
|
|
324
|
+
66318624
|
|
325
|
+
];
|
|
326
|
+
let chk = 1;
|
|
327
|
+
data.forEach((byte) => {
|
|
328
|
+
const b = chk >> 20;
|
|
329
|
+
chk = (chk & 1048575) << 10 ^ byte;
|
|
330
|
+
for (let i = 0; i < 10; i++) {
|
|
331
|
+
let gen = (b >> i & 1) !== 0 ? GEN[i] : 0;
|
|
332
|
+
chk = chk ^ gen;
|
|
115
333
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
334
|
+
});
|
|
335
|
+
return chk;
|
|
336
|
+
}
|
|
337
|
+
function get_customization_string(extendableBackupFlag) {
|
|
338
|
+
return extendableBackupFlag ? CUSTOMIZATION_STRING_EXTENDABLE : CUSTOMIZATION_STRING_NON_EXTENDABLE;
|
|
339
|
+
}
|
|
340
|
+
function rs1024CreateChecksum(data, extendableBackupFlag) {
|
|
341
|
+
const values = get_customization_string(extendableBackupFlag).slip39EncodeHex().concat(data).concat(Array().slip39Generate(CHECKSUM_WORDS_LENGTH, () => 0));
|
|
342
|
+
const polymod = rs1024Polymod(values) ^ 1;
|
|
343
|
+
const result = Array().slip39Generate(CHECKSUM_WORDS_LENGTH, (i) => polymod >> 10 * i & 1023).reverse();
|
|
344
|
+
return result;
|
|
345
|
+
}
|
|
346
|
+
function rs1024VerifyChecksum(data, extendableBackupFlag) {
|
|
347
|
+
return rs1024Polymod(
|
|
348
|
+
get_customization_string(extendableBackupFlag).slip39EncodeHex().concat(data)
|
|
349
|
+
) === 1;
|
|
350
|
+
}
|
|
351
|
+
function intFromIndices(indices) {
|
|
352
|
+
let value = BigInt(0);
|
|
353
|
+
const radix = BigInt(Math.pow(2, RADIX_BITS));
|
|
354
|
+
indices.forEach((index) => {
|
|
355
|
+
value = value * radix + BigInt(index);
|
|
356
|
+
});
|
|
357
|
+
return value;
|
|
358
|
+
}
|
|
359
|
+
function intToIndices(value, length, bits) {
|
|
360
|
+
const mask = BigInt((1 << bits) - 1);
|
|
361
|
+
const result = Array().slip39Generate(
|
|
362
|
+
length,
|
|
363
|
+
(i) => parseInt(value >> BigInt(i) * BigInt(bits) & mask, 10)
|
|
364
|
+
);
|
|
365
|
+
return result.reverse();
|
|
366
|
+
}
|
|
367
|
+
function mnemonicFromIndices(indices) {
|
|
368
|
+
const result = indices.map((index) => {
|
|
369
|
+
return WORD_LIST[index];
|
|
370
|
+
});
|
|
371
|
+
return result.toString().split(",").join(" ");
|
|
372
|
+
}
|
|
373
|
+
function mnemonicToIndices(mnemonic) {
|
|
374
|
+
if (typeof mnemonic !== "string") {
|
|
375
|
+
throw new Error(
|
|
376
|
+
`Mnemonic expected to be typeof string with white space separated words. Instead found typeof ${typeof mnemonic}.`
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
const words = mnemonic.toLowerCase().split(" ");
|
|
380
|
+
const result = words.reduce((prev, item) => {
|
|
381
|
+
const index = WORD_LIST_MAP[item];
|
|
382
|
+
if (typeof index === "undefined") {
|
|
383
|
+
throw new Error(`Invalid mnemonic word ${item}.`);
|
|
119
384
|
}
|
|
120
|
-
return
|
|
385
|
+
return prev.concat(index);
|
|
386
|
+
}, []);
|
|
387
|
+
return result;
|
|
121
388
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
389
|
+
function recoverSecret(threshold, shares) {
|
|
390
|
+
if (threshold === 1) {
|
|
391
|
+
return shares.values().next().value;
|
|
392
|
+
}
|
|
393
|
+
const sharedSecret = interpolate(shares, SECRET_INDEX);
|
|
394
|
+
const digestShare = interpolate(shares, DIGEST_INDEX);
|
|
395
|
+
const digest = digestShare.slice(0, DIGEST_LENGTH);
|
|
396
|
+
const randomPart = digestShare.slice(DIGEST_LENGTH);
|
|
397
|
+
const recoveredDigest = createDigest(randomPart, sharedSecret);
|
|
398
|
+
if (!listsAreEqual(digest, recoveredDigest)) {
|
|
399
|
+
throw new Error("Invalid digest of the shared secret.");
|
|
400
|
+
}
|
|
401
|
+
return sharedSecret;
|
|
402
|
+
}
|
|
403
|
+
function combineMnemonics(mnemonics, passphrase = "") {
|
|
404
|
+
if (mnemonics === null || mnemonics.length === 0) {
|
|
405
|
+
throw new Error("The list of mnemonics is empty.");
|
|
406
|
+
}
|
|
407
|
+
const decoded = decodeMnemonics(mnemonics);
|
|
408
|
+
const identifier = decoded.identifier;
|
|
409
|
+
const extendableBackupFlag = decoded.extendableBackupFlag;
|
|
410
|
+
const iterationExponent = decoded.iterationExponent;
|
|
411
|
+
const groupThreshold = decoded.groupThreshold;
|
|
412
|
+
const groupCount = decoded.groupCount;
|
|
413
|
+
const groups = decoded.groups;
|
|
414
|
+
if (groups.size < groupThreshold) {
|
|
415
|
+
throw new Error(
|
|
416
|
+
`Insufficient number of mnemonic groups (${groups.size}). The required number of groups is ${groupThreshold}.`
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
if (groups.size !== groupThreshold) {
|
|
420
|
+
throw new Error(
|
|
421
|
+
`Wrong number of mnemonic groups. Expected ${groupThreshold} groups, but ${groups.size} were provided.`
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
let allShares = /* @__PURE__ */ new Map();
|
|
425
|
+
groups.forEach((members, groupIndex) => {
|
|
426
|
+
const threshold = members.keys().next().value;
|
|
427
|
+
const shares = members.values().next().value;
|
|
428
|
+
if (shares.size !== threshold) {
|
|
429
|
+
const prefix = groupPrefix(
|
|
430
|
+
identifier,
|
|
431
|
+
extendableBackupFlag,
|
|
432
|
+
iterationExponent,
|
|
433
|
+
groupIndex,
|
|
434
|
+
groupThreshold,
|
|
435
|
+
groupCount
|
|
436
|
+
);
|
|
437
|
+
throw new Error(
|
|
438
|
+
`Wrong number of mnemonics. Expected ${threshold} mnemonics starting with "${mnemonicFromIndices(prefix)}",
|
|
439
|
+
but ${shares.size} were provided.`
|
|
440
|
+
);
|
|
128
441
|
}
|
|
442
|
+
const recovered = recoverSecret(threshold, shares);
|
|
443
|
+
allShares.set(groupIndex, recovered);
|
|
444
|
+
});
|
|
445
|
+
const ems = recoverSecret(groupThreshold, allShares);
|
|
446
|
+
const id = intToIndices(BigInt(identifier), ITERATION_EXP_WORDS_LENGTH, 8);
|
|
447
|
+
const ms = crypt(
|
|
448
|
+
ems,
|
|
449
|
+
passphrase,
|
|
450
|
+
iterationExponent,
|
|
451
|
+
id,
|
|
452
|
+
extendableBackupFlag,
|
|
453
|
+
false
|
|
454
|
+
);
|
|
455
|
+
return ms;
|
|
456
|
+
}
|
|
457
|
+
function decodeMnemonics(mnemonics) {
|
|
458
|
+
if (!(mnemonics instanceof Array)) {
|
|
459
|
+
throw new Error("Mnemonics should be an array of strings");
|
|
460
|
+
}
|
|
461
|
+
const identifiers = /* @__PURE__ */ new Set();
|
|
462
|
+
const extendableBackupFlags = /* @__PURE__ */ new Set();
|
|
463
|
+
const iterationExponents = /* @__PURE__ */ new Set();
|
|
464
|
+
const groupThresholds = /* @__PURE__ */ new Set();
|
|
465
|
+
const groupCounts = /* @__PURE__ */ new Set();
|
|
466
|
+
const groups = /* @__PURE__ */ new Map();
|
|
467
|
+
mnemonics.forEach((mnemonic) => {
|
|
468
|
+
const decoded = decodeMnemonic(mnemonic);
|
|
469
|
+
identifiers.add(decoded.identifier);
|
|
470
|
+
extendableBackupFlags.add(decoded.extendableBackupFlag);
|
|
471
|
+
iterationExponents.add(decoded.iterationExponent);
|
|
472
|
+
const groupIndex = decoded.groupIndex;
|
|
473
|
+
groupThresholds.add(decoded.groupThreshold);
|
|
474
|
+
groupCounts.add(decoded.groupCount);
|
|
475
|
+
const memberIndex = decoded.memberIndex;
|
|
476
|
+
const memberThreshold = decoded.memberThreshold;
|
|
477
|
+
const share = decoded.share;
|
|
478
|
+
const group = !groups.has(groupIndex) ? /* @__PURE__ */ new Map() : groups.get(groupIndex);
|
|
479
|
+
const member = !group.has(memberThreshold) ? /* @__PURE__ */ new Map() : group.get(memberThreshold);
|
|
480
|
+
member.set(memberIndex, share);
|
|
481
|
+
group.set(memberThreshold, member);
|
|
482
|
+
if (group.size !== 1) {
|
|
483
|
+
throw new Error(
|
|
484
|
+
"Invalid set of mnemonics. All mnemonics in a group must have the same member threshold."
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
groups.set(groupIndex, group);
|
|
488
|
+
});
|
|
489
|
+
if (identifiers.size !== 1 || extendableBackupFlags.size !== 1 || iterationExponents.size !== 1) {
|
|
490
|
+
throw new Error(
|
|
491
|
+
`Invalid set of mnemonics. All mnemonics must begin with the same ${ITERATION_EXP_WORDS_LENGTH} words.`
|
|
492
|
+
);
|
|
493
|
+
}
|
|
494
|
+
if (groupThresholds.size !== 1) {
|
|
495
|
+
throw new Error(
|
|
496
|
+
"Invalid set of mnemonics. All mnemonics must have the same group threshold."
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
if (groupCounts.size !== 1) {
|
|
500
|
+
throw new Error(
|
|
501
|
+
"Invalid set of mnemonics. All mnemonics must have the same group count."
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
return {
|
|
505
|
+
identifier: identifiers.values().next().value,
|
|
506
|
+
extendableBackupFlag: extendableBackupFlags.values().next().value,
|
|
507
|
+
iterationExponent: iterationExponents.values().next().value,
|
|
508
|
+
groupThreshold: groupThresholds.values().next().value,
|
|
509
|
+
groupCount: groupCounts.values().next().value,
|
|
510
|
+
groups
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
function decodeMnemonic(mnemonic) {
|
|
514
|
+
const data = mnemonicToIndices(mnemonic);
|
|
515
|
+
if (data.length < MNEMONICS_WORDS_LENGTH) {
|
|
516
|
+
throw new Error(
|
|
517
|
+
`Invalid mnemonic length. The length of each mnemonic must be at least ${MNEMONICS_WORDS_LENGTH} words.`
|
|
518
|
+
);
|
|
519
|
+
}
|
|
520
|
+
const paddingLen = RADIX_BITS * (data.length - METADATA_WORDS_LENGTH) % 16;
|
|
521
|
+
if (paddingLen > 8) {
|
|
522
|
+
throw new Error("Invalid mnemonic length.");
|
|
523
|
+
}
|
|
524
|
+
const idExpExtInt = parseInt(
|
|
525
|
+
intFromIndices(data.slice(0, ITERATION_EXP_WORDS_LENGTH)),
|
|
526
|
+
10
|
|
527
|
+
);
|
|
528
|
+
const identifier = idExpExtInt >> ITERATION_EXP_BITS_LENGTH + EXTENDABLE_BACKUP_FLAG_BITS_LENGTH;
|
|
529
|
+
const extendableBackupFlag = idExpExtInt >> ITERATION_EXP_BITS_LENGTH & (1 << EXTENDABLE_BACKUP_FLAG_BITS_LENGTH) - 1;
|
|
530
|
+
const iterationExponent = idExpExtInt & (1 << ITERATION_EXP_BITS_LENGTH) - 1;
|
|
531
|
+
if (!rs1024VerifyChecksum(data, extendableBackupFlag)) {
|
|
532
|
+
throw new Error("Invalid mnemonic checksum");
|
|
533
|
+
}
|
|
534
|
+
const tmp = intFromIndices(
|
|
535
|
+
data.slice(ITERATION_EXP_WORDS_LENGTH, ITERATION_EXP_WORDS_LENGTH + 2)
|
|
536
|
+
);
|
|
537
|
+
const indices = intToIndices(tmp, 5, 4);
|
|
538
|
+
const groupIndex = indices[0];
|
|
539
|
+
const groupThreshold = indices[1];
|
|
540
|
+
const groupCount = indices[2];
|
|
541
|
+
const memberIndex = indices[3];
|
|
542
|
+
const memberThreshold = indices[4];
|
|
543
|
+
const valueData = data.slice(
|
|
544
|
+
ITERATION_EXP_WORDS_LENGTH + 2,
|
|
545
|
+
data.length - CHECKSUM_WORDS_LENGTH
|
|
546
|
+
);
|
|
547
|
+
if (groupCount < groupThreshold) {
|
|
548
|
+
throw new Error(
|
|
549
|
+
`Invalid mnemonic: ${mnemonic}.
|
|
550
|
+
Group threshold (${groupThreshold}) cannot be greater than group count (${groupCount}).`
|
|
551
|
+
);
|
|
552
|
+
}
|
|
553
|
+
const valueInt = intFromIndices(valueData);
|
|
554
|
+
try {
|
|
555
|
+
const valueByteCount = bitsToBytes(
|
|
556
|
+
RADIX_BITS * valueData.length - paddingLen
|
|
557
|
+
);
|
|
558
|
+
const share = encodeBigInt(valueInt, valueByteCount);
|
|
559
|
+
return {
|
|
560
|
+
identifier,
|
|
561
|
+
extendableBackupFlag,
|
|
562
|
+
iterationExponent,
|
|
563
|
+
groupIndex,
|
|
564
|
+
groupThreshold: groupThreshold + 1,
|
|
565
|
+
groupCount: groupCount + 1,
|
|
566
|
+
memberIndex,
|
|
567
|
+
memberThreshold: memberThreshold + 1,
|
|
568
|
+
share
|
|
569
|
+
};
|
|
570
|
+
} catch (e) {
|
|
571
|
+
throw new Error(`Invalid mnemonic padding (${e})`);
|
|
572
|
+
}
|
|
129
573
|
}
|
|
130
|
-
|
|
131
|
-
|
|
574
|
+
function validateMnemonic2(mnemonic) {
|
|
575
|
+
try {
|
|
576
|
+
decodeMnemonic(mnemonic);
|
|
577
|
+
return true;
|
|
578
|
+
} catch (error) {
|
|
579
|
+
return false;
|
|
580
|
+
}
|
|
132
581
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
582
|
+
function groupPrefix(identifier, extendableBackupFlag, iterationExponent, groupIndex, groupThreshold, groupCount) {
|
|
583
|
+
const idExpInt = BigInt(
|
|
584
|
+
(identifier << ITERATION_EXP_BITS_LENGTH + EXTENDABLE_BACKUP_FLAG_BITS_LENGTH) + (extendableBackupFlag << ITERATION_EXP_BITS_LENGTH) + iterationExponent
|
|
585
|
+
);
|
|
586
|
+
const indc = intToIndices(idExpInt, ITERATION_EXP_WORDS_LENGTH, RADIX_BITS);
|
|
587
|
+
const indc2 = (groupIndex << 6) + (groupThreshold - 1 << 2) + (groupCount - 1 >> 2);
|
|
588
|
+
indc.push(indc2);
|
|
589
|
+
return indc;
|
|
590
|
+
}
|
|
591
|
+
function listsAreEqual(a, b) {
|
|
592
|
+
if (a === null || b === null || a.length !== b.length) {
|
|
593
|
+
return false;
|
|
594
|
+
}
|
|
595
|
+
let i = 0;
|
|
596
|
+
return a.every((item) => {
|
|
597
|
+
return b[i++] === item;
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
function encodeMnemonic(identifier, extendableBackupFlag, iterationExponent, groupIndex, groupThreshold, groupCount, memberIndex, memberThreshold, value) {
|
|
601
|
+
const valueWordCount = bitsToWords(value.length * 8);
|
|
602
|
+
const valueInt = decodeBigInt(value);
|
|
603
|
+
let newIdentifier = parseInt(decodeBigInt(identifier), 10);
|
|
604
|
+
const gp = groupPrefix(
|
|
605
|
+
newIdentifier,
|
|
606
|
+
extendableBackupFlag,
|
|
607
|
+
iterationExponent,
|
|
608
|
+
groupIndex,
|
|
609
|
+
groupThreshold,
|
|
610
|
+
groupCount
|
|
611
|
+
);
|
|
612
|
+
const tp = intToIndices(valueInt, valueWordCount, RADIX_BITS);
|
|
613
|
+
const calc = ((groupCount - 1 & 3) << 8) + (memberIndex << 4) + (memberThreshold - 1);
|
|
614
|
+
gp.push(calc);
|
|
615
|
+
const shareData = gp.concat(tp);
|
|
616
|
+
const checksum = rs1024CreateChecksum(shareData, extendableBackupFlag);
|
|
617
|
+
return mnemonicFromIndices(shareData.concat(checksum));
|
|
618
|
+
}
|
|
619
|
+
var EXP_TABLE = [
|
|
620
|
+
1,
|
|
621
|
+
3,
|
|
622
|
+
5,
|
|
623
|
+
15,
|
|
624
|
+
17,
|
|
625
|
+
51,
|
|
626
|
+
85,
|
|
627
|
+
255,
|
|
628
|
+
26,
|
|
629
|
+
46,
|
|
630
|
+
114,
|
|
631
|
+
150,
|
|
632
|
+
161,
|
|
633
|
+
248,
|
|
634
|
+
19,
|
|
635
|
+
53,
|
|
636
|
+
95,
|
|
637
|
+
225,
|
|
638
|
+
56,
|
|
639
|
+
72,
|
|
640
|
+
216,
|
|
641
|
+
115,
|
|
642
|
+
149,
|
|
643
|
+
164,
|
|
644
|
+
247,
|
|
645
|
+
2,
|
|
646
|
+
6,
|
|
647
|
+
10,
|
|
648
|
+
30,
|
|
649
|
+
34,
|
|
650
|
+
102,
|
|
651
|
+
170,
|
|
652
|
+
229,
|
|
653
|
+
52,
|
|
654
|
+
92,
|
|
655
|
+
228,
|
|
656
|
+
55,
|
|
657
|
+
89,
|
|
658
|
+
235,
|
|
659
|
+
38,
|
|
660
|
+
106,
|
|
661
|
+
190,
|
|
662
|
+
217,
|
|
663
|
+
112,
|
|
664
|
+
144,
|
|
665
|
+
171,
|
|
666
|
+
230,
|
|
667
|
+
49,
|
|
668
|
+
83,
|
|
669
|
+
245,
|
|
670
|
+
4,
|
|
671
|
+
12,
|
|
672
|
+
20,
|
|
673
|
+
60,
|
|
674
|
+
68,
|
|
675
|
+
204,
|
|
676
|
+
79,
|
|
677
|
+
209,
|
|
678
|
+
104,
|
|
679
|
+
184,
|
|
680
|
+
211,
|
|
681
|
+
110,
|
|
682
|
+
178,
|
|
683
|
+
205,
|
|
684
|
+
76,
|
|
685
|
+
212,
|
|
686
|
+
103,
|
|
687
|
+
169,
|
|
688
|
+
224,
|
|
689
|
+
59,
|
|
690
|
+
77,
|
|
691
|
+
215,
|
|
692
|
+
98,
|
|
693
|
+
166,
|
|
694
|
+
241,
|
|
695
|
+
8,
|
|
696
|
+
24,
|
|
697
|
+
40,
|
|
698
|
+
120,
|
|
699
|
+
136,
|
|
700
|
+
131,
|
|
701
|
+
158,
|
|
702
|
+
185,
|
|
703
|
+
208,
|
|
704
|
+
107,
|
|
705
|
+
189,
|
|
706
|
+
220,
|
|
707
|
+
127,
|
|
708
|
+
129,
|
|
709
|
+
152,
|
|
710
|
+
179,
|
|
711
|
+
206,
|
|
712
|
+
73,
|
|
713
|
+
219,
|
|
714
|
+
118,
|
|
715
|
+
154,
|
|
716
|
+
181,
|
|
717
|
+
196,
|
|
718
|
+
87,
|
|
719
|
+
249,
|
|
720
|
+
16,
|
|
721
|
+
48,
|
|
722
|
+
80,
|
|
723
|
+
240,
|
|
724
|
+
11,
|
|
725
|
+
29,
|
|
726
|
+
39,
|
|
727
|
+
105,
|
|
728
|
+
187,
|
|
729
|
+
214,
|
|
730
|
+
97,
|
|
731
|
+
163,
|
|
732
|
+
254,
|
|
733
|
+
25,
|
|
734
|
+
43,
|
|
735
|
+
125,
|
|
736
|
+
135,
|
|
737
|
+
146,
|
|
738
|
+
173,
|
|
739
|
+
236,
|
|
740
|
+
47,
|
|
741
|
+
113,
|
|
742
|
+
147,
|
|
743
|
+
174,
|
|
744
|
+
233,
|
|
745
|
+
32,
|
|
746
|
+
96,
|
|
747
|
+
160,
|
|
748
|
+
251,
|
|
749
|
+
22,
|
|
750
|
+
58,
|
|
751
|
+
78,
|
|
752
|
+
210,
|
|
753
|
+
109,
|
|
754
|
+
183,
|
|
755
|
+
194,
|
|
756
|
+
93,
|
|
757
|
+
231,
|
|
758
|
+
50,
|
|
759
|
+
86,
|
|
760
|
+
250,
|
|
761
|
+
21,
|
|
762
|
+
63,
|
|
763
|
+
65,
|
|
764
|
+
195,
|
|
765
|
+
94,
|
|
766
|
+
226,
|
|
767
|
+
61,
|
|
768
|
+
71,
|
|
769
|
+
201,
|
|
770
|
+
64,
|
|
771
|
+
192,
|
|
772
|
+
91,
|
|
773
|
+
237,
|
|
774
|
+
44,
|
|
775
|
+
116,
|
|
776
|
+
156,
|
|
777
|
+
191,
|
|
778
|
+
218,
|
|
779
|
+
117,
|
|
780
|
+
159,
|
|
781
|
+
186,
|
|
782
|
+
213,
|
|
783
|
+
100,
|
|
784
|
+
172,
|
|
785
|
+
239,
|
|
786
|
+
42,
|
|
787
|
+
126,
|
|
788
|
+
130,
|
|
789
|
+
157,
|
|
790
|
+
188,
|
|
791
|
+
223,
|
|
792
|
+
122,
|
|
793
|
+
142,
|
|
794
|
+
137,
|
|
795
|
+
128,
|
|
796
|
+
155,
|
|
797
|
+
182,
|
|
798
|
+
193,
|
|
799
|
+
88,
|
|
800
|
+
232,
|
|
801
|
+
35,
|
|
802
|
+
101,
|
|
803
|
+
175,
|
|
804
|
+
234,
|
|
805
|
+
37,
|
|
806
|
+
111,
|
|
807
|
+
177,
|
|
808
|
+
200,
|
|
809
|
+
67,
|
|
810
|
+
197,
|
|
811
|
+
84,
|
|
812
|
+
252,
|
|
813
|
+
31,
|
|
814
|
+
33,
|
|
815
|
+
99,
|
|
816
|
+
165,
|
|
817
|
+
244,
|
|
818
|
+
7,
|
|
819
|
+
9,
|
|
820
|
+
27,
|
|
821
|
+
45,
|
|
822
|
+
119,
|
|
823
|
+
153,
|
|
824
|
+
176,
|
|
825
|
+
203,
|
|
826
|
+
70,
|
|
827
|
+
202,
|
|
828
|
+
69,
|
|
829
|
+
207,
|
|
830
|
+
74,
|
|
831
|
+
222,
|
|
832
|
+
121,
|
|
833
|
+
139,
|
|
834
|
+
134,
|
|
835
|
+
145,
|
|
836
|
+
168,
|
|
837
|
+
227,
|
|
838
|
+
62,
|
|
839
|
+
66,
|
|
840
|
+
198,
|
|
841
|
+
81,
|
|
842
|
+
243,
|
|
843
|
+
14,
|
|
844
|
+
18,
|
|
845
|
+
54,
|
|
846
|
+
90,
|
|
847
|
+
238,
|
|
848
|
+
41,
|
|
849
|
+
123,
|
|
850
|
+
141,
|
|
851
|
+
140,
|
|
852
|
+
143,
|
|
853
|
+
138,
|
|
854
|
+
133,
|
|
855
|
+
148,
|
|
856
|
+
167,
|
|
857
|
+
242,
|
|
858
|
+
13,
|
|
859
|
+
23,
|
|
860
|
+
57,
|
|
861
|
+
75,
|
|
862
|
+
221,
|
|
863
|
+
124,
|
|
864
|
+
132,
|
|
865
|
+
151,
|
|
866
|
+
162,
|
|
867
|
+
253,
|
|
868
|
+
28,
|
|
869
|
+
36,
|
|
870
|
+
108,
|
|
871
|
+
180,
|
|
872
|
+
199,
|
|
873
|
+
82,
|
|
874
|
+
246
|
|
875
|
+
];
|
|
876
|
+
var LOG_TABLE = [
|
|
877
|
+
0,
|
|
878
|
+
0,
|
|
879
|
+
25,
|
|
880
|
+
1,
|
|
881
|
+
50,
|
|
882
|
+
2,
|
|
883
|
+
26,
|
|
884
|
+
198,
|
|
885
|
+
75,
|
|
886
|
+
199,
|
|
887
|
+
27,
|
|
888
|
+
104,
|
|
889
|
+
51,
|
|
890
|
+
238,
|
|
891
|
+
223,
|
|
892
|
+
3,
|
|
893
|
+
100,
|
|
894
|
+
4,
|
|
895
|
+
224,
|
|
896
|
+
14,
|
|
897
|
+
52,
|
|
898
|
+
141,
|
|
899
|
+
129,
|
|
900
|
+
239,
|
|
901
|
+
76,
|
|
902
|
+
113,
|
|
903
|
+
8,
|
|
904
|
+
200,
|
|
905
|
+
248,
|
|
906
|
+
105,
|
|
907
|
+
28,
|
|
908
|
+
193,
|
|
909
|
+
125,
|
|
910
|
+
194,
|
|
911
|
+
29,
|
|
912
|
+
181,
|
|
913
|
+
249,
|
|
914
|
+
185,
|
|
915
|
+
39,
|
|
916
|
+
106,
|
|
917
|
+
77,
|
|
918
|
+
228,
|
|
919
|
+
166,
|
|
920
|
+
114,
|
|
921
|
+
154,
|
|
922
|
+
201,
|
|
923
|
+
9,
|
|
924
|
+
120,
|
|
925
|
+
101,
|
|
926
|
+
47,
|
|
927
|
+
138,
|
|
928
|
+
5,
|
|
929
|
+
33,
|
|
930
|
+
15,
|
|
931
|
+
225,
|
|
932
|
+
36,
|
|
933
|
+
18,
|
|
934
|
+
240,
|
|
935
|
+
130,
|
|
936
|
+
69,
|
|
937
|
+
53,
|
|
938
|
+
147,
|
|
939
|
+
218,
|
|
940
|
+
142,
|
|
941
|
+
150,
|
|
942
|
+
143,
|
|
943
|
+
219,
|
|
944
|
+
189,
|
|
945
|
+
54,
|
|
946
|
+
208,
|
|
947
|
+
206,
|
|
948
|
+
148,
|
|
949
|
+
19,
|
|
950
|
+
92,
|
|
951
|
+
210,
|
|
952
|
+
241,
|
|
953
|
+
64,
|
|
954
|
+
70,
|
|
955
|
+
131,
|
|
956
|
+
56,
|
|
957
|
+
102,
|
|
958
|
+
221,
|
|
959
|
+
253,
|
|
960
|
+
48,
|
|
961
|
+
191,
|
|
962
|
+
6,
|
|
963
|
+
139,
|
|
964
|
+
98,
|
|
965
|
+
179,
|
|
966
|
+
37,
|
|
967
|
+
226,
|
|
968
|
+
152,
|
|
969
|
+
34,
|
|
970
|
+
136,
|
|
971
|
+
145,
|
|
972
|
+
16,
|
|
973
|
+
126,
|
|
974
|
+
110,
|
|
975
|
+
72,
|
|
976
|
+
195,
|
|
977
|
+
163,
|
|
978
|
+
182,
|
|
979
|
+
30,
|
|
980
|
+
66,
|
|
981
|
+
58,
|
|
982
|
+
107,
|
|
983
|
+
40,
|
|
984
|
+
84,
|
|
985
|
+
250,
|
|
986
|
+
133,
|
|
987
|
+
61,
|
|
988
|
+
186,
|
|
989
|
+
43,
|
|
990
|
+
121,
|
|
991
|
+
10,
|
|
992
|
+
21,
|
|
993
|
+
155,
|
|
994
|
+
159,
|
|
995
|
+
94,
|
|
996
|
+
202,
|
|
997
|
+
78,
|
|
998
|
+
212,
|
|
999
|
+
172,
|
|
1000
|
+
229,
|
|
1001
|
+
243,
|
|
1002
|
+
115,
|
|
1003
|
+
167,
|
|
1004
|
+
87,
|
|
1005
|
+
175,
|
|
1006
|
+
88,
|
|
1007
|
+
168,
|
|
1008
|
+
80,
|
|
1009
|
+
244,
|
|
1010
|
+
234,
|
|
1011
|
+
214,
|
|
1012
|
+
116,
|
|
1013
|
+
79,
|
|
1014
|
+
174,
|
|
1015
|
+
233,
|
|
1016
|
+
213,
|
|
1017
|
+
231,
|
|
1018
|
+
230,
|
|
1019
|
+
173,
|
|
1020
|
+
232,
|
|
1021
|
+
44,
|
|
1022
|
+
215,
|
|
1023
|
+
117,
|
|
1024
|
+
122,
|
|
1025
|
+
235,
|
|
1026
|
+
22,
|
|
1027
|
+
11,
|
|
1028
|
+
245,
|
|
1029
|
+
89,
|
|
1030
|
+
203,
|
|
1031
|
+
95,
|
|
1032
|
+
176,
|
|
1033
|
+
156,
|
|
1034
|
+
169,
|
|
1035
|
+
81,
|
|
1036
|
+
160,
|
|
1037
|
+
127,
|
|
1038
|
+
12,
|
|
1039
|
+
246,
|
|
1040
|
+
111,
|
|
1041
|
+
23,
|
|
1042
|
+
196,
|
|
1043
|
+
73,
|
|
1044
|
+
236,
|
|
1045
|
+
216,
|
|
1046
|
+
67,
|
|
1047
|
+
31,
|
|
1048
|
+
45,
|
|
1049
|
+
164,
|
|
1050
|
+
118,
|
|
1051
|
+
123,
|
|
1052
|
+
183,
|
|
1053
|
+
204,
|
|
1054
|
+
187,
|
|
1055
|
+
62,
|
|
1056
|
+
90,
|
|
1057
|
+
251,
|
|
1058
|
+
96,
|
|
1059
|
+
177,
|
|
1060
|
+
134,
|
|
1061
|
+
59,
|
|
1062
|
+
82,
|
|
1063
|
+
161,
|
|
1064
|
+
108,
|
|
1065
|
+
170,
|
|
1066
|
+
85,
|
|
1067
|
+
41,
|
|
1068
|
+
157,
|
|
1069
|
+
151,
|
|
1070
|
+
178,
|
|
1071
|
+
135,
|
|
1072
|
+
144,
|
|
1073
|
+
97,
|
|
1074
|
+
190,
|
|
1075
|
+
220,
|
|
1076
|
+
252,
|
|
1077
|
+
188,
|
|
1078
|
+
149,
|
|
1079
|
+
207,
|
|
1080
|
+
205,
|
|
1081
|
+
55,
|
|
1082
|
+
63,
|
|
1083
|
+
91,
|
|
1084
|
+
209,
|
|
1085
|
+
83,
|
|
1086
|
+
57,
|
|
1087
|
+
132,
|
|
1088
|
+
60,
|
|
1089
|
+
65,
|
|
1090
|
+
162,
|
|
1091
|
+
109,
|
|
1092
|
+
71,
|
|
1093
|
+
20,
|
|
1094
|
+
42,
|
|
1095
|
+
158,
|
|
1096
|
+
93,
|
|
1097
|
+
86,
|
|
1098
|
+
242,
|
|
1099
|
+
211,
|
|
1100
|
+
171,
|
|
1101
|
+
68,
|
|
1102
|
+
17,
|
|
1103
|
+
146,
|
|
1104
|
+
217,
|
|
1105
|
+
35,
|
|
1106
|
+
32,
|
|
1107
|
+
46,
|
|
1108
|
+
137,
|
|
1109
|
+
180,
|
|
1110
|
+
124,
|
|
1111
|
+
184,
|
|
1112
|
+
38,
|
|
1113
|
+
119,
|
|
1114
|
+
153,
|
|
1115
|
+
227,
|
|
1116
|
+
165,
|
|
1117
|
+
103,
|
|
1118
|
+
74,
|
|
1119
|
+
237,
|
|
1120
|
+
222,
|
|
1121
|
+
197,
|
|
1122
|
+
49,
|
|
1123
|
+
254,
|
|
1124
|
+
24,
|
|
1125
|
+
13,
|
|
1126
|
+
99,
|
|
1127
|
+
140,
|
|
1128
|
+
128,
|
|
1129
|
+
192,
|
|
1130
|
+
247,
|
|
1131
|
+
112,
|
|
1132
|
+
7
|
|
1133
|
+
];
|
|
1134
|
+
var WORD_LIST = [
|
|
1135
|
+
"academic",
|
|
1136
|
+
"acid",
|
|
1137
|
+
"acne",
|
|
1138
|
+
"acquire",
|
|
1139
|
+
"acrobat",
|
|
1140
|
+
"activity",
|
|
1141
|
+
"actress",
|
|
1142
|
+
"adapt",
|
|
1143
|
+
"adequate",
|
|
1144
|
+
"adjust",
|
|
1145
|
+
"admit",
|
|
1146
|
+
"adorn",
|
|
1147
|
+
"adult",
|
|
1148
|
+
"advance",
|
|
1149
|
+
"advocate",
|
|
1150
|
+
"afraid",
|
|
1151
|
+
"again",
|
|
1152
|
+
"agency",
|
|
1153
|
+
"agree",
|
|
1154
|
+
"aide",
|
|
1155
|
+
"aircraft",
|
|
1156
|
+
"airline",
|
|
1157
|
+
"airport",
|
|
1158
|
+
"ajar",
|
|
1159
|
+
"alarm",
|
|
1160
|
+
"album",
|
|
1161
|
+
"alcohol",
|
|
1162
|
+
"alien",
|
|
1163
|
+
"alive",
|
|
1164
|
+
"alpha",
|
|
1165
|
+
"already",
|
|
1166
|
+
"alto",
|
|
1167
|
+
"aluminum",
|
|
1168
|
+
"always",
|
|
1169
|
+
"amazing",
|
|
1170
|
+
"ambition",
|
|
1171
|
+
"amount",
|
|
1172
|
+
"amuse",
|
|
1173
|
+
"analysis",
|
|
1174
|
+
"anatomy",
|
|
1175
|
+
"ancestor",
|
|
1176
|
+
"ancient",
|
|
1177
|
+
"angel",
|
|
1178
|
+
"angry",
|
|
1179
|
+
"animal",
|
|
1180
|
+
"answer",
|
|
1181
|
+
"antenna",
|
|
1182
|
+
"anxiety",
|
|
1183
|
+
"apart",
|
|
1184
|
+
"aquatic",
|
|
1185
|
+
"arcade",
|
|
1186
|
+
"arena",
|
|
1187
|
+
"argue",
|
|
1188
|
+
"armed",
|
|
1189
|
+
"artist",
|
|
1190
|
+
"artwork",
|
|
1191
|
+
"aspect",
|
|
1192
|
+
"auction",
|
|
1193
|
+
"august",
|
|
1194
|
+
"aunt",
|
|
1195
|
+
"average",
|
|
1196
|
+
"aviation",
|
|
1197
|
+
"avoid",
|
|
1198
|
+
"award",
|
|
1199
|
+
"away",
|
|
1200
|
+
"axis",
|
|
1201
|
+
"axle",
|
|
1202
|
+
"beam",
|
|
1203
|
+
"beard",
|
|
1204
|
+
"beaver",
|
|
1205
|
+
"become",
|
|
1206
|
+
"bedroom",
|
|
1207
|
+
"behavior",
|
|
1208
|
+
"being",
|
|
1209
|
+
"believe",
|
|
1210
|
+
"belong",
|
|
1211
|
+
"benefit",
|
|
1212
|
+
"best",
|
|
1213
|
+
"beyond",
|
|
1214
|
+
"bike",
|
|
1215
|
+
"biology",
|
|
1216
|
+
"birthday",
|
|
1217
|
+
"bishop",
|
|
1218
|
+
"black",
|
|
1219
|
+
"blanket",
|
|
1220
|
+
"blessing",
|
|
1221
|
+
"blimp",
|
|
1222
|
+
"blind",
|
|
1223
|
+
"blue",
|
|
1224
|
+
"body",
|
|
1225
|
+
"bolt",
|
|
1226
|
+
"boring",
|
|
1227
|
+
"born",
|
|
1228
|
+
"both",
|
|
1229
|
+
"boundary",
|
|
1230
|
+
"bracelet",
|
|
1231
|
+
"branch",
|
|
1232
|
+
"brave",
|
|
1233
|
+
"breathe",
|
|
1234
|
+
"briefing",
|
|
1235
|
+
"broken",
|
|
1236
|
+
"brother",
|
|
1237
|
+
"browser",
|
|
1238
|
+
"bucket",
|
|
1239
|
+
"budget",
|
|
1240
|
+
"building",
|
|
1241
|
+
"bulb",
|
|
1242
|
+
"bulge",
|
|
1243
|
+
"bumpy",
|
|
1244
|
+
"bundle",
|
|
1245
|
+
"burden",
|
|
1246
|
+
"burning",
|
|
1247
|
+
"busy",
|
|
1248
|
+
"buyer",
|
|
1249
|
+
"cage",
|
|
1250
|
+
"calcium",
|
|
1251
|
+
"camera",
|
|
1252
|
+
"campus",
|
|
1253
|
+
"canyon",
|
|
1254
|
+
"capacity",
|
|
1255
|
+
"capital",
|
|
1256
|
+
"capture",
|
|
1257
|
+
"carbon",
|
|
1258
|
+
"cards",
|
|
1259
|
+
"careful",
|
|
1260
|
+
"cargo",
|
|
1261
|
+
"carpet",
|
|
1262
|
+
"carve",
|
|
1263
|
+
"category",
|
|
1264
|
+
"cause",
|
|
1265
|
+
"ceiling",
|
|
1266
|
+
"center",
|
|
1267
|
+
"ceramic",
|
|
1268
|
+
"champion",
|
|
1269
|
+
"change",
|
|
1270
|
+
"charity",
|
|
1271
|
+
"check",
|
|
1272
|
+
"chemical",
|
|
1273
|
+
"chest",
|
|
1274
|
+
"chew",
|
|
1275
|
+
"chubby",
|
|
1276
|
+
"cinema",
|
|
1277
|
+
"civil",
|
|
1278
|
+
"class",
|
|
1279
|
+
"clay",
|
|
1280
|
+
"cleanup",
|
|
1281
|
+
"client",
|
|
1282
|
+
"climate",
|
|
1283
|
+
"clinic",
|
|
1284
|
+
"clock",
|
|
1285
|
+
"clogs",
|
|
1286
|
+
"closet",
|
|
1287
|
+
"clothes",
|
|
1288
|
+
"club",
|
|
1289
|
+
"cluster",
|
|
1290
|
+
"coal",
|
|
1291
|
+
"coastal",
|
|
1292
|
+
"coding",
|
|
1293
|
+
"column",
|
|
1294
|
+
"company",
|
|
1295
|
+
"corner",
|
|
1296
|
+
"costume",
|
|
1297
|
+
"counter",
|
|
1298
|
+
"course",
|
|
1299
|
+
"cover",
|
|
1300
|
+
"cowboy",
|
|
1301
|
+
"cradle",
|
|
1302
|
+
"craft",
|
|
1303
|
+
"crazy",
|
|
1304
|
+
"credit",
|
|
1305
|
+
"cricket",
|
|
1306
|
+
"criminal",
|
|
1307
|
+
"crisis",
|
|
1308
|
+
"critical",
|
|
1309
|
+
"crowd",
|
|
1310
|
+
"crucial",
|
|
1311
|
+
"crunch",
|
|
1312
|
+
"crush",
|
|
1313
|
+
"crystal",
|
|
1314
|
+
"cubic",
|
|
1315
|
+
"cultural",
|
|
1316
|
+
"curious",
|
|
1317
|
+
"curly",
|
|
1318
|
+
"custody",
|
|
1319
|
+
"cylinder",
|
|
1320
|
+
"daisy",
|
|
1321
|
+
"damage",
|
|
1322
|
+
"dance",
|
|
1323
|
+
"darkness",
|
|
1324
|
+
"database",
|
|
1325
|
+
"daughter",
|
|
1326
|
+
"deadline",
|
|
1327
|
+
"deal",
|
|
1328
|
+
"debris",
|
|
1329
|
+
"debut",
|
|
1330
|
+
"decent",
|
|
1331
|
+
"decision",
|
|
1332
|
+
"declare",
|
|
1333
|
+
"decorate",
|
|
1334
|
+
"decrease",
|
|
1335
|
+
"deliver",
|
|
1336
|
+
"demand",
|
|
1337
|
+
"density",
|
|
1338
|
+
"deny",
|
|
1339
|
+
"depart",
|
|
1340
|
+
"depend",
|
|
1341
|
+
"depict",
|
|
1342
|
+
"deploy",
|
|
1343
|
+
"describe",
|
|
1344
|
+
"desert",
|
|
1345
|
+
"desire",
|
|
1346
|
+
"desktop",
|
|
1347
|
+
"destroy",
|
|
1348
|
+
"detailed",
|
|
1349
|
+
"detect",
|
|
1350
|
+
"device",
|
|
1351
|
+
"devote",
|
|
1352
|
+
"diagnose",
|
|
1353
|
+
"dictate",
|
|
1354
|
+
"diet",
|
|
1355
|
+
"dilemma",
|
|
1356
|
+
"diminish",
|
|
1357
|
+
"dining",
|
|
1358
|
+
"diploma",
|
|
1359
|
+
"disaster",
|
|
1360
|
+
"discuss",
|
|
1361
|
+
"disease",
|
|
1362
|
+
"dish",
|
|
1363
|
+
"dismiss",
|
|
1364
|
+
"display",
|
|
1365
|
+
"distance",
|
|
1366
|
+
"dive",
|
|
1367
|
+
"divorce",
|
|
1368
|
+
"document",
|
|
1369
|
+
"domain",
|
|
1370
|
+
"domestic",
|
|
1371
|
+
"dominant",
|
|
1372
|
+
"dough",
|
|
1373
|
+
"downtown",
|
|
1374
|
+
"dragon",
|
|
1375
|
+
"dramatic",
|
|
1376
|
+
"dream",
|
|
1377
|
+
"dress",
|
|
1378
|
+
"drift",
|
|
1379
|
+
"drink",
|
|
1380
|
+
"drove",
|
|
1381
|
+
"drug",
|
|
1382
|
+
"dryer",
|
|
1383
|
+
"duckling",
|
|
1384
|
+
"duke",
|
|
1385
|
+
"duration",
|
|
1386
|
+
"dwarf",
|
|
1387
|
+
"dynamic",
|
|
1388
|
+
"early",
|
|
1389
|
+
"earth",
|
|
1390
|
+
"easel",
|
|
1391
|
+
"easy",
|
|
1392
|
+
"echo",
|
|
1393
|
+
"eclipse",
|
|
1394
|
+
"ecology",
|
|
1395
|
+
"edge",
|
|
1396
|
+
"editor",
|
|
1397
|
+
"educate",
|
|
1398
|
+
"either",
|
|
1399
|
+
"elbow",
|
|
1400
|
+
"elder",
|
|
1401
|
+
"election",
|
|
1402
|
+
"elegant",
|
|
1403
|
+
"element",
|
|
1404
|
+
"elephant",
|
|
1405
|
+
"elevator",
|
|
1406
|
+
"elite",
|
|
1407
|
+
"else",
|
|
1408
|
+
"email",
|
|
1409
|
+
"emerald",
|
|
1410
|
+
"emission",
|
|
1411
|
+
"emperor",
|
|
1412
|
+
"emphasis",
|
|
1413
|
+
"employer",
|
|
1414
|
+
"empty",
|
|
1415
|
+
"ending",
|
|
1416
|
+
"endless",
|
|
1417
|
+
"endorse",
|
|
1418
|
+
"enemy",
|
|
1419
|
+
"energy",
|
|
1420
|
+
"enforce",
|
|
1421
|
+
"engage",
|
|
1422
|
+
"enjoy",
|
|
1423
|
+
"enlarge",
|
|
1424
|
+
"entrance",
|
|
1425
|
+
"envelope",
|
|
1426
|
+
"envy",
|
|
1427
|
+
"epidemic",
|
|
1428
|
+
"episode",
|
|
1429
|
+
"equation",
|
|
1430
|
+
"equip",
|
|
1431
|
+
"eraser",
|
|
1432
|
+
"erode",
|
|
1433
|
+
"escape",
|
|
1434
|
+
"estate",
|
|
1435
|
+
"estimate",
|
|
1436
|
+
"evaluate",
|
|
1437
|
+
"evening",
|
|
1438
|
+
"evidence",
|
|
1439
|
+
"evil",
|
|
1440
|
+
"evoke",
|
|
1441
|
+
"exact",
|
|
1442
|
+
"example",
|
|
1443
|
+
"exceed",
|
|
1444
|
+
"exchange",
|
|
1445
|
+
"exclude",
|
|
1446
|
+
"excuse",
|
|
1447
|
+
"execute",
|
|
1448
|
+
"exercise",
|
|
1449
|
+
"exhaust",
|
|
1450
|
+
"exotic",
|
|
1451
|
+
"expand",
|
|
1452
|
+
"expect",
|
|
1453
|
+
"explain",
|
|
1454
|
+
"express",
|
|
1455
|
+
"extend",
|
|
1456
|
+
"extra",
|
|
1457
|
+
"eyebrow",
|
|
1458
|
+
"facility",
|
|
1459
|
+
"fact",
|
|
1460
|
+
"failure",
|
|
1461
|
+
"faint",
|
|
1462
|
+
"fake",
|
|
1463
|
+
"false",
|
|
1464
|
+
"family",
|
|
1465
|
+
"famous",
|
|
1466
|
+
"fancy",
|
|
1467
|
+
"fangs",
|
|
1468
|
+
"fantasy",
|
|
1469
|
+
"fatal",
|
|
1470
|
+
"fatigue",
|
|
1471
|
+
"favorite",
|
|
1472
|
+
"fawn",
|
|
1473
|
+
"fiber",
|
|
1474
|
+
"fiction",
|
|
1475
|
+
"filter",
|
|
1476
|
+
"finance",
|
|
1477
|
+
"findings",
|
|
1478
|
+
"finger",
|
|
1479
|
+
"firefly",
|
|
1480
|
+
"firm",
|
|
1481
|
+
"fiscal",
|
|
1482
|
+
"fishing",
|
|
1483
|
+
"fitness",
|
|
1484
|
+
"flame",
|
|
1485
|
+
"flash",
|
|
1486
|
+
"flavor",
|
|
1487
|
+
"flea",
|
|
1488
|
+
"flexible",
|
|
1489
|
+
"flip",
|
|
1490
|
+
"float",
|
|
1491
|
+
"floral",
|
|
1492
|
+
"fluff",
|
|
1493
|
+
"focus",
|
|
1494
|
+
"forbid",
|
|
1495
|
+
"force",
|
|
1496
|
+
"forecast",
|
|
1497
|
+
"forget",
|
|
1498
|
+
"formal",
|
|
1499
|
+
"fortune",
|
|
1500
|
+
"forward",
|
|
1501
|
+
"founder",
|
|
1502
|
+
"fraction",
|
|
1503
|
+
"fragment",
|
|
1504
|
+
"frequent",
|
|
1505
|
+
"freshman",
|
|
1506
|
+
"friar",
|
|
1507
|
+
"fridge",
|
|
1508
|
+
"friendly",
|
|
1509
|
+
"frost",
|
|
1510
|
+
"froth",
|
|
1511
|
+
"frozen",
|
|
1512
|
+
"fumes",
|
|
1513
|
+
"funding",
|
|
1514
|
+
"furl",
|
|
1515
|
+
"fused",
|
|
1516
|
+
"galaxy",
|
|
1517
|
+
"game",
|
|
1518
|
+
"garbage",
|
|
1519
|
+
"garden",
|
|
1520
|
+
"garlic",
|
|
1521
|
+
"gasoline",
|
|
1522
|
+
"gather",
|
|
1523
|
+
"general",
|
|
1524
|
+
"genius",
|
|
1525
|
+
"genre",
|
|
1526
|
+
"genuine",
|
|
1527
|
+
"geology",
|
|
1528
|
+
"gesture",
|
|
1529
|
+
"glad",
|
|
1530
|
+
"glance",
|
|
1531
|
+
"glasses",
|
|
1532
|
+
"glen",
|
|
1533
|
+
"glimpse",
|
|
1534
|
+
"goat",
|
|
1535
|
+
"golden",
|
|
1536
|
+
"graduate",
|
|
1537
|
+
"grant",
|
|
1538
|
+
"grasp",
|
|
1539
|
+
"gravity",
|
|
1540
|
+
"gray",
|
|
1541
|
+
"greatest",
|
|
1542
|
+
"grief",
|
|
1543
|
+
"grill",
|
|
1544
|
+
"grin",
|
|
1545
|
+
"grocery",
|
|
1546
|
+
"gross",
|
|
1547
|
+
"group",
|
|
1548
|
+
"grownup",
|
|
1549
|
+
"grumpy",
|
|
1550
|
+
"guard",
|
|
1551
|
+
"guest",
|
|
1552
|
+
"guilt",
|
|
1553
|
+
"guitar",
|
|
1554
|
+
"gums",
|
|
1555
|
+
"hairy",
|
|
1556
|
+
"hamster",
|
|
1557
|
+
"hand",
|
|
1558
|
+
"hanger",
|
|
1559
|
+
"harvest",
|
|
1560
|
+
"have",
|
|
1561
|
+
"havoc",
|
|
1562
|
+
"hawk",
|
|
1563
|
+
"hazard",
|
|
1564
|
+
"headset",
|
|
1565
|
+
"health",
|
|
1566
|
+
"hearing",
|
|
1567
|
+
"heat",
|
|
1568
|
+
"helpful",
|
|
1569
|
+
"herald",
|
|
1570
|
+
"herd",
|
|
1571
|
+
"hesitate",
|
|
1572
|
+
"hobo",
|
|
1573
|
+
"holiday",
|
|
1574
|
+
"holy",
|
|
1575
|
+
"home",
|
|
1576
|
+
"hormone",
|
|
1577
|
+
"hospital",
|
|
1578
|
+
"hour",
|
|
1579
|
+
"huge",
|
|
1580
|
+
"human",
|
|
1581
|
+
"humidity",
|
|
1582
|
+
"hunting",
|
|
1583
|
+
"husband",
|
|
1584
|
+
"hush",
|
|
1585
|
+
"husky",
|
|
1586
|
+
"hybrid",
|
|
1587
|
+
"idea",
|
|
1588
|
+
"identify",
|
|
1589
|
+
"idle",
|
|
1590
|
+
"image",
|
|
1591
|
+
"impact",
|
|
1592
|
+
"imply",
|
|
1593
|
+
"improve",
|
|
1594
|
+
"impulse",
|
|
1595
|
+
"include",
|
|
1596
|
+
"income",
|
|
1597
|
+
"increase",
|
|
1598
|
+
"index",
|
|
1599
|
+
"indicate",
|
|
1600
|
+
"industry",
|
|
1601
|
+
"infant",
|
|
1602
|
+
"inform",
|
|
1603
|
+
"inherit",
|
|
1604
|
+
"injury",
|
|
1605
|
+
"inmate",
|
|
1606
|
+
"insect",
|
|
1607
|
+
"inside",
|
|
1608
|
+
"install",
|
|
1609
|
+
"intend",
|
|
1610
|
+
"intimate",
|
|
1611
|
+
"invasion",
|
|
1612
|
+
"involve",
|
|
1613
|
+
"iris",
|
|
1614
|
+
"island",
|
|
1615
|
+
"isolate",
|
|
1616
|
+
"item",
|
|
1617
|
+
"ivory",
|
|
1618
|
+
"jacket",
|
|
1619
|
+
"jerky",
|
|
1620
|
+
"jewelry",
|
|
1621
|
+
"join",
|
|
1622
|
+
"judicial",
|
|
1623
|
+
"juice",
|
|
1624
|
+
"jump",
|
|
1625
|
+
"junction",
|
|
1626
|
+
"junior",
|
|
1627
|
+
"junk",
|
|
1628
|
+
"jury",
|
|
1629
|
+
"justice",
|
|
1630
|
+
"kernel",
|
|
1631
|
+
"keyboard",
|
|
1632
|
+
"kidney",
|
|
1633
|
+
"kind",
|
|
1634
|
+
"kitchen",
|
|
1635
|
+
"knife",
|
|
1636
|
+
"knit",
|
|
1637
|
+
"laden",
|
|
1638
|
+
"ladle",
|
|
1639
|
+
"ladybug",
|
|
1640
|
+
"lair",
|
|
1641
|
+
"lamp",
|
|
1642
|
+
"language",
|
|
1643
|
+
"large",
|
|
1644
|
+
"laser",
|
|
1645
|
+
"laundry",
|
|
1646
|
+
"lawsuit",
|
|
1647
|
+
"leader",
|
|
1648
|
+
"leaf",
|
|
1649
|
+
"learn",
|
|
1650
|
+
"leaves",
|
|
1651
|
+
"lecture",
|
|
1652
|
+
"legal",
|
|
1653
|
+
"legend",
|
|
1654
|
+
"legs",
|
|
1655
|
+
"lend",
|
|
1656
|
+
"length",
|
|
1657
|
+
"level",
|
|
1658
|
+
"liberty",
|
|
1659
|
+
"library",
|
|
1660
|
+
"license",
|
|
1661
|
+
"lift",
|
|
1662
|
+
"likely",
|
|
1663
|
+
"lilac",
|
|
1664
|
+
"lily",
|
|
1665
|
+
"lips",
|
|
1666
|
+
"liquid",
|
|
1667
|
+
"listen",
|
|
1668
|
+
"literary",
|
|
1669
|
+
"living",
|
|
1670
|
+
"lizard",
|
|
1671
|
+
"loan",
|
|
1672
|
+
"lobe",
|
|
1673
|
+
"location",
|
|
1674
|
+
"losing",
|
|
1675
|
+
"loud",
|
|
1676
|
+
"loyalty",
|
|
1677
|
+
"luck",
|
|
1678
|
+
"lunar",
|
|
1679
|
+
"lunch",
|
|
1680
|
+
"lungs",
|
|
1681
|
+
"luxury",
|
|
1682
|
+
"lying",
|
|
1683
|
+
"lyrics",
|
|
1684
|
+
"machine",
|
|
1685
|
+
"magazine",
|
|
1686
|
+
"maiden",
|
|
1687
|
+
"mailman",
|
|
1688
|
+
"main",
|
|
1689
|
+
"makeup",
|
|
1690
|
+
"making",
|
|
1691
|
+
"mama",
|
|
1692
|
+
"manager",
|
|
1693
|
+
"mandate",
|
|
1694
|
+
"mansion",
|
|
1695
|
+
"manual",
|
|
1696
|
+
"marathon",
|
|
1697
|
+
"march",
|
|
1698
|
+
"market",
|
|
1699
|
+
"marvel",
|
|
1700
|
+
"mason",
|
|
1701
|
+
"material",
|
|
1702
|
+
"math",
|
|
1703
|
+
"maximum",
|
|
1704
|
+
"mayor",
|
|
1705
|
+
"meaning",
|
|
1706
|
+
"medal",
|
|
1707
|
+
"medical",
|
|
1708
|
+
"member",
|
|
1709
|
+
"memory",
|
|
1710
|
+
"mental",
|
|
1711
|
+
"merchant",
|
|
1712
|
+
"merit",
|
|
1713
|
+
"method",
|
|
1714
|
+
"metric",
|
|
1715
|
+
"midst",
|
|
1716
|
+
"mild",
|
|
1717
|
+
"military",
|
|
1718
|
+
"mineral",
|
|
1719
|
+
"minister",
|
|
1720
|
+
"miracle",
|
|
1721
|
+
"mixed",
|
|
1722
|
+
"mixture",
|
|
1723
|
+
"mobile",
|
|
1724
|
+
"modern",
|
|
1725
|
+
"modify",
|
|
1726
|
+
"moisture",
|
|
1727
|
+
"moment",
|
|
1728
|
+
"morning",
|
|
1729
|
+
"mortgage",
|
|
1730
|
+
"mother",
|
|
1731
|
+
"mountain",
|
|
1732
|
+
"mouse",
|
|
1733
|
+
"move",
|
|
1734
|
+
"much",
|
|
1735
|
+
"mule",
|
|
1736
|
+
"multiple",
|
|
1737
|
+
"muscle",
|
|
1738
|
+
"museum",
|
|
1739
|
+
"music",
|
|
1740
|
+
"mustang",
|
|
1741
|
+
"nail",
|
|
1742
|
+
"national",
|
|
1743
|
+
"necklace",
|
|
1744
|
+
"negative",
|
|
1745
|
+
"nervous",
|
|
1746
|
+
"network",
|
|
1747
|
+
"news",
|
|
1748
|
+
"nuclear",
|
|
1749
|
+
"numb",
|
|
1750
|
+
"numerous",
|
|
1751
|
+
"nylon",
|
|
1752
|
+
"oasis",
|
|
1753
|
+
"obesity",
|
|
1754
|
+
"object",
|
|
1755
|
+
"observe",
|
|
1756
|
+
"obtain",
|
|
1757
|
+
"ocean",
|
|
1758
|
+
"often",
|
|
1759
|
+
"olympic",
|
|
1760
|
+
"omit",
|
|
1761
|
+
"oral",
|
|
1762
|
+
"orange",
|
|
1763
|
+
"orbit",
|
|
1764
|
+
"order",
|
|
1765
|
+
"ordinary",
|
|
1766
|
+
"organize",
|
|
1767
|
+
"ounce",
|
|
1768
|
+
"oven",
|
|
1769
|
+
"overall",
|
|
1770
|
+
"owner",
|
|
1771
|
+
"paces",
|
|
1772
|
+
"pacific",
|
|
1773
|
+
"package",
|
|
1774
|
+
"paid",
|
|
1775
|
+
"painting",
|
|
1776
|
+
"pajamas",
|
|
1777
|
+
"pancake",
|
|
1778
|
+
"pants",
|
|
1779
|
+
"papa",
|
|
1780
|
+
"paper",
|
|
1781
|
+
"parcel",
|
|
1782
|
+
"parking",
|
|
1783
|
+
"party",
|
|
1784
|
+
"patent",
|
|
1785
|
+
"patrol",
|
|
1786
|
+
"payment",
|
|
1787
|
+
"payroll",
|
|
1788
|
+
"peaceful",
|
|
1789
|
+
"peanut",
|
|
1790
|
+
"peasant",
|
|
1791
|
+
"pecan",
|
|
1792
|
+
"penalty",
|
|
1793
|
+
"pencil",
|
|
1794
|
+
"percent",
|
|
1795
|
+
"perfect",
|
|
1796
|
+
"permit",
|
|
1797
|
+
"petition",
|
|
1798
|
+
"phantom",
|
|
1799
|
+
"pharmacy",
|
|
1800
|
+
"photo",
|
|
1801
|
+
"phrase",
|
|
1802
|
+
"physics",
|
|
1803
|
+
"pickup",
|
|
1804
|
+
"picture",
|
|
1805
|
+
"piece",
|
|
1806
|
+
"pile",
|
|
1807
|
+
"pink",
|
|
1808
|
+
"pipeline",
|
|
1809
|
+
"pistol",
|
|
1810
|
+
"pitch",
|
|
1811
|
+
"plains",
|
|
1812
|
+
"plan",
|
|
1813
|
+
"plastic",
|
|
1814
|
+
"platform",
|
|
1815
|
+
"playoff",
|
|
1816
|
+
"pleasure",
|
|
1817
|
+
"plot",
|
|
1818
|
+
"plunge",
|
|
1819
|
+
"practice",
|
|
1820
|
+
"prayer",
|
|
1821
|
+
"preach",
|
|
1822
|
+
"predator",
|
|
1823
|
+
"pregnant",
|
|
1824
|
+
"premium",
|
|
1825
|
+
"prepare",
|
|
1826
|
+
"presence",
|
|
1827
|
+
"prevent",
|
|
1828
|
+
"priest",
|
|
1829
|
+
"primary",
|
|
1830
|
+
"priority",
|
|
1831
|
+
"prisoner",
|
|
1832
|
+
"privacy",
|
|
1833
|
+
"prize",
|
|
1834
|
+
"problem",
|
|
1835
|
+
"process",
|
|
1836
|
+
"profile",
|
|
1837
|
+
"program",
|
|
1838
|
+
"promise",
|
|
1839
|
+
"prospect",
|
|
1840
|
+
"provide",
|
|
1841
|
+
"prune",
|
|
1842
|
+
"public",
|
|
1843
|
+
"pulse",
|
|
1844
|
+
"pumps",
|
|
1845
|
+
"punish",
|
|
1846
|
+
"puny",
|
|
1847
|
+
"pupal",
|
|
1848
|
+
"purchase",
|
|
1849
|
+
"purple",
|
|
1850
|
+
"python",
|
|
1851
|
+
"quantity",
|
|
1852
|
+
"quarter",
|
|
1853
|
+
"quick",
|
|
1854
|
+
"quiet",
|
|
1855
|
+
"race",
|
|
1856
|
+
"racism",
|
|
1857
|
+
"radar",
|
|
1858
|
+
"railroad",
|
|
1859
|
+
"rainbow",
|
|
1860
|
+
"raisin",
|
|
1861
|
+
"random",
|
|
1862
|
+
"ranked",
|
|
1863
|
+
"rapids",
|
|
1864
|
+
"raspy",
|
|
1865
|
+
"reaction",
|
|
1866
|
+
"realize",
|
|
1867
|
+
"rebound",
|
|
1868
|
+
"rebuild",
|
|
1869
|
+
"recall",
|
|
1870
|
+
"receiver",
|
|
1871
|
+
"recover",
|
|
1872
|
+
"regret",
|
|
1873
|
+
"regular",
|
|
1874
|
+
"reject",
|
|
1875
|
+
"relate",
|
|
1876
|
+
"remember",
|
|
1877
|
+
"remind",
|
|
1878
|
+
"remove",
|
|
1879
|
+
"render",
|
|
1880
|
+
"repair",
|
|
1881
|
+
"repeat",
|
|
1882
|
+
"replace",
|
|
1883
|
+
"require",
|
|
1884
|
+
"rescue",
|
|
1885
|
+
"research",
|
|
1886
|
+
"resident",
|
|
1887
|
+
"response",
|
|
1888
|
+
"result",
|
|
1889
|
+
"retailer",
|
|
1890
|
+
"retreat",
|
|
1891
|
+
"reunion",
|
|
1892
|
+
"revenue",
|
|
1893
|
+
"review",
|
|
1894
|
+
"reward",
|
|
1895
|
+
"rhyme",
|
|
1896
|
+
"rhythm",
|
|
1897
|
+
"rich",
|
|
1898
|
+
"rival",
|
|
1899
|
+
"river",
|
|
1900
|
+
"robin",
|
|
1901
|
+
"rocky",
|
|
1902
|
+
"romantic",
|
|
1903
|
+
"romp",
|
|
1904
|
+
"roster",
|
|
1905
|
+
"round",
|
|
1906
|
+
"royal",
|
|
1907
|
+
"ruin",
|
|
1908
|
+
"ruler",
|
|
1909
|
+
"rumor",
|
|
1910
|
+
"sack",
|
|
1911
|
+
"safari",
|
|
1912
|
+
"salary",
|
|
1913
|
+
"salon",
|
|
1914
|
+
"salt",
|
|
1915
|
+
"satisfy",
|
|
1916
|
+
"satoshi",
|
|
1917
|
+
"saver",
|
|
1918
|
+
"says",
|
|
1919
|
+
"scandal",
|
|
1920
|
+
"scared",
|
|
1921
|
+
"scatter",
|
|
1922
|
+
"scene",
|
|
1923
|
+
"scholar",
|
|
1924
|
+
"science",
|
|
1925
|
+
"scout",
|
|
1926
|
+
"scramble",
|
|
1927
|
+
"screw",
|
|
1928
|
+
"script",
|
|
1929
|
+
"scroll",
|
|
1930
|
+
"seafood",
|
|
1931
|
+
"season",
|
|
1932
|
+
"secret",
|
|
1933
|
+
"security",
|
|
1934
|
+
"segment",
|
|
1935
|
+
"senior",
|
|
1936
|
+
"shadow",
|
|
1937
|
+
"shaft",
|
|
1938
|
+
"shame",
|
|
1939
|
+
"shaped",
|
|
1940
|
+
"sharp",
|
|
1941
|
+
"shelter",
|
|
1942
|
+
"sheriff",
|
|
1943
|
+
"short",
|
|
1944
|
+
"should",
|
|
1945
|
+
"shrimp",
|
|
1946
|
+
"sidewalk",
|
|
1947
|
+
"silent",
|
|
1948
|
+
"silver",
|
|
1949
|
+
"similar",
|
|
1950
|
+
"simple",
|
|
1951
|
+
"single",
|
|
1952
|
+
"sister",
|
|
1953
|
+
"skin",
|
|
1954
|
+
"skunk",
|
|
1955
|
+
"slap",
|
|
1956
|
+
"slavery",
|
|
1957
|
+
"sled",
|
|
1958
|
+
"slice",
|
|
1959
|
+
"slim",
|
|
1960
|
+
"slow",
|
|
1961
|
+
"slush",
|
|
1962
|
+
"smart",
|
|
1963
|
+
"smear",
|
|
1964
|
+
"smell",
|
|
1965
|
+
"smirk",
|
|
1966
|
+
"smith",
|
|
1967
|
+
"smoking",
|
|
1968
|
+
"smug",
|
|
1969
|
+
"snake",
|
|
1970
|
+
"snapshot",
|
|
1971
|
+
"sniff",
|
|
1972
|
+
"society",
|
|
1973
|
+
"software",
|
|
1974
|
+
"soldier",
|
|
1975
|
+
"solution",
|
|
1976
|
+
"soul",
|
|
1977
|
+
"source",
|
|
1978
|
+
"space",
|
|
1979
|
+
"spark",
|
|
1980
|
+
"speak",
|
|
1981
|
+
"species",
|
|
1982
|
+
"spelling",
|
|
1983
|
+
"spend",
|
|
1984
|
+
"spew",
|
|
1985
|
+
"spider",
|
|
1986
|
+
"spill",
|
|
1987
|
+
"spine",
|
|
1988
|
+
"spirit",
|
|
1989
|
+
"spit",
|
|
1990
|
+
"spray",
|
|
1991
|
+
"sprinkle",
|
|
1992
|
+
"square",
|
|
1993
|
+
"squeeze",
|
|
1994
|
+
"stadium",
|
|
1995
|
+
"staff",
|
|
1996
|
+
"standard",
|
|
1997
|
+
"starting",
|
|
1998
|
+
"station",
|
|
1999
|
+
"stay",
|
|
2000
|
+
"steady",
|
|
2001
|
+
"step",
|
|
2002
|
+
"stick",
|
|
2003
|
+
"stilt",
|
|
2004
|
+
"story",
|
|
2005
|
+
"strategy",
|
|
2006
|
+
"strike",
|
|
2007
|
+
"style",
|
|
2008
|
+
"subject",
|
|
2009
|
+
"submit",
|
|
2010
|
+
"sugar",
|
|
2011
|
+
"suitable",
|
|
2012
|
+
"sunlight",
|
|
2013
|
+
"superior",
|
|
2014
|
+
"surface",
|
|
2015
|
+
"surprise",
|
|
2016
|
+
"survive",
|
|
2017
|
+
"sweater",
|
|
2018
|
+
"swimming",
|
|
2019
|
+
"swing",
|
|
2020
|
+
"switch",
|
|
2021
|
+
"symbolic",
|
|
2022
|
+
"sympathy",
|
|
2023
|
+
"syndrome",
|
|
2024
|
+
"system",
|
|
2025
|
+
"tackle",
|
|
2026
|
+
"tactics",
|
|
2027
|
+
"tadpole",
|
|
2028
|
+
"talent",
|
|
2029
|
+
"task",
|
|
2030
|
+
"taste",
|
|
2031
|
+
"taught",
|
|
2032
|
+
"taxi",
|
|
2033
|
+
"teacher",
|
|
2034
|
+
"teammate",
|
|
2035
|
+
"teaspoon",
|
|
2036
|
+
"temple",
|
|
2037
|
+
"tenant",
|
|
2038
|
+
"tendency",
|
|
2039
|
+
"tension",
|
|
2040
|
+
"terminal",
|
|
2041
|
+
"testify",
|
|
2042
|
+
"texture",
|
|
2043
|
+
"thank",
|
|
2044
|
+
"that",
|
|
2045
|
+
"theater",
|
|
2046
|
+
"theory",
|
|
2047
|
+
"therapy",
|
|
2048
|
+
"thorn",
|
|
2049
|
+
"threaten",
|
|
2050
|
+
"thumb",
|
|
2051
|
+
"thunder",
|
|
2052
|
+
"ticket",
|
|
2053
|
+
"tidy",
|
|
2054
|
+
"timber",
|
|
2055
|
+
"timely",
|
|
2056
|
+
"ting",
|
|
2057
|
+
"tofu",
|
|
2058
|
+
"together",
|
|
2059
|
+
"tolerate",
|
|
2060
|
+
"total",
|
|
2061
|
+
"toxic",
|
|
2062
|
+
"tracks",
|
|
2063
|
+
"traffic",
|
|
2064
|
+
"training",
|
|
2065
|
+
"transfer",
|
|
2066
|
+
"trash",
|
|
2067
|
+
"traveler",
|
|
2068
|
+
"treat",
|
|
2069
|
+
"trend",
|
|
2070
|
+
"trial",
|
|
2071
|
+
"tricycle",
|
|
2072
|
+
"trip",
|
|
2073
|
+
"triumph",
|
|
2074
|
+
"trouble",
|
|
2075
|
+
"true",
|
|
2076
|
+
"trust",
|
|
2077
|
+
"twice",
|
|
2078
|
+
"twin",
|
|
2079
|
+
"type",
|
|
2080
|
+
"typical",
|
|
2081
|
+
"ugly",
|
|
2082
|
+
"ultimate",
|
|
2083
|
+
"umbrella",
|
|
2084
|
+
"uncover",
|
|
2085
|
+
"undergo",
|
|
2086
|
+
"unfair",
|
|
2087
|
+
"unfold",
|
|
2088
|
+
"unhappy",
|
|
2089
|
+
"union",
|
|
2090
|
+
"universe",
|
|
2091
|
+
"unkind",
|
|
2092
|
+
"unknown",
|
|
2093
|
+
"unusual",
|
|
2094
|
+
"unwrap",
|
|
2095
|
+
"upgrade",
|
|
2096
|
+
"upstairs",
|
|
2097
|
+
"username",
|
|
2098
|
+
"usher",
|
|
2099
|
+
"usual",
|
|
2100
|
+
"valid",
|
|
2101
|
+
"valuable",
|
|
2102
|
+
"vampire",
|
|
2103
|
+
"vanish",
|
|
2104
|
+
"various",
|
|
2105
|
+
"vegan",
|
|
2106
|
+
"velvet",
|
|
2107
|
+
"venture",
|
|
2108
|
+
"verdict",
|
|
2109
|
+
"verify",
|
|
2110
|
+
"very",
|
|
2111
|
+
"veteran",
|
|
2112
|
+
"vexed",
|
|
2113
|
+
"victim",
|
|
2114
|
+
"video",
|
|
2115
|
+
"view",
|
|
2116
|
+
"vintage",
|
|
2117
|
+
"violence",
|
|
2118
|
+
"viral",
|
|
2119
|
+
"visitor",
|
|
2120
|
+
"visual",
|
|
2121
|
+
"vitamins",
|
|
2122
|
+
"vocal",
|
|
2123
|
+
"voice",
|
|
2124
|
+
"volume",
|
|
2125
|
+
"voter",
|
|
2126
|
+
"voting",
|
|
2127
|
+
"walnut",
|
|
2128
|
+
"warmth",
|
|
2129
|
+
"warn",
|
|
2130
|
+
"watch",
|
|
2131
|
+
"wavy",
|
|
2132
|
+
"wealthy",
|
|
2133
|
+
"weapon",
|
|
2134
|
+
"webcam",
|
|
2135
|
+
"welcome",
|
|
2136
|
+
"welfare",
|
|
2137
|
+
"western",
|
|
2138
|
+
"width",
|
|
2139
|
+
"wildlife",
|
|
2140
|
+
"window",
|
|
2141
|
+
"wine",
|
|
2142
|
+
"wireless",
|
|
2143
|
+
"wisdom",
|
|
2144
|
+
"withdraw",
|
|
2145
|
+
"wits",
|
|
2146
|
+
"wolf",
|
|
2147
|
+
"woman",
|
|
2148
|
+
"work",
|
|
2149
|
+
"worthy",
|
|
2150
|
+
"wrap",
|
|
2151
|
+
"wrist",
|
|
2152
|
+
"writing",
|
|
2153
|
+
"wrote",
|
|
2154
|
+
"year",
|
|
2155
|
+
"yelp",
|
|
2156
|
+
"yield",
|
|
2157
|
+
"yoga",
|
|
2158
|
+
"zero"
|
|
2159
|
+
];
|
|
2160
|
+
var WORD_LIST_MAP = WORD_LIST.reduce((obj, val, idx) => {
|
|
2161
|
+
obj[val] = idx;
|
|
2162
|
+
return obj;
|
|
2163
|
+
}, {});
|
|
2164
|
+
exports2 = module2.exports = {
|
|
2165
|
+
MIN_ENTROPY_BITS,
|
|
2166
|
+
generateIdentifier,
|
|
2167
|
+
encodeMnemonic,
|
|
2168
|
+
validateMnemonic: validateMnemonic2,
|
|
2169
|
+
splitSecret,
|
|
2170
|
+
combineMnemonics,
|
|
2171
|
+
crypt,
|
|
2172
|
+
bitsToBytes,
|
|
2173
|
+
WORD_LIST,
|
|
2174
|
+
decodeMnemonics
|
|
2175
|
+
};
|
|
2176
|
+
}
|
|
2177
|
+
});
|
|
2178
|
+
|
|
2179
|
+
// node_modules/slip39/src/slip39.js
|
|
2180
|
+
var require_slip39 = __commonJS({
|
|
2181
|
+
"node_modules/slip39/src/slip39.js"(exports2, module2) {
|
|
2182
|
+
var slipHelper = require_slip39_helper();
|
|
2183
|
+
var MAX_DEPTH = 2;
|
|
2184
|
+
var Slip39Node = class {
|
|
2185
|
+
constructor(index = 0, description = "", mnemonic = "", children = []) {
|
|
2186
|
+
this.index = index;
|
|
2187
|
+
this.description = description;
|
|
2188
|
+
this.mnemonic = mnemonic;
|
|
2189
|
+
this.children = children;
|
|
2190
|
+
}
|
|
2191
|
+
get mnemonics() {
|
|
2192
|
+
if (this.children.length === 0) {
|
|
2193
|
+
return [this.mnemonic];
|
|
136
2194
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
2195
|
+
const result = this.children.reduce((prev, item) => {
|
|
2196
|
+
return prev.concat(item.mnemonics);
|
|
2197
|
+
}, []);
|
|
2198
|
+
return result;
|
|
2199
|
+
}
|
|
2200
|
+
};
|
|
2201
|
+
var _Slip39 = class _Slip39 {
|
|
2202
|
+
constructor({
|
|
2203
|
+
iterationExponent = 0,
|
|
2204
|
+
extendableBackupFlag = 0,
|
|
2205
|
+
identifier,
|
|
2206
|
+
groupCount,
|
|
2207
|
+
groupThreshold
|
|
2208
|
+
} = {}) {
|
|
2209
|
+
this.iterationExponent = iterationExponent;
|
|
2210
|
+
this.extendableBackupFlag = extendableBackupFlag;
|
|
2211
|
+
this.identifier = identifier;
|
|
2212
|
+
this.groupCount = groupCount;
|
|
2213
|
+
this.groupThreshold = groupThreshold;
|
|
2214
|
+
}
|
|
2215
|
+
static fromArray(masterSecret, {
|
|
2216
|
+
passphrase = "",
|
|
2217
|
+
threshold = 1,
|
|
2218
|
+
groups = [[1, 1, "Default 1-of-1 group share"]],
|
|
2219
|
+
iterationExponent = 0,
|
|
2220
|
+
extendableBackupFlag = 1,
|
|
2221
|
+
title = "My default slip39 shares"
|
|
2222
|
+
} = {}) {
|
|
2223
|
+
if (masterSecret.length * 8 < slipHelper.MIN_ENTROPY_BITS) {
|
|
2224
|
+
throw Error(
|
|
2225
|
+
`The length of the master secret (${masterSecret.length} bytes) must be at least ${slipHelper.bitsToBytes(slipHelper.MIN_ENTROPY_BITS)} bytes.`
|
|
2226
|
+
);
|
|
159
2227
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
for (const index of indexes) {
|
|
165
|
-
const [address, wallet] = this._addressFromIndex(index);
|
|
166
|
-
this.wallets.push(wallet);
|
|
167
|
-
this.activeIndexes.push(index);
|
|
168
|
-
accounts.push(address);
|
|
169
|
-
// hdPath is BIP44
|
|
170
|
-
this.setAccountDetail(address, {
|
|
171
|
-
hdPath: this.hdPath,
|
|
172
|
-
hdPathType: HD_PATH_TYPE[this.hdPath],
|
|
173
|
-
index: index,
|
|
174
|
-
});
|
|
175
|
-
if (!this.accounts.includes(address)) {
|
|
176
|
-
this.accounts.push(address);
|
|
177
|
-
}
|
|
2228
|
+
if (masterSecret.length % 2 !== 0) {
|
|
2229
|
+
throw Error(
|
|
2230
|
+
"The length of the master secret in bytes must be an even number."
|
|
2231
|
+
);
|
|
178
2232
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
return this.__getPage(1);
|
|
184
|
-
}
|
|
185
|
-
getNextPage() {
|
|
186
|
-
return this.__getPage(1);
|
|
187
|
-
}
|
|
188
|
-
getPreviousPage() {
|
|
189
|
-
return this.__getPage(-1);
|
|
190
|
-
}
|
|
191
|
-
getAddresses(start, end) {
|
|
192
|
-
const from = start;
|
|
193
|
-
const to = end;
|
|
194
|
-
const accounts = [];
|
|
195
|
-
for (let i = from; i < to; i++) {
|
|
196
|
-
const [address] = this._addressFromIndex(i);
|
|
197
|
-
accounts.push({
|
|
198
|
-
address,
|
|
199
|
-
index: i + 1,
|
|
200
|
-
});
|
|
2233
|
+
if (!/^[\x20-\x7E]*$/.test(passphrase)) {
|
|
2234
|
+
throw Error(
|
|
2235
|
+
"The passphrase must contain only printable ASCII characters (code points 32-126)."
|
|
2236
|
+
);
|
|
201
2237
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}
|
|
214
|
-
__getPage(increment) {
|
|
215
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
216
|
-
this.page += increment;
|
|
217
|
-
if (!this.page || this.page <= 0) {
|
|
218
|
-
this.page = 1;
|
|
219
|
-
}
|
|
220
|
-
const from = (this.page - 1) * this.perPage;
|
|
221
|
-
const to = from + this.perPage;
|
|
222
|
-
const accounts = [];
|
|
223
|
-
for (let i = from; i < to; i++) {
|
|
224
|
-
const [address] = this._addressFromIndex(i);
|
|
225
|
-
accounts.push({
|
|
226
|
-
address,
|
|
227
|
-
index: i + 1,
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
return accounts;
|
|
2238
|
+
if (threshold > groups.length) {
|
|
2239
|
+
throw Error(
|
|
2240
|
+
`The requested group threshold (${threshold}) must not exceed the number of groups (${groups.length}).`
|
|
2241
|
+
);
|
|
2242
|
+
}
|
|
2243
|
+
groups.forEach((item) => {
|
|
2244
|
+
if (item[0] === 1 && item[1] > 1) {
|
|
2245
|
+
throw Error(
|
|
2246
|
+
`Creating multiple member shares with member threshold 1 is not allowed. Use 1-of-1 member sharing instead. ${groups.join()}`
|
|
2247
|
+
);
|
|
2248
|
+
}
|
|
231
2249
|
});
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
2250
|
+
const identifier = slipHelper.generateIdentifier();
|
|
2251
|
+
const slip = new _Slip39({
|
|
2252
|
+
iterationExponent,
|
|
2253
|
+
extendableBackupFlag,
|
|
2254
|
+
identifier,
|
|
2255
|
+
groupCount: groups.length,
|
|
2256
|
+
groupThreshold: threshold
|
|
2257
|
+
});
|
|
2258
|
+
const encryptedMasterSecret = slipHelper.crypt(
|
|
2259
|
+
masterSecret,
|
|
2260
|
+
passphrase,
|
|
2261
|
+
iterationExponent,
|
|
2262
|
+
slip.identifier,
|
|
2263
|
+
extendableBackupFlag
|
|
2264
|
+
);
|
|
2265
|
+
const root = slip.buildRecursive(
|
|
2266
|
+
new Slip39Node(0, title),
|
|
2267
|
+
groups,
|
|
2268
|
+
encryptedMasterSecret,
|
|
2269
|
+
threshold
|
|
2270
|
+
);
|
|
2271
|
+
slip.root = root;
|
|
2272
|
+
return slip;
|
|
2273
|
+
}
|
|
2274
|
+
buildRecursive(currentNode, nodes, secret, threshold, index) {
|
|
2275
|
+
if (nodes.length === 0) {
|
|
2276
|
+
const mnemonic = slipHelper.encodeMnemonic(
|
|
2277
|
+
this.identifier,
|
|
2278
|
+
this.extendableBackupFlag,
|
|
2279
|
+
this.iterationExponent,
|
|
2280
|
+
index,
|
|
2281
|
+
this.groupThreshold,
|
|
2282
|
+
this.groupCount,
|
|
2283
|
+
currentNode.index,
|
|
2284
|
+
threshold,
|
|
2285
|
+
secret
|
|
2286
|
+
);
|
|
2287
|
+
currentNode.mnemonic = mnemonic;
|
|
2288
|
+
return currentNode;
|
|
237
2289
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
2290
|
+
const secretShares = slipHelper.splitSecret(
|
|
2291
|
+
threshold,
|
|
2292
|
+
nodes.length,
|
|
2293
|
+
secret
|
|
2294
|
+
);
|
|
2295
|
+
let children = [];
|
|
2296
|
+
let idx = 0;
|
|
2297
|
+
nodes.forEach((item) => {
|
|
2298
|
+
const n = item[0];
|
|
2299
|
+
const m = item[1];
|
|
2300
|
+
const d = item[2] || "";
|
|
2301
|
+
const members = Array().slip39Generate(m, () => [n, 0, d]);
|
|
2302
|
+
const node = new Slip39Node(idx, d);
|
|
2303
|
+
const branch = this.buildRecursive(
|
|
2304
|
+
node,
|
|
2305
|
+
members,
|
|
2306
|
+
secretShares[idx],
|
|
2307
|
+
n,
|
|
2308
|
+
currentNode.index
|
|
2309
|
+
);
|
|
2310
|
+
children = children.concat(branch);
|
|
2311
|
+
idx = idx + 1;
|
|
2312
|
+
});
|
|
2313
|
+
currentNode.children = children;
|
|
2314
|
+
return currentNode;
|
|
2315
|
+
}
|
|
2316
|
+
static recoverSecret(mnemonics, passphrase) {
|
|
2317
|
+
return slipHelper.combineMnemonics(mnemonics, passphrase);
|
|
2318
|
+
}
|
|
2319
|
+
static validateMnemonic(mnemonic) {
|
|
2320
|
+
return slipHelper.validateMnemonic(mnemonic);
|
|
2321
|
+
}
|
|
2322
|
+
fromPath(path) {
|
|
2323
|
+
this.validatePath(path);
|
|
2324
|
+
const children = this.parseChildren(path);
|
|
2325
|
+
if (typeof children === "undefined" || children.length === 0) {
|
|
2326
|
+
return this.root;
|
|
246
2327
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
2328
|
+
return children.reduce((prev, childNumber) => {
|
|
2329
|
+
let childrenLen = prev.children.length;
|
|
2330
|
+
if (childNumber >= childrenLen) {
|
|
2331
|
+
throw new Error(
|
|
2332
|
+
`The path index (${childNumber}) exceeds the children index (${childrenLen - 1}).`
|
|
2333
|
+
);
|
|
2334
|
+
}
|
|
2335
|
+
return prev.children[childNumber];
|
|
2336
|
+
}, this.root);
|
|
2337
|
+
}
|
|
2338
|
+
validatePath(path) {
|
|
2339
|
+
if (!path.match(/(^r)(\/\d{1,2}){0,2}$/)) {
|
|
2340
|
+
throw new Error('Expected valid path e.g. "r/0/0".');
|
|
258
2341
|
}
|
|
259
|
-
|
|
2342
|
+
const depth = path.split("/");
|
|
2343
|
+
const pathLength = depth.length - 1;
|
|
2344
|
+
if (pathLength > MAX_DEPTH) {
|
|
2345
|
+
throw new Error(
|
|
2346
|
+
`Path's (${path}) max depth (${MAX_DEPTH}) is exceeded (${pathLength}).`
|
|
2347
|
+
);
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2350
|
+
parseChildren(path) {
|
|
2351
|
+
const splitted = path.split("/").slice(1);
|
|
2352
|
+
const result = splitted.map((pathFragment) => {
|
|
2353
|
+
return parseInt(pathFragment);
|
|
2354
|
+
});
|
|
2355
|
+
return result;
|
|
2356
|
+
}
|
|
2357
|
+
};
|
|
2358
|
+
__publicField(_Slip39, "decodeMnemonics", slipHelper.decodeMnemonics);
|
|
2359
|
+
var Slip39 = _Slip39;
|
|
2360
|
+
exports2 = module2.exports = Slip39;
|
|
2361
|
+
}
|
|
2362
|
+
});
|
|
2363
|
+
|
|
2364
|
+
// node_modules/slip39/index.js
|
|
2365
|
+
var require_slip392 = __commonJS({
|
|
2366
|
+
"node_modules/slip39/index.js"(exports2, module2) {
|
|
2367
|
+
module2.exports = require_slip39();
|
|
2368
|
+
}
|
|
2369
|
+
});
|
|
2370
|
+
|
|
2371
|
+
// index.ts
|
|
2372
|
+
var eth_hd_keyring_exports = {};
|
|
2373
|
+
__export(eth_hd_keyring_exports, {
|
|
2374
|
+
default: () => eth_hd_keyring_default
|
|
2375
|
+
});
|
|
2376
|
+
module.exports = __toCommonJS(eth_hd_keyring_exports);
|
|
2377
|
+
var import_hdkey = require("ethereum-cryptography/hdkey");
|
|
2378
|
+
var import_eth_simple_keyring = __toESM(require("@rabby-wallet/eth-simple-keyring"));
|
|
2379
|
+
var bip39 = __toESM(require("@scure/bip39"));
|
|
2380
|
+
var import_english = require("@scure/bip39/wordlists/english");
|
|
2381
|
+
var sigUtil = __toESM(require("eth-sig-util"));
|
|
2382
|
+
var import_util = require("@ethereumjs/util");
|
|
2383
|
+
var import_slip39 = __toESM(require_slip392());
|
|
2384
|
+
var type = "HD Key Tree";
|
|
2385
|
+
var HD_PATH_BASE = {
|
|
2386
|
+
["BIP44" /* BIP44 */]: "m/44'/60'/0'/0",
|
|
2387
|
+
["Legacy" /* Legacy */]: "m/44'/60'/0'",
|
|
2388
|
+
["LedgerLive" /* LedgerLive */]: "m/44'/60'/0'/0/0"
|
|
2389
|
+
};
|
|
2390
|
+
var HD_PATH_TYPE = {
|
|
2391
|
+
[HD_PATH_BASE["BIP44" /* BIP44 */]]: "BIP44" /* BIP44 */,
|
|
2392
|
+
[HD_PATH_BASE["Legacy" /* Legacy */]]: "Legacy" /* Legacy */,
|
|
2393
|
+
[HD_PATH_BASE["LedgerLive" /* LedgerLive */]]: "LedgerLive" /* LedgerLive */
|
|
2394
|
+
};
|
|
2395
|
+
var _HdKeyring = class _HdKeyring extends import_eth_simple_keyring.default {
|
|
2396
|
+
/* PUBLIC METHODS */
|
|
2397
|
+
constructor(opts = {}) {
|
|
2398
|
+
super();
|
|
2399
|
+
this.type = type;
|
|
2400
|
+
this.mnemonic = null;
|
|
2401
|
+
this.hdPath = HD_PATH_BASE["BIP44" /* BIP44 */];
|
|
2402
|
+
this.wallets = [];
|
|
2403
|
+
this.activeIndexes = [];
|
|
2404
|
+
this.index = 0;
|
|
2405
|
+
this.page = 0;
|
|
2406
|
+
this.perPage = 5;
|
|
2407
|
+
this.byImport = false;
|
|
2408
|
+
this.publicKey = "";
|
|
2409
|
+
this.needPassphrase = false;
|
|
2410
|
+
this.accounts = [];
|
|
2411
|
+
this.accountDetails = {};
|
|
2412
|
+
this.passphrase = "";
|
|
2413
|
+
this.isSlip39 = false;
|
|
2414
|
+
this.setAccountDetail = (address, accountDetail) => {
|
|
2415
|
+
this.accountDetails = __spreadProps(__spreadValues({}, this.accountDetails), {
|
|
2416
|
+
[address.toLowerCase()]: accountDetail
|
|
2417
|
+
});
|
|
2418
|
+
};
|
|
2419
|
+
this.getAccountDetail = (address) => {
|
|
2420
|
+
return this.accountDetails[address.toLowerCase()];
|
|
2421
|
+
};
|
|
2422
|
+
this.deserialize(opts);
|
|
2423
|
+
}
|
|
2424
|
+
serialize() {
|
|
2425
|
+
return Promise.resolve({
|
|
2426
|
+
mnemonic: this.mnemonic,
|
|
2427
|
+
/**
|
|
2428
|
+
* @deprecated
|
|
2429
|
+
*/
|
|
2430
|
+
activeIndexes: this.activeIndexes,
|
|
2431
|
+
hdPath: this.hdPath,
|
|
2432
|
+
byImport: this.byImport,
|
|
2433
|
+
index: this.index,
|
|
2434
|
+
needPassphrase: this.needPassphrase,
|
|
2435
|
+
accounts: this.accounts,
|
|
2436
|
+
accountDetails: this.accountDetails,
|
|
2437
|
+
publicKey: this.publicKey,
|
|
2438
|
+
isSlip39: this.isSlip39
|
|
2439
|
+
});
|
|
2440
|
+
}
|
|
2441
|
+
deserialize(opts = {}) {
|
|
2442
|
+
this.wallets = [];
|
|
2443
|
+
this.mnemonic = null;
|
|
2444
|
+
this.hdPath = opts.hdPath || HD_PATH_BASE["BIP44" /* BIP44 */];
|
|
2445
|
+
this.byImport = !!opts.byImport;
|
|
2446
|
+
this.index = opts.index || 0;
|
|
2447
|
+
this.needPassphrase = opts.needPassphrase || !!opts.passphrase;
|
|
2448
|
+
this.passphrase = opts.passphrase;
|
|
2449
|
+
this.accounts = opts.accounts || [];
|
|
2450
|
+
this.accountDetails = opts.accountDetails || {};
|
|
2451
|
+
this.publicKey = opts.publicKey || "";
|
|
2452
|
+
this.isSlip39 = opts.isSlip39 || false;
|
|
2453
|
+
if (opts.mnemonic) {
|
|
2454
|
+
this.mnemonic = opts.mnemonic;
|
|
2455
|
+
this.setPassphrase(opts.passphrase || "");
|
|
260
2456
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
2457
|
+
if (!this.accounts.length && opts.activeIndexes) {
|
|
2458
|
+
return this.activeAccounts(opts.activeIndexes);
|
|
2459
|
+
}
|
|
2460
|
+
return Promise.resolve([]);
|
|
2461
|
+
}
|
|
2462
|
+
initFromMnemonic(mnemonic, passphrase) {
|
|
2463
|
+
this.mnemonic = mnemonic;
|
|
2464
|
+
const seed = this.getSeed(mnemonic, passphrase);
|
|
2465
|
+
this.hdWallet = import_hdkey.HDKey.fromMasterSeed(seed);
|
|
2466
|
+
if (!this.publicKey) {
|
|
2467
|
+
this.publicKey = this.calcBasePublicKey(this.hdWallet);
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2470
|
+
calcBasePublicKey(hdKey) {
|
|
2471
|
+
return (0, import_util.bytesToHex)(
|
|
2472
|
+
hdKey.derive(this.getHDPathBase("BIP44" /* BIP44 */)).publicKey
|
|
2473
|
+
);
|
|
2474
|
+
}
|
|
2475
|
+
addAccounts(numberOfAccounts = 1) {
|
|
2476
|
+
if (!this.hdWallet) {
|
|
2477
|
+
this.initFromMnemonic(bip39.generateMnemonic(import_english.wordlist));
|
|
2478
|
+
}
|
|
2479
|
+
let count = numberOfAccounts;
|
|
2480
|
+
let currentIdx = 0;
|
|
2481
|
+
const addresses = [];
|
|
2482
|
+
while (count) {
|
|
2483
|
+
const [address, wallet] = this._addressFromIndex(currentIdx);
|
|
2484
|
+
if (this.wallets.find(
|
|
2485
|
+
(w) => (0, import_util.bytesToHex)(w.publicKey) === (0, import_util.bytesToHex)(wallet.publicKey)
|
|
2486
|
+
)) {
|
|
2487
|
+
currentIdx++;
|
|
2488
|
+
} else {
|
|
2489
|
+
this.wallets.push(wallet);
|
|
2490
|
+
addresses.push(address);
|
|
2491
|
+
this.setAccountDetail(address, {
|
|
2492
|
+
hdPath: this.hdPath,
|
|
2493
|
+
hdPathType: HD_PATH_TYPE[this.hdPath],
|
|
2494
|
+
index: currentIdx
|
|
2495
|
+
});
|
|
2496
|
+
count--;
|
|
2497
|
+
}
|
|
2498
|
+
if (!this.accounts.includes(address)) {
|
|
2499
|
+
this.accounts.push(address);
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
return Promise.resolve(addresses);
|
|
2503
|
+
}
|
|
2504
|
+
activeAccounts(indexes) {
|
|
2505
|
+
const accounts = [];
|
|
2506
|
+
for (const index of indexes) {
|
|
2507
|
+
const [address, wallet] = this._addressFromIndex(index);
|
|
2508
|
+
this.wallets.push(wallet);
|
|
2509
|
+
this.activeIndexes.push(index);
|
|
2510
|
+
accounts.push(address);
|
|
2511
|
+
this.setAccountDetail(address, {
|
|
2512
|
+
hdPath: this.hdPath,
|
|
2513
|
+
hdPathType: HD_PATH_TYPE[this.hdPath],
|
|
2514
|
+
index
|
|
2515
|
+
});
|
|
2516
|
+
if (!this.accounts.includes(address)) {
|
|
2517
|
+
this.accounts.push(address);
|
|
2518
|
+
}
|
|
2519
|
+
}
|
|
2520
|
+
return accounts;
|
|
2521
|
+
}
|
|
2522
|
+
getFirstPage() {
|
|
2523
|
+
this.page = 0;
|
|
2524
|
+
return this.__getPage(1);
|
|
2525
|
+
}
|
|
2526
|
+
getNextPage() {
|
|
2527
|
+
return this.__getPage(1);
|
|
2528
|
+
}
|
|
2529
|
+
getPreviousPage() {
|
|
2530
|
+
return this.__getPage(-1);
|
|
2531
|
+
}
|
|
2532
|
+
getAddresses(start, end) {
|
|
2533
|
+
const from = start;
|
|
2534
|
+
const to = end;
|
|
2535
|
+
const accounts = [];
|
|
2536
|
+
for (let i = from; i < to; i++) {
|
|
2537
|
+
const [address] = this._addressFromIndex(i);
|
|
2538
|
+
accounts.push({
|
|
2539
|
+
address,
|
|
2540
|
+
index: i + 1
|
|
2541
|
+
});
|
|
2542
|
+
}
|
|
2543
|
+
return accounts;
|
|
2544
|
+
}
|
|
2545
|
+
removeAccount(address) {
|
|
2546
|
+
var _a;
|
|
2547
|
+
const index = (_a = this.getInfoByAddress(address)) == null ? void 0 : _a.index;
|
|
2548
|
+
this.activeIndexes = this.activeIndexes.filter((i) => i !== index);
|
|
2549
|
+
delete this.accountDetails[address];
|
|
2550
|
+
this.accounts = this.accounts.filter((acc) => acc !== address);
|
|
2551
|
+
this.wallets = this.wallets.filter(
|
|
2552
|
+
({ publicKey }) => sigUtil.normalize(this._addressFromPublicKey(publicKey)).toLowerCase() !== address.toLowerCase()
|
|
2553
|
+
);
|
|
2554
|
+
}
|
|
2555
|
+
__getPage(increment) {
|
|
2556
|
+
return __async(this, null, function* () {
|
|
2557
|
+
this.page += increment;
|
|
2558
|
+
if (!this.page || this.page <= 0) {
|
|
2559
|
+
this.page = 1;
|
|
2560
|
+
}
|
|
2561
|
+
const from = (this.page - 1) * this.perPage;
|
|
2562
|
+
const to = from + this.perPage;
|
|
2563
|
+
const accounts = [];
|
|
2564
|
+
for (let i = from; i < to; i++) {
|
|
2565
|
+
const [address] = this._addressFromIndex(i);
|
|
2566
|
+
accounts.push({
|
|
2567
|
+
address,
|
|
2568
|
+
index: i + 1
|
|
2569
|
+
});
|
|
2570
|
+
}
|
|
2571
|
+
return accounts;
|
|
2572
|
+
});
|
|
2573
|
+
}
|
|
2574
|
+
getAccounts() {
|
|
2575
|
+
var _a;
|
|
2576
|
+
if ((_a = this.accounts) == null ? void 0 : _a.length) {
|
|
2577
|
+
return Promise.resolve(this.accounts);
|
|
2578
|
+
}
|
|
2579
|
+
return Promise.resolve(
|
|
2580
|
+
this.wallets.map((w) => {
|
|
2581
|
+
return sigUtil.normalize(this._addressFromPublicKey(w.publicKey));
|
|
2582
|
+
})
|
|
2583
|
+
);
|
|
2584
|
+
}
|
|
2585
|
+
getInfoByAddress(address) {
|
|
2586
|
+
const detail = this.accountDetails[address];
|
|
2587
|
+
if (detail) {
|
|
2588
|
+
return __spreadProps(__spreadValues({}, detail), {
|
|
2589
|
+
basePublicKey: this.publicKey
|
|
2590
|
+
});
|
|
2591
|
+
}
|
|
2592
|
+
for (const key in this.wallets) {
|
|
2593
|
+
const wallet = this.wallets[key];
|
|
2594
|
+
if (sigUtil.normalize(this._addressFromPublicKey(wallet.publicKey)) === address.toLowerCase()) {
|
|
2595
|
+
return {
|
|
2596
|
+
index: Number(key),
|
|
2597
|
+
hdPathType: HD_PATH_TYPE[this.hdPath],
|
|
2598
|
+
hdPath: this.hdPath,
|
|
2599
|
+
basePublicKey: this.publicKey
|
|
266
2600
|
};
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
2601
|
+
}
|
|
2602
|
+
}
|
|
2603
|
+
return null;
|
|
2604
|
+
}
|
|
2605
|
+
_addressFromIndex(i) {
|
|
2606
|
+
const child = this.getChildForIndex(i);
|
|
2607
|
+
const wallet = {
|
|
2608
|
+
publicKey: (0, import_util.privateToPublic)(child.privateKey),
|
|
2609
|
+
privateKey: child.privateKey
|
|
2610
|
+
};
|
|
2611
|
+
const address = sigUtil.normalize(
|
|
2612
|
+
this._addressFromPublicKey(wallet.publicKey)
|
|
2613
|
+
);
|
|
2614
|
+
return [address, wallet];
|
|
2615
|
+
}
|
|
2616
|
+
_addressFromPublicKey(publicKey) {
|
|
2617
|
+
return (0, import_util.bytesToHex)((0, import_util.publicToAddress)(publicKey, true)).toLowerCase();
|
|
2618
|
+
}
|
|
2619
|
+
generateMnemonic() {
|
|
2620
|
+
return bip39.generateMnemonic(import_english.wordlist);
|
|
2621
|
+
}
|
|
2622
|
+
setHdPath(hdPath = HD_PATH_BASE["BIP44" /* BIP44 */]) {
|
|
2623
|
+
this.hdPath = hdPath;
|
|
2624
|
+
}
|
|
2625
|
+
getChildForIndex(index) {
|
|
2626
|
+
return this.hdWallet.derive(this.getPathForIndex(index));
|
|
2627
|
+
}
|
|
2628
|
+
isLedgerLiveHdPath() {
|
|
2629
|
+
return this.hdPath === HD_PATH_BASE["LedgerLive" /* LedgerLive */];
|
|
2630
|
+
}
|
|
2631
|
+
getPathForIndex(index) {
|
|
2632
|
+
return this.isLedgerLiveHdPath() ? `m/44'/60'/${index}'/0/0` : `${this.hdPath}/${index}`;
|
|
2633
|
+
}
|
|
2634
|
+
setPassphrase(passphrase) {
|
|
2635
|
+
this.passphrase = passphrase;
|
|
2636
|
+
this.initFromMnemonic(this.mnemonic, passphrase);
|
|
2637
|
+
for (const acc of this.accounts) {
|
|
2638
|
+
const detail = this.getAccountDetail(acc);
|
|
2639
|
+
if (detail) {
|
|
2640
|
+
this.setHdPath(detail.hdPath);
|
|
2641
|
+
const [address, wallet] = this._addressFromIndex(detail.index);
|
|
2642
|
+
if (address.toLowerCase() === acc.toLowerCase()) {
|
|
2643
|
+
this.wallets.push(wallet);
|
|
302
2644
|
}
|
|
2645
|
+
}
|
|
303
2646
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
2647
|
+
}
|
|
2648
|
+
/**
|
|
2649
|
+
* if passphrase is correct, the publicKey will be the same as the stored one
|
|
2650
|
+
*/
|
|
2651
|
+
checkPassphrase(passphrase) {
|
|
2652
|
+
const seed = this.getSeed(this.mnemonic, passphrase);
|
|
2653
|
+
const hdWallet = import_hdkey.HDKey.fromMasterSeed(seed);
|
|
2654
|
+
const publicKey = this.calcBasePublicKey(hdWallet);
|
|
2655
|
+
return this.publicKey === publicKey;
|
|
2656
|
+
}
|
|
2657
|
+
getHDPathBase(hdPathType) {
|
|
2658
|
+
return HD_PATH_BASE[hdPathType];
|
|
2659
|
+
}
|
|
2660
|
+
setHDPathType(hdPathType) {
|
|
2661
|
+
return __async(this, null, function* () {
|
|
2662
|
+
const hdPath = this.getHDPathBase(hdPathType);
|
|
2663
|
+
this.setHdPath(hdPath);
|
|
2664
|
+
});
|
|
2665
|
+
}
|
|
2666
|
+
getSeed(mnemonic, passphrase) {
|
|
2667
|
+
if (_HdKeyring.checkMnemonicIsSlip39(mnemonic)) {
|
|
2668
|
+
this.isSlip39 = true;
|
|
2669
|
+
return this.slip39MnemonicToSeedSync(mnemonic, passphrase);
|
|
2670
|
+
}
|
|
2671
|
+
return bip39.mnemonicToSeedSync(mnemonic, passphrase);
|
|
2672
|
+
}
|
|
2673
|
+
slip39MnemonicToSeedSync(mnemonic, passphrase) {
|
|
2674
|
+
const secretShares = mnemonic.split("\n");
|
|
2675
|
+
const secretBytes = import_slip39.default.recoverSecret(secretShares, passphrase);
|
|
2676
|
+
const seed = (0, import_util.hexToBytes)((0, import_util.bytesToHex)(secretBytes));
|
|
2677
|
+
return seed;
|
|
2678
|
+
}
|
|
2679
|
+
static checkMnemonicIsSlip39(mnemonic) {
|
|
2680
|
+
const arr = mnemonic.split("\n");
|
|
2681
|
+
try {
|
|
2682
|
+
_HdKeyring.slip39DecodeMnemonics(arr);
|
|
2683
|
+
return true;
|
|
2684
|
+
} catch (e) {
|
|
2685
|
+
return false;
|
|
321
2686
|
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
|
|
2687
|
+
}
|
|
2688
|
+
static slip39DecodeMnemonics(shares) {
|
|
2689
|
+
return import_slip39.default.decodeMnemonics(shares);
|
|
2690
|
+
}
|
|
2691
|
+
static validateMnemonic(mnemonic) {
|
|
2692
|
+
if (this.checkMnemonicIsSlip39(mnemonic)) {
|
|
2693
|
+
return true;
|
|
2694
|
+
}
|
|
2695
|
+
return bip39.validateMnemonic(mnemonic, import_english.wordlist);
|
|
2696
|
+
}
|
|
2697
|
+
};
|
|
2698
|
+
_HdKeyring.type = type;
|
|
2699
|
+
var HdKeyring = _HdKeyring;
|
|
2700
|
+
var eth_hd_keyring_default = HdKeyring;
|