@metamask-previews/keyring-controller 26.0.0-preview-1e1b476aa → 26.0.0-preview-d3cc77e
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 +7 -0
- package/dist/KeyringController.cjs +54 -6
- package/dist/KeyringController.cjs.map +1 -1
- package/dist/KeyringController.d.cts.map +1 -1
- package/dist/KeyringController.d.mts.map +1 -1
- package/dist/KeyringController.mjs +54 -6
- package/dist/KeyringController.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Automatically remove and destroy non-primary keyrings whose last account is removed during a `withKeyring` or `withKeyringV2` callback ([#8951](https://github.com/MetaMask/core/pull/8951))
|
|
13
|
+
- Previously, draining a keyring of all its accounts via these APIs left an empty keyring entry in `state.keyrings` and persisted it in the vault.
|
|
14
|
+
- Pre-existing empty keyrings (e.g. those created intentionally via `addNewKeyring` without subsequent account creation) are still preserved, matching the behavior of `removeAccount`.
|
|
15
|
+
- The primary keyring is never auto-removed, even if drained; this preserves the existing `removeAccount` invariant against losing the primary keyring.
|
|
16
|
+
|
|
10
17
|
## [26.0.0]
|
|
11
18
|
|
|
12
19
|
### Changed
|
|
@@ -36,7 +36,7 @@ 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, _KeyringController_keyringV2Builders, _KeyringController_encryptor, _KeyringController_keyrings, _KeyringController_unsupportedKeyrings, _KeyringController_encryptionKey, _KeyringController_getKeyringForAccount, _KeyringController_getKeyringEntryForAccount, _KeyringController_findKeyringIndexForAccount, _KeyringController_getKeyringEntriesByType, _KeyringController_assertNoUnsafeDirectKeyringAccess, _KeyringController_registerMessageHandlers, _KeyringController_selectKeyringEntry, _KeyringController_getKeyringById, _KeyringController_getKeyringEntryById, _KeyringController_getKeyringByIdOrDefault, _KeyringController_getKeyringMetadata, _KeyringController_getKeyringBuilderForType, _KeyringController_getKeyringV2BuilderForType, _KeyringController_createNewVaultWithKeyring, _KeyringController_deriveAndSetEncryptionKey, _KeyringController_setEncryptionKey, _KeyringController_verifySeedPhrase, _KeyringController_getUpdatedKeyrings, _KeyringController_getSerializedKeyrings, _KeyringController_getSessionState, _KeyringController_restoreSerializedKeyrings, _KeyringController_unlockKeyrings, _KeyringController_updateVault, _KeyringController_isNewEncryptionAvailable, _KeyringController_getAccountsFromKeyrings, _KeyringController_createKeyringWithFirstAccount, _KeyringController_newKeyring, _KeyringController_createKeyring, _KeyringController_clearKeyrings, _KeyringController_restoreKeyring, _KeyringController_destroyKeyring, _KeyringController_assertNoDuplicateAccounts, _KeyringController_setUnlocked, _KeyringController_assertIsUnlocked, _KeyringController_persistOrRollback, _KeyringController_withRollback, _KeyringController_assertControllerMutexIsLocked, _KeyringController_assertNotRemovingPrimaryKeyring, _KeyringController_withControllerLock, _KeyringController_withVaultLock;
|
|
39
|
+
var _KeyringController_instances, _KeyringController_controllerOperationMutex, _KeyringController_vaultOperationMutex, _KeyringController_keyringBuilders, _KeyringController_keyringV2Builders, _KeyringController_encryptor, _KeyringController_keyrings, _KeyringController_unsupportedKeyrings, _KeyringController_encryptionKey, _KeyringController_getKeyringForAccount, _KeyringController_getKeyringEntryForAccount, _KeyringController_findKeyringIndexForAccount, _KeyringController_getKeyringEntriesByType, _KeyringController_assertNoUnsafeDirectKeyringAccess, _KeyringController_registerMessageHandlers, _KeyringController_selectKeyringEntry, _KeyringController_getKeyringById, _KeyringController_getKeyringEntryById, _KeyringController_getKeyringByIdOrDefault, _KeyringController_getKeyringMetadata, _KeyringController_getKeyringBuilderForType, _KeyringController_getKeyringV2BuilderForType, _KeyringController_createNewVaultWithKeyring, _KeyringController_deriveAndSetEncryptionKey, _KeyringController_setEncryptionKey, _KeyringController_verifySeedPhrase, _KeyringController_getUpdatedKeyrings, _KeyringController_getSerializedKeyrings, _KeyringController_getSessionState, _KeyringController_restoreSerializedKeyrings, _KeyringController_unlockKeyrings, _KeyringController_updateVault, _KeyringController_isNewEncryptionAvailable, _KeyringController_getAccountsFromKeyrings, _KeyringController_createKeyringWithFirstAccount, _KeyringController_newKeyring, _KeyringController_createKeyring, _KeyringController_cleanUpEmptiedKeyringsAfter, _KeyringController_clearKeyrings, _KeyringController_restoreKeyring, _KeyringController_destroyKeyring, _KeyringController_assertNoDuplicateAccounts, _KeyringController_setUnlocked, _KeyringController_assertIsUnlocked, _KeyringController_persistOrRollback, _KeyringController_withRollback, _KeyringController_assertControllerMutexIsLocked, _KeyringController_isPrimaryKeyring, _KeyringController_assertNotRemovingPrimaryKeyring, _KeyringController_withControllerLock, _KeyringController_withVaultLock;
|
|
40
40
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
41
|
exports.KeyringController = exports.getDefaultKeyringState = exports.keyringBuilderFactory = exports.SignTypedDataVersion = exports.AccountImportStrategy = exports.isCustodyKeyring = exports.KeyringTypes = void 0;
|
|
42
42
|
const util_1 = require("@ethereumjs/util");
|
|
@@ -1026,7 +1026,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
1026
1026
|
}
|
|
1027
1027
|
const { metadata } = entry;
|
|
1028
1028
|
const keyring = entry.keyring;
|
|
1029
|
-
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertNoUnsafeDirectKeyringAccess).call(this, await operation({ keyring, metadata }), keyring);
|
|
1029
|
+
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertNoUnsafeDirectKeyringAccess).call(this, await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_cleanUpEmptiedKeyringsAfter).call(this, async () => operation({ keyring, metadata })), keyring);
|
|
1030
1030
|
});
|
|
1031
1031
|
}
|
|
1032
1032
|
/**
|
|
@@ -1111,10 +1111,10 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
1111
1111
|
}
|
|
1112
1112
|
const { metadata } = entry;
|
|
1113
1113
|
const keyring = entry.keyringV2;
|
|
1114
|
-
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertNoUnsafeDirectKeyringAccess).call(this, await operation({
|
|
1114
|
+
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertNoUnsafeDirectKeyringAccess).call(this, await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_cleanUpEmptiedKeyringsAfter).call(this, async () => operation({
|
|
1115
1115
|
keyring,
|
|
1116
1116
|
metadata,
|
|
1117
|
-
}), keyring);
|
|
1117
|
+
})), keyring);
|
|
1118
1118
|
});
|
|
1119
1119
|
}
|
|
1120
1120
|
/**
|
|
@@ -1729,6 +1729,52 @@ async function _KeyringController_createKeyring(type, data, metadata) {
|
|
|
1729
1729
|
keyringV2 = keyringBuilderV2(keyring, keyringMetadata);
|
|
1730
1730
|
}
|
|
1731
1731
|
return { keyring, keyringV2, metadata: keyringMetadata };
|
|
1732
|
+
}, _KeyringController_cleanUpEmptiedKeyringsAfter =
|
|
1733
|
+
/**
|
|
1734
|
+
* Run the given operation and afterwards clean up any keyring whose
|
|
1735
|
+
* account list transitioned from non-empty to empty during the operation.
|
|
1736
|
+
*
|
|
1737
|
+
* This mirrors the cleanup behavior of {@link KeyringController.removeAccount}
|
|
1738
|
+
* for code paths where the consumer mutates a keyring directly via
|
|
1739
|
+
* {@link KeyringController.withKeyring} or
|
|
1740
|
+
* {@link KeyringController.withKeyringV2}: if the consumer drains the last
|
|
1741
|
+
* account from a keyring, the now-empty keyring is removed from
|
|
1742
|
+
* {@link KeyringController.#keyrings} and destroyed before persistence runs.
|
|
1743
|
+
*
|
|
1744
|
+
* Pre-existing empty keyrings (e.g. those created intentionally via
|
|
1745
|
+
* {@link KeyringController.addNewKeyring} without subsequent account
|
|
1746
|
+
* creation) are left alone, as are keyrings created within the operation
|
|
1747
|
+
* itself (they are not part of the pre-operation snapshot). The primary
|
|
1748
|
+
* keyring (see {@link KeyringController.#isPrimaryKeyring}) is also preserved
|
|
1749
|
+
* unconditionally to keep `removeAccount`'s primary-keyring invariant intact.
|
|
1750
|
+
*
|
|
1751
|
+
* @param operation - The operation to execute.
|
|
1752
|
+
* @returns The result of the operation.
|
|
1753
|
+
* @template Result - The type of the value resolved by the operation.
|
|
1754
|
+
*/
|
|
1755
|
+
async function _KeyringController_cleanUpEmptiedKeyringsAfter(operation) {
|
|
1756
|
+
// Only the primary keyring exists, which is never auto-removed, so there
|
|
1757
|
+
// is nothing to clean up regardless of what the operation does.
|
|
1758
|
+
if (__classPrivateFieldGet(this, _KeyringController_keyrings, "f").length <= 1) {
|
|
1759
|
+
return operation();
|
|
1760
|
+
}
|
|
1761
|
+
const wasNonEmpty = new WeakSet();
|
|
1762
|
+
await Promise.all(__classPrivateFieldGet(this, _KeyringController_keyrings, "f").map(async ({ keyring }) => {
|
|
1763
|
+
if ((await keyring.getAccounts()).length > 0) {
|
|
1764
|
+
wasNonEmpty.add(keyring);
|
|
1765
|
+
}
|
|
1766
|
+
}));
|
|
1767
|
+
const result = await operation();
|
|
1768
|
+
const isNowEmpty = await Promise.all(__classPrivateFieldGet(this, _KeyringController_keyrings, "f").map(async ({ keyring }) => (await keyring.getAccounts()).length === 0));
|
|
1769
|
+
const emptied = __classPrivateFieldGet(this, _KeyringController_keyrings, "f").filter((entry, index) => !__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_isPrimaryKeyring).call(this, entry, __classPrivateFieldGet(this, _KeyringController_keyrings, "f")) &&
|
|
1770
|
+
wasNonEmpty.has(entry.keyring) &&
|
|
1771
|
+
isNowEmpty[index]);
|
|
1772
|
+
if (emptied.length > 0) {
|
|
1773
|
+
const removed = new Set(emptied);
|
|
1774
|
+
__classPrivateFieldSet(this, _KeyringController_keyrings, __classPrivateFieldGet(this, _KeyringController_keyrings, "f").filter((entry) => !removed.has(entry)), "f");
|
|
1775
|
+
await Promise.all(emptied.map(({ keyring, keyringV2 }) => __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_destroyKeyring).call(this, keyring, keyringV2)));
|
|
1776
|
+
}
|
|
1777
|
+
return result;
|
|
1732
1778
|
}, _KeyringController_clearKeyrings =
|
|
1733
1779
|
/**
|
|
1734
1780
|
* Remove all managed keyrings, destroying all their
|
|
@@ -1865,9 +1911,11 @@ async function _KeyringController_withRollback(callback) {
|
|
|
1865
1911
|
if (!__classPrivateFieldGet(this, _KeyringController_controllerOperationMutex, "f").isLocked()) {
|
|
1866
1912
|
throw new errors_1.KeyringControllerError(constants_1.KeyringControllerErrorMessage.ControllerLockRequired);
|
|
1867
1913
|
}
|
|
1914
|
+
}, _KeyringController_isPrimaryKeyring = function _KeyringController_isPrimaryKeyring(entry, keyrings) {
|
|
1915
|
+
return (keyrings[0] === entry &&
|
|
1916
|
+
entry.keyring.type === KeyringTypes.hd);
|
|
1868
1917
|
}, _KeyringController_assertNotRemovingPrimaryKeyring = function _KeyringController_assertNotRemovingPrimaryKeyring(entry, keyrings) {
|
|
1869
|
-
if (
|
|
1870
|
-
entry.keyring.type === KeyringTypes.hd) {
|
|
1918
|
+
if (__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_isPrimaryKeyring).call(this, entry, keyrings)) {
|
|
1871
1919
|
throw new errors_1.KeyringControllerError(constants_1.KeyringControllerErrorMessage.CannotRemovePrimaryKeyring);
|
|
1872
1920
|
}
|
|
1873
1921
|
}, _KeyringController_withControllerLock =
|