From 42263b21f989be7cbeec921c5526e8b8d28ee4b2 Mon Sep 17 00:00:00 2001 From: Owen Craston Date: Thu, 13 Feb 2025 14:03:09 -0700 Subject: [PATCH] chore: Update accounts controller to v23 and related packages (transaction controller etc) (#13436) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** This PR updates the [AccountsController](https://github.com/MetaMask/core/blob/main/packages/accounts-controller/CHANGELOG.md#2310) and the [TransactionController](https://github.com/MetaMask/core/blob/main/packages/transaction-controller/CHANGELOG.md#4510). These are the two major updates however there are a few smaller peer dep updates as well. Here is a description of the changes... ### "@metamask/accounts-controller": "^21.0.0" -> 23.1.0" - [changelog](https://github.com/MetaMask/core/blob/main/packages/accounts-controller/CHANGELOG.md#2310) - Breaking changes: - BREAKING: Now requires SnapKeyring:account{AssetList,Balances,Transactions}Updated events to be registered on the messenger (https://github.com/MetaMask/core/pull/5190) - BREAKING: Bump @metamask/snaps-controllers peer dependency from ^9.7.0 to ^9.19.0 (https://github.com/MetaMask/core/pull/5265) - Bump @metamask/base-controller from ^7.1.1 to ^8.0.0 - Non breaking changes: - Bump @metamask/keyring-api" from ^16.1.0 to ^17.0.0 (https://github.com/MetaMask/core/pull/5280) - Bump @metamask/eth-snap-keyring from ^9.1.1 to ^10.0.0 (https://github.com/MetaMask/core/pull/5280) - Bump @metamask/snaps-sdk from ^6.7.0 to ^6.17.1 (https://github.com/MetaMask/core/pull/5220), (https://github.com/MetaMask/core/pull/5265) - Bump @metamask/snaps-utils from ^8.9.0 to ^8.10.0 (https://github.com/MetaMask/core/pull/5265) ### "@metamask/transaction-controller": "^43.0.0" -> 45.1.0 - [changelog](https://github.com/MetaMask/core/blob/main/packages/transaction-controller/CHANGELOG.md#4510) - Breaking changes: - BREAKING: Bump @metamask/accounts-controller peer dependency from ^22.0.0 to ^23.0.0 ### "@metamask/keyring-api": "^13.0.0" -> 17.0.0 - [changelog](https://github.com/MetaMask/accounts/blob/main/packages/keyring-api/CHANGELOG.md#1700) - Breaking changes: - BREAKING: Make CaipAssetType type more restritive (https://github.com/MetaMask/accounts/pull/150) It used to be a string but it has been restricted with a template literal type that matches CAIP-19 asset type. - BREAKING: Make specific *AccountStruct.scopes more strict (https://github.com/MetaMask/accounts/pull/159) - BREAKING: Remove CAIP redefinitions (https://github.com/MetaMask/accounts/pull/167) We now rely on CAIP definitions coming @metamask/utils. - BREAKING: Enforce that scopes contains CAIP-2 chain IDs (https://github.com/MetaMask/accounts/pull/165) Initially scopes accepted CAIP-2 namespaces as well to address the EVM EOA accounts that supports all EVM chains. This has been dropped in favor of eip155:0 scope. - BREAKING: Rename *Scopes enums to *Scope (https://github.com/MetaMask/accounts/pull/165) - BREAKING: Use CaipAccountId for ResolvedAccountAddress.address (https://github.com/MetaMask/accounts/pull/186) This was missing from SIP-26, but we expect this address to be CAIP-10 compliant. ### "@metamask/keyring-internal-api": "^2.0.0" -> 4.0.2 - [changelog](https://github.com/MetaMask/accounts/blob/main/packages/keyring-internal-api/CHANGELOG.md#402) - Breaking changes - BREAKING: Bump @metamask/keyring-api from ^14.0.0 to ^15.0.0 (https://github.com/MetaMask/accounts/pull/160) The scopes from each *AccountStruct types is now more strict which impact all Internal*AccountStruct types. - BREAKING: Bump @metamask/keyring-api from ^15.0.0 to ^16.0.0 (https://github.com/MetaMask/accounts/pull/172) The scopes from each *AccountStruct types is now more strict (remove support of CAIP-2 namespaces) which impact all Internal*AccountStruct types. - Bump @metamask/keyring-api from ^16.1.0 to ^17.0.0 (https://github.com/MetaMask/accounts/pull/192) ### "@metamask/eth-snap-keyring": "^7.1.0" -> 10.0.0 - [changelog](https://github.com/MetaMask/accounts/blob/main/packages/keyring-snap-bridge/CHANGELOG.md) - Breaking changes: - BREAKING: Bump @metamask/keyring-api from ^12.0.0 to ^13.0.0 (https://github.com/MetaMask/accounts/pull/101) This change was not properly reported as breaking on the 7.1.0. KeyringAccount and InternalAccount have a new required field (scopes) and are part of the public API. - BREAKING: Bump @metamask/keyring-internal-api from ^1.0.0 to ^2.0.0 (https://github.com/MetaMask/accounts/pull/135) This change was not properly reported as breaking on the 7.1.0. InternalAccount extends KeyringAccount which has a new required field (scopes) and is part of the public API. - BREAKING: Bump @metamask/keyring-snap-internal-client from ^1.0.0 to ^2.0.0 (https://github.com/MetaMask/accounts/pull/135) This change was not properly reported as breaking on the 7.1.0. KeyringAccount has a new required field (scopes) and is part of the public API. - BREAKING: Use Messenger instead of SnapsController (https://github.com/MetaMask/accounts/pull/152) This allows to break the runtime dependency we had with some snaps-* pacakges. - BREAKING: Make scopes more strict (https://github.com/MetaMask/accounts/pull/159) We now use specific *AccountStucts when checking created/updated accounts to make the scopes sent by the Snap are valid regarding their account type definition. - BREAKING: Use CaipAccountId for ResolvedAccountAddress.address (https://github.com/MetaMask/accounts/pull/186) This was missing from SIP-26, but we expect this address to be CAIP-10 compliant. ### "@metamask/snaps-sdk": "^6.13.0" -> 6.17.1 - [changelog](https://github.com/MetaMask/snaps/blob/main/packages/snaps-sdk/CHANGELOG.md#6171) - no breaking changes ### "@metamask/snaps-utils": "^8.6.1" -> ^8.10.0 - [changelog](https://github.com/MetaMask/snaps/blob/main/packages/snaps-utils/CHANGELOG.md#8100) - no breaking changes ## **Related issues** Fixes: https://github.com/MetaMask/metamask-mobile/issues/13374 Fixes: https://github.com/MetaMask/metamask-mobile/issues/13377 ## **Manual testing steps** #### Testing snap accounts 1. ensure you are building metamask flask by setting the value of `METAMASK_BUILD_TYPE` to `flask` in your `.js.env` 2. source .js.env 3. yarn setup 4. yarn start:ios 5. create/import a wallet 6. click on the selected account at the top of the home page 7. click on the Add account button 8. then click the Add Solana account (Beta) button 9. a popup with a suggested name should appeaer 10. click OK, the account should now be added to your account list. if you have a balance on this address then it should show in the portfolio view. 11. repeat the above steps with the Bitcoin and Bitcoin testnet account #### Testing transactions 1. ensure you are NOT building flask by setting the value of `METAMASK_BUILD_TYPE` to `main` in your `.js.env` 2. source .js.env 3. yarn setup 4. yarn start:ios 5. import an account that has funds 6. click on the selected account at the top of the screen and the account list should open 7. then click on the add account button, then click add account 8. a new eth account should appear in your wallet 9. click on main bottom tab navigator icon which should open a list of actions, select Send. 10. the Send flow should open. 11. set your from account to the account that has funds and the to account to your newly created account. 12. type in a valid amount then go through the rest of the send flow 13. in the end the transaction should go through. 14. the account balances on the home page should be updated ## **Screenshots/Recordings** ### **Before** ### **After** On-boarding and Account Creation Flow https://github.com/user-attachments/assets/2ccd8fb4-4857-4a99-ab52-cdb071bd0447 Send flow https://github.com/user-attachments/assets/da81d49c-b472-49a7-83c4-1d1046521072 ## **Pre-merge author checklist** - [x] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --- .../RevealPrivateCredential/index.test.tsx | 4 +- app/core/Engine/Engine.ts | 17 +- .../AccountsController/utils.test.ts | 11 +- app/core/Engine/types.ts | 4 +- app/core/Multichain/test/utils.test.ts | 14 +- app/core/SnapKeyring/SnapKeyring.test.ts | 6 +- app/core/SnapKeyring/SnapKeyring.ts | 11 +- app/core/SnapKeyring/constants.ts | 15 + app/core/SnapKeyring/types.ts | 10 +- app/selectors/accountsController.test.ts | 10 +- app/store/migrations/036.test.ts | 4 +- app/store/migrations/036.ts | 4 +- app/store/migrations/066.test.ts | 78 ++- app/store/migrations/066.ts | 86 ++- app/store/migrations/067.test.ts | 535 ++++++++++++++++++ app/store/migrations/067.ts | 14 + app/store/migrations/index.ts | 2 + .../accountsController.test.ts | 8 +- .../sentry/__snapshots__/utils.test.ts.snap | 4 +- app/util/sentry/utils.test.ts | 10 +- app/util/test/accountsControllerTestUtils.ts | 32 +- package.json | 14 +- scripts/setup.mjs | 2 +- yarn.lock | 367 ++++++------ 24 files changed, 946 insertions(+), 316 deletions(-) create mode 100644 app/core/SnapKeyring/constants.ts create mode 100644 app/store/migrations/067.test.ts create mode 100644 app/store/migrations/067.ts diff --git a/app/components/Views/RevealPrivateCredential/index.test.tsx b/app/components/Views/RevealPrivateCredential/index.test.tsx index bbf92a7743f..7dfd277abd3 100644 --- a/app/components/Views/RevealPrivateCredential/index.test.tsx +++ b/app/components/Views/RevealPrivateCredential/index.test.tsx @@ -7,7 +7,7 @@ import { backgroundState } from '../../../util/test/initial-root-state'; import { RevealPrivateCredential } from './'; import { ThemeContext, mockTheme } from '../../../util/theme'; import { RevealSeedViewSelectorsIDs } from '../../../../e2e/selectors/Settings/SecurityAndPrivacy/RevealSeedView.selectors'; -import { EthAccountType, EthMethod, EthScopes } from '@metamask/keyring-api'; +import { EthAccountType, EthMethod, EthScope } from '@metamask/keyring-api'; import { KeyringTypes } from '@metamask/keyring-controller'; jest.mock('react-redux', () => ({ @@ -156,7 +156,7 @@ describe('RevealPrivateCredential', () => { someOption: 'optionValue', anotherOption: 42, }, - scopes: [EthScopes.Namespace], + scopes: [EthScope.Eoa], methods: [ EthMethod.PersonalSign, EthMethod.SignTransaction, diff --git a/app/core/Engine/Engine.ts b/app/core/Engine/Engine.ts index c495c754efa..a44695c9e5e 100644 --- a/app/core/Engine/Engine.ts +++ b/app/core/Engine/Engine.ts @@ -231,6 +231,11 @@ import { SnapControllerStateChangeEvent, SnapControllerUpdateSnapStateAction, } from './controllers/SnapController/constants'; +import { + SnapKeyringAccountAssetListUpdatedEvent, + SnapKeyringAccountBalancesUpdatedEvent, + SnapKeyringAccountTransactionsUpdatedEvent, +} from '../SnapKeyring/constants'; const NON_EMPTY = 'NON_EMPTY'; @@ -377,7 +382,6 @@ export class Engine { }); // Create AccountsController - // @ts-expect-error TODO: Resolve mismatch between base-controller versions. const accountsControllerMessenger: AccountsControllerMessenger = this.controllerMessenger.getRestricted({ name: 'AccountsController', @@ -385,6 +389,9 @@ export class Engine { SnapControllerStateChangeEvent, 'KeyringController:accountRemoved', 'KeyringController:stateChange', + SnapKeyringAccountAssetListUpdatedEvent, + SnapKeyringAccountBalancesUpdatedEvent, + SnapKeyringAccountTransactionsUpdatedEvent, ], allowedActions: [ 'KeyringController:getAccounts', @@ -620,7 +627,7 @@ export class Engine { ///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps) const snapKeyringBuildMessenger = this.controllerMessenger.getRestricted({ - name: 'SnapKeyringBuilder', + name: 'SnapKeyring', allowedActions: [ 'ApprovalController:addRequest', 'ApprovalController:acceptRequest', @@ -635,12 +642,12 @@ export class Engine { AccountsControllerSetSelectedAccountAction, AccountsControllerGetAccountByAddressAction, AccountsControllerSetAccountNameAction, + SnapControllerHandleRequestAction, + SnapControllerGetSnapAction, ], allowedEvents: [], }); - const getSnapController = () => this.snapController; - // Necessary to persist the keyrings and update the accounts both within the keyring controller and accounts controller const persistAndUpdateAccounts = async () => { await this.keyringController.persistAllKeyrings(); @@ -650,7 +657,6 @@ export class Engine { additionalKeyrings.push( snapKeyringBuilder( snapKeyringBuildMessenger, - getSnapController, persistAndUpdateAccounts, (address) => this.removeAccount(address), ), @@ -1265,7 +1271,6 @@ export class Engine { }, isSimulationEnabled: () => preferencesController.state.useTransactionSimulations, - // @ts-expect-error TODO: Resolve mismatch between base-controller versions. messenger: this.controllerMessenger.getRestricted({ name: 'TransactionController', allowedActions: [ diff --git a/app/core/Engine/controllers/AccountsController/utils.test.ts b/app/core/Engine/controllers/AccountsController/utils.test.ts index c2415d4b198..b35ec88ce05 100644 --- a/app/core/Engine/controllers/AccountsController/utils.test.ts +++ b/app/core/Engine/controllers/AccountsController/utils.test.ts @@ -20,6 +20,12 @@ import { AGREED, METRICS_OPT_IN } from '../../../../constants/storage'; import StorageWrapper from '../../../../store/storage-wrapper'; import { logAccountsControllerCreation } from './logger'; import { SnapControllerStateChangeEvent } from '../SnapController/constants'; +import { SnapKeyringEvents } from '@metamask/eth-snap-keyring'; +import { + SnapKeyringAccountAssetListUpdatedEvent, + SnapKeyringAccountBalancesUpdatedEvent, + SnapKeyringAccountTransactionsUpdatedEvent, +} from '../../../SnapKeyring/constants'; jest.mock('@sentry/react-native', () => ({ withScope: jest.fn(), @@ -45,14 +51,17 @@ describe('accountControllersUtils', () => { | SnapStateChange | KeyringControllerAccountRemovedEvent | KeyringControllerStateChangeEvent + | SnapKeyringEvents >(); - // @ts-expect-error TODO: Resolve mismatch between base-controller versions. accountsControllerMessenger = globalMessenger.getRestricted({ name: 'AccountsController', allowedEvents: [ SnapControllerStateChangeEvent, 'KeyringController:accountRemoved', 'KeyringController:stateChange', + SnapKeyringAccountAssetListUpdatedEvent, + SnapKeyringAccountBalancesUpdatedEvent, + SnapKeyringAccountTransactionsUpdatedEvent, ], allowedActions: [ 'KeyringController:getAccounts', diff --git a/app/core/Engine/types.ts b/app/core/Engine/types.ts index 8351633cff3..647a38f7a7e 100644 --- a/app/core/Engine/types.ts +++ b/app/core/Engine/types.ts @@ -180,6 +180,7 @@ import { RemoteFeatureFlagControllerActions, RemoteFeatureFlagControllerEvents, } from '@metamask/remote-feature-flag-controller/dist/remote-feature-flag-controller.cjs'; +import { SnapKeyringEvents } from '@metamask/eth-snap-keyring'; /** * Controllers that area always instantiated @@ -291,7 +292,8 @@ type GlobalEvents = | SelectedNetworkControllerEvents | SmartTransactionsControllerEvents | AssetsContractControllerEvents - | RemoteFeatureFlagControllerEvents; + | RemoteFeatureFlagControllerEvents + | SnapKeyringEvents; // TODO: Abstract this into controller utils for TransactionController export interface TransactionEventPayload { diff --git a/app/core/Multichain/test/utils.test.ts b/app/core/Multichain/test/utils.test.ts index 51d3bb96418..d6a9a9858a9 100644 --- a/app/core/Multichain/test/utils.test.ts +++ b/app/core/Multichain/test/utils.test.ts @@ -3,9 +3,9 @@ import { BtcAccountType, EthMethod, BtcMethod, - EthScopes, - BtcScopes, - SolScopes, + EthScope, + BtcScope, + SolScope, SolAccountType, SolMethod, } from '@metamask/keyring-api'; @@ -34,7 +34,7 @@ const SOL_ADDRESS = '7EcDhSYGxXyscszYEp35KHN8vvw3svAuLKTzXwCFLtV'; const mockEthEOAAccount: InternalAccount = { address: MOCK_ETH_ADDRESS, id: '1', - scopes: [EthScopes.Namespace], + scopes: [EthScope.Eoa], metadata: { name: 'Eth Account 1', importTime: 1684232000456, @@ -56,7 +56,7 @@ const mockEthEOAAccount: InternalAccount = { const mockEthERC4337Account: InternalAccount = { address: '0xC4966c0D659D99699BFD7EB54D8fafEE40e4a756', id: '1', - scopes: [EthScopes.Namespace], + scopes: [EthScope.Eoa], metadata: { name: 'Eth Account ERC4337 1', importTime: 1684232000456, @@ -78,7 +78,7 @@ const mockEthERC4337Account: InternalAccount = { const mockBTCAccount: InternalAccount = { address: MOCK_BTC_MAINNET_ADDRESS, id: '1', - scopes: [BtcScopes.Namespace], + scopes: [BtcScope.Mainnet], metadata: { name: 'Bitcoin Account', importTime: 1684232000456, @@ -114,7 +114,7 @@ const mockSolAccount: InternalAccount = { enabled: true, }, }, - scopes: [SolScopes.Mainnet, SolScopes.Testnet, SolScopes.Devnet], + scopes: [SolScope.Mainnet, SolScope.Testnet, SolScope.Devnet], }; describe('MultiChain utils', () => { diff --git a/app/core/SnapKeyring/SnapKeyring.test.ts b/app/core/SnapKeyring/SnapKeyring.test.ts index 9eb8e6acc89..d5d5017aef8 100644 --- a/app/core/SnapKeyring/SnapKeyring.test.ts +++ b/app/core/SnapKeyring/SnapKeyring.test.ts @@ -1,5 +1,5 @@ import { Messenger } from '@metamask/base-controller'; -import { EthAccountType, EthScopes, KeyringEvent } from '@metamask/keyring-api'; +import { EthAccountType, EthScope, KeyringEvent } from '@metamask/keyring-api'; import { InternalAccount } from '@metamask/keyring-internal-api'; import { snapKeyringBuilder } from './SnapKeyring'; import { @@ -15,7 +15,6 @@ const mockEndFlow = jest.fn(); const mockGetAccounts = jest.fn(); const mockSnapId: SnapId = 'snapId' as SnapId; const mockSnapName = 'mock-snap'; -const mockSnapController = jest.fn(); const mockPersisKeyringHelper = jest.fn(); const mockSetSelectedAccount = jest.fn(); const mockRemoveAccountHelper = jest.fn(); @@ -35,7 +34,7 @@ const mockAccount = { }; const mockInternalAccount: InternalAccount = { ...mockAccount, - scopes: [EthScopes.Namespace], + scopes: [EthScope.Eoa], metadata: { snap: { enabled: true, @@ -109,7 +108,6 @@ const createControllerMessenger = ({ const createSnapKeyringBuilder = () => snapKeyringBuilder( createControllerMessenger(), - mockSnapController, mockPersisKeyringHelper, mockRemoveAccountHelper, ); diff --git a/app/core/SnapKeyring/SnapKeyring.ts b/app/core/SnapKeyring/SnapKeyring.ts index 6d63ce6709d..ec498b3248d 100644 --- a/app/core/SnapKeyring/SnapKeyring.ts +++ b/app/core/SnapKeyring/SnapKeyring.ts @@ -1,15 +1,13 @@ import { SnapKeyring } from '@metamask/eth-snap-keyring'; -import type { SnapController } from '@metamask/snaps-controllers'; -import { SnapKeyringBuilderMessenger } from './types'; import Logger from '../../util/Logger'; import { showAccountNameSuggestionDialog } from './utils/showDialog'; +import { SnapKeyringBuilderMessenger } from './types'; /** * Constructs a SnapKeyring builder with specified handlers for managing snap accounts. * - Here is the equivalent function on the extension: https://github.com/MetaMask/metamask-extension/blob/develop/app/scripts/lib/snap-keyring/snap-keyring.ts#L111 * * @param controllerMessenger - The controller messenger instance. - * @param getSnapController - A function that retrieves the Snap Controller instance. * @param persistKeyringHelper - A function that persists all keyrings in the vault. * @param removeAccountHelper - A function to help remove an account based on its address. * @returns The constructed SnapKeyring builder instance with the following methods: @@ -21,13 +19,14 @@ import { showAccountNameSuggestionDialog } from './utils/showDialog'; */ export const snapKeyringBuilder = ( controllerMessenger: SnapKeyringBuilderMessenger, - getSnapController: () => SnapController, + persistKeyringHelper: () => Promise, removeAccountHelper: (address: string) => Promise, ): { (): SnapKeyring; type: string } => { const builder = () => - new SnapKeyring(getSnapController(), { - addressExists: async (address) => + // @ts-expect-error TODO: Resolve mismatch between base-controller versions. + new SnapKeyring(controllerMessenger, { + addressExists: async (address: string) => ( await controllerMessenger.call('KeyringController:getAccounts') ).includes(address.toLowerCase()), diff --git a/app/core/SnapKeyring/constants.ts b/app/core/SnapKeyring/constants.ts new file mode 100644 index 00000000000..c08359c767f --- /dev/null +++ b/app/core/SnapKeyring/constants.ts @@ -0,0 +1,15 @@ +import { + SnapKeyringAccountAssetListUpdatedEvent as SnapKeyringAccountAssetListUpdatedEventType, + SnapKeyringAccountBalancesUpdatedEvent as SnapKeyringAccountBalancesUpdatedEventType, + SnapKeyringAccountTransactionsUpdatedEvent as SnapKeyringAccountTransactionsUpdatedEventType, +} from '@metamask/eth-snap-keyring'; + +// Events +export const SnapKeyringAccountAssetListUpdatedEvent: SnapKeyringAccountAssetListUpdatedEventType['type'] = + 'SnapKeyring:accountAssetListUpdated'; + +export const SnapKeyringAccountBalancesUpdatedEvent: SnapKeyringAccountBalancesUpdatedEventType['type'] = + 'SnapKeyring:accountBalancesUpdated'; + +export const SnapKeyringAccountTransactionsUpdatedEvent: SnapKeyringAccountTransactionsUpdatedEventType['type'] = + 'SnapKeyring:accountTransactionsUpdated'; diff --git a/app/core/SnapKeyring/types.ts b/app/core/SnapKeyring/types.ts index 3cb336bdff4..96521f9ffd1 100644 --- a/app/core/SnapKeyring/types.ts +++ b/app/core/SnapKeyring/types.ts @@ -16,6 +16,10 @@ import type { ShowSuccess, StartFlow, } from '@metamask/approval-controller'; +import { + HandleSnapRequest as SnapControllerHandleRequestActionType, + GetSnap as SnapControllerGetSnapActionType, +} from '@metamask/snaps-controllers'; export type SnapKeyringBuilderAllowActions = | StartFlow @@ -31,10 +35,12 @@ export type SnapKeyringBuilderAllowActions = | GetSubjectMetadata | AccountsControllerSetSelectedAccountAction | AccountsControllerGetAccountByAddressAction - | AccountsControllerSetAccountNameAction; + | AccountsControllerSetAccountNameAction + | SnapControllerHandleRequestActionType + | SnapControllerGetSnapActionType; export type SnapKeyringBuilderMessenger = RestrictedMessenger< - 'SnapKeyringBuilder', + 'SnapKeyring', SnapKeyringBuilderAllowActions, never, SnapKeyringBuilderAllowActions['type'], diff --git a/app/selectors/accountsController.test.ts b/app/selectors/accountsController.test.ts index 3c33cdf3af9..f4c6a51d5c3 100644 --- a/app/selectors/accountsController.test.ts +++ b/app/selectors/accountsController.test.ts @@ -1,7 +1,11 @@ import { AccountsControllerState } from '@metamask/accounts-controller'; import { captureException } from '@sentry/react-native'; import { Hex, isValidChecksumAddress } from '@metamask/utils'; -import { BtcAccountType } from '@metamask/keyring-api'; +import { + BtcAccountType, + EthAccountType, + EthScope, +} from '@metamask/keyring-api'; import { InternalAccount } from '@metamask/keyring-internal-api'; import StorageWrapper from '../store/storage-wrapper'; import { @@ -85,7 +89,7 @@ describe('Accounts Controller Selectors', () => { address: '0xc4966c0d659d99699bfd7eb54d8fafee40e4a756', id: expectedUuid2, options: {}, - scopes: ['eip155'], + scopes: [EthScope.Eoa], metadata: { name: 'Account 2', importTime: 1684232000456, @@ -100,7 +104,7 @@ describe('Accounts Controller Selectors', () => { 'eth_signTypedData_v3', 'eth_signTypedData_v4', ], - type: 'eip155:eoa', + type: EthAccountType.Eoa, }); }); it('throws an error if the selected account ID does not exist', () => { diff --git a/app/store/migrations/036.test.ts b/app/store/migrations/036.test.ts index ebf5f797375..9f48e457b9a 100644 --- a/app/store/migrations/036.test.ts +++ b/app/store/migrations/036.test.ts @@ -1,4 +1,4 @@ -import { EthAccountType, EthMethod, EthScopes } from '@metamask/keyring-api'; +import { EthAccountType, EthMethod, EthScope } from '@metamask/keyring-api'; import { InternalAccount } from '@metamask/keyring-internal-api'; import migrate, { Identity } from './036'; import { captureException } from '@sentry/react-native'; @@ -50,7 +50,7 @@ function expectedInternalAccount( ): InternalAccount { return { address, - scopes: [EthScopes.Namespace], + scopes: [EthScope.Eoa], id: getUUIDFromAddressOfNormalAccount(address), metadata: { name: nickname, diff --git a/app/store/migrations/036.ts b/app/store/migrations/036.ts index b73aeae3171..1fea8129061 100644 --- a/app/store/migrations/036.ts +++ b/app/store/migrations/036.ts @@ -1,4 +1,4 @@ -import { EthAccountType, EthScopes } from '@metamask/keyring-api'; +import { EthAccountType, EthScope } from '@metamask/keyring-api'; import { InternalAccount } from '@metamask/keyring-internal-api'; import { isObject, hasProperty } from '@metamask/utils'; import { captureException } from '@sentry/react-native'; @@ -113,7 +113,7 @@ function createInternalAccountsForAccountsController( accounts[expectedId] = { address: identity.address, - scopes: [EthScopes.Namespace], + scopes: [EthScope.Eoa], id: expectedId, options: {}, metadata: { diff --git a/app/store/migrations/066.test.ts b/app/store/migrations/066.test.ts index 970593be3ea..91930983476 100644 --- a/app/store/migrations/066.test.ts +++ b/app/store/migrations/066.test.ts @@ -1,8 +1,9 @@ import { - BtcScopes, - EthScopes, - SolScopes, + BtcScope, + EthScope, + SolScope, EthMethod, + CaipChainId, } from '@metamask/keyring-api'; import { AccountsControllerState } from '@metamask/accounts-controller'; import { captureException } from '@sentry/react-native'; @@ -82,13 +83,26 @@ describe('migration #66', () => { ], scopes: [], }, - 'btc-1': { - id: 'btc-1', + 'btc-mainnet': { + id: 'btc-mainnet', type: 'bip122:p2wpkh', - address: 'bc1abc', + address: 'bc1qwl8399fz829uqvqly9tcatgrgtwp3udnhxfq4k', options: {}, metadata: { - name: 'BTC Account', + name: 'BTC Mainnet Account', + keyring: { type: 'HD Key Tree' }, + importTime: Date.now(), + }, + methods: [], + scopes: [], + }, + 'btc-testnet': { + id: 'btc-testnet', + type: 'bip122:p2wpkh', + address: 'tb1q6rmsq3vlfdhjdhtkxlqtuhhlr6pmj09y6w43g8', + options: {}, + metadata: { + name: 'BTC Testnet Account', keyring: { type: 'HD Key Tree' }, importTime: Date.now(), }, @@ -137,7 +151,7 @@ describe('migration #66', () => { EthMethod.SignTransaction, EthMethod.SignTypedDataV4, ], - scopes: [EthScopes.Namespace], + scopes: [EthScope.Eoa], }, }, }, @@ -220,19 +234,22 @@ describe('migration #66', () => { .accounts; // Check EVM EOA account - expect(accounts['evm-1']?.scopes).toEqual([EthScopes.Namespace]); + expect(accounts['evm-1']?.scopes).toEqual([EthScope.Eoa]); // Check EVM ERC4337 account - expect(accounts['evm-2']?.scopes).toEqual([EthScopes.Namespace]); + expect(accounts['evm-2']?.scopes).toEqual([EthScope.Testnet]); - // Check BTC account - expect(accounts['btc-1']?.scopes).toEqual([BtcScopes.Mainnet]); + // Check BTC mainnet account + expect(accounts['btc-mainnet']?.scopes).toEqual([BtcScope.Mainnet]); + + // Check BTC testnet account + expect(accounts['btc-testnet']?.scopes).toEqual([BtcScope.Testnet]); // Check Solana account expect(accounts['sol-1']?.scopes).toEqual([ - SolScopes.Mainnet, - SolScopes.Testnet, - SolScopes.Devnet, + SolScope.Mainnet, + SolScope.Testnet, + SolScope.Devnet, ]); }); @@ -274,7 +291,7 @@ describe('migration #66', () => { .accounts; // Should still process valid accounts - expect(accounts['valid-1']?.scopes).toEqual([EthScopes.Namespace]); + expect(accounts['valid-1']?.scopes).toEqual([EthScope.Eoa]); }); it('handles invalid scopes property gracefully', () => { @@ -338,6 +355,24 @@ describe('migration #66', () => { // @ts-expect-error Testing invalid scope type scopes: undefined, }, + 'invalid-4': { + id: 'evm-1', + type: 'eip155:eoa', + address: '0x123', + options: {}, + metadata: { + name: 'Account 1', + keyring: { type: 'HD Key Tree' }, + importTime: Date.now(), + }, + methods: [ + EthMethod.PersonalSign, + EthMethod.SignTransaction, + EthMethod.SignTypedDataV4, + ], + // Invalid scope value that's not in any enum + scopes: ['some-random-scope' as CaipChainId], + }, }, }, }, @@ -351,9 +386,10 @@ describe('migration #66', () => { .accounts; // Should fix accounts with invalid scopes - expect(accounts['invalid-1']?.scopes).toEqual([EthScopes.Namespace]); - expect(accounts['invalid-2']?.scopes).toEqual([EthScopes.Namespace]); - expect(accounts['invalid-3']?.scopes).toEqual([EthScopes.Namespace]); + expect(accounts['invalid-1']?.scopes).toEqual([EthScope.Eoa]); + expect(accounts['invalid-2']?.scopes).toEqual([EthScope.Eoa]); + expect(accounts['invalid-3']?.scopes).toEqual([EthScope.Eoa]); + expect(accounts['invalid-4']?.scopes).toEqual([EthScope.Eoa]); }); it('logs unknown account types to Sentry', () => { @@ -391,12 +427,12 @@ describe('migration #66', () => { .accounts; // Verify scopes are set to default EVM namespace - expect(accounts['unknown-1']?.scopes).toEqual([EthScopes.Namespace]); + expect(accounts['unknown-1']?.scopes).toEqual([EthScope.Eoa]); // Verify Sentry exception was captured expect(mockedCaptureException).toHaveBeenCalledWith( new Error( - 'Migration 66: Unknown account type unknown-type, defaulting to EVM namespace', + 'Migration 66: Unknown account type unknown-type, defaulting to EVM EOA', ), ); }); diff --git a/app/store/migrations/066.ts b/app/store/migrations/066.ts index 210a0db07f4..5d408e9272a 100644 --- a/app/store/migrations/066.ts +++ b/app/store/migrations/066.ts @@ -1,52 +1,76 @@ -import { hasProperty, isObject } from '@metamask/utils'; +import { CaipChainId, hasProperty, isObject } from '@metamask/utils'; import { ensureValidState } from './util'; import Logger from '../../util/Logger'; import { BtcAccountType, - BtcScopes, + BtcScope, EthAccountType, - EthScopes, + EthScope, + KeyringAccount, SolAccountType, - SolScopes, + SolScope, } from '@metamask/keyring-api'; import { captureException } from '@sentry/react-native'; +import { isBtcMainnetAddress } from '../../core/Multichain/utils'; -const migrationVersion = 66; +// Helper to check if a scope is a valid enum value +function isValidScope(scope: string): boolean { + return ( + Object.values(EthScope).includes(scope as EthScope) || + Object.values(BtcScope).includes(scope as BtcScope) || + Object.values(SolScope).includes(scope as SolScope) + ); +} -function getScopesForAccountType(accountType: string): string[] { - switch (accountType) { +function getScopesForAccountType( + account: KeyringAccount, + migrationNumber: number, +): CaipChainId[] { + switch (account.type) { case EthAccountType.Eoa: - case EthAccountType.Erc4337: - return [EthScopes.Namespace]; - case BtcAccountType.P2wpkh: - // Default to mainnet scope if address is missing or invalid - return [BtcScopes.Mainnet]; + return [EthScope.Eoa]; + case EthAccountType.Erc4337: { + // EVM Erc4337 account + // NOTE: A Smart Contract account might not be compatible with every chain, in this case we just default + // to testnet since we cannot really "guess" it from here. + // Also, there's no official Snap as of today that uses this account type. So this case should never happen + // in production. + return [EthScope.Testnet]; + } + case BtcAccountType.P2wpkh: { + // Bitcoin uses different accounts for testnet and mainnet + return [ + isBtcMainnetAddress(account.address) + ? BtcScope.Mainnet + : BtcScope.Testnet, + ]; + } case SolAccountType.DataAccount: - return [SolScopes.Mainnet, SolScopes.Testnet, SolScopes.Devnet]; + return [SolScope.Mainnet, SolScope.Testnet, SolScope.Devnet]; default: // Default to EVM namespace for unknown account types captureException( new Error( - `Migration ${migrationVersion}: Unknown account type ${accountType}, defaulting to EVM namespace`, + `Migration ${migrationNumber}: Unknown account type ${account.type}, defaulting to EVM EOA`, ), ); - return [EthScopes.Namespace]; + return [EthScope.Eoa]; } } /** * Migration for adding scopes to accounts in the AccountsController. * Each account type gets its appropriate scopes: - * - EVM EOA: [EthScopes.Namespace] - * - EVM ERC4337: [EthScopes.Namespace] - * - BTC P2WPKH: [BtcScopes.Mainnet] or [BtcScopes.Testnet] based on address - * - Solana: [SolScopes.Mainnet, SolScopes.Testnet, SolScopes.Devnet] + * - EVM EOA: [EthScope.Eoa] + * - EVM ERC4337: [EthScope.Eoa] + * - BTC P2WPKH: [BtcScope.Mainnet] or [BtcScope.Testnet] based on address + * - Solana: [SolScope.Mainnet, SolScope.Testnet, SolScope.Devnet] * * @param state - The state to migrate * @returns The migrated state */ -export default function migrate(state: unknown) { - if (!ensureValidState(state, migrationVersion)) { +export function migration66(state: unknown, migrationNumber: number) { + if (!ensureValidState(state, migrationNumber)) { return state; } @@ -70,7 +94,7 @@ export default function migrate(state: unknown) { ) { captureException( new Error( - `Migration ${migrationVersion}: Invalid state structure for AccountsController`, + `Migration ${migrationNumber}: Invalid state structure for AccountsController`, ), ); return state; @@ -89,17 +113,29 @@ export default function migrate(state: unknown) { hasProperty(account, 'scopes') && Array.isArray(account.scopes) && account.scopes.length > 0 && - account.scopes.every((scope) => typeof scope === 'string') + account.scopes.every( + (scope) => typeof scope === 'string' && isValidScope(scope), + ) ) { continue; } Logger.log( - `Migration ${migrationVersion}: Adding scopes for account type ${account.type}`, + `Migration ${migrationNumber}: Adding scopes for account type ${account.type}`, ); - account.scopes = getScopesForAccountType(account.type as string); + account.scopes = getScopesForAccountType( + account as KeyringAccount, + migrationNumber, + ); } return state; } + +/** + * Migration for adding scopes to accounts in the AccountsController. + */ +export default function migrate(state: unknown) { + return migration66(state, 66); +} diff --git a/app/store/migrations/067.test.ts b/app/store/migrations/067.test.ts new file mode 100644 index 00000000000..277919eabf6 --- /dev/null +++ b/app/store/migrations/067.test.ts @@ -0,0 +1,535 @@ +import { + BtcScope, + EthScope, + SolScope, + EthMethod, + CaipChainId, +} from '@metamask/keyring-api'; +import { AccountsControllerState } from '@metamask/accounts-controller'; +import { captureException } from '@sentry/react-native'; +import migration from './067'; + +jest.mock('../../util/Logger'); +jest.mock('@sentry/react-native', () => ({ + captureException: jest.fn(), +})); + +const mockedCaptureException = jest.mocked(captureException); + +interface StateType { + engine: { + backgroundState: { + AccountsController: AccountsControllerState; + }; + }; +} + +// Migration 67 is a re-run of migration 66 with updated scope values. The tests are the same as 66 with a few extra checks +describe('migration #67', () => { + const MOCK_INVALID_STATE = { + someKey: 'someValue', + }; + + const MOCK_EMPTY_STATE: StateType = { + engine: { + backgroundState: { + AccountsController: { + internalAccounts: { + accounts: {}, + selectedAccount: '', + }, + }, + }, + }, + }; + + const MOCK_STATE_WITH_ACCOUNTS: StateType = { + engine: { + backgroundState: { + AccountsController: { + internalAccounts: { + selectedAccount: 'evm-1', + accounts: { + 'evm-1': { + id: 'evm-1', + type: 'eip155:eoa', + address: '0x123', + options: {}, + metadata: { + name: 'Account 1', + keyring: { type: 'HD Key Tree' }, + importTime: Date.now(), + }, + methods: [ + EthMethod.PersonalSign, + EthMethod.SignTransaction, + EthMethod.SignTypedDataV4, + ], + scopes: [], + }, + 'evm-2': { + id: 'evm-2', + type: 'eip155:erc4337', + address: '0x456', + options: {}, + metadata: { + name: 'Account 2', + keyring: { type: 'HD Key Tree' }, + importTime: Date.now(), + }, + methods: [ + EthMethod.PersonalSign, + EthMethod.SignTransaction, + EthMethod.SignTypedDataV4, + ], + scopes: [], + }, + 'btc-mainnet': { + id: 'btc-mainnet', + type: 'bip122:p2wpkh', + address: 'bc1qwl8399fz829uqvqly9tcatgrgtwp3udnhxfq4k', + options: {}, + metadata: { + name: 'BTC Mainnet Account', + keyring: { type: 'HD Key Tree' }, + importTime: Date.now(), + }, + methods: [], + scopes: [], + }, + 'btc-testnet': { + id: 'btc-testnet', + type: 'bip122:p2wpkh', + address: 'tb1q6rmsq3vlfdhjdhtkxlqtuhhlr6pmj09y6w43g8', + options: {}, + metadata: { + name: 'BTC Testnet Account', + keyring: { type: 'HD Key Tree' }, + importTime: Date.now(), + }, + methods: [], + scopes: [], + }, + 'sol-1': { + id: 'sol-1', + type: 'solana:data-account', + address: 'solana123', + options: {}, + metadata: { + name: 'Solana Account', + keyring: { type: 'HD Key Tree' }, + importTime: Date.now(), + }, + methods: [], + scopes: [], + }, + }, + }, + }, + }, + }, + }; + + const MOCK_STATE_WITH_EXISTING_SCOPES: StateType = { + engine: { + backgroundState: { + AccountsController: { + internalAccounts: { + selectedAccount: 'evm-1', + accounts: { + 'evm-1': { + id: 'evm-1', + type: 'eip155:eoa', + address: '0x123', + options: {}, + metadata: { + name: 'Account 1', + keyring: { type: 'HD Key Tree' }, + importTime: Date.now(), + }, + methods: [ + EthMethod.PersonalSign, + EthMethod.SignTransaction, + EthMethod.SignTypedDataV4, + ], + scopes: [EthScope.Eoa], + }, + }, + }, + }, + }, + }, + }; + + it('captures exception for invalid state structure', () => { + const invalidState = { + engine: { + backgroundState: { + AccountsController: 'not an object', // Invalid type + }, + }, + }; + + const result = migration(invalidState); + + expect(captureException).toHaveBeenCalledWith( + expect.objectContaining({ + message: expect.stringContaining( + 'Invalid state structure for AccountsController', + ), + }), + ); + expect(result).toBe(invalidState); + }); + + it('handles completely missing AccountsController', () => { + const stateWithoutAccounts = { + engine: { + backgroundState: {}, + }, + }; + + const result = migration(stateWithoutAccounts); + + expect(captureException).toHaveBeenCalledWith( + expect.objectContaining({ + message: expect.stringContaining( + 'Invalid state structure for AccountsController', + ), + }), + ); + expect(result).toBe(stateWithoutAccounts); + }); + + it('handles unexpected errors', () => { + const malformedState = null; + + const result = migration(malformedState); + + expect(captureException).toHaveBeenCalled(); + expect(result).toBe(malformedState); + }); + it('returns state if not valid', () => { + const result = migration(MOCK_INVALID_STATE); + expect(result).toEqual(MOCK_INVALID_STATE); + }); + + it('returns state if empty accounts', () => { + const result = migration(MOCK_EMPTY_STATE); + expect(result).toEqual(MOCK_EMPTY_STATE); + }); + + it('preserves accounts that have valid scopes', () => { + const stateCopy = JSON.parse( + JSON.stringify(MOCK_STATE_WITH_EXISTING_SCOPES), + ); + const result = migration(stateCopy) as StateType; + expect(result).toEqual(MOCK_STATE_WITH_EXISTING_SCOPES); + }); + + it('adds correct scopes for all account types', () => { + const stateCopy = JSON.parse(JSON.stringify(MOCK_STATE_WITH_ACCOUNTS)); + const result = migration(stateCopy) as StateType; + const accounts = + result.engine.backgroundState.AccountsController.internalAccounts + .accounts; + + // Check EVM EOA account + expect(accounts['evm-1']?.scopes).toEqual([EthScope.Eoa]); + + // Check EVM ERC4337 account + expect(accounts['evm-2']?.scopes).toEqual([EthScope.Testnet]); + + // Check BTC account + expect(accounts['btc-mainnet']?.scopes).toEqual([BtcScope.Mainnet]); + expect(accounts['btc-testnet']?.scopes).toEqual([BtcScope.Testnet]); + + // Check Solana account + expect(accounts['sol-1']?.scopes).toEqual([ + SolScope.Mainnet, + SolScope.Testnet, + SolScope.Devnet, + ]); + }); + + it('handles malformed account objects gracefully', () => { + const malformedState: StateType = { + engine: { + backgroundState: { + AccountsController: { + internalAccounts: { + selectedAccount: 'valid-1', + accounts: { + 'valid-1': { + id: 'valid-1', + type: 'eip155:eoa', + address: '0x123', + options: {}, + metadata: { + name: 'Account 1', + keyring: { type: 'HD Key Tree' }, + importTime: Date.now(), + }, + methods: [ + EthMethod.PersonalSign, + EthMethod.SignTransaction, + EthMethod.SignTypedDataV4, + ], + scopes: [], + }, + }, + }, + }, + }, + }, + }; + + const result = migration(malformedState) as StateType; + const accounts = + result.engine.backgroundState.AccountsController.internalAccounts + .accounts; + + // Should still process valid accounts + expect(accounts['valid-1']?.scopes).toEqual([EthScope.Eoa]); + }); + + it('handles invalid scopes property gracefully', () => { + const stateWithInvalidScopes: StateType = { + engine: { + backgroundState: { + AccountsController: { + internalAccounts: { + selectedAccount: 'invalid-1', + accounts: { + 'invalid-1': { + id: 'invalid-1', + type: 'eip155:eoa', + address: '0x123', + options: {}, + metadata: { + name: 'Account 1', + keyring: { type: 'HD Key Tree' }, + importTime: Date.now(), + }, + methods: [ + EthMethod.PersonalSign, + EthMethod.SignTransaction, + EthMethod.SignTypedDataV4, + ], + // @ts-expect-error Testing invalid scope type + scopes: null, + }, + 'invalid-2': { + id: 'invalid-2', + type: 'eip155:eoa', + address: '0x456', + options: {}, + metadata: { + name: 'Account 2', + keyring: { type: 'HD Key Tree' }, + importTime: Date.now(), + }, + methods: [ + EthMethod.PersonalSign, + EthMethod.SignTransaction, + EthMethod.SignTypedDataV4, + ], + scopes: [], + }, + 'invalid-3': { + id: 'invalid-3', + type: 'eip155:eoa', + address: '0x789', + options: {}, + metadata: { + name: 'Account 3', + keyring: { type: 'HD Key Tree' }, + importTime: Date.now(), + }, + methods: [ + EthMethod.PersonalSign, + EthMethod.SignTransaction, + EthMethod.SignTypedDataV4, + ], + // @ts-expect-error Testing invalid scope type + scopes: undefined, + }, + }, + }, + }, + }, + }, + }; + + const result = migration(stateWithInvalidScopes) as StateType; + const accounts = + result.engine.backgroundState.AccountsController.internalAccounts + .accounts; + + // Should fix accounts with invalid scopes + expect(accounts['invalid-1']?.scopes).toEqual([EthScope.Eoa]); + expect(accounts['invalid-2']?.scopes).toEqual([EthScope.Eoa]); + expect(accounts['invalid-3']?.scopes).toEqual([EthScope.Eoa]); + }); + + it('logs unknown account types to Sentry', () => { + const stateWithUnknownType: StateType = { + engine: { + backgroundState: { + AccountsController: { + internalAccounts: { + selectedAccount: 'unknown-1', + accounts: { + 'unknown-1': { + id: 'unknown-1', + // @ts-expect-error Testing unknown account type + type: 'unknown-type', + address: '0x123', + options: {}, + metadata: { + name: 'Unknown Account', + keyring: { type: 'HD Key Tree' }, + importTime: Date.now(), + }, + methods: [], + scopes: [], + }, + }, + }, + }, + }, + }, + }; + + const result = migration(stateWithUnknownType) as StateType; + const accounts = + result.engine.backgroundState.AccountsController.internalAccounts + .accounts; + + // Verify scopes are set to default EVM namespace + expect(accounts['unknown-1']?.scopes).toEqual([EthScope.Eoa]); + + // Verify Sentry exception was captured + expect(mockedCaptureException).toHaveBeenCalledWith( + new Error( + 'Migration 67: Unknown account type unknown-type, defaulting to EVM EOA', + ), + ); + }); + + it('updates accounts that were previously migrated with old scope values', () => { + // Old scope values for testing migration from previous state + const OLD_ETH_NAMESPACE_SCOPE = 'eip155' as CaipChainId; + const OLD_SOL_NAMESPACE_SCOPE = 'solana' as CaipChainId; + const OLD_BTC_NAMESPACE_SCOPE = 'bip122' as CaipChainId; + + const stateWithOldScopes: StateType = { + engine: { + backgroundState: { + AccountsController: { + internalAccounts: { + selectedAccount: 'evm-1', + accounts: { + 'evm-1': { + id: 'evm-1', + type: 'eip155:eoa', + address: '0x123', + options: {}, + metadata: { + name: 'Account 1', + keyring: { type: 'HD Key Tree' }, + importTime: Date.now(), + }, + methods: [ + EthMethod.PersonalSign, + EthMethod.SignTransaction, + EthMethod.SignTypedDataV4, + ], + // This represents the old scope value from migration 66 + scopes: [OLD_ETH_NAMESPACE_SCOPE], + }, + 'evm-2': { + id: 'evm-2', + type: 'eip155:erc4337', + address: '0x456', + options: {}, + metadata: { + name: 'Account 2', + keyring: { type: 'HD Key Tree' }, + importTime: Date.now(), + }, + methods: [ + EthMethod.PersonalSign, + EthMethod.SignTransaction, + EthMethod.SignTypedDataV4, + ], + // This represents the old scope value from migration 66 + scopes: [OLD_ETH_NAMESPACE_SCOPE], + }, + 'sol-1': { + id: 'sol-1', + type: 'solana:data-account', + address: 'solana123', + options: {}, + metadata: { + name: 'Solana Account', + keyring: { type: 'HD Key Tree' }, + importTime: Date.now(), + }, + methods: [], + // Old Solana namespace scope + scopes: [OLD_SOL_NAMESPACE_SCOPE], + }, + 'btc-mainnet': { + id: 'btc-mainnet', + type: 'bip122:p2wpkh', + address: 'bc1qwl8399fz829uqvqly9tcatgrgtwp3udnhxfq4k', + options: {}, + metadata: { + name: 'BTC Account', + keyring: { type: 'HD Key Tree' }, + importTime: Date.now(), + }, + methods: [], + // Old BTC namespace scope + scopes: [OLD_BTC_NAMESPACE_SCOPE], + }, + 'btc-testnet': { + id: 'btc-testnet', + type: 'bip122:p2wpkh', + address: 'tb1q6rmsq3vlfdhjdhtkxlqtuhhlr6pmj09y6w43g8', + options: {}, + metadata: { + name: 'BTC Account', + keyring: { type: 'HD Key Tree' }, + importTime: Date.now(), + }, + methods: [], + // Old BTC namespace scope + scopes: [OLD_BTC_NAMESPACE_SCOPE], + }, + }, + }, + }, + }, + }, + }; + + const stateCopy = JSON.parse(JSON.stringify(stateWithOldScopes)); + const result = migration(stateCopy) as StateType; + const accounts = + result.engine.backgroundState.AccountsController.internalAccounts + .accounts; + + // Check that old scope values were updated to new ones + expect(accounts['evm-1']?.scopes).toEqual([EthScope.Eoa]); + expect(accounts['evm-2']?.scopes).toEqual([EthScope.Testnet]); + expect(accounts['sol-1']?.scopes).toEqual([ + SolScope.Mainnet, + SolScope.Testnet, + SolScope.Devnet, + ]); + expect(accounts['btc-mainnet']?.scopes).toEqual([BtcScope.Mainnet]); + expect(accounts['btc-testnet']?.scopes).toEqual([BtcScope.Testnet]); + }); +}); diff --git a/app/store/migrations/067.ts b/app/store/migrations/067.ts new file mode 100644 index 00000000000..c837db9bd86 --- /dev/null +++ b/app/store/migrations/067.ts @@ -0,0 +1,14 @@ +import { migration66 } from './066'; + +/** + * Migration for ensuring that all internal accounts have the correct scopes + * Re-uses logic from migration 66 + * We have to re-run 66 as 67 because the values for the scopes changed + * and users who already had 66 ran would not have the updated scope values. + * The migration 66 was initially injecting a CAIP-2 namespace (eip155 for EVM EOA) rather than a full scope (eip155:0). + * We now require full scopes (namespace:chain-id) for all Internal Accounts. + * See https://github.com/MetaMask/accounts/pull/165 for more details. + */ +export default function migrate(state: unknown) { + return migration66(state, 67); +} diff --git a/app/store/migrations/index.ts b/app/store/migrations/index.ts index 94522a41af3..b7e9af854b5 100644 --- a/app/store/migrations/index.ts +++ b/app/store/migrations/index.ts @@ -67,6 +67,7 @@ import migration63 from './063'; import migration64 from './064'; import migration65 from './065'; import migration66 from './066'; +import migration67 from './067'; import { validatePostMigrationState } from '../validateMigration/validateMigration'; import { RootState } from '../../reducers'; @@ -148,6 +149,7 @@ export const migrationList: MigrationsList = { 64: migration64, 65: migration65, 66: migration66, + 67: migration67, }; // Enable both synchronous and asynchronous migrations diff --git a/app/store/validateMigration/accountsController.test.ts b/app/store/validateMigration/accountsController.test.ts index 1ea53201d9a..722ff4abd05 100644 --- a/app/store/validateMigration/accountsController.test.ts +++ b/app/store/validateMigration/accountsController.test.ts @@ -4,7 +4,7 @@ import { RootState } from '../../reducers'; import { AccountsControllerState } from '@metamask/accounts-controller'; import { EngineState } from '../../core/Engine/types'; import { Json } from '@metamask/utils'; -import { EthScopes } from '@metamask/keyring-api'; +import { EthScope } from '@metamask/keyring-api'; describe('validateAccountsController', () => { const createMockState = ( @@ -26,7 +26,7 @@ describe('validateAccountsController', () => { id: 'account-1', address: '0x123', type: 'eip155:eoa', - scopes: [EthScopes.Namespace], + scopes: [EthScope.Eoa], options: {} as Record, methods: [], metadata: { @@ -89,7 +89,7 @@ describe('validateAccountsController', () => { id: 'account-1', address: '0x123', type: 'eip155:eoa', - scopes: [EthScopes.Namespace], + scopes: [EthScope.Eoa], options: {} as Record, methods: [], metadata: { @@ -120,7 +120,7 @@ describe('validateAccountsController', () => { id: 'account-1', address: '0x123', type: 'eip155:eoa', - scopes: [EthScopes.Namespace], + scopes: [EthScope.Eoa], options: {} as Record, methods: [], metadata: { diff --git a/app/util/sentry/__snapshots__/utils.test.ts.snap b/app/util/sentry/__snapshots__/utils.test.ts.snap index 01e4488c0b5..470f81fe5a4 100644 --- a/app/util/sentry/__snapshots__/utils.test.ts.snap +++ b/app/util/sentry/__snapshots__/utils.test.ts.snap @@ -53,7 +53,7 @@ exports[`captureSentryFeedback maskObject masks initial root state fixture 1`] = ], "options": {}, "scopes": [ - "eip155", + "eip155:0", ], "type": "eip155:eoa", }, @@ -74,7 +74,7 @@ exports[`captureSentryFeedback maskObject masks initial root state fixture 1`] = ], "options": {}, "scopes": [ - "eip155", + "eip155:0", ], "type": "eip155:eoa", }, diff --git a/app/util/sentry/utils.test.ts b/app/util/sentry/utils.test.ts index e17bc88224d..18ac7afb043 100644 --- a/app/util/sentry/utils.test.ts +++ b/app/util/sentry/utils.test.ts @@ -11,7 +11,7 @@ import { import { DeepPartial } from '../test/renderWithProvider'; import { RootState } from '../../reducers'; import { NetworkStatus } from '@metamask/network-controller'; -import { EthScopes } from '@metamask/keyring-api'; +import { EthScope } from '@metamask/keyring-api'; jest.mock('@sentry/react-native', () => ({ ...jest.requireActual('@sentry/react-native'), @@ -178,7 +178,7 @@ describe('captureSentryFeedback', () => { 'eth_signTypedData_v3', 'eth_signTypedData_v4', ], - scopes: [EthScopes.Namespace], + scopes: [EthScope.Eoa], options: {}, type: 'eip155:eoa', }, @@ -193,7 +193,7 @@ describe('captureSentryFeedback', () => { lastSelected: 1720023898237, name: 'Account 2', }, - scopes: [EthScopes.Namespace], + scopes: [EthScope.Eoa], methods: ['personal_sign', 'eth_signTransaction'], options: {}, type: 'eip155:eoa', @@ -633,7 +633,7 @@ describe('captureSentryFeedback', () => { 'eth_signTypedData_v3', 'eth_signTypedData_v4', ]); - expect(maskedAccount1.scopes).toEqual([EthScopes.Namespace]); + expect(maskedAccount1.scopes).toEqual([EthScope.Eoa]); expect(maskedAccount1.metadata).toEqual({ importTime: 1720023898234, keyring: { type: 'HD Key Tree' }, @@ -649,7 +649,7 @@ describe('captureSentryFeedback', () => { 'personal_sign', 'eth_signTransaction', ]); - expect(maskedAccount2.scopes).toEqual([EthScopes.Namespace]); + expect(maskedAccount2.scopes).toEqual([EthScope.Eoa]); expect(maskedAccount2.metadata).toEqual({ importTime: 1720023898235, keyring: { type: 'HD Key Tree' }, diff --git a/app/util/test/accountsControllerTestUtils.ts b/app/util/test/accountsControllerTestUtils.ts index 34a82eeb4b1..3ebc1a4e68f 100644 --- a/app/util/test/accountsControllerTestUtils.ts +++ b/app/util/test/accountsControllerTestUtils.ts @@ -4,15 +4,19 @@ import { BtcAccountType, SolAccountType, EthMethod, - EthScopes, - BtcScopes, - SolScopes, + EthScope, + BtcScope, + SolScope, KeyringAccountType, BtcMethod, SolMethod, + CaipChainId, } from '@metamask/keyring-api'; import { InternalAccount } from '@metamask/keyring-internal-api'; -import { AccountsControllerState } from '@metamask/accounts-controller'; +import { + AccountId, + AccountsControllerState, +} from '@metamask/accounts-controller'; import { KeyringTypes } from '@metamask/keyring-controller'; import { mockQrKeyringAddress, @@ -21,7 +25,7 @@ import { mockSnapAddress2, } from './keyringControllerTestUtils'; -export function createMockUuidFromAddress(address: string): string { +export function createMockUuidFromAddress(address: string): AccountId { const fakeShaFromAddress = Array.from( { length: 16 }, (_, i) => address.charCodeAt(i) || 0, @@ -36,18 +40,18 @@ export function createMockUuidFromAddress(address: string): string { * @param accountType - The type of account (ETH, BTC, or Solana) * @returns Array of scopes corresponding to the account type */ -function getAccountTypeScopes(accountType: KeyringAccountType): string[] { +function getAccountTypeScopes(accountType: KeyringAccountType): CaipChainId[] { // Define scope mappings const scopeMappings = { // Ethereum account types - [EthAccountType.Eoa]: [EthScopes.Namespace], - [EthAccountType.Erc4337]: [EthScopes.Namespace], + [EthAccountType.Eoa]: [EthScope.Eoa], + [EthAccountType.Erc4337]: [EthScope.Testnet], // Bitcoin account types - [BtcAccountType.P2wpkh]: [BtcScopes.Namespace], + [BtcAccountType.P2wpkh]: [BtcScope.Mainnet], // Solana account types - [SolAccountType.DataAccount]: [SolScopes.Namespace], + [SolAccountType.DataAccount]: [SolScope.Mainnet], }; const scopes = scopeMappings[accountType]; @@ -128,7 +132,7 @@ export function createMockSnapInternalAccount( EthMethod.SignTypedDataV4, ], type: EthAccountType.Eoa, - scopes: [EthScopes.Namespace], + scopes: [EthScope.Eoa], }; } @@ -137,7 +141,7 @@ export const MOCK_ACCOUNT_BIP122_P2WPKH: InternalAccount = { address: 'bc1qwl8399fz829uqvqly9tcatgrgtwp3udnhxfq4k', options: {}, methods: [BtcMethod.SendBitcoin], - scopes: [BtcScopes.Mainnet], + scopes: [BtcScope.Mainnet], type: BtcAccountType.P2wpkh, metadata: { name: 'Bitcoin Account', @@ -152,7 +156,7 @@ export const MOCK_ACCOUNT_BIP122_P2WPKH_TESTNET: InternalAccount = { address: 'tb1q6rmsq3vlfdhjdhtkxlqtuhhlr6pmj09y6w43g8', options: {}, methods: [BtcMethod.SendBitcoin], - scopes: [BtcScopes.Testnet], + scopes: [BtcScope.Testnet], type: BtcAccountType.P2wpkh, metadata: { name: 'Bitcoin Testnet Account', @@ -180,7 +184,7 @@ export const MOCK_SOLANA_ACCOUNT: InternalAccount = { enabled: true, }, }, - scopes: [SolScopes.Mainnet, SolScopes.Testnet, SolScopes.Devnet], + scopes: [SolScope.Mainnet, SolScope.Testnet, SolScope.Devnet], }; export const MOCK_MULTICHAIN_NON_EVM_ACCOUNTS = { diff --git a/package.json b/package.json index b5a84527f42..e782ace213f 100644 --- a/package.json +++ b/package.json @@ -152,7 +152,7 @@ "@keystonehq/metamask-airgapped-keyring": "^0.13.1", "@keystonehq/ur-decoder": "^0.12.2", "@ledgerhq/react-native-hw-transport-ble": "^6.33.2", - "@metamask/accounts-controller": "^21.0.0", + "@metamask/accounts-controller": "^23.1.0", "@metamask/address-book-controller": "^6.0.3", "@metamask/approval-controller": "^7.1.0", "@metamask/assets-controllers": "^46.0.0", @@ -167,7 +167,7 @@ "@metamask/eth-ledger-bridge-keyring": "8.0.3", "@metamask/eth-query": "^4.0.0", "@metamask/eth-sig-util": "^8.0.0", - "@metamask/eth-snap-keyring": "^7.1.0", + "@metamask/eth-snap-keyring": "^10.0.0", "@metamask/etherscan-link": "^2.0.0", "@metamask/ethjs-contract": "^0.4.1", "@metamask/ethjs-query": "^0.7.1", @@ -176,9 +176,9 @@ "@metamask/json-rpc-engine": "^10.0.3", "@metamask/json-rpc-middleware-stream": "^8.0.6", "@metamask/key-tree": "^9.0.0", - "@metamask/keyring-api": "^13.0.0", + "@metamask/keyring-api": "^17.0.0", "@metamask/keyring-controller": "^19.0.1", - "@metamask/keyring-internal-api": "^2.0.0", + "@metamask/keyring-internal-api": "^4.0.2", "@metamask/keyring-snap-client": "^2.0.0", "@metamask/logging-controller": "^6.0.4", "@metamask/message-signing-snap": "^0.3.3", @@ -206,13 +206,13 @@ "@metamask/snaps-controllers": "^9.15.0", "@metamask/snaps-execution-environments": "^6.10.0", "@metamask/snaps-rpc-methods": "^11.7.0", - "@metamask/snaps-sdk": "^6.13.0", - "@metamask/snaps-utils": "^8.6.1", + "@metamask/snaps-sdk": "^6.17.1", + "@metamask/snaps-utils": "^8.10.0", "@metamask/solana-wallet-snap": "^1.2.0", "@metamask/stake-sdk": "^1.0.0", "@metamask/swappable-obj-proxy": "^2.1.0", "@metamask/swaps-controller": "^12.1.0", - "@metamask/transaction-controller": "^43.0.0", + "@metamask/transaction-controller": "^45.1.0", "@metamask/utils": "^11.1.0", "@ngraveio/bc-ur": "^1.1.6", "@notifee/react-native": "^9.0.0", diff --git a/scripts/setup.mjs b/scripts/setup.mjs index 4495a141c0e..c48d533e545 100644 --- a/scripts/setup.mjs +++ b/scripts/setup.mjs @@ -238,7 +238,7 @@ const jetifyTask = { const patchPackageTask = { title: 'Patch npm packages', task: async () => { - await $`yarn patch-package`; + await $`yarn patch-package --error-on-fail`; }, }; diff --git a/yarn.lock b/yarn.lock index ebabe795bad..66218e9ff86 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1957,12 +1957,12 @@ "@ethereumjs/util" "^8.1.0" crc-32 "^1.2.0" -"@ethereumjs/common@^4.3.0": - version "4.3.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-4.3.0.tgz#5b45eec7dcf521fa4ddaf0b383072fbcf9913553" - integrity sha512-shBNJ0ewcPNTUfZduHiczPmqkfJDn0Dh/9BR5fq7xUFTuIq7Fu1Vx00XDwQVIrpVL70oycZocOhBM6nDO+4FEQ== +"@ethereumjs/common@^4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-4.4.0.tgz#fba41612f527a815bf304e98653d6b5fc5d6d4de" + integrity sha512-Fy5hMqF6GsE6DpYTyqdDIJPJgUtDn4dL120zKw+Pswuo+iLyBsEYuSyzMw6NVzD2vDzcBG9fE4+qX4X2bPc97w== dependencies: - "@ethereumjs/util" "^9.0.3" + "@ethereumjs/util" "^9.1.0" "@ethereumjs/rlp@^4.0.1": version "4.0.1" @@ -1984,15 +1984,15 @@ "@ethereumjs/util" "^8.1.0" ethereum-cryptography "^2.0.0" -"@ethereumjs/tx@^5.2.1": - version "5.3.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-5.3.0.tgz#473f351729ef4e30eaa3a3fb5aaccd4405a7ee41" - integrity sha512-uv++XYuIfuqYbvymL3/o14hHuC6zX0nRQ1nI2FHsbkkorLZ2ChEIDqVeeVk7Xc9/jQNU/22sk9qZZkRlsveXxw== +"@ethereumjs/tx@^5.2.1", "@ethereumjs/tx@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-5.4.0.tgz#6f47894cc3e2d4e63d87c62b41ed7e8180a1de58" + integrity sha512-SCHnK7m/AouZ7nyoR0MEXw1OO/tQojSbp88t8oxhwes5iZkZCtfFdUrJaiIb72qIpH2FVw6s1k1uP7LXuH7PsA== dependencies: - "@ethereumjs/common" "^4.3.0" + "@ethereumjs/common" "^4.4.0" "@ethereumjs/rlp" "^5.0.2" - "@ethereumjs/util" "^9.0.3" - ethereum-cryptography "^2.1.3" + "@ethereumjs/util" "^9.1.0" + ethereum-cryptography "^2.2.1" "@ethereumjs/util@^8.0.0", "@ethereumjs/util@^8.1.0": version "8.1.0" @@ -2003,13 +2003,13 @@ ethereum-cryptography "^2.0.0" micro-ftch "^0.3.1" -"@ethereumjs/util@^9.0.2", "@ethereumjs/util@^9.0.3": - version "9.0.3" - resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-9.0.3.tgz#c2709e6127a85bbe23a71937ac78358ac93e7241" - integrity sha512-PmwzWDflky+7jlZIFqiGsBPap12tk9zK5SVH9YW2OEnDN7OEhCjUOMzbOqwuClrbkSIkM2ERivd7sXZ48Rh/vg== +"@ethereumjs/util@^9.0.2", "@ethereumjs/util@^9.1.0": + version "9.1.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-9.1.0.tgz#75e3898a3116d21c135fa9e29886565609129bce" + integrity sha512-XBEKsYqLGXLah9PNJbgdkigthkG7TAGvlD/sH12beMXEyHDyigfcbdvHhmLyDWgDyOJn4QwiQUaF7yeuhnjdog== dependencies: "@ethereumjs/rlp" "^5.0.2" - ethereum-cryptography "^2.1.3" + ethereum-cryptography "^2.2.1" "@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.7.0": version "5.7.0" @@ -4436,19 +4436,19 @@ "@metamask/superstruct" "^3.1.0" "@metamask/utils" "^11.0.1" -"@metamask/accounts-controller@^21.0.0": - version "21.0.0" - resolved "https://registry.yarnpkg.com/@metamask/accounts-controller/-/accounts-controller-21.0.0.tgz#d4ef858cd9ec126423fe4a287edada1b9aa9d45a" - integrity sha512-Jt5knLn6n9DQ3IUsfjmtx6NjOTSZrUxHWdvU+SHtQxqkrtNlldqv1C+hQv4DxCTmk6MfSttuEdWObCaxpB2sMA== +"@metamask/accounts-controller@^23.1.0": + version "23.1.0" + resolved "https://registry.yarnpkg.com/@metamask/accounts-controller/-/accounts-controller-23.1.0.tgz#f399f0a92d280abb3ec222fe46fe3d86bb97bcfb" + integrity sha512-woIahBg0PqzfcP/O4iIk2yk1WGmUIA2a4qplok2OEV0a2ZAIENfyaysvDCXwC5RO8Ka53mX/cDn/lRd4rFNeLw== dependencies: "@ethereumjs/util" "^8.1.0" - "@metamask/base-controller" "^7.1.1" - "@metamask/eth-snap-keyring" "^8.0.0" - "@metamask/keyring-api" "^13.0.0" - "@metamask/keyring-internal-api" "^2.0.0" - "@metamask/snaps-sdk" "^6.7.0" - "@metamask/snaps-utils" "^8.3.0" - "@metamask/utils" "^11.0.1" + "@metamask/base-controller" "^8.0.0" + "@metamask/eth-snap-keyring" "^10.0.0" + "@metamask/keyring-api" "^17.0.0" + "@metamask/keyring-internal-api" "^4.0.1" + "@metamask/snaps-sdk" "^6.17.1" + "@metamask/snaps-utils" "^8.10.0" + "@metamask/utils" "^11.1.0" deepmerge "^4.2.2" ethereum-cryptography "^2.1.2" immer "^9.0.6" @@ -4506,7 +4506,7 @@ single-call-balance-checker-abi "^1.0.0" uuid "^8.3.2" -"@metamask/base-controller@^7.0.1", "@metamask/base-controller@^7.0.2", "@metamask/base-controller@^7.1.0", "@metamask/base-controller@^7.1.1": +"@metamask/base-controller@^7.0.1", "@metamask/base-controller@^7.0.2", "@metamask/base-controller@^7.0.3", "@metamask/base-controller@^7.1.0", "@metamask/base-controller@^7.1.1": version "7.1.1" resolved "https://registry.yarnpkg.com/@metamask/base-controller/-/base-controller-7.1.1.tgz#837216ee099563b2106202fa0ed376dc909dfbb9" integrity sha512-4nbA6RL9y0SdHdn4MmMTREX6ISJL7OGHn0GXXszv0tp1fdjsn+SBs28uu1a9ceg1J7R/lO6JH7jAAz8zRtt8Nw== @@ -4708,11 +4708,12 @@ ethereum-cryptography "^2.1.2" tweetnacl "^1.0.3" -"@metamask/eth-sig-util@^8.0.0", "@metamask/eth-sig-util@^8.1.2": - version "8.1.2" - resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-8.1.2.tgz#8869bd9cdc989af7402812d5fa4d9a0f6cc30b98" - integrity sha512-+M7TKF8+RwqmfmDCfhgn7jDLtWfbpPCuBfkYPBpk9ptuqINu7+QzthNlU0Rn7jiJ//buyg2pModXVtpRBmgAeA== +"@metamask/eth-sig-util@^8.0.0", "@metamask/eth-sig-util@^8.1.2", "@metamask/eth-sig-util@^8.2.0": + version "8.2.0" + resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-8.2.0.tgz#f114ca5b2a1a997b467933c902e7ec44123eb8fb" + integrity sha512-LZDglIh4gYGw9Myp+2aIwKrj6lIJpMC4e0m7wKJU+BxLLBFcrTgKrjdjstXGVWvuYG3kutlh9J+uNBRPJqffWQ== dependencies: + "@ethereumjs/rlp" "^4.0.1" "@ethereumjs/util" "^8.1.0" "@metamask/abi-utils" "^3.0.0" "@metamask/utils" "^11.0.1" @@ -4731,45 +4732,22 @@ ethereum-cryptography "^2.1.2" randombytes "^2.1.0" -"@metamask/eth-snap-keyring@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@metamask/eth-snap-keyring/-/eth-snap-keyring-7.1.0.tgz#d472ff8c9abee1f438398d749408cd12ee44ada7" - integrity sha512-aOP8WkapqFmne7xt7Xo39YPxA3fvwSzKEO+Eo+o76r4rBAutH6QLNO9gmy6e4wm2TG9hHzsQjceZmLns75suvg== - dependencies: - "@ethereumjs/tx" "^4.2.0" - "@metamask/eth-sig-util" "^8.1.2" - "@metamask/keyring-api" "^13.0.0" - "@metamask/keyring-internal-api" "^1.1.0" - "@metamask/keyring-internal-snap-client" "^1.1.0" - "@metamask/keyring-utils" "^1.0.0" - "@metamask/snaps-controllers" "^9.10.0" - "@metamask/snaps-sdk" "^6.7.0" - "@metamask/snaps-utils" "^8.3.0" - "@metamask/superstruct" "^3.1.0" - "@metamask/utils" "^11.0.1" - "@types/uuid" "^9.0.8" - uuid "^9.0.1" - webextension-polyfill "^0.12.0" - -"@metamask/eth-snap-keyring@^8.0.0": - version "8.0.0" - resolved "https://registry.yarnpkg.com/@metamask/eth-snap-keyring/-/eth-snap-keyring-8.0.0.tgz#60f6bdf3ed80b096172ebd983773fdc095a94c28" - integrity sha512-NLJmEcJYA+EAnX40N18aVlUZkXARHLDsJT7YoAtVBppRXZRNl9o5FGMe7xh5NrMdcy/Yss1TbQOnqyD0Ox2boA== +"@metamask/eth-snap-keyring@^10.0.0": + version "10.0.0" + resolved "https://registry.yarnpkg.com/@metamask/eth-snap-keyring/-/eth-snap-keyring-10.0.0.tgz#d0fc41ee4f9ec60c144a6230fde49c2684713d19" + integrity sha512-BOUZ1uM5sszDpFoJnWN5PhtOkz7laE8uUMF36Vqs1czmRkeHRREluuUMpyKUlFmk1XmVj6toRui6l8ayUXAAkg== dependencies: "@ethereumjs/tx" "^4.2.0" - "@metamask/eth-sig-util" "^8.1.2" - "@metamask/keyring-api" "^13.0.0" - "@metamask/keyring-internal-api" "^2.0.0" - "@metamask/keyring-internal-snap-client" "^2.0.0" - "@metamask/keyring-utils" "^1.0.0" - "@metamask/snaps-controllers" "^9.10.0" - "@metamask/snaps-sdk" "^6.7.0" - "@metamask/snaps-utils" "^8.3.0" + "@metamask/base-controller" "^7.1.1" + "@metamask/eth-sig-util" "^8.2.0" + "@metamask/keyring-api" "^17.0.0" + "@metamask/keyring-internal-api" "^4.0.2" + "@metamask/keyring-internal-snap-client" "^4.0.0" + "@metamask/keyring-utils" "^2.0.0" "@metamask/superstruct" "^3.1.0" - "@metamask/utils" "^11.0.1" + "@metamask/utils" "^11.1.0" "@types/uuid" "^9.0.8" uuid "^9.0.1" - webextension-polyfill "^0.12.0" "@metamask/etherscan-link@^2.0.0": version "2.1.0" @@ -4890,13 +4868,13 @@ "@metamask/utils" "^11.0.1" readable-stream "^3.6.2" -"@metamask/key-tree@^10.0.0", "@metamask/key-tree@^10.0.1": - version "10.0.1" - resolved "https://registry.yarnpkg.com/@metamask/key-tree/-/key-tree-10.0.1.tgz#b8928750121b122a9d83a5cebdb2b5e34a16eaae" - integrity sha512-R+xjgxKRsEzr37dE4oaA7u7itQZiO0X3FtBqlDDHi3wMB5RK/oTqH1RIPBOyUHnXxL59ldTc6hA+ZmvXos28eg== +"@metamask/key-tree@^10.0.0", "@metamask/key-tree@^10.0.1", "@metamask/key-tree@^10.0.2": + version "10.0.2" + resolved "https://registry.yarnpkg.com/@metamask/key-tree/-/key-tree-10.0.2.tgz#d6fe993cdae423adc5a755a14a19b4a951416f56" + integrity sha512-GFCPZfiiaJAjAXthdvgxa4/ZD41IOZyCVc5MjgWnzj6Euur5URPqhMuefak6hBtY/Hz50gbDwLn8ODj4hbFF3A== dependencies: "@metamask/scure-bip39" "^2.1.1" - "@metamask/utils" "^10.0.1" + "@metamask/utils" "^11.0.1" "@noble/curves" "^1.2.0" "@noble/hashes" "^1.3.2" "@scure/base" "^1.0.0" @@ -4935,6 +4913,16 @@ "@metamask/utils" "^11.0.1" bech32 "^2.0.0" +"@metamask/keyring-api@^17.0.0": + version "17.0.0" + resolved "https://registry.yarnpkg.com/@metamask/keyring-api/-/keyring-api-17.0.0.tgz#016e2b9a4dc116a063aa362a23b6c441d5e043d1" + integrity sha512-e0i+4pHjjCLHahdsnpqll2crfhW7655fS2oz89EMVatt4TSTNwNCQEdMu4MLrRFgz8e0K+RMoXGpshHp16DDlQ== + dependencies: + "@metamask/keyring-utils" "^2.0.0" + "@metamask/superstruct" "^3.1.0" + "@metamask/utils" "^11.1.0" + bech32 "^2.0.0" + "@metamask/keyring-controller@^19.0.1": version "19.0.1" resolved "https://registry.yarnpkg.com/@metamask/keyring-controller/-/keyring-controller-19.0.1.tgz#6fee40a46a780a720f4c864ea779673569be06a7" @@ -4954,56 +4942,30 @@ ethereumjs-wallet "^1.0.1" immer "^9.0.6" -"@metamask/keyring-internal-api@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@metamask/keyring-internal-api/-/keyring-internal-api-1.1.0.tgz#3614c1a9d6f88e40421c2232789529cb395a2157" - integrity sha512-bKY7Iy0JfWyHK+E3HKrGgQrJM6TY2FjrBTaBiyc4Jrl1aOh55BIW57WygSkMvHT3rsBI/Vg3GWnq1io+7PG+Zw== - dependencies: - "@metamask/keyring-api" "^13.0.0" - "@metamask/keyring-utils" "^1.0.0" - "@metamask/superstruct" "^3.1.0" - "@metamask/utils" "^11.0.1" - -"@metamask/keyring-internal-api@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@metamask/keyring-internal-api/-/keyring-internal-api-2.0.0.tgz#809b1acea178384bb704e8025d8557a30072f6f1" - integrity sha512-CG9MSt3CdcnIQpvgJ4StQqUkdVfv3YX0dXQuZG6czKtW+TNV/43xbgoaQuAk+XsisqfY5zMCmr+XTL3Wvwfc7Q== +"@metamask/keyring-internal-api@^4.0.1", "@metamask/keyring-internal-api@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@metamask/keyring-internal-api/-/keyring-internal-api-4.0.2.tgz#0283bb725ab0f17e6ff720c773dc475af06126b1" + integrity sha512-y8KeTRS6M0xjGOCaCcvAxC7FDYLmIn4O/XVFMa5k91MTT5DDnlmSH73JYpIFulaZ3cgiR/NvK9KlwiuqZ6GtiQ== dependencies: - "@metamask/keyring-api" "^13.0.0" - "@metamask/keyring-utils" "^1.0.0" + "@metamask/keyring-api" "^17.0.0" + "@metamask/keyring-utils" "^2.0.0" "@metamask/superstruct" "^3.1.0" - "@metamask/utils" "^11.0.1" + "@metamask/utils" "^11.1.0" -"@metamask/keyring-internal-snap-client@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@metamask/keyring-internal-snap-client/-/keyring-internal-snap-client-1.1.0.tgz#8e6bf842502f314fecb777c31a389f779c22bb62" - integrity sha512-5sl5c9QEZ7tCWLZgBXeDc0h/QquxYmnz5jetW5LEle1wa6WaUC/qryyt4FWe/Qy8mcMO05EIOMBDMKIQfea6ww== +"@metamask/keyring-internal-snap-client@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@metamask/keyring-internal-snap-client/-/keyring-internal-snap-client-4.0.0.tgz#856e2ed7f0880692ac540331f58d36582034f3af" + integrity sha512-Ms5PNqj/8NfiovE1aGXjHzBjQnSx+/KdaygSipSmUj4tsi4tGVxaCn/Nxf6GHxgoDCU+88OsexLCEfNH6mZI9Q== dependencies: - "@metamask/keyring-api" "^13.0.0" - "@metamask/keyring-snap-client" "^1.1.0" - "@metamask/keyring-utils" "^1.0.0" - "@metamask/snaps-controllers" "^9.10.0" - "@metamask/snaps-sdk" "^6.7.0" - "@metamask/snaps-utils" "^8.3.0" - webextension-polyfill "^0.12.0" + "@metamask/base-controller" "^7.1.1" + "@metamask/keyring-api" "^17.0.0" + "@metamask/keyring-snap-client" "^4.0.0" + "@metamask/keyring-utils" "^2.0.0" -"@metamask/keyring-internal-snap-client@^2.0.0": +"@metamask/keyring-snap-client@^2.0.0": version "2.0.0" - resolved "https://registry.yarnpkg.com/@metamask/keyring-internal-snap-client/-/keyring-internal-snap-client-2.0.0.tgz#c44194af6d880c7b39fe583f4500e740a157fd8b" - integrity sha512-jfJkpsEgaUfbvT6gvqinZB72EnqZF1PkVByalAe2M9RGIvDkSkg6VNilgkEWXtzhz0xttaYD1wET6zJdmdaNFg== - dependencies: - "@metamask/keyring-api" "^13.0.0" - "@metamask/keyring-snap-client" "^2.0.0" - "@metamask/keyring-utils" "^1.0.0" - "@metamask/snaps-controllers" "^9.10.0" - "@metamask/snaps-sdk" "^6.7.0" - "@metamask/snaps-utils" "^8.3.0" - webextension-polyfill "^0.12.0" - -"@metamask/keyring-snap-client@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@metamask/keyring-snap-client/-/keyring-snap-client-1.1.0.tgz#0d215ed923d24bebb11721ffe093ea362176adce" - integrity sha512-Iv59YZlx/P67Jz9aq5XBE3AqS2TBXVcsGppw4busdhjgUG+vC9LXf7HeXwQmhnNh8IX8YAL03dX3cATg//d0KA== + resolved "https://registry.yarnpkg.com/@metamask/keyring-snap-client/-/keyring-snap-client-2.0.0.tgz#395af45471ba8bf79e4778d5afd6dd56327b9e97" + integrity sha512-P6xR4sbYEp9vhg5yxTcPLDW1fFve1FHgYT72HS10KXZQvKlGgoOwZe8kcNpQGarqa/Cr4IwzpULJP8Xm/sAF+w== dependencies: "@metamask/keyring-api" "^13.0.0" "@metamask/keyring-utils" "^1.0.0" @@ -5012,13 +4974,13 @@ uuid "^9.0.1" webextension-polyfill "^0.12.0" -"@metamask/keyring-snap-client@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@metamask/keyring-snap-client/-/keyring-snap-client-2.0.0.tgz#395af45471ba8bf79e4778d5afd6dd56327b9e97" - integrity sha512-P6xR4sbYEp9vhg5yxTcPLDW1fFve1FHgYT72HS10KXZQvKlGgoOwZe8kcNpQGarqa/Cr4IwzpULJP8Xm/sAF+w== +"@metamask/keyring-snap-client@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@metamask/keyring-snap-client/-/keyring-snap-client-4.0.0.tgz#630b0f1f11e555507d5e91fe7dc84ebada75e5cf" + integrity sha512-ZVZwCQnbYbnqenU0LYO1erF70pdgZDqbgiCljDZ2NDwGlUHX2vrMVeCmFtw2zTnIr3IMo6DR+ybEKjVoAe2Gog== dependencies: - "@metamask/keyring-api" "^13.0.0" - "@metamask/keyring-utils" "^1.0.0" + "@metamask/keyring-api" "^17.0.0" + "@metamask/keyring-utils" "^2.0.0" "@metamask/superstruct" "^3.1.0" "@types/uuid" "^9.0.8" uuid "^9.0.1" @@ -5032,6 +4994,16 @@ "@metamask/superstruct" "^3.1.0" "@metamask/utils" "^9.3.0" +"@metamask/keyring-utils@^2.0.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@metamask/keyring-utils/-/keyring-utils-2.1.0.tgz#5f7e382ca7925aaee1b859b30270607a0a7a0c29" + integrity sha512-1K3MFjNya/8YZ1EhFPilL8nVi3h8C5qGsdSJBrvXkEVGVPbZDLsQuPnzeuG1MoZk6wWcByo6h/8CPDlefCVe1Q== + dependencies: + "@ethereumjs/tx" "^4.2.0" + "@metamask/superstruct" "^3.1.0" + "@metamask/utils" "^11.1.0" + bitcoin-address-validation "^2.2.3" + "@metamask/logging-controller@^6.0.4": version "6.0.4" resolved "https://registry.yarnpkg.com/@metamask/logging-controller/-/logging-controller-6.0.4.tgz#05b9b445e8c09f25eb0d4342e5c5281601d8d11c" @@ -5164,7 +5136,7 @@ "@metamask/safe-event-emitter" "^3.0.0" readable-stream "^3.6.2" -"@metamask/permission-controller@^11.0.3", "@metamask/permission-controller@^11.0.6": +"@metamask/permission-controller@^11.0.3", "@metamask/permission-controller@^11.0.5", "@metamask/permission-controller@^11.0.6": version "11.0.6" resolved "https://registry.yarnpkg.com/@metamask/permission-controller/-/permission-controller-11.0.6.tgz#4069f6ed29d514a7e897f177efc9f798bba8668a" integrity sha512-BGznKBEiSZMsF7TuyBUp5xt93nfhGHyl4xAs1rvJUNUWVSUtry+mb1A6H8bq82/T4ZrxNhrnx3ISYr99ZDo7rA== @@ -5391,7 +5363,7 @@ lodash "^4.17.21" uuid "^8.3.2" -"@metamask/slip44@^4.0.0", "@metamask/slip44@^4.1.0": +"@metamask/slip44@^4.1.0": version "4.1.0" resolved "https://registry.yarnpkg.com/@metamask/slip44/-/slip44-4.1.0.tgz#6f2702de7ba64dad3ab6586ea3ac4e5647804b0a" integrity sha512-RQ2MJO0X3QLnJo0rFlb83h2tNAkqqx/VNOPLc3/S2CvY3/cXy3UAEw/xRM/475BeAAkWI93yiIn/FoGUy3E0Ig== @@ -5414,7 +5386,7 @@ fast-json-patch "^3.1.0" lodash "^4.17.21" -"@metamask/snaps-controllers@^9.10.0", "@metamask/snaps-controllers@^9.15.0": +"@metamask/snaps-controllers@^9.15.0": version "9.15.0" resolved "https://registry.yarnpkg.com/@metamask/snaps-controllers/-/snaps-controllers-9.15.0.tgz#2091d72e0a8bd4c637e8b25e3222e597b5d62060" integrity sha512-ElvlaX6u2MKwiuDbZ7yoJw6YuRhMspUcx0OnDSj1PhjF1apoKnOJVR/968BshqNDsTpDFFsGdvbFMX7wE3yLPQ== @@ -5463,13 +5435,13 @@ nanoid "^3.1.31" readable-stream "^3.6.2" -"@metamask/snaps-registry@^3.2.2": - version "3.2.2" - resolved "https://registry.yarnpkg.com/@metamask/snaps-registry/-/snaps-registry-3.2.2.tgz#c0402e7beeb3fbaaeb829a508c2277bd7e4a1622" - integrity sha512-20JqmfqAMcQgdR0rkWqLdiWoZYtMNhqzAUs64sO7jMBG0dBUYI+ktatH3ZlLLILqrOPumDDv+Goj7DozXLf33g== +"@metamask/snaps-registry@^3.2.2", "@metamask/snaps-registry@^3.2.3": + version "3.2.3" + resolved "https://registry.yarnpkg.com/@metamask/snaps-registry/-/snaps-registry-3.2.3.tgz#7385482ded8929b7feca5659e9344b0b171c871d" + integrity sha512-XO5zk2DMLlixk5tKydIxYn0seSU453oR8PAoorVkgvCRmprdGC4qNqxfDZ7t1xf5qquqHvRaNHQ/Ir5cAwxXyw== dependencies: "@metamask/superstruct" "^3.1.0" - "@metamask/utils" "^10.0.0" + "@metamask/utils" "^11.0.1" "@noble/curves" "^1.2.0" "@noble/hashes" "^1.3.2" @@ -5499,33 +5471,33 @@ fast-xml-parser "^4.3.4" superstruct "^1.0.3" -"@metamask/snaps-sdk@^6.11.0", "@metamask/snaps-sdk@^6.13.0", "@metamask/snaps-sdk@^6.7.0": - version "6.13.0" - resolved "https://registry.yarnpkg.com/@metamask/snaps-sdk/-/snaps-sdk-6.13.0.tgz#cbfef71253264efd4e0ef4606f89e93f83885816" - integrity sha512-WXNt0XZSnmgbwgETL0RiRvl0CMa78ZA1zLS0olK8QR/+9zcPCSrh68v1lVAa+LcctvzpRJ8NiRAar2fRBthqyw== +"@metamask/snaps-sdk@^6.11.0", "@metamask/snaps-sdk@^6.13.0", "@metamask/snaps-sdk@^6.17.0", "@metamask/snaps-sdk@^6.17.1", "@metamask/snaps-sdk@^6.7.0": + version "6.17.1" + resolved "https://registry.yarnpkg.com/@metamask/snaps-sdk/-/snaps-sdk-6.17.1.tgz#9bd25c4ff417e1572ef1a9bf59ba7cfb65ff5f46" + integrity sha512-5eWXMBzmX2QOtHxKBsuEcm1+BjqkgPioEtmoaCkiBoWihJ4kh88Lh6OZUmZhPH6Kyo2MlrtdZ1RmYbq/rme2xg== dependencies: - "@metamask/key-tree" "^10.0.1" - "@metamask/providers" "^18.1.1" - "@metamask/rpc-errors" "^7.0.1" + "@metamask/key-tree" "^10.0.2" + "@metamask/providers" "^18.3.1" + "@metamask/rpc-errors" "^7.0.2" "@metamask/superstruct" "^3.1.0" - "@metamask/utils" "^10.0.0" + "@metamask/utils" "^11.0.1" -"@metamask/snaps-utils@^8.3.0", "@metamask/snaps-utils@^8.6.0", "@metamask/snaps-utils@^8.6.1": - version "8.6.1" - resolved "https://registry.yarnpkg.com/@metamask/snaps-utils/-/snaps-utils-8.6.1.tgz#9f3b52f9b00a93ce9e3f22e79066fea0d6df458a" - integrity sha512-R6Gj6Im5gV09kjkSH9vDKrvsqNGaFGbSAl95fhlQBW3QevLaMbvAF4bCfhA3YCfsEYZUWsgplYpCjX78q2jvBA== +"@metamask/snaps-utils@^8.10.0", "@metamask/snaps-utils@^8.3.0", "@metamask/snaps-utils@^8.6.0", "@metamask/snaps-utils@^8.6.1": + version "8.10.0" + resolved "https://registry.yarnpkg.com/@metamask/snaps-utils/-/snaps-utils-8.10.0.tgz#ae44480887908643bdf134d3a96f9994cd52f693" + integrity sha512-3UXDVwk9H8Led76VSCbF/fuB90fBa9ZBAHftwD7HSIOsZeYkEkvie+3B+4rCEExBCXcfpyj/eiDgMpHg3orqhQ== dependencies: "@babel/core" "^7.23.2" "@babel/types" "^7.23.0" - "@metamask/base-controller" "^7.0.2" - "@metamask/key-tree" "^10.0.1" - "@metamask/permission-controller" "^11.0.3" - "@metamask/rpc-errors" "^7.0.1" - "@metamask/slip44" "^4.0.0" - "@metamask/snaps-registry" "^3.2.2" - "@metamask/snaps-sdk" "^6.13.0" + "@metamask/base-controller" "^7.0.3" + "@metamask/key-tree" "^10.0.2" + "@metamask/permission-controller" "^11.0.5" + "@metamask/rpc-errors" "^7.0.2" + "@metamask/slip44" "^4.1.0" + "@metamask/snaps-registry" "^3.2.3" + "@metamask/snaps-sdk" "^6.17.0" "@metamask/superstruct" "^3.1.0" - "@metamask/utils" "^10.0.0" + "@metamask/utils" "^11.0.1" "@noble/hashes" "^1.3.1" "@scure/base" "^1.1.1" chalk "^4.1.2" @@ -5580,24 +5552,24 @@ resolved "https://registry.yarnpkg.com/@metamask/test-dapp/-/test-dapp-8.9.0.tgz#bac680e8f0007b3a11440f7e311674d6457d37ed" integrity sha512-N/WfmdrzJm+xbpuqJsfMrlrAhiNDsllIpwt9gDDeEKDlQAfJnMtT9xvOvBJbXY7zgMdtGZuD+KY64jNKabbuVQ== -"@metamask/transaction-controller@^43.0.0": - version "43.0.0" - resolved "https://registry.yarnpkg.com/@metamask/transaction-controller/-/transaction-controller-43.0.0.tgz#d4206cf671c4b9938dcf5fc0a190c7b8bf062967" - integrity sha512-QdAQRhuaL5a2vdX0yIsyeBhg+Tu9S7k0jY1xGrKJTdttdko8/KEEnkfOXZPf3VEATY7qw81WgSok4OLY3DXocA== +"@metamask/transaction-controller@^45.1.0": + version "45.1.0" + resolved "https://registry.yarnpkg.com/@metamask/transaction-controller/-/transaction-controller-45.1.0.tgz#271f0a9575551bfd494ff79be70fb142d792a987" + integrity sha512-LyNjcZ6zbLAKgkCJbFK+e7oPespl8c4kGJXV8JKzLGOmdU1LORpNgeo61nUK7/0b/LVovFTCyJO8wjk7ESFI2Q== dependencies: - "@ethereumjs/common" "^3.2.0" - "@ethereumjs/tx" "^4.2.0" + "@ethereumjs/common" "^4.4.0" + "@ethereumjs/tx" "^5.4.0" "@ethereumjs/util" "^8.1.0" "@ethersproject/abi" "^5.7.0" "@ethersproject/contracts" "^5.7.0" "@ethersproject/providers" "^5.7.0" - "@metamask/base-controller" "^7.1.1" - "@metamask/controller-utils" "^11.4.5" + "@metamask/base-controller" "^8.0.0" + "@metamask/controller-utils" "^11.5.0" "@metamask/eth-query" "^4.0.0" "@metamask/metamask-eth-abis" "^3.1.1" "@metamask/nonce-tracker" "^6.0.0" "@metamask/rpc-errors" "^7.0.2" - "@metamask/utils" "^11.0.1" + "@metamask/utils" "^11.1.0" async-mutex "^0.5.0" bn.js "^5.2.1" eth-method-registry "^4.0.0" @@ -5605,7 +5577,7 @@ lodash "^4.17.21" uuid "^8.3.2" -"@metamask/utils@^10.0.0", "@metamask/utils@^10.0.1", "@metamask/utils@^11.0.1", "@metamask/utils@^11.1.0", "@metamask/utils@^8.2.0", "@metamask/utils@^8.3.0", "@metamask/utils@^9.0.0", "@metamask/utils@^9.1.0", "@metamask/utils@^9.2.1", "@metamask/utils@^9.3.0": +"@metamask/utils@^10.0.0", "@metamask/utils@^11.0.1", "@metamask/utils@^11.1.0", "@metamask/utils@^8.2.0", "@metamask/utils@^8.3.0", "@metamask/utils@^9.0.0", "@metamask/utils@^9.1.0", "@metamask/utils@^9.2.1", "@metamask/utils@^9.3.0": version "11.2.0" resolved "https://registry.yarnpkg.com/@metamask/utils/-/utils-11.2.0.tgz#f2b35cbe6536c56071b0971f97f2395b860885c4" integrity sha512-5Y4bd8Axvi2kJKjp6Jlbb9wyoTrSZxQjWvVGPevpErAc7SCUYUuW0QOOPVu7YmT+bzisTpnFnRE8LjtwYCKGAg== @@ -5667,30 +5639,23 @@ resolved "https://registry.yarnpkg.com/@noble/ciphers/-/ciphers-0.5.3.tgz#48b536311587125e0d0c1535f73ec8375cd76b23" integrity sha512-B0+6IIHiqEs3BPMT0hcRmHvEj2QHOLu+uwt+tqDDeVd0oyVzh7BPrDcPjRnV1PV/5LaknXJJQvOuRGR0zQJz+w== -"@noble/curves@1.3.0", "@noble/curves@~1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.3.0.tgz#01be46da4fd195822dab821e72f71bf4aeec635e" - integrity sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA== +"@noble/curves@1.4.2", "@noble/curves@^1.2.0", "@noble/curves@^1.4.0", "@noble/curves@~1.4.0": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.2.tgz#40309198c76ed71bc6dbf7ba24e81ceb4d0d1fe9" + integrity sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw== dependencies: - "@noble/hashes" "1.3.3" + "@noble/hashes" "1.4.0" -"@noble/curves@^1.2.0", "@noble/curves@^1.4.0": +"@noble/hashes@1.4.0", "@noble/hashes@^1.1.2", "@noble/hashes@^1.3.1", "@noble/hashes@^1.3.2", "@noble/hashes@^1.4.0", "@noble/hashes@~1.4.0": version "1.4.0" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.0.tgz#f05771ef64da724997f69ee1261b2417a49522d6" - integrity sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg== - dependencies: - "@noble/hashes" "1.4.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" + integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== -"@noble/hashes@1.3.3", "@noble/hashes@~1.3.2": +"@noble/hashes@~1.3.2": version "1.3.3" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== -"@noble/hashes@1.4.0", "@noble/hashes@^1.1.2", "@noble/hashes@^1.3.1", "@noble/hashes@^1.3.2", "@noble/hashes@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" - integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== - "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -6905,27 +6870,27 @@ image-to-base64 "^2.2.0" open "^8.2.0" -"@scure/base@^1.0.0", "@scure/base@^1.1.1", "@scure/base@^1.1.3", "@scure/base@~1.1.3", "@scure/base@~1.1.4": - version "1.1.6" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.6.tgz#8ce5d304b436e4c84f896e0550c83e4d88cb917d" - integrity sha512-ok9AWwhcgYuGG3Zfhyqg+zwl+Wn5uE+dwC0NV/2qQkx4dABbb/bx96vWu8NSj+BNjjSjno+JRYRjle1jV08k3g== +"@scure/base@^1.0.0", "@scure/base@^1.1.1", "@scure/base@^1.1.3", "@scure/base@~1.1.3", "@scure/base@~1.1.6": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.9.tgz#e5e142fbbfe251091f9c5f1dd4c834ac04c3dbd1" + integrity sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg== -"@scure/bip32@1.3.3": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.3.tgz#a9624991dc8767087c57999a5d79488f48eae6c8" - integrity sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ== +"@scure/bip32@1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.4.0.tgz#4e1f1e196abedcef395b33b9674a042524e20d67" + integrity sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg== dependencies: - "@noble/curves" "~1.3.0" - "@noble/hashes" "~1.3.2" - "@scure/base" "~1.1.4" + "@noble/curves" "~1.4.0" + "@noble/hashes" "~1.4.0" + "@scure/base" "~1.1.6" -"@scure/bip39@1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.2.tgz#f3426813f4ced11a47489cbcf7294aa963966527" - integrity sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA== +"@scure/bip39@1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.3.0.tgz#0f258c16823ddd00739461ac31398b4e7d6a18c3" + integrity sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ== dependencies: - "@noble/hashes" "~1.3.2" - "@scure/base" "~1.1.4" + "@noble/hashes" "~1.4.0" + "@scure/base" "~1.1.6" "@segment/analytics-react-native@^2.17.0": version "2.17.0" @@ -16551,15 +16516,15 @@ ethereum-cryptography@^0.1.3: secp256k1 "^4.0.1" setimmediate "^1.0.5" -ethereum-cryptography@^2.0.0, ethereum-cryptography@^2.1.2, ethereum-cryptography@^2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.1.3.tgz#1352270ed3b339fe25af5ceeadcf1b9c8e30768a" - integrity sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA== +ethereum-cryptography@^2.0.0, ethereum-cryptography@^2.1.2, ethereum-cryptography@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz#58f2810f8e020aecb97de8c8c76147600b0b8ccf" + integrity sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg== dependencies: - "@noble/curves" "1.3.0" - "@noble/hashes" "1.3.3" - "@scure/bip32" "1.3.3" - "@scure/bip39" "1.2.2" + "@noble/curves" "1.4.2" + "@noble/hashes" "1.4.0" + "@scure/bip32" "1.4.0" + "@scure/bip39" "1.3.0" ethereum-ens-network-map@^1.0.0: version "1.0.2"