@metamask-previews/keyring-controller 19.0.5-preview-37653b42 → 19.0.5-preview-fbd9878
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 +28 -98
- package/dist/KeyringController.cjs.map +1 -1
- package/dist/KeyringController.d.cts +29 -40
- package/dist/KeyringController.d.cts.map +1 -1
- package/dist/KeyringController.d.mts +29 -40
- package/dist/KeyringController.d.mts.map +1 -1
- package/dist/KeyringController.mjs +30 -97
- package/dist/KeyringController.mjs.map +1 -1
- package/dist/constants.cjs +0 -1
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +1 -2
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.mts +1 -2
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.mjs +0 -1
- package/dist/constants.mjs.map +1 -1
- package/package.json +2 -2
|
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
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");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var _KeyringController_instances, _KeyringController_controllerOperationMutex, _KeyringController_vaultOperationMutex, _KeyringController_keyringBuilders,
|
|
12
|
+
var _KeyringController_instances, _KeyringController_controllerOperationMutex, _KeyringController_vaultOperationMutex, _KeyringController_keyringBuilders, _KeyringController_unsupportedKeyrings, _KeyringController_encryptor, _KeyringController_cacheEncryptionKey, _KeyringController_keyrings, _KeyringController_password, _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;
|
|
13
13
|
function $importDefault(module) {
|
|
14
14
|
if (module?.__esModule) {
|
|
15
15
|
return module.default;
|
|
@@ -19,7 +19,8 @@ function $importDefault(module) {
|
|
|
19
19
|
import { isValidPrivate, toBuffer, getBinarySize } from "@ethereumjs/util";
|
|
20
20
|
import { BaseController } from "@metamask/base-controller";
|
|
21
21
|
import * as encryptorUtils from "@metamask/browser-passworder";
|
|
22
|
-
import HDKeyring from "@metamask/eth-hd-keyring";
|
|
22
|
+
import $HDKeyring from "@metamask/eth-hd-keyring";
|
|
23
|
+
const HDKeyring = $importDefault($HDKeyring);
|
|
23
24
|
import { normalize as ethNormalize } from "@metamask/eth-sig-util";
|
|
24
25
|
import $SimpleKeyring from "@metamask/eth-simple-keyring";
|
|
25
26
|
const SimpleKeyring = $importDefault($SimpleKeyring);
|
|
@@ -35,31 +36,18 @@ const name = 'KeyringController';
|
|
|
35
36
|
*/
|
|
36
37
|
export var KeyringTypes;
|
|
37
38
|
(function (KeyringTypes) {
|
|
38
|
-
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
39
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
40
39
|
KeyringTypes["simple"] = "Simple Key Pair";
|
|
41
|
-
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
42
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
43
40
|
KeyringTypes["hd"] = "HD Key Tree";
|
|
44
|
-
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
45
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
46
41
|
KeyringTypes["qr"] = "QR Hardware Wallet Device";
|
|
47
|
-
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
48
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
49
42
|
KeyringTypes["trezor"] = "Trezor Hardware";
|
|
50
|
-
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
51
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
52
43
|
KeyringTypes["ledger"] = "Ledger Hardware";
|
|
53
|
-
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
54
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
55
44
|
KeyringTypes["lattice"] = "Lattice Hardware";
|
|
56
|
-
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
57
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
58
45
|
KeyringTypes["snap"] = "Snap Keyring";
|
|
59
46
|
})(KeyringTypes || (KeyringTypes = {}));
|
|
60
47
|
/**
|
|
61
48
|
* Custody keyring types are a special case, as they are not a single type
|
|
62
49
|
* but they all start with the prefix "Custody".
|
|
50
|
+
*
|
|
63
51
|
* @param keyringType - The type of the keyring.
|
|
64
52
|
* @returns Whether the keyring type is a custody keyring.
|
|
65
53
|
*/
|
|
@@ -71,11 +59,7 @@ export const isCustodyKeyring = (keyringType) => {
|
|
|
71
59
|
*/
|
|
72
60
|
export var AccountImportStrategy;
|
|
73
61
|
(function (AccountImportStrategy) {
|
|
74
|
-
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
75
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
76
62
|
AccountImportStrategy["privateKey"] = "privateKey";
|
|
77
|
-
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
78
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
79
63
|
AccountImportStrategy["json"] = "json";
|
|
80
64
|
})(AccountImportStrategy || (AccountImportStrategy = {}));
|
|
81
65
|
/**
|
|
@@ -174,35 +158,15 @@ function isSerializedKeyringsArray(array) {
|
|
|
174
158
|
* @param keyring - The keyring to display.
|
|
175
159
|
* @returns A keyring display object, with type and accounts properties.
|
|
176
160
|
*/
|
|
177
|
-
|
|
161
|
+
async function displayForKeyring(keyring) {
|
|
178
162
|
const accounts = await keyring.getAccounts();
|
|
179
163
|
return {
|
|
180
164
|
type: keyring.type,
|
|
181
165
|
// Cast to `string[]` here is safe here because `accounts` has no nullish
|
|
182
166
|
// values, and `normalize` returns `string` unless given a nullish value
|
|
183
167
|
accounts: accounts.map(normalize),
|
|
184
|
-
// @ts-expect-error TODO: update type in @metamask/utils
|
|
185
|
-
fingerprint: await keyring?.getFingerprint?.(),
|
|
186
168
|
};
|
|
187
169
|
}
|
|
188
|
-
/**
|
|
189
|
-
* Retrieves a keyring from an array of keyrings based on its fingerprint.
|
|
190
|
-
*
|
|
191
|
-
* @param keyrings - Array of keyrings to search through.
|
|
192
|
-
* @param fingerprint - The fingerprint to match against.
|
|
193
|
-
* @returns Promise resolving to the matching keyring, or undefined if not found.
|
|
194
|
-
*/
|
|
195
|
-
export async function getKeyringByFingerprint(keyrings, fingerprint) {
|
|
196
|
-
// Do not attempt to return a keyring if the fingerprint is not provided
|
|
197
|
-
if (!fingerprint) {
|
|
198
|
-
return undefined;
|
|
199
|
-
}
|
|
200
|
-
const fingerprints = await Promise.all(
|
|
201
|
-
// @ts-expect-error TODO: update type in @metamask/utils
|
|
202
|
-
keyrings.map((kr) => kr?.getFingerprint?.()));
|
|
203
|
-
const index = fingerprints.indexOf(fingerprint);
|
|
204
|
-
return keyrings[index];
|
|
205
|
-
}
|
|
206
170
|
/**
|
|
207
171
|
* Check if address is an ethereum address
|
|
208
172
|
*
|
|
@@ -273,11 +237,11 @@ export class KeyringController extends BaseController {
|
|
|
273
237
|
_KeyringController_controllerOperationMutex.set(this, new Mutex());
|
|
274
238
|
_KeyringController_vaultOperationMutex.set(this, new Mutex());
|
|
275
239
|
_KeyringController_keyringBuilders.set(this, void 0);
|
|
276
|
-
_KeyringController_keyrings.set(this, void 0);
|
|
277
240
|
_KeyringController_unsupportedKeyrings.set(this, void 0);
|
|
278
|
-
_KeyringController_password.set(this, void 0);
|
|
279
241
|
_KeyringController_encryptor.set(this, void 0);
|
|
280
242
|
_KeyringController_cacheEncryptionKey.set(this, void 0);
|
|
243
|
+
_KeyringController_keyrings.set(this, void 0);
|
|
244
|
+
_KeyringController_password.set(this, void 0);
|
|
281
245
|
_KeyringController_qrKeyringStateListener.set(this, void 0);
|
|
282
246
|
__classPrivateFieldSet(this, _KeyringController_keyringBuilders, keyringBuilders
|
|
283
247
|
? keyringBuilders.concat(defaultKeyringBuilders)
|
|
@@ -379,6 +343,7 @@ export class KeyringController extends BaseController {
|
|
|
379
343
|
* If there is a pre-existing locked vault, it will be replaced.
|
|
380
344
|
*
|
|
381
345
|
* @param password - Password to unlock the new vault.
|
|
346
|
+
* @returns Promise resolving when the operation ends successfully.
|
|
382
347
|
*/
|
|
383
348
|
async createNewVaultAndKeychain(password) {
|
|
384
349
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
|
|
@@ -428,27 +393,12 @@ export class KeyringController extends BaseController {
|
|
|
428
393
|
* Gets the seed phrase of the HD keyring.
|
|
429
394
|
*
|
|
430
395
|
* @param password - Password of the keyring.
|
|
431
|
-
* @param keyringId - The keyring identifier.
|
|
432
396
|
* @returns Promise resolving to the seed phrase.
|
|
433
397
|
*/
|
|
434
|
-
async exportSeedPhrase(password
|
|
398
|
+
async exportSeedPhrase(password) {
|
|
435
399
|
await this.verifyPassword(password);
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
keyring = await getKeyringByFingerprint(__classPrivateFieldGet(this, _KeyringController_keyrings, "f"), keyringId);
|
|
439
|
-
if (!keyring) {
|
|
440
|
-
throw new Error(KeyringControllerError.KeyringNotFound);
|
|
441
|
-
}
|
|
442
|
-
if (keyring.type !== KeyringTypes.hd) {
|
|
443
|
-
throw new Error(KeyringControllerError.UnsupportedExportSeedPhrase);
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
else {
|
|
447
|
-
// There will always be an HD keyring
|
|
448
|
-
keyring = this.getKeyringsByType(KeyringTypes.hd)[0];
|
|
449
|
-
}
|
|
450
|
-
assertHasUint8ArrayMnemonic(keyring);
|
|
451
|
-
return keyring.mnemonic;
|
|
400
|
+
assertHasUint8ArrayMnemonic(__classPrivateFieldGet(this, _KeyringController_keyrings, "f")[0]);
|
|
401
|
+
return __classPrivateFieldGet(this, _KeyringController_keyrings, "f")[0].mnemonic;
|
|
452
402
|
}
|
|
453
403
|
/**
|
|
454
404
|
* Gets the private key from the keyring controlling an address.
|
|
@@ -574,7 +524,7 @@ export class KeyringController extends BaseController {
|
|
|
574
524
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
|
|
575
525
|
let privateKey;
|
|
576
526
|
switch (strategy) {
|
|
577
|
-
case
|
|
527
|
+
case AccountImportStrategy.privateKey:
|
|
578
528
|
const [importedKey] = args;
|
|
579
529
|
if (!importedKey) {
|
|
580
530
|
throw new Error('Cannot import an empty key.');
|
|
@@ -594,7 +544,7 @@ export class KeyringController extends BaseController {
|
|
|
594
544
|
}
|
|
595
545
|
privateKey = remove0x(prefixed);
|
|
596
546
|
break;
|
|
597
|
-
case
|
|
547
|
+
case AccountImportStrategy.json:
|
|
598
548
|
let wallet;
|
|
599
549
|
const [input, password] = args;
|
|
600
550
|
try {
|
|
@@ -606,7 +556,7 @@ export class KeyringController extends BaseController {
|
|
|
606
556
|
privateKey = bytesToHex(wallet.getPrivateKey());
|
|
607
557
|
break;
|
|
608
558
|
default:
|
|
609
|
-
throw new Error(`Unexpected import strategy: '${strategy}'`);
|
|
559
|
+
throw new Error(`Unexpected import strategy: '${String(strategy)}'`);
|
|
610
560
|
}
|
|
611
561
|
const newKeyring = (await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_newKeyring).call(this, KeyringTypes.simple, [
|
|
612
562
|
privateKey,
|
|
@@ -631,7 +581,6 @@ export class KeyringController extends BaseController {
|
|
|
631
581
|
}
|
|
632
582
|
// The `removeAccount` method of snaps keyring is async. We have to update
|
|
633
583
|
// the interface of the other keyrings to be async as well.
|
|
634
|
-
// eslint-disable-next-line @typescript-eslint/await-thenable
|
|
635
584
|
// FIXME: We do cast to `Hex` to makes the type checker happy here, and
|
|
636
585
|
// because `Keyring<State>.removeAccount` requires address to be `Hex`. Those
|
|
637
586
|
// type would need to be updated for a full non-EVM support.
|
|
@@ -862,9 +811,6 @@ export class KeyringController extends BaseController {
|
|
|
862
811
|
if ('address' in selector) {
|
|
863
812
|
keyring = (await this.getKeyringForAccount(selector.address));
|
|
864
813
|
}
|
|
865
|
-
else if ('fingerprint' in selector) {
|
|
866
|
-
keyring = (await getKeyringByFingerprint(__classPrivateFieldGet(this, _KeyringController_keyrings, "f"), selector.fingerprint));
|
|
867
|
-
}
|
|
868
814
|
else {
|
|
869
815
|
keyring = this.getKeyringsByType(selector.type)[selector.index || 0];
|
|
870
816
|
if (!keyring && options.createIfMissing) {
|
|
@@ -1069,7 +1015,7 @@ export class KeyringController extends BaseController {
|
|
|
1069
1015
|
});
|
|
1070
1016
|
}
|
|
1071
1017
|
}
|
|
1072
|
-
_KeyringController_controllerOperationMutex = new WeakMap(), _KeyringController_vaultOperationMutex = new WeakMap(), _KeyringController_keyringBuilders = new WeakMap(),
|
|
1018
|
+
_KeyringController_controllerOperationMutex = new WeakMap(), _KeyringController_vaultOperationMutex = new WeakMap(), _KeyringController_keyringBuilders = new WeakMap(), _KeyringController_unsupportedKeyrings = new WeakMap(), _KeyringController_encryptor = new WeakMap(), _KeyringController_cacheEncryptionKey = new WeakMap(), _KeyringController_keyrings = new WeakMap(), _KeyringController_password = new WeakMap(), _KeyringController_qrKeyringStateListener = new WeakMap(), _KeyringController_instances = new WeakSet(), _KeyringController_registerMessageHandlers = function _KeyringController_registerMessageHandlers() {
|
|
1073
1019
|
this.messagingSystem.registerActionHandler(`${name}:signMessage`, this.signMessage.bind(this));
|
|
1074
1020
|
this.messagingSystem.registerActionHandler(`${name}:signPersonalMessage`, this.signPersonalMessage.bind(this));
|
|
1075
1021
|
this.messagingSystem.registerActionHandler(`${name}:signTypedMessage`, this.signTypedMessage.bind(this));
|
|
@@ -1404,9 +1350,6 @@ async function _KeyringController_newKeyring(type, data) {
|
|
|
1404
1350
|
// NOTE: Not all keyrings implement this method in a asynchronous-way. Using `await` for
|
|
1405
1351
|
// non-thenable will still be valid (despite not being really useful). It allows us to cover both
|
|
1406
1352
|
// cases and allow retro-compatibility too.
|
|
1407
|
-
// FIXME: For some reason, it seems that eslint is complaining about this call being non-thenable
|
|
1408
|
-
// even though it is... For now, we just disable it:
|
|
1409
|
-
// eslint-disable-next-line @typescript-eslint/await-thenable
|
|
1410
1353
|
await keyring.generateRandomMnemonic();
|
|
1411
1354
|
await keyring.addAccounts(1);
|
|
1412
1355
|
}
|
|
@@ -1521,14 +1464,12 @@ async function _KeyringController_checkForDuplicate(type, newAccountArray) {
|
|
|
1521
1464
|
* and save the keyrings to state after it, or rollback to their
|
|
1522
1465
|
* previous state in case of error.
|
|
1523
1466
|
*
|
|
1524
|
-
* @param
|
|
1467
|
+
* @param callback - The function to execute.
|
|
1525
1468
|
* @returns The result of the function.
|
|
1526
1469
|
*/
|
|
1527
|
-
|
|
1528
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1529
|
-
async function _KeyringController_persistOrRollback(fn) {
|
|
1470
|
+
async function _KeyringController_persistOrRollback(callback) {
|
|
1530
1471
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async ({ releaseLock }) => {
|
|
1531
|
-
const callbackResult = await
|
|
1472
|
+
const callbackResult = await callback({ releaseLock });
|
|
1532
1473
|
// State is committed only if the operation is successful
|
|
1533
1474
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
|
|
1534
1475
|
return callbackResult;
|
|
@@ -1538,17 +1479,15 @@ async function _KeyringController_persistOrRollback(fn) {
|
|
|
1538
1479
|
* Execute the given function after acquiring the controller lock
|
|
1539
1480
|
* and rollback keyrings and password states in case of error.
|
|
1540
1481
|
*
|
|
1541
|
-
* @param
|
|
1482
|
+
* @param callback - The function to execute atomically.
|
|
1542
1483
|
* @returns The result of the function.
|
|
1543
1484
|
*/
|
|
1544
|
-
|
|
1545
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1546
|
-
async function _KeyringController_withRollback(fn) {
|
|
1485
|
+
async function _KeyringController_withRollback(callback) {
|
|
1547
1486
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async ({ releaseLock }) => {
|
|
1548
1487
|
const currentSerializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
|
|
1549
1488
|
const currentPassword = __classPrivateFieldGet(this, _KeyringController_password, "f");
|
|
1550
1489
|
try {
|
|
1551
|
-
return await
|
|
1490
|
+
return await callback({ releaseLock });
|
|
1552
1491
|
}
|
|
1553
1492
|
catch (e) {
|
|
1554
1493
|
// Keyrings and password are restored to their previous state
|
|
@@ -1571,13 +1510,11 @@ async function _KeyringController_withRollback(fn) {
|
|
|
1571
1510
|
* controller and that changes its state is executed in a mutually exclusive way,
|
|
1572
1511
|
* preventing unsafe concurrent access that could lead to unpredictable behavior.
|
|
1573
1512
|
*
|
|
1574
|
-
* @param
|
|
1513
|
+
* @param callback - The function to execute while the controller mutex is locked.
|
|
1575
1514
|
* @returns The result of the function.
|
|
1576
1515
|
*/
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
async function _KeyringController_withControllerLock(fn) {
|
|
1580
|
-
return withLock(__classPrivateFieldGet(this, _KeyringController_controllerOperationMutex, "f"), fn);
|
|
1516
|
+
async function _KeyringController_withControllerLock(callback) {
|
|
1517
|
+
return withLock(__classPrivateFieldGet(this, _KeyringController_controllerOperationMutex, "f"), callback);
|
|
1581
1518
|
}, _KeyringController_withVaultLock =
|
|
1582
1519
|
/**
|
|
1583
1520
|
* Lock the vault mutex before executing the given function,
|
|
@@ -1587,14 +1524,12 @@ async function _KeyringController_withControllerLock(fn) {
|
|
|
1587
1524
|
* This ensures that each operation that interacts with the vault
|
|
1588
1525
|
* is executed in a mutually exclusive way.
|
|
1589
1526
|
*
|
|
1590
|
-
* @param
|
|
1527
|
+
* @param callback - The function to execute while the vault mutex is locked.
|
|
1591
1528
|
* @returns The result of the function.
|
|
1592
1529
|
*/
|
|
1593
|
-
|
|
1594
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1595
|
-
async function _KeyringController_withVaultLock(fn) {
|
|
1530
|
+
async function _KeyringController_withVaultLock(callback) {
|
|
1596
1531
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
|
|
1597
|
-
return withLock(__classPrivateFieldGet(this, _KeyringController_vaultOperationMutex, "f"),
|
|
1532
|
+
return withLock(__classPrivateFieldGet(this, _KeyringController_vaultOperationMutex, "f"), callback);
|
|
1598
1533
|
};
|
|
1599
1534
|
/**
|
|
1600
1535
|
* Lock the given mutex before executing the given function,
|
|
@@ -1602,15 +1537,13 @@ async function _KeyringController_withVaultLock(fn) {
|
|
|
1602
1537
|
* error is thrown.
|
|
1603
1538
|
*
|
|
1604
1539
|
* @param mutex - The mutex to lock.
|
|
1605
|
-
* @param
|
|
1540
|
+
* @param callback - The function to execute while the mutex is locked.
|
|
1606
1541
|
* @returns The result of the function.
|
|
1607
1542
|
*/
|
|
1608
|
-
|
|
1609
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1610
|
-
async function withLock(mutex, fn) {
|
|
1543
|
+
async function withLock(mutex, callback) {
|
|
1611
1544
|
const releaseLock = await mutex.acquire();
|
|
1612
1545
|
try {
|
|
1613
|
-
return await
|
|
1546
|
+
return await callback({ releaseLock });
|
|
1614
1547
|
}
|
|
1615
1548
|
finally {
|
|
1616
1549
|
releaseLock();
|