@metamask-previews/keyring-controller 12.2.0-preview.2431602 → 12.2.0-preview.303e509
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 +82 -4
- package/dist/KeyringController.d.ts +110 -16
- package/dist/KeyringController.d.ts.map +1 -1
- package/dist/KeyringController.js +524 -139
- 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 +8 -9
|
@@ -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.isCustodyKeyring = exports.KeyringTypes = void 0;
|
|
51
|
+
const util_1 = require("@ethereumjs/util");
|
|
48
52
|
const base_controller_1 = require("@metamask/base-controller");
|
|
49
|
-
const
|
|
53
|
+
const encryptorUtils = __importStar(require("@metamask/browser-passworder"));
|
|
54
|
+
const eth_hd_keyring_1 = __importDefault(require("@metamask/eth-hd-keyring"));
|
|
55
|
+
const eth_sig_util_1 = require("@metamask/eth-sig-util");
|
|
56
|
+
const eth_simple_keyring_1 = __importDefault(require("@metamask/eth-simple-keyring"));
|
|
50
57
|
const utils_1 = require("@metamask/utils");
|
|
51
58
|
const async_mutex_1 = require("async-mutex");
|
|
52
|
-
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
|
|
@@ -64,8 +71,17 @@ var KeyringTypes;
|
|
|
64
71
|
KeyringTypes["ledger"] = "Ledger Hardware";
|
|
65
72
|
KeyringTypes["lattice"] = "Lattice Hardware";
|
|
66
73
|
KeyringTypes["snap"] = "Snap Keyring";
|
|
67
|
-
KeyringTypes["custody"] = "Custody - JSONRPC";
|
|
68
74
|
})(KeyringTypes = exports.KeyringTypes || (exports.KeyringTypes = {}));
|
|
75
|
+
/**
|
|
76
|
+
* Custody keyring types are a special case, as they are not a single type
|
|
77
|
+
* but they all start with the prefix "Custody".
|
|
78
|
+
* @param keyringType - The type of the keyring.
|
|
79
|
+
* @returns Whether the keyring type is a custody keyring.
|
|
80
|
+
*/
|
|
81
|
+
const isCustodyKeyring = (keyringType) => {
|
|
82
|
+
return keyringType.startsWith('Custody');
|
|
83
|
+
};
|
|
84
|
+
exports.isCustodyKeyring = isCustodyKeyring;
|
|
69
85
|
/**
|
|
70
86
|
* A strategy for importing an account
|
|
71
87
|
*/
|
|
@@ -85,6 +101,24 @@ var SignTypedDataVersion;
|
|
|
85
101
|
SignTypedDataVersion["V3"] = "V3";
|
|
86
102
|
SignTypedDataVersion["V4"] = "V4";
|
|
87
103
|
})(SignTypedDataVersion = exports.SignTypedDataVersion || (exports.SignTypedDataVersion = {}));
|
|
104
|
+
/**
|
|
105
|
+
* Get builder function for `Keyring`
|
|
106
|
+
*
|
|
107
|
+
* Returns a builder function for `Keyring` with a `type` property.
|
|
108
|
+
*
|
|
109
|
+
* @param KeyringConstructor - The Keyring class for the builder.
|
|
110
|
+
* @returns A builder function for the given Keyring.
|
|
111
|
+
*/
|
|
112
|
+
function keyringBuilderFactory(KeyringConstructor) {
|
|
113
|
+
const builder = () => new KeyringConstructor();
|
|
114
|
+
builder.type = KeyringConstructor.type;
|
|
115
|
+
return builder;
|
|
116
|
+
}
|
|
117
|
+
exports.keyringBuilderFactory = keyringBuilderFactory;
|
|
118
|
+
const defaultKeyringBuilders = [
|
|
119
|
+
keyringBuilderFactory(eth_simple_keyring_1.default),
|
|
120
|
+
keyringBuilderFactory(eth_hd_keyring_1.default),
|
|
121
|
+
];
|
|
88
122
|
const getDefaultKeyringState = () => {
|
|
89
123
|
return {
|
|
90
124
|
isUnlocked: false,
|
|
@@ -104,6 +138,53 @@ function assertHasUint8ArrayMnemonic(keyring) {
|
|
|
104
138
|
throw new Error("Can't get mnemonic bytes from keyring");
|
|
105
139
|
}
|
|
106
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* Assert that the provided encryptor supports
|
|
143
|
+
* encryption and encryption key export.
|
|
144
|
+
*
|
|
145
|
+
* @param encryptor - The encryptor to check.
|
|
146
|
+
* @throws If the encryptor does not support key encryption.
|
|
147
|
+
*/
|
|
148
|
+
function assertIsExportableKeyEncryptor(encryptor) {
|
|
149
|
+
if (!('importKey' in encryptor &&
|
|
150
|
+
typeof encryptor.importKey === 'function' &&
|
|
151
|
+
'decryptWithKey' in encryptor &&
|
|
152
|
+
typeof encryptor.decryptWithKey === 'function' &&
|
|
153
|
+
'encryptWithKey' in encryptor &&
|
|
154
|
+
typeof encryptor.encryptWithKey === 'function')) {
|
|
155
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedEncryptionKeyExport);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Checks if the provided value is a serialized keyrings array.
|
|
160
|
+
*
|
|
161
|
+
* @param array - The value to check.
|
|
162
|
+
* @returns True if the value is a serialized keyrings array.
|
|
163
|
+
*/
|
|
164
|
+
function isSerializedKeyringsArray(array) {
|
|
165
|
+
return (typeof array === 'object' &&
|
|
166
|
+
Array.isArray(array) &&
|
|
167
|
+
array.every((value) => value.type && (0, utils_1.isValidJson)(value.data)));
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Display For Keyring
|
|
171
|
+
*
|
|
172
|
+
* Is used for adding the current keyrings to the state object.
|
|
173
|
+
*
|
|
174
|
+
* @param keyring - The keyring to display.
|
|
175
|
+
* @returns A keyring display object, with type and accounts properties.
|
|
176
|
+
*/
|
|
177
|
+
function displayForKeyring(keyring) {
|
|
178
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
179
|
+
const accounts = yield keyring.getAccounts();
|
|
180
|
+
return {
|
|
181
|
+
type: keyring.type,
|
|
182
|
+
// Cast to `Hex[]` here is safe here because `accounts` has no nullish
|
|
183
|
+
// values, and `normalize` returns `Hex` unless given a nullish value
|
|
184
|
+
accounts: accounts.map(eth_sig_util_1.normalize),
|
|
185
|
+
};
|
|
186
|
+
});
|
|
187
|
+
}
|
|
107
188
|
/**
|
|
108
189
|
* Controller responsible for establishing and managing user identity.
|
|
109
190
|
*
|
|
@@ -118,10 +199,6 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
118
199
|
* Creates a KeyringController instance.
|
|
119
200
|
*
|
|
120
201
|
* @param options - Initial options used to configure this controller
|
|
121
|
-
* @param options.syncIdentities - Sync identities with the given list of addresses.
|
|
122
|
-
* @param options.updateIdentities - Generate an identity for each address given that doesn't already have an identity.
|
|
123
|
-
* @param options.setSelectedAddress - Set the selected address.
|
|
124
|
-
* @param options.setAccountLabel - Set a new name for account.
|
|
125
202
|
* @param options.encryptor - An optional object for defining encryption schemes.
|
|
126
203
|
* @param options.keyringBuilders - Set a new name for account.
|
|
127
204
|
* @param options.cacheEncryptionKey - Whether to cache or not encryption key.
|
|
@@ -129,8 +206,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
129
206
|
* @param options.state - Initial state to set on this controller.
|
|
130
207
|
*/
|
|
131
208
|
constructor(options) {
|
|
132
|
-
|
|
133
|
-
const { syncIdentities, updateIdentities, setSelectedAddress, setAccountLabel, keyringBuilders, messenger, state, } = options;
|
|
209
|
+
const { encryptor = encryptorUtils, keyringBuilders, messenger, state, } = options;
|
|
134
210
|
super({
|
|
135
211
|
name,
|
|
136
212
|
metadata: {
|
|
@@ -145,32 +221,25 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
145
221
|
});
|
|
146
222
|
_KeyringController_instances.add(this);
|
|
147
223
|
this.mutex = new async_mutex_1.Mutex();
|
|
148
|
-
|
|
224
|
+
_KeyringController_keyringBuilders.set(this, void 0);
|
|
225
|
+
_KeyringController_keyrings.set(this, void 0);
|
|
226
|
+
_KeyringController_unsupportedKeyrings.set(this, void 0);
|
|
227
|
+
_KeyringController_password.set(this, void 0);
|
|
228
|
+
_KeyringController_encryptor.set(this, void 0);
|
|
229
|
+
_KeyringController_cacheEncryptionKey.set(this, void 0);
|
|
149
230
|
_KeyringController_qrKeyringStateListener.set(this, void 0);
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
encryptor: options.encryptor,
|
|
162
|
-
keyringBuilders,
|
|
163
|
-
cacheEncryptionKey: (_a = options.cacheEncryptionKey) !== null && _a !== void 0 ? _a : false,
|
|
164
|
-
}), "f");
|
|
231
|
+
__classPrivateFieldSet(this, _KeyringController_keyringBuilders, keyringBuilders
|
|
232
|
+
? defaultKeyringBuilders.concat(keyringBuilders)
|
|
233
|
+
: defaultKeyringBuilders, "f");
|
|
234
|
+
__classPrivateFieldSet(this, _KeyringController_encryptor, encryptor, "f");
|
|
235
|
+
__classPrivateFieldSet(this, _KeyringController_keyrings, [], "f");
|
|
236
|
+
__classPrivateFieldSet(this, _KeyringController_unsupportedKeyrings, [], "f");
|
|
237
|
+
// This option allows the controller to cache an exported key
|
|
238
|
+
// for use in decrypting and encrypting data without password
|
|
239
|
+
__classPrivateFieldSet(this, _KeyringController_cacheEncryptionKey, Boolean(options.cacheEncryptionKey), "f");
|
|
240
|
+
if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
|
|
241
|
+
assertIsExportableKeyEncryptor(encryptor);
|
|
165
242
|
}
|
|
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
|
-
this.syncIdentities = syncIdentities;
|
|
171
|
-
this.updateIdentities = updateIdentities;
|
|
172
|
-
this.setSelectedAddress = setSelectedAddress;
|
|
173
|
-
this.setAccountLabel = setAccountLabel;
|
|
174
243
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_registerMessageHandlers).call(this);
|
|
175
244
|
}
|
|
176
245
|
/**
|
|
@@ -183,12 +252,11 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
183
252
|
*/
|
|
184
253
|
addNewAccount(accountCount) {
|
|
185
254
|
return __awaiter(this, void 0, void 0, function* () {
|
|
186
|
-
const primaryKeyring =
|
|
187
|
-
/* istanbul ignore if */
|
|
255
|
+
const primaryKeyring = this.getKeyringsByType('HD Key Tree')[0];
|
|
188
256
|
if (!primaryKeyring) {
|
|
189
257
|
throw new Error('No HD keyring found');
|
|
190
258
|
}
|
|
191
|
-
const oldAccounts = yield
|
|
259
|
+
const oldAccounts = yield this.getAccounts();
|
|
192
260
|
if (accountCount && oldAccounts.length !== accountCount) {
|
|
193
261
|
if (accountCount > oldAccounts.length) {
|
|
194
262
|
throw new Error('Account out of sequence');
|
|
@@ -200,12 +268,8 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
200
268
|
addedAccountAddress: primaryKeyringAccounts[accountCount],
|
|
201
269
|
};
|
|
202
270
|
}
|
|
203
|
-
yield
|
|
204
|
-
const newAccounts = yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").getAccounts();
|
|
271
|
+
const addedAccountAddress = yield this.addNewAccountForKeyring(primaryKeyring);
|
|
205
272
|
yield this.verifySeedPhrase();
|
|
206
|
-
this.updateIdentities(newAccounts);
|
|
207
|
-
const addedAccountAddress = newAccounts.find((selectedAddress) => !oldAccounts.includes(selectedAddress));
|
|
208
|
-
(0, utils_1.assertIsStrictHexString)(addedAccountAddress);
|
|
209
273
|
return {
|
|
210
274
|
keyringState: __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getMemState).call(this),
|
|
211
275
|
addedAccountAddress,
|
|
@@ -230,10 +294,10 @@ 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 __classPrivateFieldGet(this, _KeyringController_keyring, "f").getAccounts());
|
|
237
301
|
return addedAccountAddress;
|
|
238
302
|
});
|
|
239
303
|
}
|
|
@@ -244,12 +308,12 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
244
308
|
*/
|
|
245
309
|
addNewAccountWithoutUpdate() {
|
|
246
310
|
return __awaiter(this, void 0, void 0, function* () {
|
|
247
|
-
const primaryKeyring =
|
|
248
|
-
/* istanbul ignore if */
|
|
311
|
+
const primaryKeyring = this.getKeyringsByType('HD Key Tree')[0];
|
|
249
312
|
if (!primaryKeyring) {
|
|
250
313
|
throw new Error('No HD keyring found');
|
|
251
314
|
}
|
|
252
|
-
yield
|
|
315
|
+
yield primaryKeyring.addAccounts(1);
|
|
316
|
+
yield this.persistAllKeyrings();
|
|
253
317
|
yield this.verifySeedPhrase();
|
|
254
318
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getMemState).call(this);
|
|
255
319
|
});
|
|
@@ -270,15 +334,13 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
270
334
|
throw new Error('Invalid password');
|
|
271
335
|
}
|
|
272
336
|
try {
|
|
273
|
-
this.
|
|
274
|
-
|
|
275
|
-
type: eth_keyring_controller_1.KeyringType.HD,
|
|
337
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createNewVaultWithKeyring).call(this, password, {
|
|
338
|
+
type: KeyringTypes.hd,
|
|
276
339
|
opts: {
|
|
277
340
|
mnemonic: seed,
|
|
278
341
|
numberOfAccounts: 1,
|
|
279
342
|
},
|
|
280
343
|
});
|
|
281
|
-
this.updateIdentities(yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").getAccounts());
|
|
282
344
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getMemState).call(this);
|
|
283
345
|
}
|
|
284
346
|
finally {
|
|
@@ -298,10 +360,9 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
298
360
|
try {
|
|
299
361
|
const accounts = yield this.getAccounts();
|
|
300
362
|
if (!accounts.length) {
|
|
301
|
-
yield __classPrivateFieldGet(this,
|
|
302
|
-
type:
|
|
363
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createNewVaultWithKeyring).call(this, password, {
|
|
364
|
+
type: KeyringTypes.hd,
|
|
303
365
|
});
|
|
304
|
-
this.updateIdentities(yield this.getAccounts());
|
|
305
366
|
}
|
|
306
367
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getMemState).call(this);
|
|
307
368
|
}
|
|
@@ -323,7 +384,19 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
323
384
|
if (type === KeyringTypes.qr) {
|
|
324
385
|
return this.getOrAddQRKeyring();
|
|
325
386
|
}
|
|
326
|
-
|
|
387
|
+
const keyring = yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_newKeyring).call(this, type, opts);
|
|
388
|
+
if (type === KeyringTypes.hd && (!(0, utils_1.isObject)(opts) || !opts.mnemonic)) {
|
|
389
|
+
if (!keyring.generateRandomMnemonic) {
|
|
390
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedGenerateRandomMnemonic);
|
|
391
|
+
}
|
|
392
|
+
keyring.generateRandomMnemonic();
|
|
393
|
+
yield keyring.addAccounts(1);
|
|
394
|
+
}
|
|
395
|
+
const accounts = yield keyring.getAccounts();
|
|
396
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_checkForDuplicate).call(this, type, accounts);
|
|
397
|
+
__classPrivateFieldGet(this, _KeyringController_keyrings, "f").push(keyring);
|
|
398
|
+
yield this.persistAllKeyrings();
|
|
399
|
+
return keyring;
|
|
327
400
|
});
|
|
328
401
|
}
|
|
329
402
|
/**
|
|
@@ -334,7 +407,10 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
334
407
|
*/
|
|
335
408
|
verifyPassword(password) {
|
|
336
409
|
return __awaiter(this, void 0, void 0, function* () {
|
|
337
|
-
|
|
410
|
+
if (!this.state.vault) {
|
|
411
|
+
throw new Error(constants_1.KeyringControllerError.VaultError);
|
|
412
|
+
}
|
|
413
|
+
yield __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, this.state.vault);
|
|
338
414
|
});
|
|
339
415
|
}
|
|
340
416
|
/**
|
|
@@ -354,8 +430,8 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
354
430
|
exportSeedPhrase(password) {
|
|
355
431
|
return __awaiter(this, void 0, void 0, function* () {
|
|
356
432
|
yield this.verifyPassword(password);
|
|
357
|
-
assertHasUint8ArrayMnemonic(__classPrivateFieldGet(this,
|
|
358
|
-
return __classPrivateFieldGet(this,
|
|
433
|
+
assertHasUint8ArrayMnemonic(__classPrivateFieldGet(this, _KeyringController_keyrings, "f")[0]);
|
|
434
|
+
return __classPrivateFieldGet(this, _KeyringController_keyrings, "f")[0].mnemonic;
|
|
359
435
|
});
|
|
360
436
|
}
|
|
361
437
|
/**
|
|
@@ -368,7 +444,11 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
368
444
|
exportAccount(password, address) {
|
|
369
445
|
return __awaiter(this, void 0, void 0, function* () {
|
|
370
446
|
yield this.verifyPassword(password);
|
|
371
|
-
|
|
447
|
+
const keyring = (yield this.getKeyringForAccount(address));
|
|
448
|
+
if (!keyring.exportAccount) {
|
|
449
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedExportAccount);
|
|
450
|
+
}
|
|
451
|
+
return yield keyring.exportAccount((0, eth_sig_util_1.normalize)(address));
|
|
372
452
|
});
|
|
373
453
|
}
|
|
374
454
|
/**
|
|
@@ -377,7 +457,16 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
377
457
|
* @returns A promise resolving to an array of addresses.
|
|
378
458
|
*/
|
|
379
459
|
getAccounts() {
|
|
380
|
-
return
|
|
460
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
461
|
+
const keyrings = __classPrivateFieldGet(this, _KeyringController_keyrings, "f");
|
|
462
|
+
const keyringArrays = yield Promise.all(keyrings.map((keyring) => __awaiter(this, void 0, void 0, function* () { return keyring.getAccounts(); })));
|
|
463
|
+
const addresses = keyringArrays.reduce((res, arr) => {
|
|
464
|
+
return res.concat(arr);
|
|
465
|
+
}, []);
|
|
466
|
+
// Cast to `Hex[]` here is safe here because `addresses` has no nullish
|
|
467
|
+
// values, and `normalize` returns `Hex` unless given a nullish value
|
|
468
|
+
return addresses.map(eth_sig_util_1.normalize);
|
|
469
|
+
});
|
|
381
470
|
}
|
|
382
471
|
/**
|
|
383
472
|
* Get encryption public key.
|
|
@@ -389,7 +478,12 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
389
478
|
*/
|
|
390
479
|
getEncryptionPublicKey(account, opts) {
|
|
391
480
|
return __awaiter(this, void 0, void 0, function* () {
|
|
392
|
-
|
|
481
|
+
const normalizedAddress = (0, eth_sig_util_1.normalize)(account);
|
|
482
|
+
const keyring = (yield this.getKeyringForAccount(account));
|
|
483
|
+
if (!keyring.getEncryptionPublicKey) {
|
|
484
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedGetEncryptionPublicKey);
|
|
485
|
+
}
|
|
486
|
+
return yield keyring.getEncryptionPublicKey(normalizedAddress, opts);
|
|
393
487
|
});
|
|
394
488
|
}
|
|
395
489
|
/**
|
|
@@ -402,7 +496,12 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
402
496
|
*/
|
|
403
497
|
decryptMessage(messageParams) {
|
|
404
498
|
return __awaiter(this, void 0, void 0, function* () {
|
|
405
|
-
|
|
499
|
+
const address = (0, eth_sig_util_1.normalize)(messageParams.from);
|
|
500
|
+
const keyring = (yield this.getKeyringForAccount(address));
|
|
501
|
+
if (!keyring.decryptMessage) {
|
|
502
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedDecryptMessage);
|
|
503
|
+
}
|
|
504
|
+
return keyring.decryptMessage(address, messageParams.data);
|
|
406
505
|
});
|
|
407
506
|
}
|
|
408
507
|
/**
|
|
@@ -416,8 +515,33 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
416
515
|
* @returns Promise resolving to keyring of the `account` if one exists.
|
|
417
516
|
*/
|
|
418
517
|
getKeyringForAccount(account) {
|
|
518
|
+
var _a;
|
|
419
519
|
return __awaiter(this, void 0, void 0, function* () {
|
|
420
|
-
|
|
520
|
+
// Cast to `Hex` here is safe here because `address` is not nullish.
|
|
521
|
+
// `normalizeToHex` returns `Hex` unless given a nullish value.
|
|
522
|
+
const hexed = (0, eth_sig_util_1.normalize)(account);
|
|
523
|
+
const candidates = yield Promise.all(__classPrivateFieldGet(this, _KeyringController_keyrings, "f").map((keyring) => __awaiter(this, void 0, void 0, function* () {
|
|
524
|
+
return Promise.all([keyring, keyring.getAccounts()]);
|
|
525
|
+
})));
|
|
526
|
+
const winners = candidates.filter((candidate) => {
|
|
527
|
+
const accounts = candidate[1].map(eth_sig_util_1.normalize);
|
|
528
|
+
return accounts.includes(hexed);
|
|
529
|
+
});
|
|
530
|
+
if (winners.length && ((_a = winners[0]) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
531
|
+
return winners[0][0];
|
|
532
|
+
}
|
|
533
|
+
// Adding more info to the error
|
|
534
|
+
let errorInfo = '';
|
|
535
|
+
if (!(0, utils_1.isValidHexAddress)(hexed)) {
|
|
536
|
+
errorInfo = 'The address passed in is invalid/empty';
|
|
537
|
+
}
|
|
538
|
+
else if (!candidates.length) {
|
|
539
|
+
errorInfo = 'There are no keyrings';
|
|
540
|
+
}
|
|
541
|
+
else if (!winners.length) {
|
|
542
|
+
errorInfo = 'There are keyrings, but none match the address';
|
|
543
|
+
}
|
|
544
|
+
throw new Error(`${constants_1.KeyringControllerError.NoKeyring}. Error info: ${errorInfo}`);
|
|
421
545
|
});
|
|
422
546
|
}
|
|
423
547
|
/**
|
|
@@ -430,7 +554,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
430
554
|
* @returns An array of keyrings of the given type.
|
|
431
555
|
*/
|
|
432
556
|
getKeyringsByType(type) {
|
|
433
|
-
return __classPrivateFieldGet(this,
|
|
557
|
+
return __classPrivateFieldGet(this, _KeyringController_keyrings, "f").filter((keyring) => keyring.type === type);
|
|
434
558
|
}
|
|
435
559
|
/**
|
|
436
560
|
* Persist all serialized keyrings in the vault.
|
|
@@ -440,7 +564,58 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
440
564
|
*/
|
|
441
565
|
persistAllKeyrings() {
|
|
442
566
|
return __awaiter(this, void 0, void 0, function* () {
|
|
443
|
-
|
|
567
|
+
const { encryptionKey, encryptionSalt } = this.state;
|
|
568
|
+
if (!__classPrivateFieldGet(this, _KeyringController_password, "f") && !encryptionKey) {
|
|
569
|
+
throw new Error(constants_1.KeyringControllerError.MissingCredentials);
|
|
570
|
+
}
|
|
571
|
+
const serializedKeyrings = yield Promise.all(__classPrivateFieldGet(this, _KeyringController_keyrings, "f").map((keyring) => __awaiter(this, void 0, void 0, function* () {
|
|
572
|
+
const [type, data] = yield Promise.all([
|
|
573
|
+
keyring.type,
|
|
574
|
+
keyring.serialize(),
|
|
575
|
+
]);
|
|
576
|
+
return { type, data };
|
|
577
|
+
})));
|
|
578
|
+
serializedKeyrings.push(...__classPrivateFieldGet(this, _KeyringController_unsupportedKeyrings, "f"));
|
|
579
|
+
let vault;
|
|
580
|
+
let newEncryptionKey;
|
|
581
|
+
if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
|
|
582
|
+
assertIsExportableKeyEncryptor(__classPrivateFieldGet(this, _KeyringController_encryptor, "f"));
|
|
583
|
+
if (encryptionKey) {
|
|
584
|
+
const key = yield __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
|
|
585
|
+
const vaultJSON = yield __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithKey(key, serializedKeyrings);
|
|
586
|
+
vaultJSON.salt = encryptionSalt;
|
|
587
|
+
vault = JSON.stringify(vaultJSON);
|
|
588
|
+
}
|
|
589
|
+
else if (__classPrivateFieldGet(this, _KeyringController_password, "f")) {
|
|
590
|
+
const { vault: newVault, exportedKeyString } = yield __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithDetail(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
|
|
591
|
+
vault = newVault;
|
|
592
|
+
newEncryptionKey = exportedKeyString;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
else {
|
|
596
|
+
if (typeof __classPrivateFieldGet(this, _KeyringController_password, "f") !== 'string') {
|
|
597
|
+
throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
|
|
598
|
+
}
|
|
599
|
+
vault = yield __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encrypt(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
|
|
600
|
+
}
|
|
601
|
+
if (!vault) {
|
|
602
|
+
throw new Error(constants_1.KeyringControllerError.MissingVaultData);
|
|
603
|
+
}
|
|
604
|
+
this.update((state) => {
|
|
605
|
+
state.vault = vault;
|
|
606
|
+
});
|
|
607
|
+
// The keyring updates need to be announced before updating the encryptionKey
|
|
608
|
+
// so that the updated keyring gets propagated to the extension first.
|
|
609
|
+
// Not calling {@link updateKeyringsInState} results in the wrong account being selected
|
|
610
|
+
// in the extension.
|
|
611
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateKeyringsInState).call(this);
|
|
612
|
+
if (newEncryptionKey) {
|
|
613
|
+
this.update((state) => {
|
|
614
|
+
state.encryptionKey = newEncryptionKey;
|
|
615
|
+
state.encryptionSalt = JSON.parse(vault).salt;
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
return true;
|
|
444
619
|
});
|
|
445
620
|
}
|
|
446
621
|
/**
|
|
@@ -464,21 +639,20 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
464
639
|
if (!importedKey) {
|
|
465
640
|
throw new Error('Cannot import an empty key.');
|
|
466
641
|
}
|
|
467
|
-
const prefixed = (0,
|
|
642
|
+
const prefixed = (0, utils_1.add0x)(importedKey);
|
|
468
643
|
let bufferedPrivateKey;
|
|
469
644
|
try {
|
|
470
|
-
bufferedPrivateKey = (0,
|
|
645
|
+
bufferedPrivateKey = (0, util_1.toBuffer)(prefixed);
|
|
471
646
|
}
|
|
472
647
|
catch (_a) {
|
|
473
648
|
throw new Error('Cannot import invalid private key.');
|
|
474
649
|
}
|
|
475
|
-
|
|
476
|
-
if (!(0, ethereumjs_util_1.isValidPrivate)(bufferedPrivateKey) ||
|
|
650
|
+
if (!(0, util_1.isValidPrivate)(bufferedPrivateKey) ||
|
|
477
651
|
// ensures that the key is 64 bytes long
|
|
478
|
-
(0,
|
|
652
|
+
(0, util_1.getBinarySize)(prefixed) !== 64 + '0x'.length) {
|
|
479
653
|
throw new Error('Cannot import invalid private key.');
|
|
480
654
|
}
|
|
481
|
-
privateKey = (0,
|
|
655
|
+
privateKey = (0, utils_1.remove0x)(prefixed);
|
|
482
656
|
break;
|
|
483
657
|
case 'json':
|
|
484
658
|
let wallet;
|
|
@@ -489,17 +663,15 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
489
663
|
catch (e) {
|
|
490
664
|
wallet = wallet || (yield ethereumjs_wallet_1.default.fromV3(input, password, true));
|
|
491
665
|
}
|
|
492
|
-
privateKey = (0,
|
|
666
|
+
privateKey = (0, utils_1.bytesToHex)(wallet.getPrivateKey());
|
|
493
667
|
break;
|
|
494
668
|
default:
|
|
495
669
|
throw new Error(`Unexpected import strategy: '${strategy}'`);
|
|
496
670
|
}
|
|
497
|
-
const newKeyring = yield
|
|
671
|
+
const newKeyring = (yield this.addNewKeyring(KeyringTypes.simple, [
|
|
498
672
|
privateKey,
|
|
499
|
-
]);
|
|
673
|
+
]));
|
|
500
674
|
const accounts = yield newKeyring.getAccounts();
|
|
501
|
-
const allAccounts = yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").getAccounts();
|
|
502
|
-
this.updateIdentities(allAccounts);
|
|
503
675
|
return {
|
|
504
676
|
keyringState: __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getMemState).call(this),
|
|
505
677
|
importedAccountAddress: accounts[0],
|
|
@@ -515,7 +687,21 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
515
687
|
*/
|
|
516
688
|
removeAccount(address) {
|
|
517
689
|
return __awaiter(this, void 0, void 0, function* () {
|
|
518
|
-
yield
|
|
690
|
+
const keyring = (yield this.getKeyringForAccount(address));
|
|
691
|
+
// Not all the keyrings support this, so we have to check
|
|
692
|
+
if (!keyring.removeAccount) {
|
|
693
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedRemoveAccount);
|
|
694
|
+
}
|
|
695
|
+
// The `removeAccount` method of snaps keyring is async. We have to update
|
|
696
|
+
// the interface of the other keyrings to be async as well.
|
|
697
|
+
// eslint-disable-next-line @typescript-eslint/await-thenable
|
|
698
|
+
yield keyring.removeAccount(address);
|
|
699
|
+
const accounts = yield keyring.getAccounts();
|
|
700
|
+
// Check if this was the last/only account
|
|
701
|
+
if (accounts.length === 0) {
|
|
702
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_removeEmptyKeyrings).call(this);
|
|
703
|
+
}
|
|
704
|
+
yield this.persistAllKeyrings();
|
|
519
705
|
this.messagingSystem.publish(`${name}:accountRemoved`, address);
|
|
520
706
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getMemState).call(this);
|
|
521
707
|
});
|
|
@@ -528,7 +714,13 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
528
714
|
setLocked() {
|
|
529
715
|
return __awaiter(this, void 0, void 0, function* () {
|
|
530
716
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unsubscribeFromQRKeyringsEvents).call(this);
|
|
531
|
-
|
|
717
|
+
__classPrivateFieldSet(this, _KeyringController_password, undefined, "f");
|
|
718
|
+
this.update((state) => {
|
|
719
|
+
state.isUnlocked = false;
|
|
720
|
+
state.keyrings = [];
|
|
721
|
+
});
|
|
722
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
|
|
723
|
+
this.messagingSystem.publish(`${name}:lock`);
|
|
532
724
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getMemState).call(this);
|
|
533
725
|
});
|
|
534
726
|
}
|
|
@@ -539,10 +731,17 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
539
731
|
* @returns Promise resolving to a signed message string.
|
|
540
732
|
*/
|
|
541
733
|
signMessage(messageParams) {
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
734
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
735
|
+
if (!messageParams.data) {
|
|
736
|
+
throw new Error("Can't sign an empty message");
|
|
737
|
+
}
|
|
738
|
+
const address = (0, eth_sig_util_1.normalize)(messageParams.from);
|
|
739
|
+
const keyring = (yield this.getKeyringForAccount(address));
|
|
740
|
+
if (!keyring.signMessage) {
|
|
741
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedSignMessage);
|
|
742
|
+
}
|
|
743
|
+
return yield keyring.signMessage(address, messageParams.data);
|
|
744
|
+
});
|
|
546
745
|
}
|
|
547
746
|
/**
|
|
548
747
|
* Signs personal message by calling down into a specific keyring.
|
|
@@ -551,7 +750,15 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
551
750
|
* @returns Promise resolving to a signed message string.
|
|
552
751
|
*/
|
|
553
752
|
signPersonalMessage(messageParams) {
|
|
554
|
-
return
|
|
753
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
754
|
+
const address = (0, eth_sig_util_1.normalize)(messageParams.from);
|
|
755
|
+
const keyring = (yield this.getKeyringForAccount(address));
|
|
756
|
+
if (!keyring.signPersonalMessage) {
|
|
757
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedSignPersonalMessage);
|
|
758
|
+
}
|
|
759
|
+
const normalizedData = (0, eth_sig_util_1.normalize)(messageParams.data);
|
|
760
|
+
return yield keyring.signPersonalMessage(address, normalizedData);
|
|
761
|
+
});
|
|
555
762
|
}
|
|
556
763
|
/**
|
|
557
764
|
* Signs typed message by calling down into a specific keyring.
|
|
@@ -571,13 +778,17 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
571
778
|
].includes(version)) {
|
|
572
779
|
throw new Error(`Unexpected signTypedMessage version: '${version}'`);
|
|
573
780
|
}
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
}
|
|
781
|
+
// Cast to `Hex` here is safe here because `messageParams.from` is not nullish.
|
|
782
|
+
// `normalize` returns `Hex` unless given a nullish value.
|
|
783
|
+
const address = (0, eth_sig_util_1.normalize)(messageParams.from);
|
|
784
|
+
const keyring = (yield this.getKeyringForAccount(address));
|
|
785
|
+
if (!keyring.signTypedData) {
|
|
786
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedSignTypedMessage);
|
|
787
|
+
}
|
|
788
|
+
return yield keyring.signTypedData(address, version !== SignTypedDataVersion.V1 &&
|
|
789
|
+
typeof messageParams.data === 'string'
|
|
790
|
+
? JSON.parse(messageParams.data)
|
|
791
|
+
: messageParams.data, { version });
|
|
581
792
|
}
|
|
582
793
|
catch (error) {
|
|
583
794
|
throw new Error(`Keyring Controller signTypedMessage: ${error}`);
|
|
@@ -593,7 +804,14 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
593
804
|
* @returns Promise resolving to a signed transaction string.
|
|
594
805
|
*/
|
|
595
806
|
signTransaction(transaction, from, opts) {
|
|
596
|
-
return
|
|
807
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
808
|
+
const address = (0, eth_sig_util_1.normalize)(from);
|
|
809
|
+
const keyring = (yield this.getKeyringForAccount(address));
|
|
810
|
+
if (!keyring.signTransaction) {
|
|
811
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedSignTransaction);
|
|
812
|
+
}
|
|
813
|
+
return yield keyring.signTransaction(address, transaction, opts);
|
|
814
|
+
});
|
|
597
815
|
}
|
|
598
816
|
/**
|
|
599
817
|
* Convert a base transaction to a base UserOperation.
|
|
@@ -604,7 +822,12 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
604
822
|
*/
|
|
605
823
|
prepareUserOperation(from, transactions) {
|
|
606
824
|
return __awaiter(this, void 0, void 0, function* () {
|
|
607
|
-
|
|
825
|
+
const address = (0, eth_sig_util_1.normalize)(from);
|
|
826
|
+
const keyring = (yield this.getKeyringForAccount(address));
|
|
827
|
+
if (!keyring.prepareUserOperation) {
|
|
828
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedPrepareUserOperation);
|
|
829
|
+
}
|
|
830
|
+
return yield keyring.prepareUserOperation(address, transactions);
|
|
608
831
|
});
|
|
609
832
|
}
|
|
610
833
|
/**
|
|
@@ -617,7 +840,12 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
617
840
|
*/
|
|
618
841
|
patchUserOperation(from, userOp) {
|
|
619
842
|
return __awaiter(this, void 0, void 0, function* () {
|
|
620
|
-
|
|
843
|
+
const address = (0, eth_sig_util_1.normalize)(from);
|
|
844
|
+
const keyring = (yield this.getKeyringForAccount(address));
|
|
845
|
+
if (!keyring.patchUserOperation) {
|
|
846
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedPatchUserOperation);
|
|
847
|
+
}
|
|
848
|
+
return yield keyring.patchUserOperation(address, userOp);
|
|
621
849
|
});
|
|
622
850
|
}
|
|
623
851
|
/**
|
|
@@ -629,7 +857,12 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
629
857
|
*/
|
|
630
858
|
signUserOperation(from, userOp) {
|
|
631
859
|
return __awaiter(this, void 0, void 0, function* () {
|
|
632
|
-
|
|
860
|
+
const address = (0, eth_sig_util_1.normalize)(from);
|
|
861
|
+
const keyring = (yield this.getKeyringForAccount(address));
|
|
862
|
+
if (!keyring.signUserOperation) {
|
|
863
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedSignUserOperation);
|
|
864
|
+
}
|
|
865
|
+
return yield keyring.signUserOperation(address, userOp);
|
|
633
866
|
});
|
|
634
867
|
}
|
|
635
868
|
/**
|
|
@@ -642,7 +875,8 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
642
875
|
*/
|
|
643
876
|
submitEncryptionKey(encryptionKey, encryptionSalt) {
|
|
644
877
|
return __awaiter(this, void 0, void 0, function* () {
|
|
645
|
-
yield __classPrivateFieldGet(this,
|
|
878
|
+
__classPrivateFieldSet(this, _KeyringController_keyrings, yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, undefined, encryptionKey, encryptionSalt), "f");
|
|
879
|
+
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
646
880
|
const qrKeyring = this.getQRKeyring();
|
|
647
881
|
if (qrKeyring) {
|
|
648
882
|
// if there is a QR keyring, we need to subscribe
|
|
@@ -661,15 +895,14 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
661
895
|
*/
|
|
662
896
|
submitPassword(password) {
|
|
663
897
|
return __awaiter(this, void 0, void 0, function* () {
|
|
664
|
-
yield __classPrivateFieldGet(this,
|
|
665
|
-
|
|
898
|
+
__classPrivateFieldSet(this, _KeyringController_keyrings, yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, password), "f");
|
|
899
|
+
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
666
900
|
const qrKeyring = this.getQRKeyring();
|
|
667
901
|
if (qrKeyring) {
|
|
668
902
|
// if there is a QR keyring, we need to subscribe
|
|
669
903
|
// to its events after unlocking the vault
|
|
670
904
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_subscribeToQRKeyringEvents).call(this, qrKeyring);
|
|
671
905
|
}
|
|
672
|
-
yield this.syncIdentities(accounts);
|
|
673
906
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getMemState).call(this);
|
|
674
907
|
});
|
|
675
908
|
}
|
|
@@ -680,8 +913,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
680
913
|
*/
|
|
681
914
|
verifySeedPhrase() {
|
|
682
915
|
return __awaiter(this, void 0, void 0, function* () {
|
|
683
|
-
const primaryKeyring =
|
|
684
|
-
/* istanbul ignore if */
|
|
916
|
+
const primaryKeyring = this.getKeyringsByType(KeyringTypes.hd)[0];
|
|
685
917
|
if (!primaryKeyring) {
|
|
686
918
|
throw new Error('No HD keyring found.');
|
|
687
919
|
}
|
|
@@ -694,7 +926,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
694
926
|
}
|
|
695
927
|
// The HD Keyring Builder is a default keyring builder
|
|
696
928
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
697
|
-
const hdKeyringBuilder = __classPrivateFieldGet(this,
|
|
929
|
+
const hdKeyringBuilder = __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getKeyringBuilderForType).call(this, KeyringTypes.hd);
|
|
698
930
|
const hdKeyring = hdKeyringBuilder();
|
|
699
931
|
// @ts-expect-error @metamask/eth-hd-keyring correctly handles
|
|
700
932
|
// Uint8Array seed phrases in the `deserialize` method.
|
|
@@ -724,7 +956,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
724
956
|
*/
|
|
725
957
|
getQRKeyring() {
|
|
726
958
|
// QRKeyring is not yet compatible with Keyring type from @metamask/utils
|
|
727
|
-
return
|
|
959
|
+
return this.getKeyringsByType(KeyringTypes.qr)[0];
|
|
728
960
|
}
|
|
729
961
|
/**
|
|
730
962
|
* Get QR hardware keyring. If it doesn't exist, add it.
|
|
@@ -741,8 +973,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
741
973
|
restoreQRKeyring(serialized) {
|
|
742
974
|
return __awaiter(this, void 0, void 0, function* () {
|
|
743
975
|
(yield this.getOrAddQRKeyring()).deserialize(serialized);
|
|
744
|
-
yield
|
|
745
|
-
this.updateIdentities(yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").getAccounts());
|
|
976
|
+
yield this.persistAllKeyrings();
|
|
746
977
|
});
|
|
747
978
|
}
|
|
748
979
|
resetQRKeyringState() {
|
|
@@ -816,45 +1047,34 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
816
1047
|
return __awaiter(this, void 0, void 0, function* () {
|
|
817
1048
|
const keyring = yield this.getOrAddQRKeyring();
|
|
818
1049
|
keyring.setAccountToUnlock(index);
|
|
819
|
-
const oldAccounts = yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").getAccounts();
|
|
820
1050
|
// QRKeyring is not yet compatible with Keyring from
|
|
821
1051
|
// @metamask/utils, but we can use the `addNewAccount` method
|
|
822
1052
|
// as it internally calls `addAccounts` from on the keyring instance,
|
|
823
1053
|
// which is supported by QRKeyring API.
|
|
824
|
-
yield
|
|
825
|
-
|
|
826
|
-
this.updateIdentities(newAccounts);
|
|
827
|
-
newAccounts.forEach((address) => {
|
|
828
|
-
if (!oldAccounts.includes(address)) {
|
|
829
|
-
if (this.setAccountLabel) {
|
|
830
|
-
this.setAccountLabel(address, `${keyring.getName()} ${index}`);
|
|
831
|
-
}
|
|
832
|
-
this.setSelectedAddress(address);
|
|
833
|
-
}
|
|
834
|
-
});
|
|
835
|
-
yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").persistAllKeyrings();
|
|
1054
|
+
yield this.addNewAccountForKeyring(keyring);
|
|
1055
|
+
yield this.persistAllKeyrings();
|
|
836
1056
|
});
|
|
837
1057
|
}
|
|
838
1058
|
getAccountKeyringType(account) {
|
|
839
1059
|
return __awaiter(this, void 0, void 0, function* () {
|
|
840
|
-
|
|
1060
|
+
const keyring = (yield this.getKeyringForAccount(account));
|
|
1061
|
+
return keyring.type;
|
|
841
1062
|
});
|
|
842
1063
|
}
|
|
843
1064
|
forgetQRDevice() {
|
|
844
1065
|
return __awaiter(this, void 0, void 0, function* () {
|
|
845
1066
|
const keyring = yield this.getOrAddQRKeyring();
|
|
846
|
-
const allAccounts = (yield
|
|
1067
|
+
const allAccounts = (yield this.getAccounts());
|
|
847
1068
|
keyring.forgetDevice();
|
|
848
|
-
const remainingAccounts = (yield
|
|
1069
|
+
const remainingAccounts = (yield this.getAccounts());
|
|
849
1070
|
const removedAccounts = allAccounts.filter((address) => !remainingAccounts.includes(address));
|
|
850
|
-
this.
|
|
851
|
-
yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").persistAllKeyrings();
|
|
1071
|
+
yield this.persistAllKeyrings();
|
|
852
1072
|
return { removedAccounts, remainingAccounts };
|
|
853
1073
|
});
|
|
854
1074
|
}
|
|
855
1075
|
}
|
|
856
1076
|
exports.KeyringController = KeyringController;
|
|
857
|
-
|
|
1077
|
+
_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
1078
|
this.messagingSystem.registerActionHandler(`${name}:signMessage`, this.signMessage.bind(this));
|
|
859
1079
|
this.messagingSystem.registerActionHandler(`${name}:signPersonalMessage`, this.signPersonalMessage.bind(this));
|
|
860
1080
|
this.messagingSystem.registerActionHandler(`${name}:signTypedMessage`, this.signTypedMessage.bind(this));
|
|
@@ -867,10 +1087,18 @@ _KeyringController_keyring = new WeakMap(), _KeyringController_qrKeyringStateLis
|
|
|
867
1087
|
this.messagingSystem.registerActionHandler(`${name}:prepareUserOperation`, this.prepareUserOperation.bind(this));
|
|
868
1088
|
this.messagingSystem.registerActionHandler(`${name}:patchUserOperation`, this.patchUserOperation.bind(this));
|
|
869
1089
|
this.messagingSystem.registerActionHandler(`${name}:signUserOperation`, this.signUserOperation.bind(this));
|
|
1090
|
+
}, _KeyringController_getKeyringBuilderForType = function _KeyringController_getKeyringBuilderForType(type) {
|
|
1091
|
+
return __classPrivateFieldGet(this, _KeyringController_keyringBuilders, "f").find((keyringBuilder) => keyringBuilder.type === type);
|
|
870
1092
|
}, _KeyringController_addQRKeyring = function _KeyringController_addQRKeyring() {
|
|
871
1093
|
return __awaiter(this, void 0, void 0, function* () {
|
|
872
1094
|
// QRKeyring is not yet compatible with Keyring type from @metamask/utils
|
|
873
|
-
const qrKeyring = (yield __classPrivateFieldGet(this,
|
|
1095
|
+
const qrKeyring = (yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_newKeyring).call(this, KeyringTypes.qr, {
|
|
1096
|
+
accounts: [],
|
|
1097
|
+
}));
|
|
1098
|
+
const accounts = yield qrKeyring.getAccounts();
|
|
1099
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_checkForDuplicate).call(this, KeyringTypes.qr, accounts);
|
|
1100
|
+
__classPrivateFieldGet(this, _KeyringController_keyrings, "f").push(qrKeyring);
|
|
1101
|
+
yield this.persistAllKeyrings();
|
|
874
1102
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_subscribeToQRKeyringEvents).call(this, qrKeyring);
|
|
875
1103
|
return qrKeyring;
|
|
876
1104
|
});
|
|
@@ -880,25 +1108,182 @@ _KeyringController_keyring = new WeakMap(), _KeyringController_qrKeyringStateLis
|
|
|
880
1108
|
}, "f");
|
|
881
1109
|
qrKeyring.getMemStore().subscribe(__classPrivateFieldGet(this, _KeyringController_qrKeyringStateListener, "f"));
|
|
882
1110
|
}, _KeyringController_unsubscribeFromQRKeyringsEvents = function _KeyringController_unsubscribeFromQRKeyringsEvents() {
|
|
883
|
-
const qrKeyrings =
|
|
1111
|
+
const qrKeyrings = this.getKeyringsByType(KeyringTypes.qr);
|
|
884
1112
|
qrKeyrings.forEach((qrKeyring) => {
|
|
885
1113
|
if (__classPrivateFieldGet(this, _KeyringController_qrKeyringStateListener, "f")) {
|
|
886
1114
|
qrKeyring.getMemStore().unsubscribe(__classPrivateFieldGet(this, _KeyringController_qrKeyringStateListener, "f"));
|
|
887
1115
|
}
|
|
888
1116
|
});
|
|
889
|
-
},
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
|
|
1117
|
+
}, _KeyringController_createNewVaultWithKeyring = function _KeyringController_createNewVaultWithKeyring(password, keyring) {
|
|
1118
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1119
|
+
if (typeof password !== 'string') {
|
|
1120
|
+
throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
|
|
1121
|
+
}
|
|
1122
|
+
__classPrivateFieldSet(this, _KeyringController_password, password, "f");
|
|
1123
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
|
|
1124
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createKeyringWithFirstAccount).call(this, keyring.type, keyring.opts);
|
|
1125
|
+
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
1126
|
+
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getMemState).call(this);
|
|
1127
|
+
});
|
|
1128
|
+
}, _KeyringController_updateKeyringsInState = function _KeyringController_updateKeyringsInState() {
|
|
1129
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1130
|
+
const keyrings = yield Promise.all(__classPrivateFieldGet(this, _KeyringController_keyrings, "f").map(displayForKeyring));
|
|
1131
|
+
this.update((state) => {
|
|
1132
|
+
state.keyrings = keyrings;
|
|
1133
|
+
});
|
|
1134
|
+
});
|
|
1135
|
+
}, _KeyringController_unlockKeyrings = function _KeyringController_unlockKeyrings(password, encryptionKey, encryptionSalt) {
|
|
1136
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1137
|
+
const encryptedVault = this.state.vault;
|
|
1138
|
+
if (!encryptedVault) {
|
|
1139
|
+
throw new Error(constants_1.KeyringControllerError.VaultError);
|
|
1140
|
+
}
|
|
1141
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
|
|
1142
|
+
let vault;
|
|
1143
|
+
if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
|
|
1144
|
+
assertIsExportableKeyEncryptor(__classPrivateFieldGet(this, _KeyringController_encryptor, "f"));
|
|
1145
|
+
if (password) {
|
|
1146
|
+
const result = yield __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithDetail(password, encryptedVault);
|
|
1147
|
+
vault = result.vault;
|
|
1148
|
+
__classPrivateFieldSet(this, _KeyringController_password, password, "f");
|
|
1149
|
+
this.update((state) => {
|
|
1150
|
+
state.encryptionKey = result.exportedKeyString;
|
|
1151
|
+
state.encryptionSalt = result.salt;
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1154
|
+
else {
|
|
1155
|
+
const parsedEncryptedVault = JSON.parse(encryptedVault);
|
|
1156
|
+
if (encryptionSalt !== parsedEncryptedVault.salt) {
|
|
1157
|
+
throw new Error(constants_1.KeyringControllerError.ExpiredCredentials);
|
|
1158
|
+
}
|
|
1159
|
+
if (typeof encryptionKey !== 'string') {
|
|
1160
|
+
throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
|
|
1161
|
+
}
|
|
1162
|
+
const key = yield __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
|
|
1163
|
+
vault = yield __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
|
|
1164
|
+
// This call is required on the first call because encryptionKey
|
|
1165
|
+
// is not yet inside the memStore
|
|
1166
|
+
this.update((state) => {
|
|
1167
|
+
state.encryptionKey = encryptionKey;
|
|
1168
|
+
// we can safely assume that encryptionSalt is defined here
|
|
1169
|
+
// because we compare it with the salt from the vault
|
|
1170
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1171
|
+
state.encryptionSalt = encryptionSalt;
|
|
1172
|
+
});
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
else {
|
|
1176
|
+
if (typeof password !== 'string') {
|
|
1177
|
+
throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
|
|
1178
|
+
}
|
|
1179
|
+
vault = yield __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, encryptedVault);
|
|
1180
|
+
__classPrivateFieldSet(this, _KeyringController_password, password, "f");
|
|
1181
|
+
}
|
|
1182
|
+
if (!isSerializedKeyringsArray(vault)) {
|
|
1183
|
+
throw new Error(constants_1.KeyringControllerError.VaultDataError);
|
|
1184
|
+
}
|
|
1185
|
+
yield Promise.all(vault.map(__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_restoreKeyring).bind(this)));
|
|
1186
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateKeyringsInState).call(this);
|
|
1187
|
+
if (__classPrivateFieldGet(this, _KeyringController_password, "f") &&
|
|
1188
|
+
(!__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f") || !encryptionKey) &&
|
|
1189
|
+
__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated &&
|
|
1190
|
+
!__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated(encryptedVault)) {
|
|
1191
|
+
// Re-encrypt the vault with safer method if one is available
|
|
1192
|
+
yield this.persistAllKeyrings();
|
|
1193
|
+
}
|
|
1194
|
+
return __classPrivateFieldGet(this, _KeyringController_keyrings, "f");
|
|
1195
|
+
});
|
|
1196
|
+
}, _KeyringController_createKeyringWithFirstAccount = function _KeyringController_createKeyringWithFirstAccount(type, opts) {
|
|
1197
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1198
|
+
const keyring = (yield this.addNewKeyring(type, opts));
|
|
1199
|
+
const [firstAccount] = yield keyring.getAccounts();
|
|
1200
|
+
if (!firstAccount) {
|
|
1201
|
+
throw new Error(constants_1.KeyringControllerError.NoFirstAccount);
|
|
1202
|
+
}
|
|
1203
|
+
});
|
|
1204
|
+
}, _KeyringController_newKeyring = function _KeyringController_newKeyring(type, data) {
|
|
1205
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1206
|
+
const keyringBuilder = __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getKeyringBuilderForType).call(this, type);
|
|
1207
|
+
if (!keyringBuilder) {
|
|
1208
|
+
throw new Error(`${constants_1.KeyringControllerError.NoKeyringBuilder}. Keyring type: ${type}`);
|
|
1209
|
+
}
|
|
1210
|
+
const keyring = keyringBuilder();
|
|
1211
|
+
// @ts-expect-error Enforce data type after updating clients
|
|
1212
|
+
yield keyring.deserialize(data);
|
|
1213
|
+
if (keyring.init) {
|
|
1214
|
+
yield keyring.init();
|
|
1215
|
+
}
|
|
1216
|
+
return keyring;
|
|
1217
|
+
});
|
|
1218
|
+
}, _KeyringController_clearKeyrings = function _KeyringController_clearKeyrings() {
|
|
1219
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1220
|
+
for (const keyring of __classPrivateFieldGet(this, _KeyringController_keyrings, "f")) {
|
|
1221
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_destroyKeyring).call(this, keyring);
|
|
1222
|
+
}
|
|
1223
|
+
__classPrivateFieldSet(this, _KeyringController_keyrings, [], "f");
|
|
1224
|
+
this.update((state) => {
|
|
1225
|
+
state.keyrings = [];
|
|
1226
|
+
});
|
|
1227
|
+
});
|
|
1228
|
+
}, _KeyringController_restoreKeyring = function _KeyringController_restoreKeyring(serialized) {
|
|
1229
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1230
|
+
try {
|
|
1231
|
+
const { type, data } = serialized;
|
|
1232
|
+
const keyring = yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_newKeyring).call(this, type, data);
|
|
1233
|
+
// getAccounts also validates the accounts for some keyrings
|
|
1234
|
+
yield keyring.getAccounts();
|
|
1235
|
+
__classPrivateFieldGet(this, _KeyringController_keyrings, "f").push(keyring);
|
|
1236
|
+
return keyring;
|
|
1237
|
+
}
|
|
1238
|
+
catch (_) {
|
|
1239
|
+
__classPrivateFieldGet(this, _KeyringController_unsupportedKeyrings, "f").push(serialized);
|
|
1240
|
+
return undefined;
|
|
1241
|
+
}
|
|
1242
|
+
});
|
|
1243
|
+
}, _KeyringController_destroyKeyring = function _KeyringController_destroyKeyring(keyring) {
|
|
1244
|
+
var _a;
|
|
1245
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1246
|
+
yield ((_a = keyring.destroy) === null || _a === void 0 ? void 0 : _a.call(keyring));
|
|
1247
|
+
});
|
|
1248
|
+
}, _KeyringController_removeEmptyKeyrings = function _KeyringController_removeEmptyKeyrings() {
|
|
1249
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1250
|
+
const validKeyrings = [];
|
|
1251
|
+
// Since getAccounts returns a Promise
|
|
1252
|
+
// We need to wait to hear back form each keyring
|
|
1253
|
+
// in order to decide which ones are now valid (accounts.length > 0)
|
|
1254
|
+
yield Promise.all(__classPrivateFieldGet(this, _KeyringController_keyrings, "f").map((keyring) => __awaiter(this, void 0, void 0, function* () {
|
|
1255
|
+
const accounts = yield keyring.getAccounts();
|
|
1256
|
+
if (accounts.length > 0) {
|
|
1257
|
+
validKeyrings.push(keyring);
|
|
1258
|
+
}
|
|
1259
|
+
else {
|
|
1260
|
+
yield __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_destroyKeyring).call(this, keyring);
|
|
1261
|
+
}
|
|
1262
|
+
})));
|
|
1263
|
+
__classPrivateFieldSet(this, _KeyringController_keyrings, validKeyrings, "f");
|
|
1264
|
+
});
|
|
1265
|
+
}, _KeyringController_checkForDuplicate = function _KeyringController_checkForDuplicate(type, newAccountArray) {
|
|
1266
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1267
|
+
const accounts = yield this.getAccounts();
|
|
1268
|
+
switch (type) {
|
|
1269
|
+
case KeyringTypes.simple: {
|
|
1270
|
+
const isIncluded = Boolean(accounts.find((key) => newAccountArray[0] &&
|
|
1271
|
+
(key === newAccountArray[0] ||
|
|
1272
|
+
key === (0, utils_1.remove0x)(newAccountArray[0]))));
|
|
1273
|
+
if (isIncluded) {
|
|
1274
|
+
throw new Error(constants_1.KeyringControllerError.DuplicatedAccount);
|
|
1275
|
+
}
|
|
1276
|
+
return newAccountArray;
|
|
1277
|
+
}
|
|
1278
|
+
default: {
|
|
1279
|
+
return newAccountArray;
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
});
|
|
1283
|
+
}, _KeyringController_setUnlocked = function _KeyringController_setUnlocked() {
|
|
1284
|
+
this.update((state) => {
|
|
1285
|
+
state.isUnlocked = true;
|
|
1286
|
+
});
|
|
902
1287
|
this.messagingSystem.publish(`${name}:unlock`);
|
|
903
1288
|
}, _KeyringController_getMemState = function _KeyringController_getMemState() {
|
|
904
1289
|
return {
|