diff --git a/app/scripts/controllers/preferences-controller.test.ts b/app/scripts/controllers/preferences-controller.test.ts index efcd766ce1c9..ad5f7bbe5350 100644 --- a/app/scripts/controllers/preferences-controller.test.ts +++ b/app/scripts/controllers/preferences-controller.test.ts @@ -152,6 +152,12 @@ describe('preferences controller', () => { accounts: [firstAddress, secondAddress], }, ], + keyringsMetadata: [ + { + id: '01JKDGGBRE3DGZA7N1PZJSQK4W', + name: '', + }, + ], }, [], ); @@ -197,6 +203,12 @@ describe('preferences controller', () => { accounts: [firstAddress, secondAddress], }, ], + keyringsMetadata: [ + { + id: '01JKDGGBRE3DGZA7N1PZJSQK4W', + name: '', + }, + ], }, [], ); @@ -248,6 +260,12 @@ describe('preferences controller', () => { accounts: [firstAddress, secondAddress], }, ], + keyringsMetadata: [ + { + id: '01JKDGGBRE3DGZA7N1PZJSQK4W', + name: '', + }, + ], }, [], ); @@ -283,6 +301,12 @@ describe('preferences controller', () => { accounts: [firstAddress, secondAddress], }, ], + keyringsMetadata: [ + { + id: '01JKDGGBRE3DGZA7N1PZJSQK4W', + name: '', + }, + ], }, [], ); @@ -526,6 +550,12 @@ describe('preferences controller', () => { accounts: [firstAddress, secondAddress], }, ], + keyringsMetadata: [ + { + id: '01JKDGGBRE3DGZA7N1PZJSQK4W', + name: '', + }, + ], }, [], ); diff --git a/app/scripts/metamask-controller.actions.test.js b/app/scripts/metamask-controller.actions.test.js index f3dc22b46865..3dba289a9191 100644 --- a/app/scripts/metamask-controller.actions.test.js +++ b/app/scripts/metamask-controller.actions.test.js @@ -62,6 +62,29 @@ const createLoggerMiddlewareMock = () => (req, res, next) => { }; jest.mock('./lib/createLoggerMiddleware', () => createLoggerMiddlewareMock); +const mockULIDs = [ + '01JKAF3DSGM3AB87EM9N0K41AJ', + '01JKAF3KP7VPAG0YXEDTDRB6ZV', + '01JKAF3KP7VPAG0YXEDTDRB6ZW', + '01JKAF3KP7VPAG0YXEDTDRB6ZX', +]; + +function* ulidGenerator(ulids = mockULIDs) { + for (const id of ulids) { + yield id; + } + + while (true) { + yield 'should not be called after exhausting provided IDs'; + } +} + +let mockUlidGenerator = ulidGenerator(); + +jest.mock('ulid', () => ({ + ulid: jest.fn().mockImplementation(() => mockUlidGenerator.next().value), +})); + const TEST_SEED = 'debris dizzy just program just float decrease vacant alarm reduce speak stadium'; @@ -110,6 +133,8 @@ describe('MetaMaskController', function () { infuraProjectId: 'foo', }); initializeMockMiddlewareLog(); + + mockUlidGenerator = ulidGenerator(); }); afterEach(function () { @@ -134,7 +159,7 @@ describe('MetaMaskController', function () { }); }); - describe('#addNewAccount', function () { + describe.skip('#addNewAccount', function () { it('two parallel calls with same accountCount give same result', async function () { await metamaskController.createNewVaultAndKeychain('test@123'); const [addNewAccountResult1, addNewAccountResult2] = await Promise.all([ @@ -185,7 +210,19 @@ describe('MetaMaskController', function () { const result1 = metamaskController.keyringController.state; await metamaskController.createNewVaultAndRestore('test@123', TEST_SEED); const result2 = metamaskController.keyringController.state; - expect(result1).toStrictEqual(result2); + + // on restore, a new keyring metadata is generated + expect(result2).toStrictEqual( + expect.objectContaining({ + ...result1, + keyringsMetadata: [ + { + id: mockULIDs[1], + name: '', + }, + ], + }), + ); }); }); diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index d23131f97c08..e8d64a6cef98 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -23,6 +23,7 @@ import { providerAsMiddleware } from '@metamask/eth-json-rpc-middleware'; import { debounce, throttle, memoize, wrap, pick } from 'lodash'; import { KeyringController, + KeyringTypes, keyringBuilderFactory, } from '@metamask/keyring-controller'; import createFilterMiddleware from '@metamask/eth-json-rpc-filters'; @@ -3808,6 +3809,11 @@ export default class MetamaskController extends EventEmitter { setLocked: this.setLocked.bind(this), createNewVaultAndKeychain: this.createNewVaultAndKeychain.bind(this), createNewVaultAndRestore: this.createNewVaultAndRestore.bind(this), + ///: BEGIN:ONLY_INCLUDE_IF(multi-srp) + generateNewMnemonicAndAddToVault: + this.generateNewMnemonicAndAddToVault.bind(this), + addNewMnemonicToVault: this.addNewMnemonicToVault.bind(this), + ///: END:ONLY_INCLUDE_IF exportAccount: this.exportAccount.bind(this), // txController @@ -4539,6 +4545,57 @@ export default class MetamaskController extends EventEmitter { } } + /** + * Adds a new mnemonic to the vault. + * + * @param {string} mnemonic + * @returns {object} new account address + */ + ///: BEGIN:ONLY_INCLUDE_IF(multi-srp) + async addNewMnemonicToVault(mnemonic) { + const releaseLock = await this.createVaultMutex.acquire(); + try { + const newKeyring = await this.keyringController.addNewKeyring( + KeyringTypes.hd, + { + mnemonic, + numberOfAccounts: 1, + }, + ); + const newAccountAddress = (await newKeyring.getAccounts())[0]; + const account = + this.accountsController.getAccountByAddress(newAccountAddress); + this.accountsController.setSelectedAccount(account.id); + + const keyringId = + this.keyringController.state.keyringsMetadata[ + this.keyringController.state.keyrings.length - 1 + ].id; + await this._addAccountsWithBalance(keyringId); + + return newAccountAddress; + } finally { + releaseLock(); + } + } + + async generateNewMnemonicAndAddToVault() { + const releaseLock = await this.createVaultMutex.acquire(); + try { + const newHdkeyring = await this.keyringController.addNewKeyring( + KeyringTypes.hd, + ); + const newAccount = (await newHdkeyring.getAccounts())[0]; + const account = this.accountsController.getAccountByAddress(newAccount); + this.accountsController.setSelectedAccount(account.id); + + return newAccount; + } finally { + releaseLock(); + } + } + ///: END:ONLY_INCLUDE_IF + /** * Create a new Vault and restore an existent keyring. * @@ -4591,11 +4648,21 @@ export default class MetamaskController extends EventEmitter { } } - async _addAccountsWithBalance() { + async _addAccountsWithBalance(keyringId) { try { // Scan accounts until we find an empty one const chainId = this.#getGlobalChainId(); - const accounts = await this.keyringController.getAccounts(); + + const keyringSelector = keyringId + ? { id: keyringId } + : { type: KeyringTypes.hd }; + + const accounts = await this.keyringController.withKeyring( + keyringSelector, + async (keyring) => { + return await keyring.getAccounts(); + }, + ); let address = accounts[accounts.length - 1]; for (let count = accounts.length; ; count++) { @@ -4626,7 +4693,12 @@ export default class MetamaskController extends EventEmitter { } // This account has assets, so check the next one - address = await this.keyringController.addNewAccount(count); + address = await this.keyringController.withKeyring( + keyringSelector, + async (keyring) => { + return (await keyring.addAccounts(1))[0]; + }, + ); } } catch (e) { log.warn(`Failed to add accounts with balance. Error: ${e}`); @@ -5058,14 +5130,22 @@ export default class MetamaskController extends EventEmitter { /** * Adds a new account to the default (first) HD seed phrase Keyring. * - * @param accountCount + * @param {number} accountCount - The number of accounts to create + * @param {string} _keyringId - The keyring identifier. * @returns {Promise} The address of the newly-created account. */ - async addNewAccount(accountCount) { + async addNewAccount(accountCount, _keyringId) { const oldAccounts = await this.keyringController.getAccounts(); + const keyringSelector = _keyringId + ? { id: _keyringId } + : { type: KeyringTypes.hd }; - const addedAccountAddress = await this.keyringController.addNewAccount( - accountCount, + const addedAccountAddress = await this.keyringController.withKeyring( + keyringSelector, + async (keyring) => { + const [newAddress] = await keyring.addAccounts(accountCount); + return newAddress; + }, ); if (!oldAccounts.includes(addedAccountAddress)) { @@ -5082,13 +5162,19 @@ export default class MetamaskController extends EventEmitter { * * Called when the first account is created and on unlocking the vault. * - * @param password + * @param {string} password + * @param {string} _keyringId - This is the identifier for the hd keyring. * @returns {Promise} The seed phrase to be confirmed by the user, * encoded as an array of UTF-8 bytes. */ - async getSeedPhrase(password) { + async getSeedPhrase(password, _keyringId) { return this._convertEnglishWordlistIndicesToCodepoints( - await this.keyringController.exportSeedPhrase(password), + await this.keyringController.exportSeedPhrase( + password, + ///: BEGIN:ONLY_INCLUDE_IF(multi-srp) + _keyringId, + ///: END:ONLY_INCLUDE_IF + ), ); } diff --git a/app/scripts/metamask-controller.test.js b/app/scripts/metamask-controller.test.js index c3b42e29fe94..e68cfb1e1130 100644 --- a/app/scripts/metamask-controller.test.js +++ b/app/scripts/metamask-controller.test.js @@ -96,6 +96,29 @@ const browserPolyfillMock = { }, }; +const mockULIDs = [ + '01JKAF3DSGM3AB87EM9N0K41AJ', + '01JKAF3KP7VPAG0YXEDTDRB6ZV', + '01JKAF3KP7VPAG0YXEDTDRB6ZW', + '01JKAF3KP7VPAG0YXEDTDRB6ZX', +]; + +function* ulidGenerator(ulids = mockULIDs) { + for (const id of ulids) { + yield id; + } + + while (true) { + yield 'should not be called after exhausting provided IDs'; + } +} + +let mockUlidGenerator = ulidGenerator(); + +jest.mock('ulid', () => ({ + ulid: jest.fn().mockImplementation(() => mockUlidGenerator.next().value), +})); + let loggerMiddlewareMock; const initializeMockMiddlewareLog = () => { loggerMiddlewareMock = { @@ -323,6 +346,8 @@ describe('MetaMaskController', () => { globalThis.sentry = { withIsolationScope: jest.fn(), }; + + mockUlidGenerator = ulidGenerator(); }); afterEach(() => { @@ -2568,7 +2593,9 @@ describe('MetaMaskController', () => { it('errors when an primary keyring is does not exist', async () => { const addNewAccount = metamaskController.addNewAccount(); - await expect(addNewAccount).rejects.toThrow('No HD keyring found'); + await expect(addNewAccount).rejects.toThrow( + 'KeyringController - Keyring not found.', + ); }); }); @@ -4168,6 +4195,61 @@ describe('MetaMaskController', () => { }); }); }); + + describe('generateNewMnemonicAndAddToVault', () => { + it('generates a new hd keyring instance', async () => { + const password = 'what-what-what'; + jest.spyOn(metamaskController, 'getBalance').mockResolvedValue('0x0'); + + await metamaskController.createNewVaultAndRestore(password, TEST_SEED); + + const previousKeyrings = + metamaskController.keyringController.state.keyrings; + + await metamaskController.addNewMnemonicToVault(TEST_SEED_ALT); + + const currentKeyrings = + metamaskController.keyringController.state.keyrings; + + expect( + currentKeyrings.filter((kr) => kr.type === 'HD Key Tree'), + ).toHaveLength(2); + expect(currentKeyrings).toHaveLength(previousKeyrings.length + 1); + }); + }); + + describe('addNewMnemonicToVault', () => { + it('generates a new hd keyring instance with a mnemonic', async () => { + const password = 'what-what-what'; + jest.spyOn(metamaskController, 'getBalance').mockResolvedValue('0x0'); + + await metamaskController.createNewVaultAndRestore(password, TEST_SEED); + + const previousKeyrings = + metamaskController.keyringController.state.keyrings; + + await metamaskController.addNewMnemonicToVault(TEST_SEED_ALT); + + const currentKeyrings = + metamaskController.keyringController.state.keyrings; + + const newlyAddedKeyringId = + metamaskController.keyringController.state.keyringsMetadata[ + metamaskController.keyringController.state.keyringsMetadata.length - + 1 + ].id; + + const newSRP = Buffer.from( + await metamaskController.getSeedPhrase(password, newlyAddedKeyringId), + ).toString('utf8'); + + expect( + currentKeyrings.filter((kr) => kr.type === 'HD Key Tree'), + ).toHaveLength(2); + expect(currentKeyrings).toHaveLength(previousKeyrings.length + 1); + expect(newSRP).toStrictEqual(TEST_SEED_ALT); + }); + }); }); describe('onFeatureFlagResponseReceived', () => { diff --git a/builds.yml b/builds.yml index dde73817d489..656558a1f73b 100644 --- a/builds.yml +++ b/builds.yml @@ -65,6 +65,7 @@ buildTypes: - build-flask - keyring-snaps - solana + - multi-srp - solana-swaps env: - INFURA_FLASK_PROJECT_ID @@ -140,6 +141,10 @@ features: solana: assets: - ./{app,shared,ui}/**/solana/** + multi-srp: + assets: + # srp-list is a special case and is used in the srp recovery flow now. + - ./{app,shared,ui}/**/multi-srp/(?!.*srp-list)/** solana-swaps: # Env variables that are required for all types of builds diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index c5c71601da26..ad1ce2d6ed7f 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -1381,7 +1381,8 @@ "@metamask/keyring-controller>@metamask/eth-simple-keyring": true, "@metamask/keyring-controller>@metamask/utils": true, "@metamask/name-controller>async-mutex": true, - "@metamask/keyring-controller>ethereumjs-wallet": true + "@metamask/keyring-controller>ethereumjs-wallet": true, + "@metamask/keyring-controller>ulid": true } }, "@metamask/eth-snap-keyring>@metamask/keyring-internal-snap-client": { @@ -5719,6 +5720,13 @@ "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true } }, + "@metamask/keyring-controller>ulid": { + "globals": { + "console.error": true, + "crypto": true, + "define": true + } + }, "react-markdown>unified": { "packages": { "react-markdown>unified>bail": true, diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index 2bc83d9e9cef..52471ddc9330 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -1389,7 +1389,8 @@ "@metamask/keyring-controller>@metamask/eth-simple-keyring": true, "@metamask/keyring-controller>@metamask/utils": true, "@metamask/name-controller>async-mutex": true, - "@metamask/keyring-controller>ethereumjs-wallet": true + "@metamask/keyring-controller>ethereumjs-wallet": true, + "@metamask/keyring-controller>ulid": true } }, "@metamask/eth-snap-keyring>@metamask/keyring-internal-snap-client": { @@ -5765,6 +5766,13 @@ "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true } }, + "@metamask/keyring-controller>ulid": { + "globals": { + "console.error": true, + "crypto": true, + "define": true + } + }, "react-markdown>unified": { "packages": { "react-markdown>unified>bail": true, diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index c5c71601da26..ad1ce2d6ed7f 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -1381,7 +1381,8 @@ "@metamask/keyring-controller>@metamask/eth-simple-keyring": true, "@metamask/keyring-controller>@metamask/utils": true, "@metamask/name-controller>async-mutex": true, - "@metamask/keyring-controller>ethereumjs-wallet": true + "@metamask/keyring-controller>ethereumjs-wallet": true, + "@metamask/keyring-controller>ulid": true } }, "@metamask/eth-snap-keyring>@metamask/keyring-internal-snap-client": { @@ -5719,6 +5720,13 @@ "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true } }, + "@metamask/keyring-controller>ulid": { + "globals": { + "console.error": true, + "crypto": true, + "define": true + } + }, "react-markdown>unified": { "packages": { "react-markdown>unified>bail": true, diff --git a/lavamoat/browserify/mmi/policy.json b/lavamoat/browserify/mmi/policy.json index 81964ddaf4d6..6087c1c10a4c 100644 --- a/lavamoat/browserify/mmi/policy.json +++ b/lavamoat/browserify/mmi/policy.json @@ -1473,7 +1473,8 @@ "@metamask/keyring-controller>@metamask/eth-simple-keyring": true, "@metamask/keyring-controller>@metamask/utils": true, "@metamask/name-controller>async-mutex": true, - "@metamask/keyring-controller>ethereumjs-wallet": true + "@metamask/keyring-controller>ethereumjs-wallet": true, + "@metamask/keyring-controller>ulid": true } }, "@metamask/eth-snap-keyring>@metamask/keyring-internal-snap-client": { @@ -5811,6 +5812,13 @@ "@ensdomains/content-hash>multicodec>uint8arrays>multiformats": true } }, + "@metamask/keyring-controller>ulid": { + "globals": { + "console.error": true, + "crypto": true, + "define": true + } + }, "react-markdown>unified": { "packages": { "react-markdown>unified>bail": true, diff --git a/lavamoat/browserify/policy-override.json b/lavamoat/browserify/policy-override.json index 3ece77c837c6..8dfc11cf6026 100644 --- a/lavamoat/browserify/policy-override.json +++ b/lavamoat/browserify/policy-override.json @@ -163,6 +163,11 @@ "packages": { "immer": true } + }, + "@metamask/keyring-controller>ulid": { + "globals": { + "crypto": true + } } } } diff --git a/lavamoat/build-system/policy.json b/lavamoat/build-system/policy.json index bae075d9b3fb..b7409df2f24c 100644 --- a/lavamoat/build-system/policy.json +++ b/lavamoat/build-system/policy.json @@ -1795,6 +1795,7 @@ "chokidar>anymatch": true, "chokidar>braces": true, "chokidar>fsevents": true, + "tsx>fsevents": true, "eslint>glob-parent": true, "chokidar>is-binary-path": true, "del>is-glob": true, @@ -3364,6 +3365,13 @@ "gulp-watch>chokidar>fsevents>node-pre-gyp": true } }, + "tsx>fsevents": { + "globals": { + "console.assert": true, + "process.platform": true + }, + "native": true + }, "@lavamoat/allow-scripts>@npmcli/run-script>node-gyp>npmlog>gauge": { "builtin": { "util.format": true diff --git a/package.json b/package.json index 5550176ccf44..989cf17a4cce 100644 --- a/package.json +++ b/package.json @@ -316,7 +316,7 @@ "@metamask/json-rpc-engine": "^10.0.0", "@metamask/json-rpc-middleware-stream": "^8.0.4", "@metamask/keyring-api": "^16.1.0", - "@metamask/keyring-controller": "^19.0.4", + "@metamask/keyring-controller": "npm:@metamask-previews/keyring-controller@19.0.5-preview-553ac792", "@metamask/keyring-internal-api": "^4.0.1", "@metamask/keyring-snap-client": "^3.0.3", "@metamask/logging-controller": "^6.0.0", diff --git a/test/data/mock-send-state.json b/test/data/mock-send-state.json index 124487281ca9..6eb9e5e897d1 100644 --- a/test/data/mock-send-state.json +++ b/test/data/mock-send-state.json @@ -269,6 +269,20 @@ "accounts": ["0xeb9e64b93097bc15f01f13eae97015c57ab64823"] } ], + "keyringsMetadata": [ + { + "id": "01JKAF3DSGM3AB87EM9N0K41AJ", + "name": "" + }, + { + "id": "01JKAF3KP7VPAG0YXEDTDRB6ZV", + "name": "" + }, + { + "id": "01JKAF3PJ247KAM6C03G5Q0NP8", + "name": "" + } + ], "identities": { "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc": { "address": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc", diff --git a/test/data/mock-state.json b/test/data/mock-state.json index f0f7365133ee..69e376434b8b 100644 --- a/test/data/mock-state.json +++ b/test/data/mock-state.json @@ -625,6 +625,28 @@ "accounts": ["0xca8f1F0245530118D0cf14a06b01Daf8f76Cf281"] } ], + "keyringsMetadata": [ + { + "id": "01JKAF3DSGM3AB87EM9N0K41AJ", + "name": "" + }, + { + "id": "01JKAF3KP7VPAG0YXEDTDRB6ZV", + "name": "" + }, + { + "id": "01JKAF3PJ247KAM6C03G5Q0NP8", + "name": "" + }, + { + "id": "01JKAF3SSWRQK818R830GE8PHX", + "name": "" + }, + { + "id": "01JKAF3WYGWF7JX6PC4YYVSK2Q", + "name": "" + } + ], "identities": { "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc": { "address": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc", diff --git a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json index 9f636ad802ca..2a7020dfd304 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json @@ -121,6 +121,7 @@ "KeyringController": { "isUnlocked": true, "keyrings": "object", + "keyringsMetadata": "object", "vault": "string", "encryptionKey": "string", "encryptionSalt": "string" diff --git a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json index c1bdabf2ace9..93a6730e8f0d 100644 --- a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json +++ b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json @@ -165,6 +165,7 @@ }, "networkConfigurationsByChainId": "object", "keyrings": "object", + "keyringsMetadata": "object", "selectedAddress": "string", "usePhishDetect": true, "dismissSeedBackUpReminder": true, diff --git a/test/jest/mock-store.js b/test/jest/mock-store.js index 9b68f248507b..aa01c33ffbdf 100644 --- a/test/jest/mock-store.js +++ b/test/jest/mock-store.js @@ -365,6 +365,16 @@ export const createSwapsMockStore = () => { accounts: ['0xd85a4b6a394794842887b8284293d69163007bbb'], }, ], + keyringsMetadata: [ + { + id: '01JKAF3DSGM3AB87EM9N0K41AJ', + name: '', + }, + { + id: '01JKAF3KP7VPAG0YXEDTDRB6ZV', + name: '', + }, + ], ...mockNetworkState({ chainId: CHAIN_IDS.MAINNET, ticker: CURRENCY_SYMBOLS.ETH, diff --git a/ui/store/actions.test.js b/ui/store/actions.test.js index c34238b3432b..85415636881a 100644 --- a/ui/store/actions.test.js +++ b/ui/store/actions.test.js @@ -39,6 +39,16 @@ const defaultState = { balance: '0x0', }, }, + keyrings: [ + { + type: 'HD Key Tree', + accounts: [ + { + address: '0xFirstAddress', + }, + ], + }, + ], ...mockNetworkState({ chainId: CHAIN_IDS.MAINNET }), internalAccounts: { accounts: { diff --git a/ui/store/actions.ts b/ui/store/actions.ts index 12629a03f7eb..0efa72948674 100644 --- a/ui/store/actions.ts +++ b/ui/store/actions.ts @@ -67,7 +67,6 @@ import { ///: END:ONLY_INCLUDE_IF getInternalAccountByAddress, getSelectedInternalAccount, - getInternalAccounts, } from '../selectors'; import { getSelectedNetworkClientId, @@ -451,17 +450,13 @@ export function addNewAccount(): ThunkAction< AnyAction > { log.debug(`background.addNewAccount`); - return async (dispatch, getState) => { - const oldAccounts = getInternalAccounts(getState()).filter( - (internalAccount) => - internalAccount.metadata.keyring.type === KeyringTypes.hd, - ); + return async (dispatch) => { dispatch(showLoadingIndication()); let addedAccountAddress; try { addedAccountAddress = await submitRequestToBackground('addNewAccount', [ - Object.keys(oldAccounts).length, + 1, ]); } catch (error) { dispatch(displayWarning(error)); diff --git a/yarn.lock b/yarn.lock index 4a975d9bc7aa..de2605716c1b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5563,6 +5563,29 @@ __metadata: languageName: node linkType: hard +"@metamask/keyring-controller@npm:@metamask-previews/keyring-controller@19.0.5-preview-553ac792": + version: 19.0.5-preview-553ac792 + resolution: "@metamask-previews/keyring-controller@npm:19.0.5-preview-553ac792" + dependencies: + "@ethereumjs/util": "npm:^8.1.0" + "@keystonehq/metamask-airgapped-keyring": "npm:^0.14.1" + "@metamask/base-controller": "npm:^7.1.1" + "@metamask/browser-passworder": "npm:^4.3.0" + "@metamask/eth-hd-keyring": "npm:^7.0.4" + "@metamask/eth-sig-util": "npm:^8.0.0" + "@metamask/eth-simple-keyring": "npm:^6.0.5" + "@metamask/keyring-api": "npm:^16.1.0" + "@metamask/keyring-internal-api": "npm:^4.0.1" + "@metamask/message-manager": "npm:^12.0.0" + "@metamask/utils": "npm:^11.1.0" + async-mutex: "npm:^0.5.0" + ethereumjs-wallet: "npm:^1.0.1" + immer: "npm:^9.0.6" + ulid: "npm:^2.3.0" + checksum: 10/99ba73ea9ef68cd448bfedccc85fd043e605e685066888911ec56d72d27752d6056aec7e7834fb4c1e50d69ee7b663ed8db7ea5b84d73b6a4764aa06792314c1 + languageName: node + linkType: hard + "@metamask/keyring-controller@npm:^19.0.4": version: 19.0.4 resolution: "@metamask/keyring-controller@npm:19.0.4" @@ -5638,13 +5661,13 @@ __metadata: linkType: hard "@metamask/keyring-utils@npm:^1.2.0": - version: 1.3.1 - resolution: "@metamask/keyring-utils@npm:1.3.1" + version: 1.3.0 + resolution: "@metamask/keyring-utils@npm:1.3.0" dependencies: "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.1.0" + "@metamask/utils": "npm:^11.0.1" bitcoin-address-validation: "npm:^2.2.3" - checksum: 10/9072791320108218875bdbcc7823a4ab4d8c29675deab3163373d31a997ae6fc23995a74ffa085e06534d14b72c2edb5e7192d371cd1ef69ac7fae70fa50d8d0 + checksum: 10/b2789e9870e5c83653de7631b641fef1f7718d5cedb16e88ea04ab77cca29d077325be2d67b53b01e3eaddcb09c7d03ead15dd0f52dfef72cab6b19f27e76dc0 languageName: node linkType: hard @@ -7806,9 +7829,9 @@ __metadata: linkType: hard "@scure/base@npm:^1.0.0, @scure/base@npm:^1.1.1, @scure/base@npm:^1.1.3, @scure/base@npm:~1.1.0, @scure/base@npm:~1.1.3, @scure/base@npm:~1.1.6": - version: 1.1.7 - resolution: "@scure/base@npm:1.1.7" - checksum: 10/fc50ffaab36cb46ff9fa4dc5052a06089ab6a6707f63d596bb34aaaec76173c9a564ac312a0b981b5e7a5349d60097b8878673c75d6cbfc4da7012b63a82099b + version: 1.1.9 + resolution: "@scure/base@npm:1.1.9" + checksum: 10/f0ab7f687bbcdee2a01377fe3cd808bf63977999672751295b6a92625d5322f4754a96d40f6bd579bc367aad48ecf8a4e6d0390e70296e6ded1076f52adb16bb languageName: node linkType: hard @@ -13308,13 +13331,13 @@ __metadata: linkType: hard "axios@npm:^1.1.3": - version: 1.7.4 - resolution: "axios@npm:1.7.4" + version: 1.7.7 + resolution: "axios@npm:1.7.7" dependencies: follow-redirects: "npm:^1.15.6" form-data: "npm:^4.0.0" proxy-from-env: "npm:^1.1.0" - checksum: 10/7a1429be1e3d0c2e1b96d4bba4d113efbfabc7c724bed107beb535c782c7bea447ff634886b0c7c43395a264d085450d009eb1154b5f38a8bae49d469fdcbc61 + checksum: 10/7f875ea13b9298cd7b40fd09985209f7a38d38321f1118c701520939de2f113c4ba137832fe8e3f811f99a38e12c8225481011023209a77b0c0641270e20cde1 languageName: node linkType: hard @@ -15896,14 +15919,11 @@ __metadata: linkType: hard "crc-32@npm:^1.2.0": - version: 1.2.0 - resolution: "crc-32@npm:1.2.0" - dependencies: - exit-on-epipe: "npm:~1.0.1" - printj: "npm:~1.1.0" + version: 1.2.2 + resolution: "crc-32@npm:1.2.2" bin: - crc32: ./bin/crc32.njs - checksum: 10/10c648c986b005ed0ea8393bb0d1ccb99e7a102505b136d313dee6abe204aa682d9bb9bc6fd180f9cd98ef92aa029964f1cc96a2a85eb50507dedd9ead1a262f + crc32: bin/crc32.njs + checksum: 10/824f696a5baaf617809aa9cd033313c8f94f12d15ebffa69f10202480396be44aef9831d900ab291638a8022ed91c360696dd5b1ba691eb3f34e60be8835b7c3 languageName: node linkType: hard @@ -19183,13 +19203,6 @@ __metadata: languageName: node linkType: hard -"exit-on-epipe@npm:~1.0.1": - version: 1.0.1 - resolution: "exit-on-epipe@npm:1.0.1" - checksum: 10/b180aa277aec5bef2609b34e5876061f421a1f81bf343beb213c4d60b382ddcb6b83012833f0ba329d6bc38042685c8d89b1c52ea495b9b6327948ea80627398 - languageName: node - linkType: hard - "exit@npm:^0.1.2": version: 0.1.2 resolution: "exit@npm:0.1.2" @@ -26630,7 +26643,7 @@ __metadata: "@metamask/json-rpc-engine": "npm:^10.0.0" "@metamask/json-rpc-middleware-stream": "npm:^8.0.4" "@metamask/keyring-api": "npm:^16.1.0" - "@metamask/keyring-controller": "npm:^19.0.4" + "@metamask/keyring-controller": "npm:@metamask-previews/keyring-controller@19.0.5-preview-553ac792" "@metamask/keyring-internal-api": "npm:^4.0.1" "@metamask/keyring-snap-client": "npm:^3.0.3" "@metamask/logging-controller": "npm:^6.0.0" @@ -30326,15 +30339,6 @@ __metadata: languageName: node linkType: hard -"printj@npm:~1.1.0": - version: 1.1.2 - resolution: "printj@npm:1.1.2" - bin: - printj: ./bin/printj.njs - checksum: 10/45376a5ee7ef2e0d7ff0b4fecc893d73995a332e63d7e0622a544fe662c8213d22f0c9750e627c6d732a7d7a543266be960e6cd51cf19485cce87cf80468bb41 - languageName: node - linkType: hard - "prismjs@npm:^1.27.0": version: 1.29.0 resolution: "prismjs@npm:1.29.0" @@ -36072,6 +36076,15 @@ __metadata: languageName: node linkType: hard +"ulid@npm:^2.3.0": + version: 2.3.0 + resolution: "ulid@npm:2.3.0" + bin: + ulid: ./bin/cli.js + checksum: 10/11d7dd35072b863effb1249f66fb03070142a625610f00e5afd99af7e909b5de9cc7ebca6ede621a6bb1b7479b2489d6f064db6742b55c14bff6496ac60f290f + languageName: node + linkType: hard + "umd@npm:3.0.3, umd@npm:^3.0.0": version: 3.0.3 resolution: "umd@npm:3.0.3"