diff --git a/package.json b/package.json index 7ed9dd776d..4756e81694 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/core-monorepo", - "version": "253.0.0", + "version": "255.0.0", "private": true, "description": "Monorepo for packages shared between MetaMask clients", "repository": { diff --git a/packages/accounts-controller/CHANGELOG.md b/packages/accounts-controller/CHANGELOG.md index ce886e69d2..01002430f4 100644 --- a/packages/accounts-controller/CHANGELOG.md +++ b/packages/accounts-controller/CHANGELOG.md @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [20.0.0] + +### Changed + +- **BREAKING:** Bump peer dependency `@metamask/keyring-controller` from `^18.0.0` to `^19.0.0` ([#4915](https://github.com/MetaMask/core/pull/4956)) +- **BREAKING:** Bump `@metamask/keyring-api` from `^8.1.3` to `^10.1.0` ([#4948](https://github.com/MetaMask/core/pull/4948)) + - If you are depending on `@metamask/providers` directly, you will need to upgrade to `18.1.0`. +- Bump `@metamask/eth-snap-keyring` from `^4.3.6` to `^5.0.1` ([#4948](https://github.com/MetaMask/core/pull/4948)) +- Bump `@metamask/snaps-utils` from `^4.3.6` to `^8.3.0` ([#4948](https://github.com/MetaMask/core/pull/4948)) +- Bump `@metamask/snaps-sdk` from `^6.5.0` to `^6.7.0` ([#4948](https://github.com/MetaMask/core/pull/4948)) + ## [19.0.0] ### Changed @@ -343,7 +354,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial release ([#1637](https://github.com/MetaMask/core/pull/1637)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@19.0.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@20.0.0...HEAD +[20.0.0]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@19.0.0...@metamask/accounts-controller@20.0.0 [19.0.0]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@18.2.3...@metamask/accounts-controller@19.0.0 [18.2.3]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@18.2.2...@metamask/accounts-controller@18.2.3 [18.2.2]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@18.2.1...@metamask/accounts-controller@18.2.2 diff --git a/packages/accounts-controller/package.json b/packages/accounts-controller/package.json index f54492882a..d36254ead4 100644 --- a/packages/accounts-controller/package.json +++ b/packages/accounts-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/accounts-controller", - "version": "19.0.0", + "version": "20.0.0", "description": "Manages internal accounts", "keywords": [ "MetaMask", @@ -61,7 +61,7 @@ }, "devDependencies": { "@metamask/auto-changelog": "^3.4.4", - "@metamask/keyring-controller": "^18.0.0", + "@metamask/keyring-controller": "^19.0.0", "@metamask/snaps-controllers": "^9.10.0", "@types/jest": "^27.4.1", "@types/readable-stream": "^2.3.0", @@ -72,8 +72,8 @@ "typescript": "~5.2.2" }, "peerDependencies": { - "@metamask/keyring-controller": "^18.0.0", - "@metamask/snaps-controllers": "^9.10.0" + "@metamask/keyring-controller": "^19.0.0", + "@metamask/snaps-controllers": "^9.7.0" }, "engines": { "node": "^18.18 || >=20" diff --git a/packages/assets-controllers/CHANGELOG.md b/packages/assets-controllers/CHANGELOG.md index a67ac02963..d2a47f2f5d 100644 --- a/packages/assets-controllers/CHANGELOG.md +++ b/packages/assets-controllers/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [45.0.0] + +### Changed + +- **BREAKING:** Bump `@metamask/keyring-controller` peer dependency from `^18.0.0` to `^19.0.0` ([#4195](https://github.com/MetaMask/core/pull/4956)) +- **BREAKING:** Bump `@metamask/accounts-controller` peer dependency from `^19.0.0` to `^20.0.0` ([#4195](https://github.com/MetaMask/core/pull/4956)) +- **BREAKING:** Bump `@metamask/preferences-controller` peer dependency from `^14.0.0` to `^15.0.0` ([#4195](https://github.com/MetaMask/core/pull/4956)) + ## [44.1.0] ### Changed @@ -1244,7 +1252,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Use Ethers for AssetsContractController ([#845](https://github.com/MetaMask/core/pull/845)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@44.1.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@45.0.0...HEAD +[45.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@44.1.0...@metamask/assets-controllers@45.0.0 [44.1.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@44.0.1...@metamask/assets-controllers@44.1.0 [44.0.1]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@44.0.0...@metamask/assets-controllers@44.0.1 [44.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@43.1.1...@metamask/assets-controllers@44.0.0 diff --git a/packages/assets-controllers/package.json b/packages/assets-controllers/package.json index d8fa6c0cf1..29daa362a8 100644 --- a/packages/assets-controllers/package.json +++ b/packages/assets-controllers/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/assets-controllers", - "version": "44.1.0", + "version": "45.0.0", "description": "Controllers which manage interactions involving ERC-20, ERC-721, and ERC-1155 tokens (including NFTs)", "keywords": [ "MetaMask", @@ -74,14 +74,14 @@ "uuid": "^8.3.2" }, "devDependencies": { - "@metamask/accounts-controller": "^19.0.0", + "@metamask/accounts-controller": "^20.0.0", "@metamask/approval-controller": "^7.1.1", "@metamask/auto-changelog": "^3.4.4", "@metamask/ethjs-provider-http": "^0.3.0", "@metamask/keyring-api": "^10.1.0", - "@metamask/keyring-controller": "^18.0.0", + "@metamask/keyring-controller": "^19.0.0", "@metamask/network-controller": "^22.0.2", - "@metamask/preferences-controller": "^14.0.0", + "@metamask/preferences-controller": "^15.0.0", "@types/jest": "^27.4.1", "@types/lodash": "^4.14.191", "@types/node": "^16.18.54", @@ -96,11 +96,11 @@ "typescript": "~5.2.2" }, "peerDependencies": { - "@metamask/accounts-controller": "^19.0.0", + "@metamask/accounts-controller": "^20.0.0", "@metamask/approval-controller": "^7.0.0", - "@metamask/keyring-controller": "^18.0.0", + "@metamask/keyring-controller": "^19.0.0", "@metamask/network-controller": "^22.0.0", - "@metamask/preferences-controller": "^14.0.0" + "@metamask/preferences-controller": "^15.0.0" }, "engines": { "node": "^18.18 || >=20" diff --git a/packages/assets-controllers/src/TokenDetectionController.test.ts b/packages/assets-controllers/src/TokenDetectionController.test.ts index 31c82807bb..6a1a69e5ea 100644 --- a/packages/assets-controllers/src/TokenDetectionController.test.ts +++ b/packages/assets-controllers/src/TokenDetectionController.test.ts @@ -8,7 +8,10 @@ import { } from '@metamask/controller-utils'; import type { InternalAccount } from '@metamask/keyring-api'; import type { KeyringControllerState } from '@metamask/keyring-controller'; -import { getDefaultNetworkControllerState } from '@metamask/network-controller'; +import { + getDefaultNetworkControllerState, + RpcEndpointType, +} from '@metamask/network-controller'; import type { NetworkState, NetworkConfiguration, @@ -1014,6 +1017,7 @@ describe('TokenDetectionController', () => { async ({ mockGetAccount, mockTokenListGetState, + mockNetworkState, triggerPreferencesStateChange, triggerSelectedAccountChange, callActionSpy, @@ -1038,6 +1042,26 @@ describe('TokenDetectionController', () => { }, }, }); + mockNetworkState({ + networkConfigurationsByChainId: { + '0x1': { + name: 'ethereum', + nativeCurrency: 'ETH', + rpcEndpoints: [ + { + networkClientId: 'mainnet', + type: RpcEndpointType.Infura, + url: 'https://mainnet.infura.io/v3/{infuraProjectId}', + }, + ], + blockExplorerUrls: [], + chainId: '0x1', + defaultRpcEndpointIndex: 0, + }, + }, + networksMetadata: {}, + selectedNetworkClientId: 'mainnet', + }); triggerPreferencesStateChange({ ...getDefaultPreferencesState(), @@ -1059,6 +1083,85 @@ describe('TokenDetectionController', () => { ); }); + it('should detect new tokens after switching between accounts on different chains', async () => { + const mockGetBalancesInSingleCall = jest.fn().mockResolvedValue({ + [sampleTokenA.address]: new BN(1), + }); + const firstSelectedAccount = createMockInternalAccount({ + address: '0x0000000000000000000000000000000000000001', + }); + const secondSelectedAccount = createMockInternalAccount({ + address: '0x0000000000000000000000000000000000000002', + }); + await withController( + { + options: { + disabled: false, + getBalancesInSingleCall: mockGetBalancesInSingleCall, + useAccountsAPI: true, // USING ACCOUNTS API + }, + mocks: { + getSelectedAccount: firstSelectedAccount, + }, + }, + async ({ + mockGetAccount, + mockTokenListGetState, + mockNetworkState, + triggerPreferencesStateChange, + triggerSelectedAccountChange, + controller, + }) => { + const mockTokens = jest.spyOn(controller, 'detectTokens'); + mockMultiChainAccountsService(); + mockTokenListGetState({ + ...getDefaultTokenListState(), + tokensChainsCache: { + '0x1': { + timestamp: 0, + data: { + [sampleTokenA.address]: { + name: sampleTokenA.name, + symbol: sampleTokenA.symbol, + decimals: sampleTokenA.decimals, + address: sampleTokenA.address, + occurrences: 1, + aggregators: sampleTokenA.aggregators, + iconUrl: sampleTokenA.image, + }, + }, + }, + }, + }); + mockNetworkState({ + ...getDefaultNetworkControllerState(), + selectedNetworkClientId: NetworkType.mainnet, + }); + + triggerPreferencesStateChange({ + ...getDefaultPreferencesState(), + useTokenDetection: true, + }); + mockGetAccount(secondSelectedAccount); + triggerSelectedAccountChange(secondSelectedAccount); + + await advanceTime({ clock, duration: 1 }); + + expect(mockTokens).toHaveBeenNthCalledWith(1, { + chainIds: [ + '0x1', + '0x5', + '0xaa36a7', + '0xe704', + '0xe705', + '0xe708', + ], + selectedAddress: secondSelectedAccount.address, + }); + }, + ); + }); + it('should detect new tokens after enabling token detection', async () => { const mockGetBalancesInSingleCall = jest.fn().mockResolvedValue({ [sampleTokenA.address]: new BN(1), diff --git a/packages/assets-controllers/src/TokenDetectionController.ts b/packages/assets-controllers/src/TokenDetectionController.ts index e9a83f65d4..031fcd4ec4 100644 --- a/packages/assets-controllers/src/TokenDetectionController.ts +++ b/packages/assets-controllers/src/TokenDetectionController.ts @@ -394,12 +394,18 @@ export class TokenDetectionController extends StaticIntervalPollingController { + const { networkConfigurationsByChainId } = this.messagingSystem.call( + 'NetworkController:getState', + ); + + const chainIds = Object.keys(networkConfigurationsByChainId) as Hex[]; const isSelectedAccountIdChanged = this.#selectedAccountId !== selectedAccount.id; if (isSelectedAccountIdChanged) { this.#selectedAccountId = selectedAccount.id; await this.#restartTokenDetection({ selectedAddress: selectedAccount.address, + chainIds, }); } }, diff --git a/packages/chain-controller/CHANGELOG.md b/packages/chain-controller/CHANGELOG.md index 1fb577685e..e32c566071 100644 --- a/packages/chain-controller/CHANGELOG.md +++ b/packages/chain-controller/CHANGELOG.md @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.2.0] + +### Changed + +- **BREAKING:** Bump `@metamask/keyring-api` from `^8.1.3` to `^10.1.0` ([#4948](https://github.com/MetaMask/core/pull/4948)) + - If you are depending on `@metamask/providers` directly, you will need to upgrade to 18.1.0. +- Bump `@metamask/snaps-utils` from `^4.3.6` to `^8.3.0` ([#4948](https://github.com/MetaMask/core/pull/4948)) +- Bump `@metamask/snaps-sdk` from `^6.5.0` to `^6.7.0` ([#4948](https://github.com/MetaMask/core/pull/4948)) +- Bump `@metamask/snaps-controllers` from `^9.7.0`to `^9.10.0` ([#4948](https://github.com/MetaMask/core/pull/4948)) +- Bump `@metamask/utils` from `^9.1.0` to `^10.0.0` ([#4831](https://github.com/MetaMask/core/pull/4831)) + ## [0.1.3] ### Changed @@ -57,7 +68,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial release -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/chain-controller@0.1.3...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/chain-controller@0.2.0...HEAD +[0.2.0]: https://github.com/MetaMask/core/compare/@metamask/chain-controller@0.1.3...@metamask/chain-controller@0.2.0 [0.1.3]: https://github.com/MetaMask/core/compare/@metamask/chain-controller@0.1.2...@metamask/chain-controller@0.1.3 [0.1.2]: https://github.com/MetaMask/core/compare/@metamask/chain-controller@0.1.1...@metamask/chain-controller@0.1.2 [0.1.1]: https://github.com/MetaMask/core/compare/@metamask/chain-controller@0.1.0...@metamask/chain-controller@0.1.1 diff --git a/packages/chain-controller/package.json b/packages/chain-controller/package.json index fcf81b2188..22b35dc4e9 100644 --- a/packages/chain-controller/package.json +++ b/packages/chain-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/chain-controller", - "version": "0.1.3", + "version": "0.2.0", "description": "Manages chain-agnostic providers", "keywords": [ "MetaMask", diff --git a/packages/keyring-controller/CHANGELOG.md b/packages/keyring-controller/CHANGELOG.md index ee4831644e..a6e08923d1 100644 --- a/packages/keyring-controller/CHANGELOG.md +++ b/packages/keyring-controller/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [19.0.0] + +### Changed + +- **BREAKING:** Bump `@metamask/keyring-api` from `^8.1.3` to `^10.1.0` ([#4948](https://github.com/MetaMask/core/pull/4948)) + - If you are depending on `@metamask/providers` directly, you will need to upgrade to 18.1.0. + ## [18.0.0] ### Removed @@ -581,7 +588,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/keyring-controller@18.0.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/keyring-controller@19.0.0...HEAD +[19.0.0]: https://github.com/MetaMask/core/compare/@metamask/keyring-controller@18.0.0...@metamask/keyring-controller@19.0.0 [18.0.0]: https://github.com/MetaMask/core/compare/@metamask/keyring-controller@17.3.1...@metamask/keyring-controller@18.0.0 [17.3.1]: https://github.com/MetaMask/core/compare/@metamask/keyring-controller@17.3.0...@metamask/keyring-controller@17.3.1 [17.3.0]: https://github.com/MetaMask/core/compare/@metamask/keyring-controller@17.2.2...@metamask/keyring-controller@17.3.0 diff --git a/packages/keyring-controller/package.json b/packages/keyring-controller/package.json index 54b2f649d2..f8ebe7a1b2 100644 --- a/packages/keyring-controller/package.json +++ b/packages/keyring-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/keyring-controller", - "version": "18.0.0", + "version": "19.0.0", "description": "Stores identities seen in the wallet and manages interactions such as signing", "keywords": [ "MetaMask", diff --git a/packages/multichain/CHANGELOG.md b/packages/multichain/CHANGELOG.md index b518709c7b..bbe1561ee9 100644 --- a/packages/multichain/CHANGELOG.md +++ b/packages/multichain/CHANGELOG.md @@ -7,4 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -[Unreleased]: https://github.com/MetaMask/core/ +## [1.0.0] + +### Added + +- Initial release ([#4962](https://github.com/MetaMask/core/pull/4962)) + +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/multichain@1.0.0...HEAD +[1.0.0]: https://github.com/MetaMask/core/releases/tag/@metamask/multichain@1.0.0 diff --git a/packages/multichain/package.json b/packages/multichain/package.json index a65ad36a54..c23a839a8b 100644 --- a/packages/multichain/package.json +++ b/packages/multichain/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/multichain", - "version": "0.0.0", + "version": "1.0.0", "description": "Provides types, helpers, adapters, and wrappers for facilitating CAIP Multichain sessions", "keywords": [ "MetaMask", diff --git a/packages/multichain/src/adapters/caip-permission-adapter-eth-accounts.test.ts b/packages/multichain/src/adapters/caip-permission-adapter-eth-accounts.test.ts index d58a8ad4b2..e6ae16f968 100644 --- a/packages/multichain/src/adapters/caip-permission-adapter-eth-accounts.test.ts +++ b/packages/multichain/src/adapters/caip-permission-adapter-eth-accounts.test.ts @@ -16,8 +16,8 @@ describe('CAIP-25 eth_accounts adapters', () => { it('returns an empty array if the scope objects have no accounts', () => { const ethAccounts = getEthAccounts({ requiredScopes: { - 'eip155:1': { methods: [], notifications: [], accounts: [] }, - 'eip155:2': { methods: [], notifications: [], accounts: [] }, + 'eip155:1': { accounts: [] }, + 'eip155:2': { accounts: [] }, }, optionalScopes: {}, }); @@ -27,8 +27,6 @@ describe('CAIP-25 eth_accounts adapters', () => { const ethAccounts = getEthAccounts({ requiredScopes: { 'bip122:000000000019d6689c085ae165831e93': { - methods: [], - notifications: [], accounts: [ 'bip122:000000000019d6689c085ae165831e93:128Lkh3S7CkDTBZ8W7BbpsN3YYizJMp8p6', ], @@ -43,18 +41,12 @@ describe('CAIP-25 eth_accounts adapters', () => { const ethAccounts = getEthAccounts({ requiredScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: ['eip155:1:0x1', 'eip155:1:0x2'], }, 'eip155:5': { - methods: [], - notifications: [], accounts: ['eip155:5:0x2', 'eip155:1:0x3'], }, 'bip122:000000000019d6689c085ae165831e93': { - methods: [], - notifications: [], accounts: [ 'bip122:000000000019d6689c085ae165831e93:128Lkh3S7CkDTBZ8W7BbpsN3YYizJMp8p6', ], @@ -62,23 +54,15 @@ describe('CAIP-25 eth_accounts adapters', () => { }, optionalScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: ['eip155:1:0x1', 'eip155:1:0x4'], }, 'eip155:10': { - methods: [], - notifications: [], accounts: [], }, 'eip155:100': { - methods: [], - notifications: [], accounts: ['eip155:100:0x100'], }, 'wallet:eip155': { - methods: [], - notifications: [], accounts: ['wallet:eip155:0x5'], }, }, @@ -87,8 +71,8 @@ describe('CAIP-25 eth_accounts adapters', () => { expect(ethAccounts).toStrictEqual([ '0x1', '0x2', - '0x4', '0x3', + '0x4', '0x100', '0x5', ]); @@ -100,18 +84,12 @@ describe('CAIP-25 eth_accounts adapters', () => { const input: Caip25CaveatValue = { requiredScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: ['eip155:1:0x1', 'eip155:1:0x2'], }, 'eip155:5': { - methods: [], - notifications: [], accounts: ['eip155:5:0x2', 'eip155:1:0x3'], }, 'bip122:000000000019d6689c085ae165831e93': { - methods: [], - notifications: [], accounts: [ 'bip122:000000000019d6689c085ae165831e93:128Lkh3S7CkDTBZ8W7BbpsN3YYizJMp8p6', ], @@ -119,28 +97,18 @@ describe('CAIP-25 eth_accounts adapters', () => { }, optionalScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: ['eip155:1:0x1', 'eip155:1:0x4'], }, 'eip155:10': { - methods: [], - notifications: [], accounts: [], }, 'eip155:100': { - methods: [], - notifications: [], accounts: ['eip155:100:0x100'], }, 'wallet:eip155': { - methods: [], - notifications: [], accounts: [], }, wallet: { - methods: [], - notifications: [], accounts: [], }, }, @@ -151,18 +119,12 @@ describe('CAIP-25 eth_accounts adapters', () => { expect(result).toStrictEqual({ requiredScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: ['eip155:1:0x1', 'eip155:1:0x2', 'eip155:1:0x3'], }, 'eip155:5': { - methods: [], - notifications: [], accounts: ['eip155:5:0x1', 'eip155:5:0x2', 'eip155:5:0x3'], }, 'bip122:000000000019d6689c085ae165831e93': { - methods: [], - notifications: [], accounts: [ 'bip122:000000000019d6689c085ae165831e93:128Lkh3S7CkDTBZ8W7BbpsN3YYizJMp8p6', ], @@ -170,23 +132,15 @@ describe('CAIP-25 eth_accounts adapters', () => { }, optionalScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: ['eip155:1:0x1', 'eip155:1:0x2', 'eip155:1:0x3'], }, 'eip155:10': { - methods: [], - notifications: [], accounts: ['eip155:10:0x1', 'eip155:10:0x2', 'eip155:10:0x3'], }, 'eip155:100': { - methods: [], - notifications: [], accounts: ['eip155:100:0x1', 'eip155:100:0x2', 'eip155:100:0x3'], }, 'wallet:eip155': { - methods: [], - notifications: [], accounts: [ 'wallet:eip155:0x1', 'wallet:eip155:0x2', @@ -194,8 +148,6 @@ describe('CAIP-25 eth_accounts adapters', () => { ], }, wallet: { - methods: [], - notifications: [], accounts: [ 'wallet:eip155:0x1', 'wallet:eip155:0x2', @@ -219,8 +171,6 @@ describe('CAIP-25 eth_accounts adapters', () => { requiredScopes: {}, optionalScopes: { 'wallet:eip155': { - methods: [], - notifications: [], accounts: [ 'wallet:eip155:0x1', 'wallet:eip155:0x2', @@ -236,8 +186,6 @@ describe('CAIP-25 eth_accounts adapters', () => { const input: Caip25CaveatValue = { requiredScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: [], }, }, @@ -249,8 +197,6 @@ describe('CAIP-25 eth_accounts adapters', () => { expect(input).toStrictEqual({ requiredScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: [], }, }, diff --git a/packages/multichain/src/adapters/caip-permission-adapter-eth-accounts.ts b/packages/multichain/src/adapters/caip-permission-adapter-eth-accounts.ts index 6e96aac786..bcdcab9e80 100644 --- a/packages/multichain/src/adapters/caip-permission-adapter-eth-accounts.ts +++ b/packages/multichain/src/adapters/caip-permission-adapter-eth-accounts.ts @@ -8,8 +8,8 @@ import { import type { Caip25CaveatValue } from '../caip25Permission'; import { KnownWalletScopeString } from '../scope/constants'; -import { getUniqueArrayItems, mergeScopes } from '../scope/transform'; -import type { InternalScopesObject, InternalScopeString } from '../scope/types'; +import { getUniqueArrayItems } from '../scope/transform'; +import type { InternalScopeString, InternalScopesObject } from '../scope/types'; import { parseScopeString } from '../scope/types'; /** @@ -27,23 +27,14 @@ const isEip155ScopeString = (scopeString: InternalScopeString) => { }; /** - * Gets the Ethereum (EIP155 namespaced) accounts from the required and optional scopes. - * @param caip25CaveatValue - The CAIP-25 caveat value to get the Ethereum accounts from. + * Gets the Ethereum (EIP155 namespaced) accounts from internal scopes. + * @param scopes - The internal scopes from which to get the Ethereum accounts. * @returns An array of Ethereum accounts. */ -export const getEthAccounts = ( - caip25CaveatValue: Pick< - Caip25CaveatValue, - 'requiredScopes' | 'optionalScopes' - >, -): Hex[] => { +const getEthAccountsFromScopes = (scopes: InternalScopesObject) => { const ethAccounts: Hex[] = []; - const sessionScopes = mergeScopes( - caip25CaveatValue.requiredScopes, - caip25CaveatValue.optionalScopes, - ); - Object.entries(sessionScopes).forEach(([_, { accounts }]) => { + Object.entries(scopes).forEach(([_, { accounts }]) => { accounts?.forEach((account) => { const { address, chainId } = parseCaipAccountId(account); @@ -56,6 +47,27 @@ export const getEthAccounts = ( }); }); + return ethAccounts; +}; + +/** + * Gets the Ethereum (EIP155 namespaced) accounts from the required and optional scopes. + * @param caip25CaveatValue - The CAIP-25 caveat value to get the Ethereum accounts from. + * @returns An array of Ethereum accounts. + */ +export const getEthAccounts = ( + caip25CaveatValue: Pick< + Caip25CaveatValue, + 'requiredScopes' | 'optionalScopes' + >, +): Hex[] => { + const { requiredScopes, optionalScopes } = caip25CaveatValue; + + const ethAccounts: Hex[] = [ + ...getEthAccountsFromScopes(requiredScopes), + ...getEthAccountsFromScopes(optionalScopes), + ]; + return getUniqueArrayItems(ethAccounts); }; @@ -116,7 +128,7 @@ const setEthAccountsForScopesObject = ( export const setEthAccounts = ( caip25CaveatValue: Caip25CaveatValue, accounts: Hex[], -) => { +): Caip25CaveatValue => { return { ...caip25CaveatValue, requiredScopes: setEthAccountsForScopesObject( @@ -126,8 +138,6 @@ export const setEthAccounts = ( optionalScopes: setEthAccountsForScopesObject( { [KnownWalletScopeString.Eip155]: { - methods: [], - notifications: [], accounts: [], }, ...caip25CaveatValue.optionalScopes, diff --git a/packages/multichain/src/adapters/caip-permission-adapter-permittedChains.test.ts b/packages/multichain/src/adapters/caip-permission-adapter-permittedChains.test.ts index c1504bd96f..bc9b0ccd7c 100644 --- a/packages/multichain/src/adapters/caip-permission-adapter-permittedChains.test.ts +++ b/packages/multichain/src/adapters/caip-permission-adapter-permittedChains.test.ts @@ -1,5 +1,4 @@ import type { Caip25CaveatValue } from '../caip25Permission'; -import { KnownNotifications, KnownRpcMethods } from '../scope/constants'; import { addPermittedEthChainId, getPermittedEthChainIds, @@ -12,18 +11,12 @@ describe('CAIP-25 permittedChains adapters', () => { const ethChainIds = getPermittedEthChainIds({ requiredScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: ['eip155:1:0x1', 'eip155:1:0x2'], }, 'eip155:5': { - methods: [], - notifications: [], accounts: ['eip155:5:0x2', 'eip155:1:0x3'], }, 'bip122:000000000019d6689c085ae165831e93': { - methods: [], - notifications: [], accounts: [ 'bip122:000000000019d6689c085ae165831e93:128Lkh3S7CkDTBZ8W7BbpsN3YYizJMp8p6', ], @@ -31,18 +24,12 @@ describe('CAIP-25 permittedChains adapters', () => { }, optionalScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: ['eip155:1:0x1', 'eip155:1:0x4'], }, 'eip155:10': { - methods: [], - notifications: [], accounts: [], }, 'eip155:100': { - methods: [], - notifications: [], accounts: ['eip155:100:0x100'], }, }, @@ -58,20 +45,14 @@ describe('CAIP-25 permittedChains adapters', () => { { requiredScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: ['eip155:1:0x1', 'eip155:1:0x2'], }, }, optionalScopes: { 'eip155:100': { - methods: [], - notifications: [], accounts: ['eip155:100:0x100'], }, 'wallet:eip155': { - methods: [], - notifications: [], accounts: [], }, }, @@ -83,25 +64,17 @@ describe('CAIP-25 permittedChains adapters', () => { expect(result).toStrictEqual({ requiredScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: ['eip155:1:0x1', 'eip155:1:0x2'], }, }, optionalScopes: { 'eip155:100': { - methods: [], - notifications: [], accounts: ['eip155:100:0x100'], }, 'eip155:101': { - methods: KnownRpcMethods.eip155, - notifications: KnownNotifications.eip155, accounts: [], }, 'wallet:eip155': { - methods: [], - notifications: [], accounts: [], }, }, @@ -113,8 +86,6 @@ describe('CAIP-25 permittedChains adapters', () => { const input: Caip25CaveatValue = { requiredScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: ['eip155:1:0x1', 'eip155:1:0x2'], }, }, @@ -127,8 +98,6 @@ describe('CAIP-25 permittedChains adapters', () => { expect(input).toStrictEqual({ requiredScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: ['eip155:1:0x1', 'eip155:1:0x2'], }, }, @@ -142,15 +111,11 @@ describe('CAIP-25 permittedChains adapters', () => { const input: Caip25CaveatValue = { requiredScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: ['eip155:1:0x1', 'eip155:1:0x2'], }, }, optionalScopes: { 'eip155:100': { - methods: [], - notifications: [], accounts: ['eip155:100:0x100'], }, }, @@ -165,15 +130,11 @@ describe('CAIP-25 permittedChains adapters', () => { const input: Caip25CaveatValue = { requiredScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: ['eip155:1:0x1', 'eip155:1:0x2'], }, }, optionalScopes: { 'eip155:100': { - methods: [], - notifications: [], accounts: ['eip155:100:0x100'], }, }, @@ -191,30 +152,20 @@ describe('CAIP-25 permittedChains adapters', () => { { requiredScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: ['eip155:1:0x1', 'eip155:1:0x2'], }, 'bip122:000000000019d6689c085ae165831e93': { - methods: [], - notifications: [], accounts: [], }, }, optionalScopes: { wallet: { - methods: [], - notifications: [], accounts: [], }, 'eip155:1': { - methods: ['eth_chainId'], - notifications: [], accounts: [], }, 'eip155:100': { - methods: [], - notifications: [], accounts: ['eip155:100:0x100'], }, }, @@ -226,25 +177,17 @@ describe('CAIP-25 permittedChains adapters', () => { expect(result).toStrictEqual({ requiredScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: ['eip155:1:0x1', 'eip155:1:0x2'], }, 'bip122:000000000019d6689c085ae165831e93': { - methods: [], - notifications: [], accounts: [], }, }, optionalScopes: { wallet: { - methods: [], - notifications: [], accounts: [], }, 'eip155:1': { - methods: ['eth_chainId'], - notifications: [], accounts: [], }, }, @@ -257,20 +200,14 @@ describe('CAIP-25 permittedChains adapters', () => { { requiredScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: ['eip155:1:0x1', 'eip155:1:0x2'], }, }, optionalScopes: { 'eip155:1': { - methods: ['eth_chainId'], - notifications: [], accounts: [], }, 'eip155:100': { - methods: [], - notifications: [], accounts: ['eip155:100:0x100'], }, }, @@ -282,25 +219,17 @@ describe('CAIP-25 permittedChains adapters', () => { expect(result).toStrictEqual({ requiredScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: ['eip155:1:0x1', 'eip155:1:0x2'], }, }, optionalScopes: { 'eip155:1': { - methods: ['eth_chainId'], - notifications: [], accounts: [], }, 'eip155:100': { - methods: [], - notifications: [], accounts: ['eip155:100:0x100'], }, 'eip155:101': { - methods: KnownRpcMethods.eip155, - notifications: KnownNotifications.eip155, accounts: [], }, }, @@ -312,8 +241,6 @@ describe('CAIP-25 permittedChains adapters', () => { const input: Caip25CaveatValue = { requiredScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: ['eip155:1:0x1', 'eip155:1:0x2'], }, }, @@ -326,8 +253,6 @@ describe('CAIP-25 permittedChains adapters', () => { expect(input).toStrictEqual({ requiredScopes: { 'eip155:1': { - methods: [], - notifications: [], accounts: ['eip155:1:0x1', 'eip155:1:0x2'], }, }, diff --git a/packages/multichain/src/adapters/caip-permission-adapter-permittedChains.ts b/packages/multichain/src/adapters/caip-permission-adapter-permittedChains.ts index dbf1975840..f56ff36137 100644 --- a/packages/multichain/src/adapters/caip-permission-adapter-permittedChains.ts +++ b/packages/multichain/src/adapters/caip-permission-adapter-permittedChains.ts @@ -3,11 +3,28 @@ import type { Hex } from '@metamask/utils'; import { KnownCaipNamespace } from '@metamask/utils'; import type { Caip25CaveatValue } from '../caip25Permission'; -import { KnownNotifications, KnownRpcMethods } from '../scope/constants'; -import { getUniqueArrayItems, mergeScopes } from '../scope/transform'; +import { getUniqueArrayItems } from '../scope/transform'; import type { InternalScopesObject } from '../scope/types'; import { parseScopeString } from '../scope/types'; +/** + * Gets the Ethereum (EIP155 namespaced) chainIDs from internal scopes. + * @param scopes - The internal scopes from which to get the Ethereum chainIDs. + * @returns An array of Ethereum chainIDs. + */ +const getPermittedEthChainIdsFromScopes = (scopes: InternalScopesObject) => { + const ethChainIds: Hex[] = []; + + Object.keys(scopes).forEach((scopeString) => { + const { namespace, reference } = parseScopeString(scopeString); + if (namespace === KnownCaipNamespace.Eip155 && reference) { + ethChainIds.push(toHex(reference)); + } + }); + + return ethChainIds; +}; + /** * Gets the Ethereum (EIP155 namespaced) chainIDs from the required and optional scopes. * @param caip25CaveatValue - The CAIP-25 caveat value from which to get the Ethereum chainIDs. @@ -19,18 +36,12 @@ export const getPermittedEthChainIds = ( 'requiredScopes' | 'optionalScopes' >, ) => { - const ethChainIds: Hex[] = []; - const sessionScopes = mergeScopes( - caip25CaveatValue.requiredScopes, - caip25CaveatValue.optionalScopes, - ); + const { requiredScopes, optionalScopes } = caip25CaveatValue; - Object.keys(sessionScopes).forEach((scopeString) => { - const { namespace, reference } = parseScopeString(scopeString); - if (namespace === KnownCaipNamespace.Eip155 && reference) { - ethChainIds.push(toHex(reference)); - } - }); + const ethChainIds: Hex[] = [ + ...getPermittedEthChainIdsFromScopes(requiredScopes), + ...getPermittedEthChainIdsFromScopes(optionalScopes), + ]; return getUniqueArrayItems(ethChainIds); }; @@ -45,7 +56,7 @@ export const getPermittedEthChainIds = ( export const addPermittedEthChainId = ( caip25CaveatValue: Caip25CaveatValue, chainId: Hex, -) => { +): Caip25CaveatValue => { const scopeString = `eip155:${parseInt(chainId, 16)}`; if ( Object.keys(caip25CaveatValue.requiredScopes).includes(scopeString) || @@ -59,8 +70,6 @@ export const addPermittedEthChainId = ( optionalScopes: { ...caip25CaveatValue.optionalScopes, [scopeString]: { - methods: KnownRpcMethods.eip155, - notifications: KnownNotifications.eip155, accounts: [], }, }, @@ -79,7 +88,7 @@ export const addPermittedEthChainId = ( const filterEthScopesObjectByChainId = ( scopesObject: InternalScopesObject, chainIds: Hex[], -) => { +): InternalScopesObject => { const updatedScopesObject: InternalScopesObject = {}; Object.entries(scopesObject).forEach(([key, scopeObject]) => { @@ -112,7 +121,7 @@ const filterEthScopesObjectByChainId = ( export const setPermittedEthChainIds = ( caip25CaveatValue: Caip25CaveatValue, chainIds: Hex[], -) => { +): Caip25CaveatValue => { let updatedCaveatValue: Caip25CaveatValue = { ...caip25CaveatValue, requiredScopes: filterEthScopesObjectByChainId( diff --git a/packages/multichain/src/caip25Permission.test.ts b/packages/multichain/src/caip25Permission.test.ts index b124f34f9b..b434e10603 100644 --- a/packages/multichain/src/caip25Permission.test.ts +++ b/packages/multichain/src/caip25Permission.test.ts @@ -11,31 +11,17 @@ import { Caip25CaveatMutators, createCaip25Caveat, } from './caip25Permission'; -import * as ScopeAssert from './scope/assert'; -import * as ScopeAuthorization from './scope/authorization'; +import * as ScopeSupported from './scope/supported'; -jest.mock('./scope/authorization', () => ({ - validateAndNormalizeScopes: jest.fn(), +jest.mock('./scope/supported', () => ({ + ...jest.requireActual('./scope/supported'), + isSupportedScopeString: jest.fn(), })); -const MockScopeAuthorization = jest.mocked(ScopeAuthorization); - -jest.mock('./scope/assert', () => ({ - ...jest.requireActual('./scope/assert'), - assertScopesSupported: jest.fn(), -})); - -const MockScopeAssert = jest.mocked(ScopeAssert); +const MockScopeSupported = jest.mocked(ScopeSupported); const { removeAccount, removeScope } = Caip25CaveatMutators[Caip25CaveatType]; describe('caip25EndowmentBuilder', () => { - beforeEach(() => { - MockScopeAuthorization.validateAndNormalizeScopes.mockReturnValue({ - normalizedRequiredScopes: {}, - normalizedOptionalScopes: {}, - }); - }); - describe('specificationBuilder', () => { it('builds the expected permission specification', () => { const specification = caip25EndowmentBuilder.specificationBuilder({ @@ -81,15 +67,11 @@ describe('caip25EndowmentBuilder', () => { const ethereumGoerliCaveat = { requiredScopes: { 'eip155:1': { - methods: ['eth_call'], - notifications: ['chainChanged'], accounts: [], }, }, optionalScopes: { 'eip155:5': { - methods: ['eth_call'], - notifications: ['accountsChanged'], accounts: [], }, }, @@ -103,8 +85,6 @@ describe('caip25EndowmentBuilder', () => { requiredScopes: {}, optionalScopes: { 'eip155:5': { - methods: ['eth_call'], - notifications: ['accountsChanged'], accounts: [], }, }, @@ -116,15 +96,11 @@ describe('caip25EndowmentBuilder', () => { const ethereumGoerliCaveat = { requiredScopes: { 'eip155:1': { - methods: ['eth_call'], - notifications: ['chainChanged'], accounts: [], }, }, optionalScopes: { 'eip155:5': { - methods: ['eth_call'], - notifications: ['accountsChanged'], accounts: [], }, }, @@ -137,8 +113,6 @@ describe('caip25EndowmentBuilder', () => { value: { requiredScopes: { 'eip155:1': { - methods: ['eth_call'], - notifications: ['chainChanged'], accounts: [], }, }, @@ -151,20 +125,14 @@ describe('caip25EndowmentBuilder', () => { const ethereumGoerliCaveat = { requiredScopes: { 'eip155:1': { - methods: ['eth_call'], - notifications: ['chainChanged'], accounts: [], }, 'eip155:5': { - methods: [], - notifications: ['chainChanged'], accounts: [], }, }, optionalScopes: { 'eip155:5': { - methods: ['eth_call'], - notifications: ['accountsChanged'], accounts: [], }, }, @@ -177,8 +145,6 @@ describe('caip25EndowmentBuilder', () => { value: { requiredScopes: { 'eip155:1': { - methods: ['eth_call'], - notifications: ['chainChanged'], accounts: [], }, }, @@ -191,15 +157,11 @@ describe('caip25EndowmentBuilder', () => { const ethereumGoerliCaveat = { requiredScopes: { 'eip155:1': { - methods: ['eth_call'], - notifications: ['chainChanged'], accounts: [], }, }, optionalScopes: { 'eip155:5': { - methods: ['eth_call'], - notifications: ['accountsChanged'], accounts: [], }, }, @@ -218,8 +180,6 @@ describe('caip25EndowmentBuilder', () => { const ethereumGoerliCaveat: Caip25CaveatValue = { requiredScopes: { 'eip155:1': { - methods: ['eth_call'], - notifications: ['chainChanged'], accounts: ['eip155:1:0x1', 'eip155:1:0x2'], }, }, @@ -232,8 +192,6 @@ describe('caip25EndowmentBuilder', () => { value: { requiredScopes: { 'eip155:1': { - methods: ['eth_call'], - notifications: ['chainChanged'], accounts: ['eip155:1:0x2'], }, }, @@ -248,8 +206,6 @@ describe('caip25EndowmentBuilder', () => { requiredScopes: {}, optionalScopes: { 'eip155:1': { - methods: ['eth_call'], - notifications: ['chainChanged'], accounts: ['eip155:1:0x1', 'eip155:1:0x2'], }, }, @@ -262,8 +218,6 @@ describe('caip25EndowmentBuilder', () => { requiredScopes: {}, optionalScopes: { 'eip155:1': { - methods: ['eth_call'], - notifications: ['chainChanged'], accounts: ['eip155:1:0x2'], }, }, @@ -276,20 +230,14 @@ describe('caip25EndowmentBuilder', () => { const ethereumGoerliCaveat: Caip25CaveatValue = { requiredScopes: { 'eip155:1': { - methods: ['eth_call'], - notifications: ['chainChanged'], accounts: ['eip155:1:0x1', 'eip155:1:0x2'], }, 'eip155:2': { - methods: ['eth_call'], - notifications: ['chainChanged'], accounts: ['eip155:2:0x1', 'eip155:2:0x2'], }, }, optionalScopes: { 'eip155:3': { - methods: ['eth_call'], - notifications: ['chainChanged'], accounts: ['eip155:3:0x1', 'eip155:3:0x2'], }, }, @@ -301,20 +249,14 @@ describe('caip25EndowmentBuilder', () => { value: { requiredScopes: { 'eip155:1': { - methods: ['eth_call'], - notifications: ['chainChanged'], accounts: ['eip155:1:0x2'], }, 'eip155:2': { - methods: ['eth_call'], - notifications: ['chainChanged'], accounts: ['eip155:2:0x2'], }, }, optionalScopes: { 'eip155:3': { - methods: ['eth_call'], - notifications: ['chainChanged'], accounts: ['eip155:3:0x2'], }, }, @@ -327,15 +269,11 @@ describe('caip25EndowmentBuilder', () => { const ethereumGoerliCaveat: Caip25CaveatValue = { requiredScopes: { 'eip155:1': { - methods: ['eth_call'], - notifications: ['chainChanged'], accounts: ['eip155:1:0x1', 'eip155:1:0x2'], }, }, optionalScopes: { 'eip155:5': { - methods: ['eth_call'], - notifications: ['accountsChanged'], accounts: [], }, }, @@ -491,7 +429,7 @@ describe('caip25EndowmentBuilder', () => { ); }); - it('validates and normalizes the ScopesObjects', () => { + it('asserts the internal required scopeStrings are supported', () => { try { validator({ caveats: [ @@ -500,15 +438,11 @@ describe('caip25EndowmentBuilder', () => { value: { requiredScopes: { 'eip155:1': { - methods: ['eth_chainId'], - notifications: [], accounts: ['eip155:1:0xdead'], }, }, optionalScopes: { 'eip155:5': { - methods: [], - notifications: [], accounts: ['eip155:5:0xbeef'], }, }, @@ -524,111 +458,16 @@ describe('caip25EndowmentBuilder', () => { } catch (err) { // noop } - expect( - MockScopeAuthorization.validateAndNormalizeScopes, - ).toHaveBeenCalledWith( - { - 'eip155:1': { - methods: ['eth_chainId'], - notifications: [], - accounts: ['eip155:1:0xdead'], - }, - }, - { - 'eip155:5': { - methods: [], - notifications: [], - accounts: ['eip155:5:0xbeef'], - }, - }, + expect(MockScopeSupported.isSupportedScopeString).toHaveBeenCalledWith( + 'eip155:1', + expect.any(Function), ); - }); - it('asserts the validated and normalized required scopes are supported', () => { - MockScopeAuthorization.validateAndNormalizeScopes.mockReturnValue({ - normalizedRequiredScopes: { - 'eip155:1': { - methods: ['normalized_required'], - notifications: [], - accounts: [], - }, - }, - normalizedOptionalScopes: { - 'eip155:1': { - methods: ['normalized_optional'], - notifications: [], - accounts: [], - }, - }, - }); - try { - validator({ - caveats: [ - { - type: Caip25CaveatType, - value: { - requiredScopes: { - 'eip155:1': { - methods: ['eth_chainId'], - notifications: [], - accounts: ['eip155:1:0xdead'], - }, - }, - optionalScopes: { - 'eip155:5': { - methods: [], - notifications: [], - accounts: ['eip155:5:0xbeef'], - }, - }, - isMultichainOrigin: true, - }, - }, - ], - date: 1234, - id: '1', - invoker: 'test.com', - parentCapability: Caip25EndowmentPermissionName, - }); - } catch (err) { - // noop - } - expect(MockScopeAssert.assertScopesSupported).toHaveBeenCalledWith( - { - 'eip155:1': { - methods: ['normalized_required'], - notifications: [], - accounts: [], - }, - }, - expect.objectContaining({ - isChainIdSupported: expect.any(Function), - }), - ); - - MockScopeAssert.assertScopesSupported.mock.calls[0][1].isChainIdSupported( - '0x1', - ); + MockScopeSupported.isSupportedScopeString.mock.calls[0][1]('0x1'); expect(findNetworkClientIdByChainId).toHaveBeenCalledWith('0x1'); }); - it('asserts the validated and normalized optional scopes are supported', () => { - MockScopeAuthorization.validateAndNormalizeScopes.mockReturnValue({ - normalizedRequiredScopes: { - 'eip155:1': { - methods: ['normalized_required'], - notifications: [], - accounts: [], - }, - }, - normalizedOptionalScopes: { - 'eip155:5': { - methods: ['normalized_optional'], - notifications: [], - accounts: [], - }, - }, - }); + it('asserts the internal optional scopeStrings are supported', () => { try { validator({ caveats: [ @@ -637,15 +476,11 @@ describe('caip25EndowmentBuilder', () => { value: { requiredScopes: { 'eip155:1': { - methods: ['eth_chainId'], - notifications: [], accounts: ['eip155:1:0xdead'], }, }, optionalScopes: { 'eip155:5': { - methods: [], - notifications: [], accounts: ['eip155:5:0xbeef'], }, }, @@ -661,41 +496,17 @@ describe('caip25EndowmentBuilder', () => { } catch (err) { // noop } - expect(MockScopeAssert.assertScopesSupported).toHaveBeenCalledWith( - { - 'eip155:5': { - methods: ['normalized_optional'], - notifications: [], - accounts: [], - }, - }, - expect.objectContaining({ - isChainIdSupported: expect.any(Function), - }), - ); - MockScopeAssert.assertScopesSupported.mock.calls[1][1].isChainIdSupported( - '0x1', + + expect(MockScopeSupported.isSupportedScopeString).toHaveBeenCalledWith( + 'eip155:5', + expect.any(Function), ); - expect(findNetworkClientIdByChainId).toHaveBeenCalledWith('0x1'); + + MockScopeSupported.isSupportedScopeString.mock.calls[1][1]('0x5'); + expect(findNetworkClientIdByChainId).toHaveBeenCalledWith('0x5'); }); it('does not throw if unable to find a network client for the chainId', () => { - MockScopeAuthorization.validateAndNormalizeScopes.mockReturnValue({ - normalizedRequiredScopes: { - 'eip155:1': { - methods: ['normalized_required'], - notifications: [], - accounts: [], - }, - }, - normalizedOptionalScopes: { - 'eip155:5': { - methods: ['normalized_optional'], - notifications: [], - accounts: [], - }, - }, - }); findNetworkClientIdByChainId.mockImplementation(() => { throw new Error('unable to find network client'); }); @@ -707,15 +518,11 @@ describe('caip25EndowmentBuilder', () => { value: { requiredScopes: { 'eip155:1': { - methods: ['eth_chainId'], - notifications: [], accounts: ['eip155:1:0xdead'], }, }, optionalScopes: { 'eip155:5': { - methods: [], - notifications: [], accounts: ['eip155:5:0xbeef'], }, }, @@ -733,32 +540,12 @@ describe('caip25EndowmentBuilder', () => { } expect( - MockScopeAssert.assertScopesSupported.mock.calls[0][1].isChainIdSupported( - '0x1', - ), + MockScopeSupported.isSupportedScopeString.mock.calls[0][1]('0x1'), ).toBe(false); expect(findNetworkClientIdByChainId).toHaveBeenCalledWith('0x1'); }); - it('throws if the eth accounts specified in the normalized scopeObjects are not found in the wallet keyring', () => { - MockScopeAuthorization.validateAndNormalizeScopes.mockReturnValue({ - normalizedRequiredScopes: { - 'eip155:1': { - methods: ['eth_chainId'], - notifications: [], - accounts: ['eip155:1:0xdead'], - }, - }, - normalizedOptionalScopes: { - 'eip155:5': { - methods: [], - notifications: [], - accounts: ['eip155:5:0xbeef'], - }, - }, - }); - listAccounts.mockReturnValue([{ address: '0xdead' }]); // missing '0xbeef' - + it('throws if not all scopeStrings are supported', () => { expect(() => { validator({ caveats: [ @@ -767,15 +554,11 @@ describe('caip25EndowmentBuilder', () => { value: { requiredScopes: { 'eip155:1': { - methods: ['eth_chainId'], - notifications: [], accounts: ['eip155:1:0xdead'], }, }, optionalScopes: { 'eip155:5': { - methods: [], - notifications: [], accounts: ['eip155:5:0xbeef'], }, }, @@ -790,72 +573,14 @@ describe('caip25EndowmentBuilder', () => { }); }).toThrow( new Error( - `${Caip25EndowmentPermissionName} error: Received eip155 account value(s) for caveat of type "${Caip25CaveatType}" that were not found in the wallet keyring.`, + `${Caip25EndowmentPermissionName} error: Received scopeString value(s) for caveat of type "${Caip25CaveatType}" that are not supported by the wallet.`, ), ); }); - it('throws if the input requiredScopes does not match the output of validateAndNormalizeScopes', () => { - MockScopeAuthorization.validateAndNormalizeScopes.mockReturnValue({ - normalizedRequiredScopes: {}, - normalizedOptionalScopes: { - 'eip155:5': { - methods: [], - notifications: [], - accounts: ['eip155:5:0xbeef'], - }, - }, - }); - listAccounts.mockReturnValue([{ address: '0xbeef' }]); - - expect(() => { - validator({ - caveats: [ - { - type: Caip25CaveatType, - value: { - requiredScopes: { - 'eip155:1': { - methods: ['eth_chainId'], - notifications: [], - accounts: ['eip155:1:0xdead'], - }, - }, - optionalScopes: { - 'eip155:5': { - methods: [], - notifications: [], - accounts: ['eip155:5:0xbeef'], - }, - }, - isMultichainOrigin: true, - }, - }, - ], - date: 1234, - id: '1', - invoker: 'test.com', - parentCapability: Caip25EndowmentPermissionName, - }); - }).toThrow( - new Error( - `${Caip25EndowmentPermissionName} error: Received non-normalized value for caveat of type "${Caip25CaveatType}".`, - ), - ); - }); - - it('throws if the input optionalScopes does not match the output of validateAndNormalizeScopes', () => { - MockScopeAuthorization.validateAndNormalizeScopes.mockReturnValue({ - normalizedRequiredScopes: { - 'eip155:1': { - methods: ['eth_chainId'], - notifications: [], - accounts: ['eip155:1:0xdead'], - }, - }, - normalizedOptionalScopes: {}, - }); - listAccounts.mockReturnValue([{ address: '0xdead' }]); + it('throws if the eth accounts specified in the internal scopeObjects are not found in the wallet keyring', () => { + MockScopeSupported.isSupportedScopeString.mockReturnValue(true); + listAccounts.mockReturnValue([{ address: '0xdead' }]); // missing '0xbeef' expect(() => { validator({ @@ -865,15 +590,11 @@ describe('caip25EndowmentBuilder', () => { value: { requiredScopes: { 'eip155:1': { - methods: ['eth_chainId'], - notifications: [], accounts: ['eip155:1:0xdead'], }, }, optionalScopes: { 'eip155:5': { - methods: [], - notifications: [], accounts: ['eip155:5:0xbeef'], }, }, @@ -888,28 +609,13 @@ describe('caip25EndowmentBuilder', () => { }); }).toThrow( new Error( - `${Caip25EndowmentPermissionName} error: Received non-normalized value for caveat of type "${Caip25CaveatType}".`, + `${Caip25EndowmentPermissionName} error: Received eip155 account value(s) for caveat of type "${Caip25CaveatType}" that were not found in the wallet keyring.`, ), ); }); - it('does not throw if the input requiredScopes and optionalScopes InternalScopesObject are already validated and normalized', () => { - MockScopeAuthorization.validateAndNormalizeScopes.mockReturnValue({ - normalizedRequiredScopes: { - 'eip155:1': { - methods: ['eth_chainId'], - notifications: [], - accounts: ['eip155:1:0xdead'], - }, - }, - normalizedOptionalScopes: { - 'eip155:5': { - methods: [], - notifications: [], - accounts: ['eip155:5:0xbeef'], - }, - }, - }); + it('does not throw if the CAIP-25 caveat value is valid', () => { + MockScopeSupported.isSupportedScopeString.mockReturnValue(true); listAccounts.mockReturnValue([ { address: '0xdead' }, { address: '0xbeef' }, @@ -923,15 +629,11 @@ describe('caip25EndowmentBuilder', () => { value: { requiredScopes: { 'eip155:1': { - methods: ['eth_chainId'], - notifications: [], accounts: ['eip155:1:0xdead'], }, }, optionalScopes: { 'eip155:5': { - methods: [], - notifications: [], accounts: ['eip155:5:0xbeef'], }, }, diff --git a/packages/multichain/src/caip25Permission.ts b/packages/multichain/src/caip25Permission.ts index b7c1679491..7a8dd93f23 100644 --- a/packages/multichain/src/caip25Permission.ts +++ b/packages/multichain/src/caip25Permission.ts @@ -20,15 +20,12 @@ import { import { cloneDeep, isEqual } from 'lodash'; import { getEthAccounts } from './adapters/caip-permission-adapter-eth-accounts'; +import { assertIsInternalScopesObject } from './scope/assert'; +import { isSupportedScopeString } from './scope/supported'; import { - assertScopesSupported, - assertIsExternalScopesObject, -} from './scope/assert'; -import { validateAndNormalizeScopes } from './scope/authorization'; -import type { - ExternalScopeString, - InternalScopeObject, - InternalScopesObject, + type ExternalScopeString, + type InternalScopeObject, + type InternalScopesObject, } from './scope/types'; /** @@ -120,13 +117,11 @@ const specificationBuilder: PermissionSpecificationBuilder< `${Caip25EndowmentPermissionName} error: Received invalid value for caveat of type "${Caip25CaveatType}".`, ); } - const { requiredScopes, optionalScopes } = caip25Caveat.value; - assertIsExternalScopesObject(requiredScopes); - assertIsExternalScopesObject(optionalScopes); + const { requiredScopes, optionalScopes } = caip25Caveat.value; - const { normalizedRequiredScopes, normalizedOptionalScopes } = - validateAndNormalizeScopes(requiredScopes, optionalScopes); + assertIsInternalScopesObject(requiredScopes); + assertIsInternalScopesObject(optionalScopes); const isChainIdSupported = (chainId: Hex) => { try { @@ -137,12 +132,19 @@ const specificationBuilder: PermissionSpecificationBuilder< } }; - assertScopesSupported(normalizedRequiredScopes, { - isChainIdSupported, - }); - assertScopesSupported(normalizedOptionalScopes, { - isChainIdSupported, - }); + const allRequiredScopesSupported = Object.keys(requiredScopes).every( + (scopeString) => + isSupportedScopeString(scopeString, isChainIdSupported), + ); + const allOptionalScopesSupported = Object.keys(optionalScopes).every( + (scopeString) => + isSupportedScopeString(scopeString, isChainIdSupported), + ); + if (!allRequiredScopesSupported || !allOptionalScopesSupported) { + throw new Error( + `${Caip25EndowmentPermissionName} error: Received scopeString value(s) for caveat of type "${Caip25CaveatType}" that are not supported by the wallet.`, + ); + } // Fetch EVM accounts from native wallet keyring // These addresses are lowercased already @@ -150,8 +152,8 @@ const specificationBuilder: PermissionSpecificationBuilder< .listAccounts() .map((account) => account.address); const ethAccounts = getEthAccounts({ - requiredScopes: normalizedRequiredScopes, - optionalScopes: normalizedOptionalScopes, + requiredScopes, + optionalScopes, }).map((address) => address.toLowerCase() as Hex); const allEthAccountsSupported = ethAccounts.every((address) => @@ -162,15 +164,6 @@ const specificationBuilder: PermissionSpecificationBuilder< `${Caip25EndowmentPermissionName} error: Received eip155 account value(s) for caveat of type "${Caip25CaveatType}" that were not found in the wallet keyring.`, ); } - - if ( - !isEqual(requiredScopes, normalizedRequiredScopes) || - !isEqual(optionalScopes, normalizedOptionalScopes) - ) { - throw new Error( - `${Caip25EndowmentPermissionName} error: Received non-normalized value for caveat of type "${Caip25CaveatType}".`, - ); - } }, }; }; diff --git a/packages/multichain/src/index.ts b/packages/multichain/src/index.ts index 51864f461c..d322c2b74d 100644 --- a/packages/multichain/src/index.ts +++ b/packages/multichain/src/index.ts @@ -24,6 +24,8 @@ export type { InternalScopeString, InternalScopeObject, InternalScopesObject, + NormalizedScopeObject, + NormalizedScopesObject, ScopedProperties, NonWalletKnownCaipNamespace, } from './scope/types'; diff --git a/packages/multichain/src/scope/assert.test.ts b/packages/multichain/src/scope/assert.test.ts index 362078cd22..0fd23b5bf6 100644 --- a/packages/multichain/src/scope/assert.test.ts +++ b/packages/multichain/src/scope/assert.test.ts @@ -4,10 +4,11 @@ import { assertScopeSupported, assertScopesSupported, assertIsExternalScopesObject, + assertIsInternalScopesObject, } from './assert'; import { Caip25Errors } from './errors'; import * as Supported from './supported'; -import type { InternalScopeObject } from './types'; +import type { NormalizedScopeObject } from './types'; jest.mock('./supported', () => ({ isSupportedScopeString: jest.fn(), @@ -24,7 +25,7 @@ jest.mock('@metamask/utils', () => ({ const MockSupported = jest.mocked(Supported); const MockUtils = jest.mocked(Utils); -const validScopeObject: InternalScopeObject = { +const validScopeObject: NormalizedScopeObject = { methods: [], notifications: [], accounts: [], @@ -305,7 +306,6 @@ describe('Scope Assert', () => { ).toThrow( 'ExternalScopeObject.references must be an array of CaipReference', ); - jest.restoreAllMocks(); }); it('throws an error if passed an object with an ExternalScopeObject with an accounts property that is not an array', () => { @@ -345,7 +345,6 @@ describe('Scope Assert', () => { ).toThrow( 'ExternalScopeObject.accounts must be an array of CaipAccountId', ); - jest.restoreAllMocks(); }); it('throws an error if passed an object with an ExternalScopeObject with a methods property that is not an array', () => { @@ -480,4 +479,81 @@ describe('Scope Assert', () => { ).toThrow('ExternalScopeObject.rpcEndpoints must be an array of strings'); }); }); + + describe('assertIsInternalScopesObject', () => { + it('does not throw if passed obj is a valid InternalScopesObject with all valid properties', () => { + const obj = { + 'eip155:1': { + accounts: ['eip155:1:0x1234'], + }, + }; + expect(() => assertIsInternalScopesObject(obj)).not.toThrow(); + }); + + it('throws an error if passed obj is not an object', () => { + expect(() => assertIsInternalScopesObject(null)).toThrow( + 'InternalScopesObject must be an object', + ); + expect(() => assertIsInternalScopesObject(123)).toThrow( + 'InternalScopesObject must be an object', + ); + expect(() => assertIsInternalScopesObject('string')).toThrow( + 'InternalScopesObject must be an object', + ); + }); + + it('throws an error if passed an object with an InternalScopeObject value that is not an object', () => { + expect(() => assertIsInternalScopesObject({ 'eip155:1': 123 })).toThrow( + 'InternalScopeObject must be an object', + ); + }); + + it('throws an error if passed an object with a key that is not a valid InternalScopeString', () => { + jest.spyOn(Utils, 'isCaipReference').mockImplementation(() => false); + + expect(() => + assertIsInternalScopesObject({ 'invalid-scope-string': {} }), + ).toThrow('scopeString is not a valid InternalScopeString'); + }); + + it('throws an error if passed an object with an InternalScopeObject without an accounts property', () => { + const invalidInternalScopeObject = { + 'eip155:1': {}, + }; + expect(() => + assertIsInternalScopesObject(invalidInternalScopeObject), + ).toThrow( + 'InternalScopeObject.accounts must be an array of CaipAccountId', + ); + }); + + it('throws an error if passed an object with an InternalScopeObject with an accounts property that is not an array', () => { + const invalidInternalScopeObject = { + 'eip155:1': { + accounts: 'not-an-array', + }, + }; + expect(() => + assertIsInternalScopesObject(invalidInternalScopeObject), + ).toThrow( + 'InternalScopeObject.accounts must be an array of CaipAccountId', + ); + }); + + it('throws an error if accounts contains invalid CaipAccountId', () => { + const invalidInternalScopeObject = { + 'eip155:1': { + accounts: ['eip155:1:0x1234', 'invalidAccount'], + }, + }; + MockUtils.isCaipAccountId.mockImplementation( + (id) => id !== 'invalidAccount', + ); + expect(() => + assertIsInternalScopesObject(invalidInternalScopeObject), + ).toThrow( + 'InternalScopeObject.accounts must be an array of CaipAccountId', + ); + }); + }); }); diff --git a/packages/multichain/src/scope/assert.ts b/packages/multichain/src/scope/assert.ts index 522ed2f1d8..0d2c8c16cb 100644 --- a/packages/multichain/src/scope/assert.ts +++ b/packages/multichain/src/scope/assert.ts @@ -4,6 +4,7 @@ import { isCaipChainId, isCaipNamespace, isCaipReference, + KnownCaipNamespace, type Hex, } from '@metamask/utils'; @@ -19,6 +20,9 @@ import type { ExternalScopeString, InternalScopeObject, InternalScopesObject, + InternalScopeString, + NormalizedScopeObject, + NormalizedScopesObject, } from './types'; /** @@ -30,7 +34,7 @@ import type { */ export const assertScopeSupported = ( scopeString: string, - scopeObject: InternalScopeObject, + scopeObject: NormalizedScopeObject, { isChainIdSupported, }: { @@ -67,7 +71,7 @@ export const assertScopeSupported = ( * @param options.isChainIdSupported - A predicate that determines if a chainID is supported. */ export const assertScopesSupported = ( - scopes: InternalScopesObject, + scopes: NormalizedScopesObject, { isChainIdSupported, }: { @@ -188,3 +192,57 @@ export function assertIsExternalScopesObject( assertIsExternalScopeObject(scopeObject); } } + +/** + * Asserts that an object is a valid InternalScopeObject. + * @param obj - The object to assert. + */ +function assertIsInternalScopeObject( + obj: unknown, +): asserts obj is InternalScopeObject { + if (typeof obj !== 'object' || obj === null) { + throw new Error('InternalScopeObject must be an object'); + } + + if ( + !hasProperty(obj, 'accounts') || + !Array.isArray(obj.accounts) || + !obj.accounts.every(isCaipAccountId) + ) { + throw new Error( + 'InternalScopeObject.accounts must be an array of CaipAccountId', + ); + } +} + +/** + * Asserts that a scope string is a valid InternalScopeString. + * @param scopeString - The scope string to assert. + */ +function assertIsInternalScopeString( + scopeString: unknown, +): asserts scopeString is InternalScopeString { + if ( + typeof scopeString !== 'string' || + (scopeString !== KnownCaipNamespace.Wallet && !isCaipChainId(scopeString)) + ) { + throw new Error('scopeString is not a valid InternalScopeString'); + } +} + +/** + * Asserts that an object is a valid InternalScopesObject. + * @param obj - The object to assert. + */ +export function assertIsInternalScopesObject( + obj: unknown, +): asserts obj is InternalScopesObject { + if (typeof obj !== 'object' || obj === null) { + throw new Error('InternalScopesObject must be an object'); + } + + for (const [scopeString, scopeObject] of Object.entries(obj)) { + assertIsInternalScopeString(scopeString); + assertIsInternalScopeObject(scopeObject); + } +} diff --git a/packages/multichain/src/scope/authorization.ts b/packages/multichain/src/scope/authorization.ts index 6974d65295..0f43fa33e4 100644 --- a/packages/multichain/src/scope/authorization.ts +++ b/packages/multichain/src/scope/authorization.ts @@ -4,7 +4,7 @@ import { normalizeAndMergeScopes } from './transform'; import type { ExternalScopesObject, ExternalScopeString, - InternalScopesObject, + NormalizedScopesObject, } from './types'; import { getValidScopes } from './validation'; @@ -35,8 +35,8 @@ export const validateAndNormalizeScopes = ( requiredScopes: ExternalScopesObject, optionalScopes: ExternalScopesObject, ): { - normalizedRequiredScopes: InternalScopesObject; - normalizedOptionalScopes: InternalScopesObject; + normalizedRequiredScopes: NormalizedScopesObject; + normalizedOptionalScopes: NormalizedScopesObject; } => { const { validRequiredScopes, validOptionalScopes } = getValidScopes( requiredScopes, diff --git a/packages/multichain/src/scope/transform.test.ts b/packages/multichain/src/scope/transform.test.ts index 5eede12203..b5e01b5cce 100644 --- a/packages/multichain/src/scope/transform.test.ts +++ b/packages/multichain/src/scope/transform.test.ts @@ -4,14 +4,14 @@ import { mergeScopeObject, normalizeAndMergeScopes, } from './transform'; -import type { ExternalScopeObject, InternalScopeObject } from './types'; +import type { ExternalScopeObject, NormalizedScopeObject } from './types'; const externalScopeObject: ExternalScopeObject = { methods: [], notifications: [], }; -const validScopeObject: InternalScopeObject = { +const validScopeObject: NormalizedScopeObject = { methods: [], notifications: [], accounts: [], diff --git a/packages/multichain/src/scope/transform.ts b/packages/multichain/src/scope/transform.ts index 561b64b002..666ff740eb 100644 --- a/packages/multichain/src/scope/transform.ts +++ b/packages/multichain/src/scope/transform.ts @@ -4,8 +4,8 @@ import { cloneDeep } from 'lodash'; import type { ExternalScopeObject, ExternalScopesObject, - InternalScopeObject, - InternalScopesObject, + NormalizedScopeObject, + NormalizedScopesObject, } from './types'; import { parseScopeString } from './types'; @@ -21,7 +21,7 @@ export const getUniqueArrayItems = (list: Value[]): Value[] => { /** * Normalizes a ScopeString and ExternalScopeObject into a separate - * InternalScopeString and InternalScopeObject for each reference in the `references` + * InternalScopeString and NormalizedScopeObject for each reference in the `references` * value if defined and adds an empty `accounts` array if not defined. * * @param scopeString - The string representing the scope @@ -31,11 +31,11 @@ export const getUniqueArrayItems = (list: Value[]): Value[] => { export const normalizeScope = ( scopeString: string, externalScopeObject: ExternalScopeObject, -): InternalScopesObject => { +): NormalizedScopesObject => { const { references, ...scopeObject } = externalScopeObject; const { namespace, reference } = parseScopeString(scopeString); - const normalizedScopeObject: InternalScopeObject = { + const normalizedScopeObject: NormalizedScopeObject = { accounts: [], ...scopeObject, }; @@ -58,16 +58,16 @@ export const normalizeScope = ( }; /** - * Merges two InternalScopeObjects + * Merges two NormalizedScopeObjects * @param scopeObjectA - The first scope object to merge. * @param scopeObjectB - The second scope object to merge. * @returns The merged scope object. */ export const mergeScopeObject = ( - scopeObjectA: InternalScopeObject, - scopeObjectB: InternalScopeObject, + scopeObjectA: NormalizedScopeObject, + scopeObjectB: NormalizedScopeObject, ) => { - const mergedScopeObject: InternalScopeObject = { + const mergedScopeObject: NormalizedScopeObject = { methods: getUniqueArrayItems([ ...scopeObjectA.methods, ...scopeObjectB.methods, @@ -100,16 +100,16 @@ export const mergeScopeObject = ( }; /** - * Merges two InternalScopeObjects + * Merges two NormalizedScopeObjects * @param scopeA - The first scope object to merge. * @param scopeB - The second scope object to merge. * @returns The merged scope object. */ export const mergeScopes = ( - scopeA: InternalScopesObject, - scopeB: InternalScopesObject, -): InternalScopesObject => { - const scope: InternalScopesObject = {}; + scopeA: NormalizedScopesObject, + scopeB: NormalizedScopesObject, +): NormalizedScopesObject => { + const scope: NormalizedScopesObject = {}; Object.entries(scopeA).forEach(([_scopeString, scopeObjectA]) => { // Cast needed because index type is returned as `string` by `Object.entries` @@ -135,14 +135,14 @@ export const mergeScopes = ( }; /** - * Normalizes and merges a set of ExternalScopesObjects into a InternalScopesObject (i.e. a set of InternalScopeObjects where references are flattened). + * Normalizes and merges a set of ExternalScopesObjects into a NormalizedScopesObject (i.e. a set of NormalizedScopeObjects where references are flattened). * @param scopes - The external scopes to normalize and merge. * @returns The normalized and merged scopes. */ export const normalizeAndMergeScopes = ( scopes: ExternalScopesObject, -): InternalScopesObject => { - let mergedScopes: InternalScopesObject = {}; +): NormalizedScopesObject => { + let mergedScopes: NormalizedScopesObject = {}; Object.keys(scopes).forEach((scopeString) => { const normalizedScopes = normalizeScope(scopeString, scopes[scopeString]); mergedScopes = mergeScopes(mergedScopes, normalizedScopes); diff --git a/packages/multichain/src/scope/types.ts b/packages/multichain/src/scope/types.ts index 77b1669fd5..f639c58d2e 100644 --- a/packages/multichain/src/scope/types.ts +++ b/packages/multichain/src/scope/types.ts @@ -19,7 +19,7 @@ export type ExternalScopeString = CaipChainId | CaipNamespace; /** * Represents a `scopeObject` as defined in [CAIP-217](https://chainagnostic.org/CAIPs/caip-217). */ -export type ExternalScopeObject = Omit & { +export type ExternalScopeObject = Omit & { references?: CaipReference[]; accounts?: CaipAccountId[]; }; @@ -38,13 +38,31 @@ export type ExternalScopesObject = Record< * CAIP namespaces without a reference (aside from "wallet") are disallowed for our internal representations of CAIP-25 session scopes */ export type InternalScopeString = CaipChainId | KnownCaipNamespace.Wallet; + +/** + * A trimmed down version of a [CAIP-217](https://chainagnostic.org/CAIPs/caip-217) defined scopeObject that is stored in a `endowment:caip25` permission. + * The only property from the original CAIP-25 scopeObject that we use for permissioning is `accounts`. + */ +export type InternalScopeObject = { + accounts: CaipAccountId[]; +}; + +/** + * A trimmed down version of a [CAIP-217](https://chainagnostic.org/CAIPs/caip-217) scope that is stored in a `endowment:caip25` permission. + * Accounts arrays are mapped to CAIP-2 chainIds. These are currently the only properties used by the permission system. + */ +export type InternalScopesObject = Record & { + [KnownCaipNamespace.Wallet]?: InternalScopeObject; +}; + /** * Represents a `scopeObject` as defined in * [CAIP-217](https://chainagnostic.org/CAIPs/caip-217), with the exception that - * the `references` property is disallowed for our internal representations of CAIP-25 session scopes. - * e.g. We flatten each reference into its own scopeObject before storing them in a `endowment:caip25` permission. + * we resolve the `references` property into a scopeObject per reference and + * assign an empty array to the `accounts` property if not already defined + * to more easily read chain specific permissions. */ -export type InternalScopeObject = { +export type NormalizedScopeObject = { methods: string[]; notifications: string[]; accounts: CaipAccountId[]; @@ -54,11 +72,15 @@ export type InternalScopeObject = { /** * Represents a keyed `scopeObject` as defined in * [CAIP-217](https://chainagnostic.org/CAIPs/caip-217), with the exception that - * `scopeObject`s do not contain `references` in our internal representations of CAIP-25 session scopes. - * e.g. We flatten each reference into its own scopeObject before storing them in a `endowment:caip25` permission. + * we resolve the `references` property into a scopeObject per reference and + * assign an empty array to the `accounts` property if not already defined + * to more easily read chain specific permissions. */ -export type InternalScopesObject = Record & { - [KnownCaipNamespace.Wallet]?: InternalScopeObject; +export type NormalizedScopesObject = Record< + CaipChainId, + NormalizedScopeObject +> & { + [KnownCaipNamespace.Wallet]?: NormalizedScopeObject; }; export type ScopedProperties = Record> & { diff --git a/packages/notification-services-controller/CHANGELOG.md b/packages/notification-services-controller/CHANGELOG.md index 5e2aa5da30..c9113b21d4 100644 --- a/packages/notification-services-controller/CHANGELOG.md +++ b/packages/notification-services-controller/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.14.0] + +### Changed + +- **BREAKING:** Bump `@metamask/keyring-controller` peer dependency from `^18.0.0` to `^19.0.0` ([#4195](https://github.com/MetaMask/core/pull/4956)) +- **BREAKING:** Bump `@metamask/profile-sync-controller` peer dependency from `^1.0.0` to `^2.0.0` ([#4195](https://github.com/MetaMask/core/pull/4956)) + ## [0.13.0] ### Changed @@ -247,7 +254,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial release -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/notification-services-controller@0.13.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/notification-services-controller@0.14.0...HEAD +[0.14.0]: https://github.com/MetaMask/core/compare/@metamask/notification-services-controller@0.13.0...@metamask/notification-services-controller@0.14.0 [0.13.0]: https://github.com/MetaMask/core/compare/@metamask/notification-services-controller@0.12.1...@metamask/notification-services-controller@0.13.0 [0.12.1]: https://github.com/MetaMask/core/compare/@metamask/notification-services-controller@0.12.0...@metamask/notification-services-controller@0.12.1 [0.12.0]: https://github.com/MetaMask/core/compare/@metamask/notification-services-controller@0.11.0...@metamask/notification-services-controller@0.12.0 diff --git a/packages/notification-services-controller/package.json b/packages/notification-services-controller/package.json index 5223c6c795..9dc69409ce 100644 --- a/packages/notification-services-controller/package.json +++ b/packages/notification-services-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/notification-services-controller", - "version": "0.13.0", + "version": "0.14.0", "description": "Manages New MetaMask decentralized Notification system", "keywords": [ "MetaMask", @@ -111,8 +111,8 @@ "devDependencies": { "@lavamoat/allow-scripts": "^3.0.4", "@metamask/auto-changelog": "^3.4.4", - "@metamask/keyring-controller": "^18.0.0", - "@metamask/profile-sync-controller": "^1.0.2", + "@metamask/keyring-controller": "^19.0.0", + "@metamask/profile-sync-controller": "^2.0.0", "@types/jest": "^27.4.1", "@types/readable-stream": "^2.3.0", "contentful": "^10.15.0", @@ -126,8 +126,8 @@ "typescript": "~5.2.2" }, "peerDependencies": { - "@metamask/keyring-controller": "^18.0.0", - "@metamask/profile-sync-controller": "^1.0.0" + "@metamask/keyring-controller": "^19.0.0", + "@metamask/profile-sync-controller": "^2.0.0" }, "engines": { "node": "^18.18 || >=20" diff --git a/packages/preferences-controller/CHANGELOG.md b/packages/preferences-controller/CHANGELOG.md index c1b301a341..6b4b45aa67 100644 --- a/packages/preferences-controller/CHANGELOG.md +++ b/packages/preferences-controller/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [15.0.0] + +### Changed + +- **BREAKING:** Bump `@metamask/keyring-controller` peer dependency from `^18.0.0` to `^19.0.0` ([#4195](https://github.com/MetaMask/core/pull/4956)) + ## [14.0.0] ### Changed @@ -321,7 +327,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/preferences-controller@14.0.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/preferences-controller@15.0.0...HEAD +[15.0.0]: https://github.com/MetaMask/core/compare/@metamask/preferences-controller@14.0.0...@metamask/preferences-controller@15.0.0 [14.0.0]: https://github.com/MetaMask/core/compare/@metamask/preferences-controller@13.3.0...@metamask/preferences-controller@14.0.0 [13.3.0]: https://github.com/MetaMask/core/compare/@metamask/preferences-controller@13.2.0...@metamask/preferences-controller@13.3.0 [13.2.0]: https://github.com/MetaMask/core/compare/@metamask/preferences-controller@13.1.0...@metamask/preferences-controller@13.2.0 diff --git a/packages/preferences-controller/package.json b/packages/preferences-controller/package.json index bcebd59c43..93f366a8e3 100644 --- a/packages/preferences-controller/package.json +++ b/packages/preferences-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/preferences-controller", - "version": "14.0.0", + "version": "15.0.0", "description": "Manages user-configurable settings for MetaMask", "keywords": [ "MetaMask", @@ -52,7 +52,7 @@ }, "devDependencies": { "@metamask/auto-changelog": "^3.4.4", - "@metamask/keyring-controller": "^18.0.0", + "@metamask/keyring-controller": "^19.0.0", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "jest": "^27.5.1", @@ -63,7 +63,7 @@ "typescript": "~5.2.2" }, "peerDependencies": { - "@metamask/keyring-controller": "^18.0.0" + "@metamask/keyring-controller": "^19.0.0" }, "engines": { "node": "^18.18 || >=20" diff --git a/packages/profile-sync-controller/CHANGELOG.md b/packages/profile-sync-controller/CHANGELOG.md index a106a4e548..9129585fc1 100644 --- a/packages/profile-sync-controller/CHANGELOG.md +++ b/packages/profile-sync-controller/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [2.0.0] + +### Changed + +- **BREAKING:** Bump `@metamask/keyring-controller` peer dependency from `^18.0.0` to `^19.0.0` ([#4195](https://github.com/MetaMask/core/pull/4956)) +- **BREAKING:** Bump `@metamask/accounts-controller` peer dependency from `^19.0.0` to `^20.0.0` ([#4195](https://github.com/MetaMask/core/pull/4956)) + ## [1.0.2] ### Added @@ -321,7 +328,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial release -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/profile-sync-controller@1.0.2...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/profile-sync-controller@2.0.0...HEAD +[2.0.0]: https://github.com/MetaMask/core/compare/@metamask/profile-sync-controller@1.0.2...@metamask/profile-sync-controller@2.0.0 [1.0.2]: https://github.com/MetaMask/core/compare/@metamask/profile-sync-controller@1.0.1...@metamask/profile-sync-controller@1.0.2 [1.0.1]: https://github.com/MetaMask/core/compare/@metamask/profile-sync-controller@1.0.0...@metamask/profile-sync-controller@1.0.1 [1.0.0]: https://github.com/MetaMask/core/compare/@metamask/profile-sync-controller@0.9.8...@metamask/profile-sync-controller@1.0.0 diff --git a/packages/profile-sync-controller/package.json b/packages/profile-sync-controller/package.json index 11e13db87c..23c2e7b73f 100644 --- a/packages/profile-sync-controller/package.json +++ b/packages/profile-sync-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/profile-sync-controller", - "version": "1.0.2", + "version": "2.0.0", "description": "The profile sync helps developers synchronize data across multiple clients and devices in a privacy-preserving way. All data saved in the user storage database is encrypted client-side to preserve privacy. The user storage provides a modular design, giving developers the flexibility to construct and manage their storage spaces in a way that best suits their needs", "keywords": [ "MetaMask", @@ -102,7 +102,7 @@ "dependencies": { "@metamask/base-controller": "^7.0.2", "@metamask/keyring-api": "^10.1.0", - "@metamask/keyring-controller": "^18.0.0", + "@metamask/keyring-controller": "^19.0.0", "@metamask/network-controller": "^22.0.2", "@metamask/snaps-sdk": "^6.7.0", "@metamask/snaps-utils": "^8.3.0", @@ -114,7 +114,7 @@ }, "devDependencies": { "@lavamoat/allow-scripts": "^3.0.4", - "@metamask/accounts-controller": "^19.0.0", + "@metamask/accounts-controller": "^20.0.0", "@metamask/auto-changelog": "^3.4.4", "@metamask/snaps-controllers": "^9.10.0", "@types/jest": "^27.4.1", @@ -129,8 +129,8 @@ "typescript": "~5.2.2" }, "peerDependencies": { - "@metamask/accounts-controller": "^19.0.0", - "@metamask/keyring-controller": "^18.0.0", + "@metamask/accounts-controller": "^20.0.0", + "@metamask/keyring-controller": "^19.0.0", "@metamask/network-controller": "^22.0.0", "@metamask/snaps-controllers": "^9.10.0" }, diff --git a/packages/signature-controller/CHANGELOG.md b/packages/signature-controller/CHANGELOG.md index e90718bed8..a20da03c52 100644 --- a/packages/signature-controller/CHANGELOG.md +++ b/packages/signature-controller/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [23.0.0] + +### Changed + +- **BREAKING:** Bump `@metamask/keyring-controller` peer dependency from `^18.0.0` to `^19.0.0` ([#4195](https://github.com/MetaMask/core/pull/4956)) + ## [22.0.0] ### Changed @@ -414,7 +420,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial release ([#1214](https://github.com/MetaMask/core/pull/1214)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/signature-controller@22.0.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/signature-controller@23.0.0...HEAD +[23.0.0]: https://github.com/MetaMask/core/compare/@metamask/signature-controller@22.0.0...@metamask/signature-controller@23.0.0 [22.0.0]: https://github.com/MetaMask/core/compare/@metamask/signature-controller@21.1.0...@metamask/signature-controller@22.0.0 [21.1.0]: https://github.com/MetaMask/core/compare/@metamask/signature-controller@21.0.0...@metamask/signature-controller@21.1.0 [21.0.0]: https://github.com/MetaMask/core/compare/@metamask/signature-controller@20.1.0...@metamask/signature-controller@21.0.0 diff --git a/packages/signature-controller/package.json b/packages/signature-controller/package.json index 7180728e34..67e8aec015 100644 --- a/packages/signature-controller/package.json +++ b/packages/signature-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/signature-controller", - "version": "22.0.0", + "version": "23.0.0", "description": "Processes signing requests in order to sign arbitrary and typed data", "keywords": [ "MetaMask", @@ -58,7 +58,7 @@ "devDependencies": { "@metamask/approval-controller": "^7.1.1", "@metamask/auto-changelog": "^3.4.4", - "@metamask/keyring-controller": "^18.0.0", + "@metamask/keyring-controller": "^19.0.0", "@metamask/logging-controller": "^6.0.2", "@metamask/network-controller": "^22.0.2", "@types/jest": "^27.4.1", @@ -71,7 +71,7 @@ }, "peerDependencies": { "@metamask/approval-controller": "^7.0.0", - "@metamask/keyring-controller": "^18.0.0", + "@metamask/keyring-controller": "^19.0.0", "@metamask/logging-controller": "^6.0.0", "@metamask/network-controller": "^22.0.0" }, diff --git a/packages/transaction-controller/CHANGELOG.md b/packages/transaction-controller/CHANGELOG.md index df784f3076..9d01062f17 100644 --- a/packages/transaction-controller/CHANGELOG.md +++ b/packages/transaction-controller/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [40.0.0] + +### Changed + +- **BREAKING:** Bump `@metamask/accounts-controller` peer dependency from `^19.0.0` to `^20.0.0` ([#4195](https://github.com/MetaMask/core/pull/4956)) + ## [39.1.0] ### Changed @@ -1127,7 +1133,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@39.1.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@40.0.0...HEAD +[40.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@39.1.0...@metamask/transaction-controller@40.0.0 [39.1.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@39.0.0...@metamask/transaction-controller@39.1.0 [39.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@38.3.0...@metamask/transaction-controller@39.0.0 [38.3.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@38.2.0...@metamask/transaction-controller@38.3.0 diff --git a/packages/transaction-controller/package.json b/packages/transaction-controller/package.json index 2029b29036..f387f3a5d3 100644 --- a/packages/transaction-controller/package.json +++ b/packages/transaction-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/transaction-controller", - "version": "39.1.0", + "version": "40.0.0", "description": "Stores transactions alongside their periodically updated statuses and manages interactions such as approval and cancellation", "keywords": [ "MetaMask", @@ -69,7 +69,7 @@ }, "devDependencies": { "@babel/runtime": "^7.23.9", - "@metamask/accounts-controller": "^19.0.0", + "@metamask/accounts-controller": "^20.0.0", "@metamask/approval-controller": "^7.1.1", "@metamask/auto-changelog": "^3.4.4", "@metamask/eth-json-rpc-provider": "^4.1.6", @@ -91,7 +91,7 @@ }, "peerDependencies": { "@babel/runtime": "^7.23.9", - "@metamask/accounts-controller": "^19.0.0", + "@metamask/accounts-controller": "^20.0.0", "@metamask/approval-controller": "^7.0.0", "@metamask/gas-fee-controller": "^22.0.0", "@metamask/network-controller": "^22.0.0" diff --git a/packages/user-operation-controller/CHANGELOG.md b/packages/user-operation-controller/CHANGELOG.md index 1edad7b589..64739f9307 100644 --- a/packages/user-operation-controller/CHANGELOG.md +++ b/packages/user-operation-controller/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [19.0.0] + +### Changed + +- **BREAKING:** Bump `@metamask/keyring-controller` peer dependency from `^18.0.0` to `^19.0.0` ([#4195](https://github.com/MetaMask/core/pull/4956)) +- **BREAKING:** Bump `@metamask/transaction-controller` peer dependency from `^39.0.0` to `^40.0.0` ([#4195](https://github.com/MetaMask/core/pull/4956)) + ## [18.0.0] ### Changed @@ -268,7 +275,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial Release ([#3749](https://github.com/MetaMask/core/pull/3749)) -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/user-operation-controller@18.0.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/user-operation-controller@19.0.0...HEAD +[19.0.0]: https://github.com/MetaMask/core/compare/@metamask/user-operation-controller@18.0.0...@metamask/user-operation-controller@19.0.0 [18.0.0]: https://github.com/MetaMask/core/compare/@metamask/user-operation-controller@17.0.0...@metamask/user-operation-controller@18.0.0 [17.0.0]: https://github.com/MetaMask/core/compare/@metamask/user-operation-controller@16.0.0...@metamask/user-operation-controller@17.0.0 [16.0.0]: https://github.com/MetaMask/core/compare/@metamask/user-operation-controller@15.0.1...@metamask/user-operation-controller@16.0.0 diff --git a/packages/user-operation-controller/package.json b/packages/user-operation-controller/package.json index 2d4c6bd82f..bde5bca0d9 100644 --- a/packages/user-operation-controller/package.json +++ b/packages/user-operation-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/user-operation-controller", - "version": "18.0.0", + "version": "19.0.0", "description": "Creates user operations and manages their life cycle", "keywords": [ "MetaMask", @@ -64,9 +64,9 @@ "@metamask/approval-controller": "^7.1.1", "@metamask/auto-changelog": "^3.4.4", "@metamask/gas-fee-controller": "^22.0.1", - "@metamask/keyring-controller": "^18.0.0", + "@metamask/keyring-controller": "^19.0.0", "@metamask/network-controller": "^22.0.2", - "@metamask/transaction-controller": "^39.1.0", + "@metamask/transaction-controller": "^40.0.0", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "jest": "^27.5.1", @@ -78,9 +78,9 @@ "peerDependencies": { "@metamask/approval-controller": "^7.0.0", "@metamask/gas-fee-controller": "^22.0.0", - "@metamask/keyring-controller": "^18.0.0", + "@metamask/keyring-controller": "^19.0.0", "@metamask/network-controller": "^22.0.0", - "@metamask/transaction-controller": "^39.0.0" + "@metamask/transaction-controller": "^40.0.0" }, "engines": { "node": "^18.18 || >=20" diff --git a/yarn.lock b/yarn.lock index 58a8eb65d3..a3d0d0886a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2027,7 +2027,7 @@ __metadata: languageName: node linkType: hard -"@metamask/accounts-controller@npm:^19.0.0, @metamask/accounts-controller@workspace:packages/accounts-controller": +"@metamask/accounts-controller@npm:^20.0.0, @metamask/accounts-controller@workspace:packages/accounts-controller": version: 0.0.0-use.local resolution: "@metamask/accounts-controller@workspace:packages/accounts-controller" dependencies: @@ -2036,7 +2036,7 @@ __metadata: "@metamask/base-controller": "npm:^7.0.2" "@metamask/eth-snap-keyring": "npm:^5.0.1" "@metamask/keyring-api": "npm:^10.1.0" - "@metamask/keyring-controller": "npm:^18.0.0" + "@metamask/keyring-controller": "npm:^19.0.0" "@metamask/snaps-controllers": "npm:^9.10.0" "@metamask/snaps-sdk": "npm:^6.7.0" "@metamask/snaps-utils": "npm:^8.3.0" @@ -2053,8 +2053,8 @@ __metadata: typescript: "npm:~5.2.2" uuid: "npm:^8.3.2" peerDependencies: - "@metamask/keyring-controller": ^18.0.0 - "@metamask/snaps-controllers": ^9.10.0 + "@metamask/keyring-controller": ^19.0.0 + "@metamask/snaps-controllers": ^9.7.0 languageName: unknown linkType: soft @@ -2141,7 +2141,7 @@ __metadata: "@ethersproject/contracts": "npm:^5.7.0" "@ethersproject/providers": "npm:^5.7.0" "@metamask/abi-utils": "npm:^2.0.3" - "@metamask/accounts-controller": "npm:^19.0.0" + "@metamask/accounts-controller": "npm:^20.0.0" "@metamask/approval-controller": "npm:^7.1.1" "@metamask/auto-changelog": "npm:^3.4.4" "@metamask/base-controller": "npm:^7.0.2" @@ -2150,11 +2150,11 @@ __metadata: "@metamask/eth-query": "npm:^4.0.0" "@metamask/ethjs-provider-http": "npm:^0.3.0" "@metamask/keyring-api": "npm:^10.1.0" - "@metamask/keyring-controller": "npm:^18.0.0" + "@metamask/keyring-controller": "npm:^19.0.0" "@metamask/metamask-eth-abis": "npm:^3.1.1" "@metamask/network-controller": "npm:^22.0.2" "@metamask/polling-controller": "npm:^12.0.1" - "@metamask/preferences-controller": "npm:^14.0.0" + "@metamask/preferences-controller": "npm:^15.0.0" "@metamask/rpc-errors": "npm:^7.0.1" "@metamask/utils": "npm:^10.0.0" "@types/bn.js": "npm:^5.1.5" @@ -2180,11 +2180,11 @@ __metadata: typescript: "npm:~5.2.2" uuid: "npm:^8.3.2" peerDependencies: - "@metamask/accounts-controller": ^19.0.0 + "@metamask/accounts-controller": ^20.0.0 "@metamask/approval-controller": ^7.0.0 - "@metamask/keyring-controller": ^18.0.0 + "@metamask/keyring-controller": ^19.0.0 "@metamask/network-controller": ^22.0.0 - "@metamask/preferences-controller": ^14.0.0 + "@metamask/preferences-controller": ^15.0.0 languageName: unknown linkType: soft @@ -2943,7 +2943,7 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-controller@npm:^18.0.0, @metamask/keyring-controller@workspace:packages/keyring-controller": +"@metamask/keyring-controller@npm:^19.0.0, @metamask/keyring-controller@workspace:packages/keyring-controller": version: 0.0.0-use.local resolution: "@metamask/keyring-controller@workspace:packages/keyring-controller" dependencies: @@ -3149,8 +3149,8 @@ __metadata: "@metamask/auto-changelog": "npm:^3.4.4" "@metamask/base-controller": "npm:^7.0.2" "@metamask/controller-utils": "npm:^11.4.3" - "@metamask/keyring-controller": "npm:^18.0.0" - "@metamask/profile-sync-controller": "npm:^1.0.2" + "@metamask/keyring-controller": "npm:^19.0.0" + "@metamask/profile-sync-controller": "npm:^2.0.0" "@metamask/utils": "npm:^10.0.0" "@types/jest": "npm:^27.4.1" "@types/readable-stream": "npm:^2.3.0" @@ -3168,8 +3168,8 @@ __metadata: typescript: "npm:~5.2.2" uuid: "npm:^8.3.2" peerDependencies: - "@metamask/keyring-controller": ^18.0.0 - "@metamask/profile-sync-controller": ^1.0.0 + "@metamask/keyring-controller": ^19.0.0 + "@metamask/profile-sync-controller": ^2.0.0 languageName: unknown linkType: soft @@ -3310,14 +3310,14 @@ __metadata: languageName: node linkType: hard -"@metamask/preferences-controller@npm:^14.0.0, @metamask/preferences-controller@workspace:packages/preferences-controller": +"@metamask/preferences-controller@npm:^15.0.0, @metamask/preferences-controller@workspace:packages/preferences-controller": version: 0.0.0-use.local resolution: "@metamask/preferences-controller@workspace:packages/preferences-controller" dependencies: "@metamask/auto-changelog": "npm:^3.4.4" "@metamask/base-controller": "npm:^7.0.2" "@metamask/controller-utils": "npm:^11.4.3" - "@metamask/keyring-controller": "npm:^18.0.0" + "@metamask/keyring-controller": "npm:^19.0.0" "@types/jest": "npm:^27.4.1" deepmerge: "npm:^4.2.2" jest: "npm:^27.5.1" @@ -3327,20 +3327,20 @@ __metadata: typedoc-plugin-missing-exports: "npm:^2.0.0" typescript: "npm:~5.2.2" peerDependencies: - "@metamask/keyring-controller": ^18.0.0 + "@metamask/keyring-controller": ^19.0.0 languageName: unknown linkType: soft -"@metamask/profile-sync-controller@npm:^1.0.2, @metamask/profile-sync-controller@workspace:packages/profile-sync-controller": +"@metamask/profile-sync-controller@npm:^2.0.0, @metamask/profile-sync-controller@workspace:packages/profile-sync-controller": version: 0.0.0-use.local resolution: "@metamask/profile-sync-controller@workspace:packages/profile-sync-controller" dependencies: "@lavamoat/allow-scripts": "npm:^3.0.4" - "@metamask/accounts-controller": "npm:^19.0.0" + "@metamask/accounts-controller": "npm:^20.0.0" "@metamask/auto-changelog": "npm:^3.4.4" "@metamask/base-controller": "npm:^7.0.2" "@metamask/keyring-api": "npm:^10.1.0" - "@metamask/keyring-controller": "npm:^18.0.0" + "@metamask/keyring-controller": "npm:^19.0.0" "@metamask/network-controller": "npm:^22.0.2" "@metamask/snaps-controllers": "npm:^9.10.0" "@metamask/snaps-sdk": "npm:^6.7.0" @@ -3361,8 +3361,8 @@ __metadata: typedoc-plugin-missing-exports: "npm:^2.0.0" typescript: "npm:~5.2.2" peerDependencies: - "@metamask/accounts-controller": ^19.0.0 - "@metamask/keyring-controller": ^18.0.0 + "@metamask/accounts-controller": ^20.0.0 + "@metamask/keyring-controller": ^19.0.0 "@metamask/network-controller": ^22.0.0 "@metamask/snaps-controllers": ^9.10.0 languageName: unknown @@ -3511,7 +3511,7 @@ __metadata: "@metamask/base-controller": "npm:^7.0.2" "@metamask/controller-utils": "npm:^11.4.3" "@metamask/eth-sig-util": "npm:^8.0.0" - "@metamask/keyring-controller": "npm:^18.0.0" + "@metamask/keyring-controller": "npm:^19.0.0" "@metamask/logging-controller": "npm:^6.0.2" "@metamask/network-controller": "npm:^22.0.2" "@metamask/utils": "npm:^10.0.0" @@ -3527,7 +3527,7 @@ __metadata: uuid: "npm:^8.3.2" peerDependencies: "@metamask/approval-controller": ^7.0.0 - "@metamask/keyring-controller": ^18.0.0 + "@metamask/keyring-controller": ^19.0.0 "@metamask/logging-controller": ^6.0.0 "@metamask/network-controller": ^22.0.0 languageName: unknown @@ -3664,7 +3664,7 @@ __metadata: languageName: node linkType: hard -"@metamask/transaction-controller@npm:^39.1.0, @metamask/transaction-controller@workspace:packages/transaction-controller": +"@metamask/transaction-controller@npm:^40.0.0, @metamask/transaction-controller@workspace:packages/transaction-controller": version: 0.0.0-use.local resolution: "@metamask/transaction-controller@workspace:packages/transaction-controller" dependencies: @@ -3675,7 +3675,7 @@ __metadata: "@ethersproject/abi": "npm:^5.7.0" "@ethersproject/contracts": "npm:^5.7.0" "@ethersproject/providers": "npm:^5.7.0" - "@metamask/accounts-controller": "npm:^19.0.0" + "@metamask/accounts-controller": "npm:^20.0.0" "@metamask/approval-controller": "npm:^7.1.1" "@metamask/auto-changelog": "npm:^3.4.4" "@metamask/base-controller": "npm:^7.0.2" @@ -3709,7 +3709,7 @@ __metadata: uuid: "npm:^8.3.2" peerDependencies: "@babel/runtime": ^7.23.9 - "@metamask/accounts-controller": ^19.0.0 + "@metamask/accounts-controller": ^20.0.0 "@metamask/approval-controller": ^7.0.0 "@metamask/gas-fee-controller": ^22.0.0 "@metamask/network-controller": ^22.0.0 @@ -3726,12 +3726,12 @@ __metadata: "@metamask/controller-utils": "npm:^11.4.3" "@metamask/eth-query": "npm:^4.0.0" "@metamask/gas-fee-controller": "npm:^22.0.1" - "@metamask/keyring-controller": "npm:^18.0.0" + "@metamask/keyring-controller": "npm:^19.0.0" "@metamask/network-controller": "npm:^22.0.2" "@metamask/polling-controller": "npm:^12.0.1" "@metamask/rpc-errors": "npm:^7.0.1" "@metamask/superstruct": "npm:^3.1.0" - "@metamask/transaction-controller": "npm:^39.1.0" + "@metamask/transaction-controller": "npm:^40.0.0" "@metamask/utils": "npm:^10.0.0" "@types/jest": "npm:^27.4.1" bn.js: "npm:^5.2.1" @@ -3747,9 +3747,9 @@ __metadata: peerDependencies: "@metamask/approval-controller": ^7.0.0 "@metamask/gas-fee-controller": ^22.0.0 - "@metamask/keyring-controller": ^18.0.0 + "@metamask/keyring-controller": ^19.0.0 "@metamask/network-controller": ^22.0.0 - "@metamask/transaction-controller": ^39.0.0 + "@metamask/transaction-controller": ^40.0.0 languageName: unknown linkType: soft