@metamask-previews/keyring-controller 19.0.5-preview-d21875e1 → 19.0.5-preview-37653b42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/KeyringController.cjs +98 -28
- package/dist/KeyringController.cjs.map +1 -1
- package/dist/KeyringController.d.cts +40 -29
- package/dist/KeyringController.d.cts.map +1 -1
- package/dist/KeyringController.d.mts +40 -29
- package/dist/KeyringController.d.mts.map +1 -1
- package/dist/KeyringController.mjs +97 -30
- package/dist/KeyringController.mjs.map +1 -1
- package/dist/constants.cjs +1 -0
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +2 -1
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.mts +2 -1
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.mjs +1 -0
- package/dist/constants.mjs.map +1 -1
- package/package.json +2 -2
|
@@ -36,9 +36,9 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
36
36
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
37
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
38
|
};
|
|
39
|
-
var _KeyringController_instances, _KeyringController_controllerOperationMutex, _KeyringController_vaultOperationMutex, _KeyringController_keyringBuilders,
|
|
39
|
+
var _KeyringController_instances, _KeyringController_controllerOperationMutex, _KeyringController_vaultOperationMutex, _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_verifySeedPhrase, _KeyringController_getUpdatedKeyrings, _KeyringController_getSerializedKeyrings, _KeyringController_restoreSerializedKeyrings, _KeyringController_unlockKeyrings, _KeyringController_updateVault, _KeyringController_getAccountsFromKeyrings, _KeyringController_createKeyringWithFirstAccount, _KeyringController_newKeyring, _KeyringController_clearKeyrings, _KeyringController_restoreKeyring, _KeyringController_destroyKeyring, _KeyringController_removeEmptyKeyrings, _KeyringController_checkForDuplicate, _KeyringController_setUnlocked, _KeyringController_persistOrRollback, _KeyringController_withRollback, _KeyringController_assertControllerMutexIsLocked, _KeyringController_withControllerLock, _KeyringController_withVaultLock;
|
|
40
40
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
-
exports.KeyringController = exports.getDefaultKeyringState = exports.keyringBuilderFactory = exports.SignTypedDataVersion = exports.AccountImportStrategy = exports.isCustodyKeyring = exports.KeyringTypes = void 0;
|
|
41
|
+
exports.KeyringController = exports.getKeyringByFingerprint = exports.displayForKeyring = exports.getDefaultKeyringState = exports.keyringBuilderFactory = exports.SignTypedDataVersion = exports.AccountImportStrategy = exports.isCustodyKeyring = exports.KeyringTypes = void 0;
|
|
42
42
|
const util_1 = require("@ethereumjs/util");
|
|
43
43
|
const base_controller_1 = require("@metamask/base-controller");
|
|
44
44
|
const encryptorUtils = __importStar(require("@metamask/browser-passworder"));
|
|
@@ -55,18 +55,31 @@ const name = 'KeyringController';
|
|
|
55
55
|
*/
|
|
56
56
|
var KeyringTypes;
|
|
57
57
|
(function (KeyringTypes) {
|
|
58
|
+
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
59
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
58
60
|
KeyringTypes["simple"] = "Simple Key Pair";
|
|
61
|
+
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
59
63
|
KeyringTypes["hd"] = "HD Key Tree";
|
|
64
|
+
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
60
66
|
KeyringTypes["qr"] = "QR Hardware Wallet Device";
|
|
67
|
+
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
61
69
|
KeyringTypes["trezor"] = "Trezor Hardware";
|
|
70
|
+
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
62
72
|
KeyringTypes["ledger"] = "Ledger Hardware";
|
|
73
|
+
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
63
75
|
KeyringTypes["lattice"] = "Lattice Hardware";
|
|
76
|
+
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
77
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
64
78
|
KeyringTypes["snap"] = "Snap Keyring";
|
|
65
79
|
})(KeyringTypes || (exports.KeyringTypes = KeyringTypes = {}));
|
|
66
80
|
/**
|
|
67
81
|
* Custody keyring types are a special case, as they are not a single type
|
|
68
82
|
* but they all start with the prefix "Custody".
|
|
69
|
-
*
|
|
70
83
|
* @param keyringType - The type of the keyring.
|
|
71
84
|
* @returns Whether the keyring type is a custody keyring.
|
|
72
85
|
*/
|
|
@@ -79,7 +92,11 @@ exports.isCustodyKeyring = isCustodyKeyring;
|
|
|
79
92
|
*/
|
|
80
93
|
var AccountImportStrategy;
|
|
81
94
|
(function (AccountImportStrategy) {
|
|
95
|
+
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
96
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
82
97
|
AccountImportStrategy["privateKey"] = "privateKey";
|
|
98
|
+
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
83
100
|
AccountImportStrategy["json"] = "json";
|
|
84
101
|
})(AccountImportStrategy || (exports.AccountImportStrategy = AccountImportStrategy = {}));
|
|
85
102
|
/**
|
|
@@ -187,8 +204,30 @@ async function displayForKeyring(keyring) {
|
|
|
187
204
|
// Cast to `string[]` here is safe here because `accounts` has no nullish
|
|
188
205
|
// values, and `normalize` returns `string` unless given a nullish value
|
|
189
206
|
accounts: accounts.map(normalize),
|
|
207
|
+
// @ts-expect-error TODO: update type in @metamask/utils
|
|
208
|
+
fingerprint: await keyring?.getFingerprint?.(),
|
|
190
209
|
};
|
|
191
210
|
}
|
|
211
|
+
exports.displayForKeyring = displayForKeyring;
|
|
212
|
+
/**
|
|
213
|
+
* Retrieves a keyring from an array of keyrings based on its fingerprint.
|
|
214
|
+
*
|
|
215
|
+
* @param keyrings - Array of keyrings to search through.
|
|
216
|
+
* @param fingerprint - The fingerprint to match against.
|
|
217
|
+
* @returns Promise resolving to the matching keyring, or undefined if not found.
|
|
218
|
+
*/
|
|
219
|
+
async function getKeyringByFingerprint(keyrings, fingerprint) {
|
|
220
|
+
// Do not attempt to return a keyring if the fingerprint is not provided
|
|
221
|
+
if (!fingerprint) {
|
|
222
|
+
return undefined;
|
|
223
|
+
}
|
|
224
|
+
const fingerprints = await Promise.all(
|
|
225
|
+
// @ts-expect-error TODO: update type in @metamask/utils
|
|
226
|
+
keyrings.map((kr) => kr?.getFingerprint?.()));
|
|
227
|
+
const index = fingerprints.indexOf(fingerprint);
|
|
228
|
+
return keyrings[index];
|
|
229
|
+
}
|
|
230
|
+
exports.getKeyringByFingerprint = getKeyringByFingerprint;
|
|
192
231
|
/**
|
|
193
232
|
* Check if address is an ethereum address
|
|
194
233
|
*
|
|
@@ -259,11 +298,11 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
259
298
|
_KeyringController_controllerOperationMutex.set(this, new async_mutex_1.Mutex());
|
|
260
299
|
_KeyringController_vaultOperationMutex.set(this, new async_mutex_1.Mutex());
|
|
261
300
|
_KeyringController_keyringBuilders.set(this, void 0);
|
|
301
|
+
_KeyringController_keyrings.set(this, void 0);
|
|
262
302
|
_KeyringController_unsupportedKeyrings.set(this, void 0);
|
|
303
|
+
_KeyringController_password.set(this, void 0);
|
|
263
304
|
_KeyringController_encryptor.set(this, void 0);
|
|
264
305
|
_KeyringController_cacheEncryptionKey.set(this, void 0);
|
|
265
|
-
_KeyringController_keyrings.set(this, void 0);
|
|
266
|
-
_KeyringController_password.set(this, void 0);
|
|
267
306
|
_KeyringController_qrKeyringStateListener.set(this, void 0);
|
|
268
307
|
__classPrivateFieldSet(this, _KeyringController_keyringBuilders, keyringBuilders
|
|
269
308
|
? keyringBuilders.concat(defaultKeyringBuilders)
|
|
@@ -365,7 +404,6 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
365
404
|
* If there is a pre-existing locked vault, it will be replaced.
|
|
366
405
|
*
|
|
367
406
|
* @param password - Password to unlock the new vault.
|
|
368
|
-
* @returns Promise resolving when the operation ends successfully.
|
|
369
407
|
*/
|
|
370
408
|
async createNewVaultAndKeychain(password) {
|
|
371
409
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
|
|
@@ -415,12 +453,27 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
415
453
|
* Gets the seed phrase of the HD keyring.
|
|
416
454
|
*
|
|
417
455
|
* @param password - Password of the keyring.
|
|
456
|
+
* @param keyringId - The keyring identifier.
|
|
418
457
|
* @returns Promise resolving to the seed phrase.
|
|
419
458
|
*/
|
|
420
|
-
async exportSeedPhrase(password) {
|
|
459
|
+
async exportSeedPhrase(password, keyringId) {
|
|
421
460
|
await this.verifyPassword(password);
|
|
422
|
-
|
|
423
|
-
|
|
461
|
+
let keyring;
|
|
462
|
+
if (keyringId) {
|
|
463
|
+
keyring = await getKeyringByFingerprint(__classPrivateFieldGet(this, _KeyringController_keyrings, "f"), keyringId);
|
|
464
|
+
if (!keyring) {
|
|
465
|
+
throw new Error(constants_1.KeyringControllerError.KeyringNotFound);
|
|
466
|
+
}
|
|
467
|
+
if (keyring.type !== KeyringTypes.hd) {
|
|
468
|
+
throw new Error(constants_1.KeyringControllerError.UnsupportedExportSeedPhrase);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
else {
|
|
472
|
+
// There will always be an HD keyring
|
|
473
|
+
keyring = this.getKeyringsByType(KeyringTypes.hd)[0];
|
|
474
|
+
}
|
|
475
|
+
assertHasUint8ArrayMnemonic(keyring);
|
|
476
|
+
return keyring.mnemonic;
|
|
424
477
|
}
|
|
425
478
|
/**
|
|
426
479
|
* Gets the private key from the keyring controlling an address.
|
|
@@ -546,7 +599,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
546
599
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
|
|
547
600
|
let privateKey;
|
|
548
601
|
switch (strategy) {
|
|
549
|
-
case
|
|
602
|
+
case 'privateKey':
|
|
550
603
|
const [importedKey] = args;
|
|
551
604
|
if (!importedKey) {
|
|
552
605
|
throw new Error('Cannot import an empty key.');
|
|
@@ -566,7 +619,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
566
619
|
}
|
|
567
620
|
privateKey = (0, utils_1.remove0x)(prefixed);
|
|
568
621
|
break;
|
|
569
|
-
case
|
|
622
|
+
case 'json':
|
|
570
623
|
let wallet;
|
|
571
624
|
const [input, password] = args;
|
|
572
625
|
try {
|
|
@@ -578,7 +631,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
578
631
|
privateKey = (0, utils_1.bytesToHex)(wallet.getPrivateKey());
|
|
579
632
|
break;
|
|
580
633
|
default:
|
|
581
|
-
throw new Error(`Unexpected import strategy: '${
|
|
634
|
+
throw new Error(`Unexpected import strategy: '${strategy}'`);
|
|
582
635
|
}
|
|
583
636
|
const newKeyring = (await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_newKeyring).call(this, KeyringTypes.simple, [
|
|
584
637
|
privateKey,
|
|
@@ -603,6 +656,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
603
656
|
}
|
|
604
657
|
// The `removeAccount` method of snaps keyring is async. We have to update
|
|
605
658
|
// the interface of the other keyrings to be async as well.
|
|
659
|
+
// eslint-disable-next-line @typescript-eslint/await-thenable
|
|
606
660
|
// FIXME: We do cast to `Hex` to makes the type checker happy here, and
|
|
607
661
|
// because `Keyring<State>.removeAccount` requires address to be `Hex`. Those
|
|
608
662
|
// type would need to be updated for a full non-EVM support.
|
|
@@ -833,6 +887,9 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
833
887
|
if ('address' in selector) {
|
|
834
888
|
keyring = (await this.getKeyringForAccount(selector.address));
|
|
835
889
|
}
|
|
890
|
+
else if ('fingerprint' in selector) {
|
|
891
|
+
keyring = (await getKeyringByFingerprint(__classPrivateFieldGet(this, _KeyringController_keyrings, "f"), selector.fingerprint));
|
|
892
|
+
}
|
|
836
893
|
else {
|
|
837
894
|
keyring = this.getKeyringsByType(selector.type)[selector.index || 0];
|
|
838
895
|
if (!keyring && options.createIfMissing) {
|
|
@@ -1038,7 +1095,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
1038
1095
|
}
|
|
1039
1096
|
}
|
|
1040
1097
|
exports.KeyringController = KeyringController;
|
|
1041
|
-
_KeyringController_controllerOperationMutex = new WeakMap(), _KeyringController_vaultOperationMutex = new WeakMap(), _KeyringController_keyringBuilders = new WeakMap(),
|
|
1098
|
+
_KeyringController_controllerOperationMutex = new WeakMap(), _KeyringController_vaultOperationMutex = new WeakMap(), _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() {
|
|
1042
1099
|
this.messagingSystem.registerActionHandler(`${name}:signMessage`, this.signMessage.bind(this));
|
|
1043
1100
|
this.messagingSystem.registerActionHandler(`${name}:signPersonalMessage`, this.signPersonalMessage.bind(this));
|
|
1044
1101
|
this.messagingSystem.registerActionHandler(`${name}:signTypedMessage`, this.signTypedMessage.bind(this));
|
|
@@ -1373,6 +1430,9 @@ async function _KeyringController_newKeyring(type, data) {
|
|
|
1373
1430
|
// NOTE: Not all keyrings implement this method in a asynchronous-way. Using `await` for
|
|
1374
1431
|
// non-thenable will still be valid (despite not being really useful). It allows us to cover both
|
|
1375
1432
|
// cases and allow retro-compatibility too.
|
|
1433
|
+
// FIXME: For some reason, it seems that eslint is complaining about this call being non-thenable
|
|
1434
|
+
// even though it is... For now, we just disable it:
|
|
1435
|
+
// eslint-disable-next-line @typescript-eslint/await-thenable
|
|
1376
1436
|
await keyring.generateRandomMnemonic();
|
|
1377
1437
|
await keyring.addAccounts(1);
|
|
1378
1438
|
}
|
|
@@ -1487,12 +1547,14 @@ async function _KeyringController_checkForDuplicate(type, newAccountArray) {
|
|
|
1487
1547
|
* and save the keyrings to state after it, or rollback to their
|
|
1488
1548
|
* previous state in case of error.
|
|
1489
1549
|
*
|
|
1490
|
-
* @param
|
|
1550
|
+
* @param fn - The function to execute.
|
|
1491
1551
|
* @returns The result of the function.
|
|
1492
1552
|
*/
|
|
1493
|
-
|
|
1553
|
+
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
1554
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1555
|
+
async function _KeyringController_persistOrRollback(fn) {
|
|
1494
1556
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async ({ releaseLock }) => {
|
|
1495
|
-
const callbackResult = await
|
|
1557
|
+
const callbackResult = await fn({ releaseLock });
|
|
1496
1558
|
// State is committed only if the operation is successful
|
|
1497
1559
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
|
|
1498
1560
|
return callbackResult;
|
|
@@ -1502,15 +1564,17 @@ async function _KeyringController_persistOrRollback(callback) {
|
|
|
1502
1564
|
* Execute the given function after acquiring the controller lock
|
|
1503
1565
|
* and rollback keyrings and password states in case of error.
|
|
1504
1566
|
*
|
|
1505
|
-
* @param
|
|
1567
|
+
* @param fn - The function to execute atomically.
|
|
1506
1568
|
* @returns The result of the function.
|
|
1507
1569
|
*/
|
|
1508
|
-
|
|
1570
|
+
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
1571
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1572
|
+
async function _KeyringController_withRollback(fn) {
|
|
1509
1573
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async ({ releaseLock }) => {
|
|
1510
1574
|
const currentSerializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
|
|
1511
1575
|
const currentPassword = __classPrivateFieldGet(this, _KeyringController_password, "f");
|
|
1512
1576
|
try {
|
|
1513
|
-
return await
|
|
1577
|
+
return await fn({ releaseLock });
|
|
1514
1578
|
}
|
|
1515
1579
|
catch (e) {
|
|
1516
1580
|
// Keyrings and password are restored to their previous state
|
|
@@ -1533,11 +1597,13 @@ async function _KeyringController_withRollback(callback) {
|
|
|
1533
1597
|
* controller and that changes its state is executed in a mutually exclusive way,
|
|
1534
1598
|
* preventing unsafe concurrent access that could lead to unpredictable behavior.
|
|
1535
1599
|
*
|
|
1536
|
-
* @param
|
|
1600
|
+
* @param fn - The function to execute while the controller mutex is locked.
|
|
1537
1601
|
* @returns The result of the function.
|
|
1538
1602
|
*/
|
|
1539
|
-
|
|
1540
|
-
|
|
1603
|
+
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
1604
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1605
|
+
async function _KeyringController_withControllerLock(fn) {
|
|
1606
|
+
return withLock(__classPrivateFieldGet(this, _KeyringController_controllerOperationMutex, "f"), fn);
|
|
1541
1607
|
}, _KeyringController_withVaultLock =
|
|
1542
1608
|
/**
|
|
1543
1609
|
* Lock the vault mutex before executing the given function,
|
|
@@ -1547,12 +1613,14 @@ async function _KeyringController_withControllerLock(callback) {
|
|
|
1547
1613
|
* This ensures that each operation that interacts with the vault
|
|
1548
1614
|
* is executed in a mutually exclusive way.
|
|
1549
1615
|
*
|
|
1550
|
-
* @param
|
|
1616
|
+
* @param fn - The function to execute while the vault mutex is locked.
|
|
1551
1617
|
* @returns The result of the function.
|
|
1552
1618
|
*/
|
|
1553
|
-
|
|
1619
|
+
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
1620
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1621
|
+
async function _KeyringController_withVaultLock(fn) {
|
|
1554
1622
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
|
|
1555
|
-
return withLock(__classPrivateFieldGet(this, _KeyringController_vaultOperationMutex, "f"),
|
|
1623
|
+
return withLock(__classPrivateFieldGet(this, _KeyringController_vaultOperationMutex, "f"), fn);
|
|
1556
1624
|
};
|
|
1557
1625
|
/**
|
|
1558
1626
|
* Lock the given mutex before executing the given function,
|
|
@@ -1560,13 +1628,15 @@ async function _KeyringController_withVaultLock(callback) {
|
|
|
1560
1628
|
* error is thrown.
|
|
1561
1629
|
*
|
|
1562
1630
|
* @param mutex - The mutex to lock.
|
|
1563
|
-
* @param
|
|
1631
|
+
* @param fn - The function to execute while the mutex is locked.
|
|
1564
1632
|
* @returns The result of the function.
|
|
1565
1633
|
*/
|
|
1566
|
-
|
|
1634
|
+
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
1635
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1636
|
+
async function withLock(mutex, fn) {
|
|
1567
1637
|
const releaseLock = await mutex.acquire();
|
|
1568
1638
|
try {
|
|
1569
|
-
return await
|
|
1639
|
+
return await fn({ releaseLock });
|
|
1570
1640
|
}
|
|
1571
1641
|
finally {
|
|
1572
1642
|
releaseLock();
|