@metamask-previews/keyring-controller 12.2.0-preview.8cdddaf → 12.2.0-preview.91dd28a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +75 -4
- package/dist/KeyringController.d.ts +102 -2
- package/dist/KeyringController.d.ts.map +1 -1
- package/dist/KeyringController.js +515 -109
- package/dist/KeyringController.js.map +1 -1
- package/dist/constants.d.ts +30 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +34 -0
- package/dist/constants.js.map +1 -0
- package/package.json +5 -3
|
@@ -42,15 +42,22 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
42
42
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
43
43
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
44
44
|
};
|
|
45
|
-
var
|
|
45
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
46
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
47
|
+
};
|
|
48
|
+
var _KeyringController_instances, _KeyringController_keyringBuilders, _KeyringController_keyrings, _KeyringController_unsupportedKeyrings, _KeyringController_password, _KeyringController_encryptor, _KeyringController_cacheEncryptionKey, _KeyringController_qrKeyringStateListener, _KeyringController_registerMessageHandlers, _KeyringController_getKeyringBuilderForType, _KeyringController_addQRKeyring, _KeyringController_subscribeToQRKeyringEvents, _KeyringController_unsubscribeFromQRKeyringsEvents, _KeyringController_createNewVaultWithKeyring, _KeyringController_updateKeyringsInState, _KeyringController_unlockKeyrings, _KeyringController_createKeyringWithFirstAccount, _KeyringController_newKeyring, _KeyringController_clearKeyrings, _KeyringController_restoreKeyring, _KeyringController_destroyKeyring, _KeyringController_removeEmptyKeyrings, _KeyringController_checkForDuplicate, _KeyringController_setUnlocked, _KeyringController_getMemState;
|
|
46
49
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
-
exports.KeyringController = exports.getDefaultKeyringState = exports.SignTypedDataVersion = exports.AccountImportStrategy = exports.KeyringTypes = void 0;
|
|
50
|
+
exports.KeyringController = exports.getDefaultKeyringState = exports.keyringBuilderFactory = exports.SignTypedDataVersion = exports.AccountImportStrategy = exports.KeyringTypes = void 0;
|
|
48
51
|
const base_controller_1 = require("@metamask/base-controller");
|
|
49
|
-
const
|
|
52
|
+
const encryptorUtils = __importStar(require("@metamask/browser-passworder"));
|
|
53
|
+
const eth_hd_keyring_1 = __importDefault(require("@metamask/eth-hd-keyring"));
|
|
54
|
+
const eth_sig_util_1 = require("@metamask/eth-sig-util");
|
|
55
|
+
const eth_simple_keyring_1 = __importDefault(require("@metamask/eth-simple-keyring"));
|
|
50
56
|
const utils_1 = require("@metamask/utils");
|
|
51
57
|
const async_mutex_1 = require("async-mutex");
|
|
52
58
|
const ethereumjs_util_1 = require("ethereumjs-util");
|
|
53
59
|
const ethereumjs_wallet_1 = __importStar(require("ethereumjs-wallet"));
|
|
60
|
+
const constants_1 = require("./constants");
|
|
54
61
|
const name = 'KeyringController';
|
|
55
62
|
/**
|
|
56
63
|
* Available keyring types
|
|
@@ -85,6 +92,24 @@ var SignTypedDataVersion;
|
|
|
85
92
|
SignTypedDataVersion["V3"] = "V3";
|
|
86
93
|
SignTypedDataVersion["V4"] = "V4";
|
|
87
94
|
})(SignTypedDataVersion = exports.SignTypedDataVersion || (exports.SignTypedDataVersion = {}));
|
|
95
|
+
/**
|
|
96
|
+
* Get builder function for `Keyring`
|
|
97
|
+
*
|
|
98
|
+
* Returns a builder function for `Keyring` with a `type` property.
|
|
99
|
+
*
|
|
100
|
+
* @param KeyringConstructor - The Keyring class for the builder.
|
|
101
|
+
* @returns A builder function for the given Keyring.
|
|
102
|
+
*/
|
|
103
|
+
function keyringBuilderFactory(KeyringConstructor) {
|
|
104
|
+
const builder = () => new KeyringConstructor();
|
|
105
|
+
builder.type = KeyringConstructor.type;
|
|
106
|
+
return builder;
|
|
107
|
+
}
|
|
108
|
+
exports.keyringBuilderFactory = keyringBuilderFactory;
|
|
109
|
+
const defaultKeyringBuilders = [
|
|
110
|
+
keyringBuilderFactory(eth_simple_keyring_1.default),
|
|
111
|
+
keyringBuilderFactory(eth_hd_keyring_1.default),
|
|
112
|
+
];
|
|
88
113
|
const getDefaultKeyringState = () => {
|
|
89
114
|
return {
|
|
90
115
|
isUnlocked: false,
|
|
@@ -104,6 +129,53 @@ function assertHasUint8ArrayMnemonic(keyring) {
|
|
|
104
129
|
throw new Error("Can't get mnemonic bytes from keyring");
|
|
105
130
|
}
|
|
106
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* Assert that the provided encryptor supports
|
|
134
|
+
* encryption and encryption key export.
|
|
135
|
+
*
|
|
136
|
+
* @param encryptor - The encryptor to check.
|
|
137
|
+
* @throws If the encryptor does not support key encryption.
|
|
138
|
+
*/
|
|
139
|
+
function assertIsExportableKeyEncryptor(encryptor) {
|
|
140
|
+
if (!('importKey' in encryptor &&
|
|
141
|
+
typeof encryptor.importKey === 'function' &&
|
|
142
|
+
'decryptWithKey' in encryptor &&
|
|
143
|
+
typeof encryptor.decryptWithKey === 'function' &&
|
|
144
|
+
'encryptWithKey' in encryptor &&
|
|
145
|
+
typeof encryptor.encryptWithKey === 'function')) {
|
|
146
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedEncryptionKeyExport);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Checks if the provided value is a serialized keyrings array.
|
|
151
|
+
*
|
|
152
|
+
* @param array - The value to check.
|
|
153
|
+
* @returns True if the value is a serialized keyrings array.
|
|
154
|
+
*/
|
|
155
|
+
function isSerializedKeyringsArray(array) {
|
|
156
|
+
return (typeof array === 'object' &&
|
|
157
|
+
Array.isArray(array) &&
|
|
158
|
+
array.every((value) => value.type && (0, utils_1.isValidJson)(value.data)));
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Display For Keyring
|
|
162
|
+
*
|
|
163
|
+
* Is used for adding the current keyrings to the state object.
|
|
164
|
+
*
|
|
165
|
+
* @param keyring - The keyring to display.
|
|
166
|
+
* @returns A keyring display object, with type and accounts properties.
|
|
167
|
+
*/
|
|
168
|
+
function displayForKeyring(keyring) {
|
|
169
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
170
|
+
const accounts = yield keyring.getAccounts();
|
|
171
|
+
return {
|
|
172
|
+
type: keyring.type,
|
|
173
|
+
// Cast to `Hex[]` here is safe here because `accounts` has no nullish
|
|
174
|
+
// values, and `normalize` returns `Hex` unless given a nullish value
|
|
175
|
+
accounts: accounts.map(eth_sig_util_1.normalize),
|
|
176
|
+
};
|
|
177
|
+
});
|
|
178
|
+
}
|
|
107
179
|
/**
|
|
108
180
|
* Controller responsible for establishing and managing user identity.
|
|
109
181
|
*
|
|
@@ -129,8 +201,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
129
201
|
* @param options.state - Initial state to set on this controller.
|
|
130
202
|
*/
|
|
131
203
|
constructor(options) {
|
|
132
|
-
|
|
133
|
-
const { syncIdentities, updateIdentities, setSelectedAddress, setAccountLabel, keyringBuilders, messenger, state, } = options;
|
|
204
|
+
const { syncIdentities, updateIdentities, setSelectedAddress, setAccountLabel, encryptor = encryptorUtils, keyringBuilders, messenger, state, } = options;
|
|
134
205
|
super({
|
|
135
206
|
name,
|
|
136
207
|
metadata: {
|
|
@@ -145,28 +216,25 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
145
216
|
});
|
|
146
217
|
_KeyringController_instances.add(this);
|
|
147
218
|
this.mutex = new async_mutex_1.Mutex();
|
|
148
|
-
|
|
219
|
+
_KeyringController_keyringBuilders.set(this, void 0);
|
|
220
|
+
_KeyringController_keyrings.set(this, void 0);
|
|
221
|
+
_KeyringController_unsupportedKeyrings.set(this, void 0);
|
|
222
|
+
_KeyringController_password.set(this, void 0);
|
|
223
|
+
_KeyringController_encryptor.set(this, void 0);
|
|
224
|
+
_KeyringController_cacheEncryptionKey.set(this, void 0);
|
|
149
225
|
_KeyringController_qrKeyringStateListener.set(this, void 0);
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
226
|
+
__classPrivateFieldSet(this, _KeyringController_keyringBuilders, keyringBuilders
|
|
227
|
+
? defaultKeyringBuilders.concat(keyringBuilders)
|
|
228
|
+
: defaultKeyringBuilders, "f");
|
|
229
|
+
__classPrivateFieldSet(this, _KeyringController_encryptor, encryptor, "f");
|
|
230
|
+
__classPrivateFieldSet(this, _KeyringController_keyrings, [], "f");
|
|
231
|
+
__classPrivateFieldSet(this, _KeyringController_unsupportedKeyrings, [], "f");
|
|
232
|
+
// This option allows the controller to cache an exported key
|
|
233
|
+
// for use in decrypting and encrypting data without password
|
|
234
|
+
__classPrivateFieldSet(this, _KeyringController_cacheEncryptionKey, Boolean(options.cacheEncryptionKey), "f");
|
|
235
|
+
if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
|
|
236
|
+
assertIsExportableKeyEncryptor(encryptor);
|
|
157
237
|
}
|
|
158
|
-
else {
|
|
159
|
-
__classPrivateFieldSet(this, _KeyringController_keyring, new eth_keyring_controller_1.KeyringController({
|
|
160
|
-
initState: state,
|
|
161
|
-
encryptor: options.encryptor,
|
|
162
|
-
keyringBuilders,
|
|
163
|
-
cacheEncryptionKey: (_a = options.cacheEncryptionKey) !== null && _a !== void 0 ? _a : false,
|
|
164
|
-
}), "f");
|
|
165
|
-
}
|
|
166
|
-
__classPrivateFieldGet(this, _KeyringController_keyring, "f").memStore.subscribe(__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_fullUpdate).bind(this));
|
|
167
|
-
__classPrivateFieldGet(this, _KeyringController_keyring, "f").store.subscribe(__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_fullUpdate).bind(this));
|
|
168
|
-
__classPrivateFieldGet(this, _KeyringController_keyring, "f").on('lock', __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_handleLock).bind(this));
|
|
169
|
-
__classPrivateFieldGet(this, _KeyringController_keyring, "f").on('unlock', __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_handleUnlock).bind(this));
|
|
170
238
|
this.syncIdentities = syncIdentities;
|
|
171
239
|
this.updateIdentities = updateIdentities;
|
|
172
240
|
this.setSelectedAddress = setSelectedAddress;
|
|
@@ -183,12 +251,11 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
183
251
|
*/
|
|
184
252
|
addNewAccount(accountCount) {
|
|
185
253
|
return __awaiter(this, void 0, void 0, function* () {
|
|
186
|
-
const primaryKeyring =
|
|
187
|
-
/* istanbul ignore if */
|
|
254
|
+
const primaryKeyring = this.getKeyringsByType('HD Key Tree')[0];
|
|
188
255
|
if (!primaryKeyring) {
|
|
189
256
|
throw new Error('No HD keyring found');
|
|
190
257
|
}
|
|
191
|
-
const oldAccounts = yield
|
|
258
|
+
const oldAccounts = yield this.getAccounts();
|
|
192
259
|
if (accountCount && oldAccounts.length !== accountCount) {
|
|
193
260
|
if (accountCount > oldAccounts.length) {
|
|
194
261
|
throw new Error('Account out of sequence');
|
|
@@ -200,12 +267,9 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
200
267
|
addedAccountAddress: primaryKeyringAccounts[accountCount],
|
|
201
268
|
};
|
|
202
269
|
}
|
|
203
|
-
yield
|
|
204
|
-
const newAccounts = yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").getAccounts();
|
|
270
|
+
const addedAccountAddress = yield this.addNewAccountForKeyring(primaryKeyring);
|
|
205
271
|
yield this.verifySeedPhrase();
|
|
206
|
-
this.updateIdentities(
|
|
207
|
-
const addedAccountAddress = newAccounts.find((selectedAddress) => !oldAccounts.includes(selectedAddress));
|
|
208
|
-
(0, utils_1.assertIsStrictHexString)(addedAccountAddress);
|
|
272
|
+
this.updateIdentities(yield this.getAccounts());
|
|
209
273
|
return {
|
|
210
274
|
keyringState: __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getMemState).call(this),
|
|
211
275
|
addedAccountAddress,
|
|
@@ -230,10 +294,11 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
230
294
|
(0, utils_1.assertIsStrictHexString)(existingAccount);
|
|
231
295
|
return existingAccount;
|
|
232
296
|
}
|
|
233
|
-
yield
|
|
297
|
+
yield keyring.addAccounts(1);
|
|
298
|
+
yield this.persistAllKeyrings();
|
|
234
299
|
const addedAccountAddress = (yield this.getAccounts()).find((selectedAddress) => !oldAccounts.includes(selectedAddress));
|
|
235
300
|
(0, utils_1.assertIsStrictHexString)(addedAccountAddress);
|
|
236
|
-
this.updateIdentities(yield
|
|
301
|
+
this.updateIdentities(yield this.getAccounts());
|
|
237
302
|
return addedAccountAddress;
|
|
238
303
|
});
|
|
239
304
|
}
|
|
@@ -244,12 +309,12 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
244
309
|
*/
|
|
245
310
|
addNewAccountWithoutUpdate() {
|
|
246
311
|
return __awaiter(this, void 0, void 0, function* () {
|
|
247
|
-
const primaryKeyring =
|
|
248
|
-
/* istanbul ignore if */
|
|
312
|
+
const primaryKeyring = this.getKeyringsByType('HD Key Tree')[0];
|
|
249
313
|
if (!primaryKeyring) {
|
|
250
314
|
throw new Error('No HD keyring found');
|
|
251
315
|
}
|
|
252
|
-
yield
|
|
316
|
+
yield primaryKeyring.addAccounts(1);
|
|
317
|
+
yield this.persistAllKeyrings();
|
|
253
318
|
yield this.verifySeedPhrase();
|
|
254
319
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getMemState).call(this);
|
|
255
320
|
});
|
|
@@ -271,14 +336,14 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
271
336
|
}
|
|
272
337
|
try {
|
|
273
338
|
this.updateIdentities([]);
|
|
274
|
-
yield __classPrivateFieldGet(this,
|
|
275
|
-
type:
|
|
339
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createNewVaultWithKeyring).call(this, password, {
|
|
340
|
+
type: KeyringTypes.hd,
|
|
276
341
|
opts: {
|
|
277
342
|
mnemonic: seed,
|
|
278
343
|
numberOfAccounts: 1,
|
|
279
344
|
},
|
|
280
345
|
});
|
|
281
|
-
this.updateIdentities(yield
|
|
346
|
+
this.updateIdentities(yield this.getAccounts());
|
|
282
347
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getMemState).call(this);
|
|
283
348
|
}
|
|
284
349
|
finally {
|
|
@@ -298,8 +363,8 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
298
363
|
try {
|
|
299
364
|
const accounts = yield this.getAccounts();
|
|
300
365
|
if (!accounts.length) {
|
|
301
|
-
yield __classPrivateFieldGet(this,
|
|
302
|
-
type:
|
|
366
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createNewVaultWithKeyring).call(this, password, {
|
|
367
|
+
type: KeyringTypes.hd,
|
|
303
368
|
});
|
|
304
369
|
this.updateIdentities(yield this.getAccounts());
|
|
305
370
|
}
|
|
@@ -323,7 +388,19 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
323
388
|
if (type === KeyringTypes.qr) {
|
|
324
389
|
return this.getOrAddQRKeyring();
|
|
325
390
|
}
|
|
326
|
-
|
|
391
|
+
const keyring = yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_newKeyring).call(this, type, opts);
|
|
392
|
+
if (type === KeyringTypes.hd && (!(0, utils_1.isObject)(opts) || !opts.mnemonic)) {
|
|
393
|
+
if (!keyring.generateRandomMnemonic) {
|
|
394
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedGenerateRandomMnemonic);
|
|
395
|
+
}
|
|
396
|
+
keyring.generateRandomMnemonic();
|
|
397
|
+
yield keyring.addAccounts(1);
|
|
398
|
+
}
|
|
399
|
+
const accounts = yield keyring.getAccounts();
|
|
400
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_checkForDuplicate).call(this, type, accounts);
|
|
401
|
+
__classPrivateFieldGet(this, _KeyringController_keyrings, "f").push(keyring);
|
|
402
|
+
yield this.persistAllKeyrings();
|
|
403
|
+
return keyring;
|
|
327
404
|
});
|
|
328
405
|
}
|
|
329
406
|
/**
|
|
@@ -334,7 +411,10 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
334
411
|
*/
|
|
335
412
|
verifyPassword(password) {
|
|
336
413
|
return __awaiter(this, void 0, void 0, function* () {
|
|
337
|
-
|
|
414
|
+
if (!this.state.vault) {
|
|
415
|
+
throw new Error(constants_1.KeyringControllerError.VaultError);
|
|
416
|
+
}
|
|
417
|
+
yield __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, this.state.vault);
|
|
338
418
|
});
|
|
339
419
|
}
|
|
340
420
|
/**
|
|
@@ -354,8 +434,8 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
354
434
|
exportSeedPhrase(password) {
|
|
355
435
|
return __awaiter(this, void 0, void 0, function* () {
|
|
356
436
|
yield this.verifyPassword(password);
|
|
357
|
-
assertHasUint8ArrayMnemonic(__classPrivateFieldGet(this,
|
|
358
|
-
return __classPrivateFieldGet(this,
|
|
437
|
+
assertHasUint8ArrayMnemonic(__classPrivateFieldGet(this, _KeyringController_keyrings, "f")[0]);
|
|
438
|
+
return __classPrivateFieldGet(this, _KeyringController_keyrings, "f")[0].mnemonic;
|
|
359
439
|
});
|
|
360
440
|
}
|
|
361
441
|
/**
|
|
@@ -368,7 +448,11 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
368
448
|
exportAccount(password, address) {
|
|
369
449
|
return __awaiter(this, void 0, void 0, function* () {
|
|
370
450
|
yield this.verifyPassword(password);
|
|
371
|
-
|
|
451
|
+
const keyring = (yield this.getKeyringForAccount(address));
|
|
452
|
+
if (!keyring.exportAccount) {
|
|
453
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedExportAccount);
|
|
454
|
+
}
|
|
455
|
+
return yield keyring.exportAccount((0, eth_sig_util_1.normalize)(address));
|
|
372
456
|
});
|
|
373
457
|
}
|
|
374
458
|
/**
|
|
@@ -377,7 +461,16 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
377
461
|
* @returns A promise resolving to an array of addresses.
|
|
378
462
|
*/
|
|
379
463
|
getAccounts() {
|
|
380
|
-
return
|
|
464
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
465
|
+
const keyrings = __classPrivateFieldGet(this, _KeyringController_keyrings, "f");
|
|
466
|
+
const keyringArrays = yield Promise.all(keyrings.map((keyring) => __awaiter(this, void 0, void 0, function* () { return keyring.getAccounts(); })));
|
|
467
|
+
const addresses = keyringArrays.reduce((res, arr) => {
|
|
468
|
+
return res.concat(arr);
|
|
469
|
+
}, []);
|
|
470
|
+
// Cast to `Hex[]` here is safe here because `addresses` has no nullish
|
|
471
|
+
// values, and `normalize` returns `Hex` unless given a nullish value
|
|
472
|
+
return addresses.map(eth_sig_util_1.normalize);
|
|
473
|
+
});
|
|
381
474
|
}
|
|
382
475
|
/**
|
|
383
476
|
* Get encryption public key.
|
|
@@ -389,7 +482,12 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
389
482
|
*/
|
|
390
483
|
getEncryptionPublicKey(account, opts) {
|
|
391
484
|
return __awaiter(this, void 0, void 0, function* () {
|
|
392
|
-
|
|
485
|
+
const normalizedAddress = (0, eth_sig_util_1.normalize)(account);
|
|
486
|
+
const keyring = (yield this.getKeyringForAccount(account));
|
|
487
|
+
if (!keyring.getEncryptionPublicKey) {
|
|
488
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedGetEncryptionPublicKey);
|
|
489
|
+
}
|
|
490
|
+
return yield keyring.getEncryptionPublicKey(normalizedAddress, opts);
|
|
393
491
|
});
|
|
394
492
|
}
|
|
395
493
|
/**
|
|
@@ -402,7 +500,12 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
402
500
|
*/
|
|
403
501
|
decryptMessage(messageParams) {
|
|
404
502
|
return __awaiter(this, void 0, void 0, function* () {
|
|
405
|
-
|
|
503
|
+
const address = (0, eth_sig_util_1.normalize)(messageParams.from);
|
|
504
|
+
const keyring = (yield this.getKeyringForAccount(address));
|
|
505
|
+
if (!keyring.decryptMessage) {
|
|
506
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedDecryptMessage);
|
|
507
|
+
}
|
|
508
|
+
return keyring.decryptMessage(address, messageParams.data);
|
|
406
509
|
});
|
|
407
510
|
}
|
|
408
511
|
/**
|
|
@@ -416,8 +519,33 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
416
519
|
* @returns Promise resolving to keyring of the `account` if one exists.
|
|
417
520
|
*/
|
|
418
521
|
getKeyringForAccount(account) {
|
|
522
|
+
var _a;
|
|
419
523
|
return __awaiter(this, void 0, void 0, function* () {
|
|
420
|
-
|
|
524
|
+
// Cast to `Hex` here is safe here because `address` is not nullish.
|
|
525
|
+
// `normalizeToHex` returns `Hex` unless given a nullish value.
|
|
526
|
+
const hexed = (0, eth_sig_util_1.normalize)(account);
|
|
527
|
+
const candidates = yield Promise.all(__classPrivateFieldGet(this, _KeyringController_keyrings, "f").map((keyring) => __awaiter(this, void 0, void 0, function* () {
|
|
528
|
+
return Promise.all([keyring, keyring.getAccounts()]);
|
|
529
|
+
})));
|
|
530
|
+
const winners = candidates.filter((candidate) => {
|
|
531
|
+
const accounts = candidate[1].map(eth_sig_util_1.normalize);
|
|
532
|
+
return accounts.includes(hexed);
|
|
533
|
+
});
|
|
534
|
+
if (winners.length && ((_a = winners[0]) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
535
|
+
return winners[0][0];
|
|
536
|
+
}
|
|
537
|
+
// Adding more info to the error
|
|
538
|
+
let errorInfo = '';
|
|
539
|
+
if (!(0, utils_1.isValidHexAddress)(hexed)) {
|
|
540
|
+
errorInfo = 'The address passed in is invalid/empty';
|
|
541
|
+
}
|
|
542
|
+
else if (!candidates.length) {
|
|
543
|
+
errorInfo = 'There are no keyrings';
|
|
544
|
+
}
|
|
545
|
+
else if (!winners.length) {
|
|
546
|
+
errorInfo = 'There are keyrings, but none match the address';
|
|
547
|
+
}
|
|
548
|
+
throw new Error(`${constants_1.KeyringControllerError.NoKeyring}. Error info: ${errorInfo}`);
|
|
421
549
|
});
|
|
422
550
|
}
|
|
423
551
|
/**
|
|
@@ -430,7 +558,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
430
558
|
* @returns An array of keyrings of the given type.
|
|
431
559
|
*/
|
|
432
560
|
getKeyringsByType(type) {
|
|
433
|
-
return __classPrivateFieldGet(this,
|
|
561
|
+
return __classPrivateFieldGet(this, _KeyringController_keyrings, "f").filter((keyring) => keyring.type === type);
|
|
434
562
|
}
|
|
435
563
|
/**
|
|
436
564
|
* Persist all serialized keyrings in the vault.
|
|
@@ -440,7 +568,58 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
440
568
|
*/
|
|
441
569
|
persistAllKeyrings() {
|
|
442
570
|
return __awaiter(this, void 0, void 0, function* () {
|
|
443
|
-
|
|
571
|
+
const { encryptionKey, encryptionSalt } = this.state;
|
|
572
|
+
if (!__classPrivateFieldGet(this, _KeyringController_password, "f") && !encryptionKey) {
|
|
573
|
+
throw new Error(constants_1.KeyringControllerError.MissingCredentials);
|
|
574
|
+
}
|
|
575
|
+
const serializedKeyrings = yield Promise.all(__classPrivateFieldGet(this, _KeyringController_keyrings, "f").map((keyring) => __awaiter(this, void 0, void 0, function* () {
|
|
576
|
+
const [type, data] = yield Promise.all([
|
|
577
|
+
keyring.type,
|
|
578
|
+
keyring.serialize(),
|
|
579
|
+
]);
|
|
580
|
+
return { type, data };
|
|
581
|
+
})));
|
|
582
|
+
serializedKeyrings.push(...__classPrivateFieldGet(this, _KeyringController_unsupportedKeyrings, "f"));
|
|
583
|
+
let vault;
|
|
584
|
+
let newEncryptionKey;
|
|
585
|
+
if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
|
|
586
|
+
assertIsExportableKeyEncryptor(__classPrivateFieldGet(this, _KeyringController_encryptor, "f"));
|
|
587
|
+
if (encryptionKey) {
|
|
588
|
+
const key = yield __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
|
|
589
|
+
const vaultJSON = yield __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithKey(key, serializedKeyrings);
|
|
590
|
+
vaultJSON.salt = encryptionSalt;
|
|
591
|
+
vault = JSON.stringify(vaultJSON);
|
|
592
|
+
}
|
|
593
|
+
else if (__classPrivateFieldGet(this, _KeyringController_password, "f")) {
|
|
594
|
+
const { vault: newVault, exportedKeyString } = yield __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithDetail(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
|
|
595
|
+
vault = newVault;
|
|
596
|
+
newEncryptionKey = exportedKeyString;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
else {
|
|
600
|
+
if (typeof __classPrivateFieldGet(this, _KeyringController_password, "f") !== 'string') {
|
|
601
|
+
throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
|
|
602
|
+
}
|
|
603
|
+
vault = yield __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encrypt(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
|
|
604
|
+
}
|
|
605
|
+
if (!vault) {
|
|
606
|
+
throw new Error(constants_1.KeyringControllerError.MissingVaultData);
|
|
607
|
+
}
|
|
608
|
+
this.update((state) => {
|
|
609
|
+
state.vault = vault;
|
|
610
|
+
});
|
|
611
|
+
// The keyring updates need to be announced before updating the encryptionKey
|
|
612
|
+
// so that the updated keyring gets propagated to the extension first.
|
|
613
|
+
// Not calling {@link updateKeyringsInState} results in the wrong account being selected
|
|
614
|
+
// in the extension.
|
|
615
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateKeyringsInState).call(this);
|
|
616
|
+
if (newEncryptionKey) {
|
|
617
|
+
this.update((state) => {
|
|
618
|
+
state.encryptionKey = newEncryptionKey;
|
|
619
|
+
state.encryptionSalt = JSON.parse(vault).salt;
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
return true;
|
|
444
623
|
});
|
|
445
624
|
}
|
|
446
625
|
/**
|
|
@@ -472,7 +651,6 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
472
651
|
catch (_a) {
|
|
473
652
|
throw new Error('Cannot import invalid private key.');
|
|
474
653
|
}
|
|
475
|
-
/* istanbul ignore if */
|
|
476
654
|
if (!(0, ethereumjs_util_1.isValidPrivate)(bufferedPrivateKey) ||
|
|
477
655
|
// ensures that the key is 64 bytes long
|
|
478
656
|
(0, ethereumjs_util_1.getBinarySize)(prefixed) !== 64 + '0x'.length) {
|
|
@@ -494,11 +672,11 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
494
672
|
default:
|
|
495
673
|
throw new Error(`Unexpected import strategy: '${strategy}'`);
|
|
496
674
|
}
|
|
497
|
-
const newKeyring = yield
|
|
675
|
+
const newKeyring = (yield this.addNewKeyring(KeyringTypes.simple, [
|
|
498
676
|
privateKey,
|
|
499
|
-
]);
|
|
677
|
+
]));
|
|
500
678
|
const accounts = yield newKeyring.getAccounts();
|
|
501
|
-
const allAccounts = yield
|
|
679
|
+
const allAccounts = yield this.getAccounts();
|
|
502
680
|
this.updateIdentities(allAccounts);
|
|
503
681
|
return {
|
|
504
682
|
keyringState: __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getMemState).call(this),
|
|
@@ -515,7 +693,21 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
515
693
|
*/
|
|
516
694
|
removeAccount(address) {
|
|
517
695
|
return __awaiter(this, void 0, void 0, function* () {
|
|
518
|
-
yield
|
|
696
|
+
const keyring = (yield this.getKeyringForAccount(address));
|
|
697
|
+
// Not all the keyrings support this, so we have to check
|
|
698
|
+
if (!keyring.removeAccount) {
|
|
699
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedRemoveAccount);
|
|
700
|
+
}
|
|
701
|
+
// The `removeAccount` method of snaps keyring is async. We have to update
|
|
702
|
+
// the interface of the other keyrings to be async as well.
|
|
703
|
+
// eslint-disable-next-line @typescript-eslint/await-thenable
|
|
704
|
+
yield keyring.removeAccount(address);
|
|
705
|
+
const accounts = yield keyring.getAccounts();
|
|
706
|
+
// Check if this was the last/only account
|
|
707
|
+
if (accounts.length === 0) {
|
|
708
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_removeEmptyKeyrings).call(this);
|
|
709
|
+
}
|
|
710
|
+
yield this.persistAllKeyrings();
|
|
519
711
|
this.messagingSystem.publish(`${name}:accountRemoved`, address);
|
|
520
712
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getMemState).call(this);
|
|
521
713
|
});
|
|
@@ -528,7 +720,13 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
528
720
|
setLocked() {
|
|
529
721
|
return __awaiter(this, void 0, void 0, function* () {
|
|
530
722
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unsubscribeFromQRKeyringsEvents).call(this);
|
|
531
|
-
|
|
723
|
+
__classPrivateFieldSet(this, _KeyringController_password, undefined, "f");
|
|
724
|
+
this.update((state) => {
|
|
725
|
+
state.isUnlocked = false;
|
|
726
|
+
state.keyrings = [];
|
|
727
|
+
});
|
|
728
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
|
|
729
|
+
this.messagingSystem.publish(`${name}:lock`);
|
|
532
730
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getMemState).call(this);
|
|
533
731
|
});
|
|
534
732
|
}
|
|
@@ -539,10 +737,17 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
539
737
|
* @returns Promise resolving to a signed message string.
|
|
540
738
|
*/
|
|
541
739
|
signMessage(messageParams) {
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
740
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
741
|
+
if (!messageParams.data) {
|
|
742
|
+
throw new Error("Can't sign an empty message");
|
|
743
|
+
}
|
|
744
|
+
const address = (0, eth_sig_util_1.normalize)(messageParams.from);
|
|
745
|
+
const keyring = (yield this.getKeyringForAccount(address));
|
|
746
|
+
if (!keyring.signMessage) {
|
|
747
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedSignMessage);
|
|
748
|
+
}
|
|
749
|
+
return yield keyring.signMessage(address, messageParams.data);
|
|
750
|
+
});
|
|
546
751
|
}
|
|
547
752
|
/**
|
|
548
753
|
* Signs personal message by calling down into a specific keyring.
|
|
@@ -551,7 +756,15 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
551
756
|
* @returns Promise resolving to a signed message string.
|
|
552
757
|
*/
|
|
553
758
|
signPersonalMessage(messageParams) {
|
|
554
|
-
return
|
|
759
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
760
|
+
const address = (0, eth_sig_util_1.normalize)(messageParams.from);
|
|
761
|
+
const keyring = (yield this.getKeyringForAccount(address));
|
|
762
|
+
if (!keyring.signPersonalMessage) {
|
|
763
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedSignPersonalMessage);
|
|
764
|
+
}
|
|
765
|
+
const normalizedData = (0, eth_sig_util_1.normalize)(messageParams.data);
|
|
766
|
+
return yield keyring.signPersonalMessage(address, normalizedData);
|
|
767
|
+
});
|
|
555
768
|
}
|
|
556
769
|
/**
|
|
557
770
|
* Signs typed message by calling down into a specific keyring.
|
|
@@ -571,13 +784,17 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
571
784
|
].includes(version)) {
|
|
572
785
|
throw new Error(`Unexpected signTypedMessage version: '${version}'`);
|
|
573
786
|
}
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
}
|
|
787
|
+
// Cast to `Hex` here is safe here because `messageParams.from` is not nullish.
|
|
788
|
+
// `normalize` returns `Hex` unless given a nullish value.
|
|
789
|
+
const address = (0, eth_sig_util_1.normalize)(messageParams.from);
|
|
790
|
+
const keyring = (yield this.getKeyringForAccount(address));
|
|
791
|
+
if (!keyring.signTypedData) {
|
|
792
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedSignTypedMessage);
|
|
793
|
+
}
|
|
794
|
+
return yield keyring.signTypedData(address, version !== SignTypedDataVersion.V1 &&
|
|
795
|
+
typeof messageParams.data === 'string'
|
|
796
|
+
? JSON.parse(messageParams.data)
|
|
797
|
+
: messageParams.data, { version });
|
|
581
798
|
}
|
|
582
799
|
catch (error) {
|
|
583
800
|
throw new Error(`Keyring Controller signTypedMessage: ${error}`);
|
|
@@ -593,7 +810,14 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
593
810
|
* @returns Promise resolving to a signed transaction string.
|
|
594
811
|
*/
|
|
595
812
|
signTransaction(transaction, from, opts) {
|
|
596
|
-
return
|
|
813
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
814
|
+
const address = (0, eth_sig_util_1.normalize)(from);
|
|
815
|
+
const keyring = (yield this.getKeyringForAccount(address));
|
|
816
|
+
if (!keyring.signTransaction) {
|
|
817
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedSignTransaction);
|
|
818
|
+
}
|
|
819
|
+
return yield keyring.signTransaction(address, transaction, opts);
|
|
820
|
+
});
|
|
597
821
|
}
|
|
598
822
|
/**
|
|
599
823
|
* Convert a base transaction to a base UserOperation.
|
|
@@ -604,7 +828,12 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
604
828
|
*/
|
|
605
829
|
prepareUserOperation(from, transactions) {
|
|
606
830
|
return __awaiter(this, void 0, void 0, function* () {
|
|
607
|
-
|
|
831
|
+
const address = (0, eth_sig_util_1.normalize)(from);
|
|
832
|
+
const keyring = (yield this.getKeyringForAccount(address));
|
|
833
|
+
if (!keyring.prepareUserOperation) {
|
|
834
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedPrepareUserOperation);
|
|
835
|
+
}
|
|
836
|
+
return yield keyring.prepareUserOperation(address, transactions);
|
|
608
837
|
});
|
|
609
838
|
}
|
|
610
839
|
/**
|
|
@@ -617,7 +846,12 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
617
846
|
*/
|
|
618
847
|
patchUserOperation(from, userOp) {
|
|
619
848
|
return __awaiter(this, void 0, void 0, function* () {
|
|
620
|
-
|
|
849
|
+
const address = (0, eth_sig_util_1.normalize)(from);
|
|
850
|
+
const keyring = (yield this.getKeyringForAccount(address));
|
|
851
|
+
if (!keyring.patchUserOperation) {
|
|
852
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedPatchUserOperation);
|
|
853
|
+
}
|
|
854
|
+
return yield keyring.patchUserOperation(address, userOp);
|
|
621
855
|
});
|
|
622
856
|
}
|
|
623
857
|
/**
|
|
@@ -629,7 +863,12 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
629
863
|
*/
|
|
630
864
|
signUserOperation(from, userOp) {
|
|
631
865
|
return __awaiter(this, void 0, void 0, function* () {
|
|
632
|
-
|
|
866
|
+
const address = (0, eth_sig_util_1.normalize)(from);
|
|
867
|
+
const keyring = (yield this.getKeyringForAccount(address));
|
|
868
|
+
if (!keyring.signUserOperation) {
|
|
869
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedSignUserOperation);
|
|
870
|
+
}
|
|
871
|
+
return yield keyring.signUserOperation(address, userOp);
|
|
633
872
|
});
|
|
634
873
|
}
|
|
635
874
|
/**
|
|
@@ -642,7 +881,8 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
642
881
|
*/
|
|
643
882
|
submitEncryptionKey(encryptionKey, encryptionSalt) {
|
|
644
883
|
return __awaiter(this, void 0, void 0, function* () {
|
|
645
|
-
yield __classPrivateFieldGet(this,
|
|
884
|
+
__classPrivateFieldSet(this, _KeyringController_keyrings, yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, undefined, encryptionKey, encryptionSalt), "f");
|
|
885
|
+
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
646
886
|
const qrKeyring = this.getQRKeyring();
|
|
647
887
|
if (qrKeyring) {
|
|
648
888
|
// if there is a QR keyring, we need to subscribe
|
|
@@ -661,8 +901,9 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
661
901
|
*/
|
|
662
902
|
submitPassword(password) {
|
|
663
903
|
return __awaiter(this, void 0, void 0, function* () {
|
|
664
|
-
yield __classPrivateFieldGet(this,
|
|
665
|
-
|
|
904
|
+
__classPrivateFieldSet(this, _KeyringController_keyrings, yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, password), "f");
|
|
905
|
+
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
906
|
+
const accounts = yield this.getAccounts();
|
|
666
907
|
const qrKeyring = this.getQRKeyring();
|
|
667
908
|
if (qrKeyring) {
|
|
668
909
|
// if there is a QR keyring, we need to subscribe
|
|
@@ -680,8 +921,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
680
921
|
*/
|
|
681
922
|
verifySeedPhrase() {
|
|
682
923
|
return __awaiter(this, void 0, void 0, function* () {
|
|
683
|
-
const primaryKeyring =
|
|
684
|
-
/* istanbul ignore if */
|
|
924
|
+
const primaryKeyring = this.getKeyringsByType(KeyringTypes.hd)[0];
|
|
685
925
|
if (!primaryKeyring) {
|
|
686
926
|
throw new Error('No HD keyring found.');
|
|
687
927
|
}
|
|
@@ -694,7 +934,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
694
934
|
}
|
|
695
935
|
// The HD Keyring Builder is a default keyring builder
|
|
696
936
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
697
|
-
const hdKeyringBuilder = __classPrivateFieldGet(this,
|
|
937
|
+
const hdKeyringBuilder = __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getKeyringBuilderForType).call(this, KeyringTypes.hd);
|
|
698
938
|
const hdKeyring = hdKeyringBuilder();
|
|
699
939
|
// @ts-expect-error @metamask/eth-hd-keyring correctly handles
|
|
700
940
|
// Uint8Array seed phrases in the `deserialize` method.
|
|
@@ -724,7 +964,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
724
964
|
*/
|
|
725
965
|
getQRKeyring() {
|
|
726
966
|
// QRKeyring is not yet compatible with Keyring type from @metamask/utils
|
|
727
|
-
return
|
|
967
|
+
return this.getKeyringsByType(KeyringTypes.qr)[0];
|
|
728
968
|
}
|
|
729
969
|
/**
|
|
730
970
|
* Get QR hardware keyring. If it doesn't exist, add it.
|
|
@@ -741,8 +981,8 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
741
981
|
restoreQRKeyring(serialized) {
|
|
742
982
|
return __awaiter(this, void 0, void 0, function* () {
|
|
743
983
|
(yield this.getOrAddQRKeyring()).deserialize(serialized);
|
|
744
|
-
yield
|
|
745
|
-
this.updateIdentities(yield
|
|
984
|
+
yield this.persistAllKeyrings();
|
|
985
|
+
this.updateIdentities(yield this.getAccounts());
|
|
746
986
|
});
|
|
747
987
|
}
|
|
748
988
|
resetQRKeyringState() {
|
|
@@ -816,13 +1056,13 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
816
1056
|
return __awaiter(this, void 0, void 0, function* () {
|
|
817
1057
|
const keyring = yield this.getOrAddQRKeyring();
|
|
818
1058
|
keyring.setAccountToUnlock(index);
|
|
819
|
-
const oldAccounts = yield
|
|
1059
|
+
const oldAccounts = yield this.getAccounts();
|
|
820
1060
|
// QRKeyring is not yet compatible with Keyring from
|
|
821
1061
|
// @metamask/utils, but we can use the `addNewAccount` method
|
|
822
1062
|
// as it internally calls `addAccounts` from on the keyring instance,
|
|
823
1063
|
// which is supported by QRKeyring API.
|
|
824
|
-
yield
|
|
825
|
-
const newAccounts = yield
|
|
1064
|
+
yield this.addNewAccountForKeyring(keyring);
|
|
1065
|
+
const newAccounts = yield this.getAccounts();
|
|
826
1066
|
this.updateIdentities(newAccounts);
|
|
827
1067
|
newAccounts.forEach((address) => {
|
|
828
1068
|
if (!oldAccounts.includes(address)) {
|
|
@@ -832,29 +1072,30 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
832
1072
|
this.setSelectedAddress(address);
|
|
833
1073
|
}
|
|
834
1074
|
});
|
|
835
|
-
yield
|
|
1075
|
+
yield this.persistAllKeyrings();
|
|
836
1076
|
});
|
|
837
1077
|
}
|
|
838
1078
|
getAccountKeyringType(account) {
|
|
839
1079
|
return __awaiter(this, void 0, void 0, function* () {
|
|
840
|
-
|
|
1080
|
+
const keyring = (yield this.getKeyringForAccount(account));
|
|
1081
|
+
return keyring.type;
|
|
841
1082
|
});
|
|
842
1083
|
}
|
|
843
1084
|
forgetQRDevice() {
|
|
844
1085
|
return __awaiter(this, void 0, void 0, function* () {
|
|
845
1086
|
const keyring = yield this.getOrAddQRKeyring();
|
|
846
|
-
const allAccounts = (yield
|
|
1087
|
+
const allAccounts = (yield this.getAccounts());
|
|
847
1088
|
keyring.forgetDevice();
|
|
848
|
-
const remainingAccounts = (yield
|
|
1089
|
+
const remainingAccounts = (yield this.getAccounts());
|
|
849
1090
|
const removedAccounts = allAccounts.filter((address) => !remainingAccounts.includes(address));
|
|
850
1091
|
this.updateIdentities(remainingAccounts);
|
|
851
|
-
yield
|
|
1092
|
+
yield this.persistAllKeyrings();
|
|
852
1093
|
return { removedAccounts, remainingAccounts };
|
|
853
1094
|
});
|
|
854
1095
|
}
|
|
855
1096
|
}
|
|
856
1097
|
exports.KeyringController = KeyringController;
|
|
857
|
-
|
|
1098
|
+
_KeyringController_keyringBuilders = new WeakMap(), _KeyringController_keyrings = new WeakMap(), _KeyringController_unsupportedKeyrings = new WeakMap(), _KeyringController_password = new WeakMap(), _KeyringController_encryptor = new WeakMap(), _KeyringController_cacheEncryptionKey = new WeakMap(), _KeyringController_qrKeyringStateListener = new WeakMap(), _KeyringController_instances = new WeakSet(), _KeyringController_registerMessageHandlers = function _KeyringController_registerMessageHandlers() {
|
|
858
1099
|
this.messagingSystem.registerActionHandler(`${name}:signMessage`, this.signMessage.bind(this));
|
|
859
1100
|
this.messagingSystem.registerActionHandler(`${name}:signPersonalMessage`, this.signPersonalMessage.bind(this));
|
|
860
1101
|
this.messagingSystem.registerActionHandler(`${name}:signTypedMessage`, this.signTypedMessage.bind(this));
|
|
@@ -867,10 +1108,18 @@ _KeyringController_keyring = new WeakMap(), _KeyringController_qrKeyringStateLis
|
|
|
867
1108
|
this.messagingSystem.registerActionHandler(`${name}:prepareUserOperation`, this.prepareUserOperation.bind(this));
|
|
868
1109
|
this.messagingSystem.registerActionHandler(`${name}:patchUserOperation`, this.patchUserOperation.bind(this));
|
|
869
1110
|
this.messagingSystem.registerActionHandler(`${name}:signUserOperation`, this.signUserOperation.bind(this));
|
|
1111
|
+
}, _KeyringController_getKeyringBuilderForType = function _KeyringController_getKeyringBuilderForType(type) {
|
|
1112
|
+
return __classPrivateFieldGet(this, _KeyringController_keyringBuilders, "f").find((keyringBuilder) => keyringBuilder.type === type);
|
|
870
1113
|
}, _KeyringController_addQRKeyring = function _KeyringController_addQRKeyring() {
|
|
871
1114
|
return __awaiter(this, void 0, void 0, function* () {
|
|
872
1115
|
// QRKeyring is not yet compatible with Keyring type from @metamask/utils
|
|
873
|
-
const qrKeyring = (yield __classPrivateFieldGet(this,
|
|
1116
|
+
const qrKeyring = (yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_newKeyring).call(this, KeyringTypes.qr, {
|
|
1117
|
+
accounts: [],
|
|
1118
|
+
}));
|
|
1119
|
+
const accounts = yield qrKeyring.getAccounts();
|
|
1120
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_checkForDuplicate).call(this, KeyringTypes.qr, accounts);
|
|
1121
|
+
__classPrivateFieldGet(this, _KeyringController_keyrings, "f").push(qrKeyring);
|
|
1122
|
+
yield this.persistAllKeyrings();
|
|
874
1123
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_subscribeToQRKeyringEvents).call(this, qrKeyring);
|
|
875
1124
|
return qrKeyring;
|
|
876
1125
|
});
|
|
@@ -880,25 +1129,182 @@ _KeyringController_keyring = new WeakMap(), _KeyringController_qrKeyringStateLis
|
|
|
880
1129
|
}, "f");
|
|
881
1130
|
qrKeyring.getMemStore().subscribe(__classPrivateFieldGet(this, _KeyringController_qrKeyringStateListener, "f"));
|
|
882
1131
|
}, _KeyringController_unsubscribeFromQRKeyringsEvents = function _KeyringController_unsubscribeFromQRKeyringsEvents() {
|
|
883
|
-
const qrKeyrings =
|
|
1132
|
+
const qrKeyrings = this.getKeyringsByType(KeyringTypes.qr);
|
|
884
1133
|
qrKeyrings.forEach((qrKeyring) => {
|
|
885
1134
|
if (__classPrivateFieldGet(this, _KeyringController_qrKeyringStateListener, "f")) {
|
|
886
1135
|
qrKeyring.getMemStore().unsubscribe(__classPrivateFieldGet(this, _KeyringController_qrKeyringStateListener, "f"));
|
|
887
1136
|
}
|
|
888
1137
|
});
|
|
889
|
-
},
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
|
|
1138
|
+
}, _KeyringController_createNewVaultWithKeyring = function _KeyringController_createNewVaultWithKeyring(password, keyring) {
|
|
1139
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1140
|
+
if (typeof password !== 'string') {
|
|
1141
|
+
throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
|
|
1142
|
+
}
|
|
1143
|
+
__classPrivateFieldSet(this, _KeyringController_password, password, "f");
|
|
1144
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
|
|
1145
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createKeyringWithFirstAccount).call(this, keyring.type, keyring.opts);
|
|
1146
|
+
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
1147
|
+
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getMemState).call(this);
|
|
1148
|
+
});
|
|
1149
|
+
}, _KeyringController_updateKeyringsInState = function _KeyringController_updateKeyringsInState() {
|
|
1150
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1151
|
+
const keyrings = yield Promise.all(__classPrivateFieldGet(this, _KeyringController_keyrings, "f").map(displayForKeyring));
|
|
1152
|
+
this.update((state) => {
|
|
1153
|
+
state.keyrings = keyrings;
|
|
1154
|
+
});
|
|
1155
|
+
});
|
|
1156
|
+
}, _KeyringController_unlockKeyrings = function _KeyringController_unlockKeyrings(password, encryptionKey, encryptionSalt) {
|
|
1157
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1158
|
+
const encryptedVault = this.state.vault;
|
|
1159
|
+
if (!encryptedVault) {
|
|
1160
|
+
throw new Error(constants_1.KeyringControllerError.VaultError);
|
|
1161
|
+
}
|
|
1162
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
|
|
1163
|
+
let vault;
|
|
1164
|
+
if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
|
|
1165
|
+
assertIsExportableKeyEncryptor(__classPrivateFieldGet(this, _KeyringController_encryptor, "f"));
|
|
1166
|
+
if (password) {
|
|
1167
|
+
const result = yield __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithDetail(password, encryptedVault);
|
|
1168
|
+
vault = result.vault;
|
|
1169
|
+
__classPrivateFieldSet(this, _KeyringController_password, password, "f");
|
|
1170
|
+
this.update((state) => {
|
|
1171
|
+
state.encryptionKey = result.exportedKeyString;
|
|
1172
|
+
state.encryptionSalt = result.salt;
|
|
1173
|
+
});
|
|
1174
|
+
}
|
|
1175
|
+
else {
|
|
1176
|
+
const parsedEncryptedVault = JSON.parse(encryptedVault);
|
|
1177
|
+
if (encryptionSalt !== parsedEncryptedVault.salt) {
|
|
1178
|
+
throw new Error(constants_1.KeyringControllerError.ExpiredCredentials);
|
|
1179
|
+
}
|
|
1180
|
+
if (typeof encryptionKey !== 'string') {
|
|
1181
|
+
throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
|
|
1182
|
+
}
|
|
1183
|
+
const key = yield __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
|
|
1184
|
+
vault = yield __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
|
|
1185
|
+
// This call is required on the first call because encryptionKey
|
|
1186
|
+
// is not yet inside the memStore
|
|
1187
|
+
this.update((state) => {
|
|
1188
|
+
state.encryptionKey = encryptionKey;
|
|
1189
|
+
// we can safely assume that encryptionSalt is defined here
|
|
1190
|
+
// because we compare it with the salt from the vault
|
|
1191
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1192
|
+
state.encryptionSalt = encryptionSalt;
|
|
1193
|
+
});
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
else {
|
|
1197
|
+
if (typeof password !== 'string') {
|
|
1198
|
+
throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
|
|
1199
|
+
}
|
|
1200
|
+
vault = yield __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, encryptedVault);
|
|
1201
|
+
__classPrivateFieldSet(this, _KeyringController_password, password, "f");
|
|
1202
|
+
}
|
|
1203
|
+
if (!isSerializedKeyringsArray(vault)) {
|
|
1204
|
+
throw new Error(constants_1.KeyringControllerError.VaultDataError);
|
|
1205
|
+
}
|
|
1206
|
+
yield Promise.all(vault.map(__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_restoreKeyring).bind(this)));
|
|
1207
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateKeyringsInState).call(this);
|
|
1208
|
+
if (__classPrivateFieldGet(this, _KeyringController_password, "f") &&
|
|
1209
|
+
(!__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f") || !encryptionKey) &&
|
|
1210
|
+
__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated &&
|
|
1211
|
+
!__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated(encryptedVault)) {
|
|
1212
|
+
// Re-encrypt the vault with safer method if one is available
|
|
1213
|
+
yield this.persistAllKeyrings();
|
|
1214
|
+
}
|
|
1215
|
+
return __classPrivateFieldGet(this, _KeyringController_keyrings, "f");
|
|
1216
|
+
});
|
|
1217
|
+
}, _KeyringController_createKeyringWithFirstAccount = function _KeyringController_createKeyringWithFirstAccount(type, opts) {
|
|
1218
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1219
|
+
const keyring = (yield this.addNewKeyring(type, opts));
|
|
1220
|
+
const [firstAccount] = yield keyring.getAccounts();
|
|
1221
|
+
if (!firstAccount) {
|
|
1222
|
+
throw new Error(constants_1.KeyringControllerError.NoFirstAccount);
|
|
1223
|
+
}
|
|
1224
|
+
});
|
|
1225
|
+
}, _KeyringController_newKeyring = function _KeyringController_newKeyring(type, data) {
|
|
1226
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1227
|
+
const keyringBuilder = __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getKeyringBuilderForType).call(this, type);
|
|
1228
|
+
if (!keyringBuilder) {
|
|
1229
|
+
throw new Error(`${constants_1.KeyringControllerError.NoKeyringBuilder}. Keyring type: ${type}`);
|
|
1230
|
+
}
|
|
1231
|
+
const keyring = keyringBuilder();
|
|
1232
|
+
// @ts-expect-error Enforce data type after updating clients
|
|
1233
|
+
yield keyring.deserialize(data);
|
|
1234
|
+
if (keyring.init) {
|
|
1235
|
+
yield keyring.init();
|
|
1236
|
+
}
|
|
1237
|
+
return keyring;
|
|
1238
|
+
});
|
|
1239
|
+
}, _KeyringController_clearKeyrings = function _KeyringController_clearKeyrings() {
|
|
1240
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1241
|
+
for (const keyring of __classPrivateFieldGet(this, _KeyringController_keyrings, "f")) {
|
|
1242
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_destroyKeyring).call(this, keyring);
|
|
1243
|
+
}
|
|
1244
|
+
__classPrivateFieldSet(this, _KeyringController_keyrings, [], "f");
|
|
1245
|
+
this.update((state) => {
|
|
1246
|
+
state.keyrings = [];
|
|
1247
|
+
});
|
|
1248
|
+
});
|
|
1249
|
+
}, _KeyringController_restoreKeyring = function _KeyringController_restoreKeyring(serialized) {
|
|
1250
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1251
|
+
try {
|
|
1252
|
+
const { type, data } = serialized;
|
|
1253
|
+
const keyring = yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_newKeyring).call(this, type, data);
|
|
1254
|
+
// getAccounts also validates the accounts for some keyrings
|
|
1255
|
+
yield keyring.getAccounts();
|
|
1256
|
+
__classPrivateFieldGet(this, _KeyringController_keyrings, "f").push(keyring);
|
|
1257
|
+
return keyring;
|
|
1258
|
+
}
|
|
1259
|
+
catch (_) {
|
|
1260
|
+
__classPrivateFieldGet(this, _KeyringController_unsupportedKeyrings, "f").push(serialized);
|
|
1261
|
+
return undefined;
|
|
1262
|
+
}
|
|
1263
|
+
});
|
|
1264
|
+
}, _KeyringController_destroyKeyring = function _KeyringController_destroyKeyring(keyring) {
|
|
1265
|
+
var _a;
|
|
1266
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1267
|
+
yield ((_a = keyring.destroy) === null || _a === void 0 ? void 0 : _a.call(keyring));
|
|
1268
|
+
});
|
|
1269
|
+
}, _KeyringController_removeEmptyKeyrings = function _KeyringController_removeEmptyKeyrings() {
|
|
1270
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1271
|
+
const validKeyrings = [];
|
|
1272
|
+
// Since getAccounts returns a Promise
|
|
1273
|
+
// We need to wait to hear back form each keyring
|
|
1274
|
+
// in order to decide which ones are now valid (accounts.length > 0)
|
|
1275
|
+
yield Promise.all(__classPrivateFieldGet(this, _KeyringController_keyrings, "f").map((keyring) => __awaiter(this, void 0, void 0, function* () {
|
|
1276
|
+
const accounts = yield keyring.getAccounts();
|
|
1277
|
+
if (accounts.length > 0) {
|
|
1278
|
+
validKeyrings.push(keyring);
|
|
1279
|
+
}
|
|
1280
|
+
else {
|
|
1281
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_destroyKeyring).call(this, keyring);
|
|
1282
|
+
}
|
|
1283
|
+
})));
|
|
1284
|
+
__classPrivateFieldSet(this, _KeyringController_keyrings, validKeyrings, "f");
|
|
1285
|
+
});
|
|
1286
|
+
}, _KeyringController_checkForDuplicate = function _KeyringController_checkForDuplicate(type, newAccountArray) {
|
|
1287
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1288
|
+
const accounts = yield this.getAccounts();
|
|
1289
|
+
switch (type) {
|
|
1290
|
+
case KeyringTypes.simple: {
|
|
1291
|
+
const isIncluded = Boolean(accounts.find((key) => newAccountArray[0] &&
|
|
1292
|
+
(key === newAccountArray[0] ||
|
|
1293
|
+
key === (0, utils_1.remove0x)(newAccountArray[0]))));
|
|
1294
|
+
if (isIncluded) {
|
|
1295
|
+
throw new Error(constants_1.KeyringControllerError.DuplicatedAccount);
|
|
1296
|
+
}
|
|
1297
|
+
return newAccountArray;
|
|
1298
|
+
}
|
|
1299
|
+
default: {
|
|
1300
|
+
return newAccountArray;
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
});
|
|
1304
|
+
}, _KeyringController_setUnlocked = function _KeyringController_setUnlocked() {
|
|
1305
|
+
this.update((state) => {
|
|
1306
|
+
state.isUnlocked = true;
|
|
1307
|
+
});
|
|
902
1308
|
this.messagingSystem.publish(`${name}:unlock`);
|
|
903
1309
|
}, _KeyringController_getMemState = function _KeyringController_getMemState() {
|
|
904
1310
|
return {
|