From 7a1989b6ec3d59b6ad8eb4a73ac8f0e5cd814a04 Mon Sep 17 00:00:00 2001 From: Monte Lai Date: Fri, 7 Jun 2024 23:20:34 +0800 Subject: [PATCH] fix: update transaction controllers to use selected account (#4244) This pr updates the transaction controller to use account id from the InternalAccount instead of an address Related to https://github.com/MetaMask/accounts-planning/issues/381 - **BREAKING**: `getSelectedAddress` is replaced with `getSelectedAccount` in the `TransactionController` - **BREAKING**: `getCurrentAccount` returns an `InternalAccount` instead of a `string` in the `IncomingTransactionHelper` - [x] I've updated the test suite for new or updated code as appropriate - [x] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [x] I've highlighted breaking changes using the "BREAKING" category above as appropriate Fixes https://github.com/MetaMask/accounts-planning/issues/381 --------- Co-authored-by: Charly Chevalier --- packages/transaction-controller/package.json | 3 + .../src/TransactionController.test.ts | 28 ++- .../src/TransactionController.ts | 18 +- .../TransactionControllerIntegration.test.ts | 170 ++++++++++++++---- .../helpers/IncomingTransactionHelper.test.ts | 19 +- .../src/helpers/IncomingTransactionHelper.ts | 18 +- .../tsconfig.build.json | 1 + packages/transaction-controller/tsconfig.json | 1 + yarn.lock | 53 +++++- 9 files changed, 245 insertions(+), 66 deletions(-) diff --git a/packages/transaction-controller/package.json b/packages/transaction-controller/package.json index b7e66c7ae28..1d2912bca6c 100644 --- a/packages/transaction-controller/package.json +++ b/packages/transaction-controller/package.json @@ -66,9 +66,11 @@ }, "devDependencies": { "@babel/runtime": "^7.23.9", + "@metamask/accounts-controller": "^16.0.0", "@metamask/auto-changelog": "^3.4.4", "@metamask/eth-json-rpc-provider": "^3.0.2", "@metamask/ethjs-provider-http": "^0.3.0", + "@metamask/keyring-api": "^6.4.0", "@types/bn.js": "^5.1.5", "@types/jest": "^27.4.1", "@types/node": "^16.18.54", @@ -84,6 +86,7 @@ }, "peerDependencies": { "@babel/runtime": "^7.23.9", + "@metamask/accounts-controller": "^16.0.0", "@metamask/approval-controller": "^6.0.2", "@metamask/gas-fee-controller": "^16.0.0", "@metamask/network-controller": "^18.1.3" diff --git a/packages/transaction-controller/src/TransactionController.test.ts b/packages/transaction-controller/src/TransactionController.test.ts index 6809b930d6f..ac64324b180 100644 --- a/packages/transaction-controller/src/TransactionController.test.ts +++ b/packages/transaction-controller/src/TransactionController.test.ts @@ -17,6 +17,8 @@ import { import type { SafeEventEmitterProvider } from '@metamask/eth-json-rpc-provider'; import EthQuery from '@metamask/eth-query'; import HttpProvider from '@metamask/ethjs-provider-http'; +import type { InternalAccount } from '@metamask/keyring-api'; +import { EthAccountType } from '@metamask/keyring-api'; import type { BlockTracker, NetworkController, @@ -439,6 +441,20 @@ const MOCK_CUSTOM_NETWORK: MockNetwork = { }; const ACCOUNT_MOCK = '0x6bf137f335ea1b8f193b8f6ea92561a60d23a207'; +const INTERNAL_ACCOUNT_MOCK = { + id: '58def058-d35f-49a1-a7ab-e2580565f6f5', + address: ACCOUNT_MOCK, + type: EthAccountType.Eoa, + options: {}, + methods: [], + metadata: { + name: 'Account 1', + keyring: { type: 'HD Key Tree' }, + importTime: 1631619180000, + lastSelected: 1631619180000, + }, +}; + const ACCOUNT_2_MOCK = '0x08f137f335ea1b8f193b8f6ea92561a60d23a211'; const NONCE_MOCK = 12; const ACTION_ID_MOCK = '123456'; @@ -551,12 +567,14 @@ describe('TransactionController', () => { * messenger. * @param args.messengerOptions.addTransactionApprovalRequest - Options to mock * the `ApprovalController:addRequest` action call for transactions. + * @param args.selectedAccount - The selected account to use with the controller. * @returns The new TransactionController instance. */ function setupController({ options: givenOptions = {}, network = MOCK_NETWORK, messengerOptions = {}, + selectedAccount = INTERNAL_ACCOUNT_MOCK, }: { options?: Partial[0]>; network?: MockNetwork; @@ -565,6 +583,7 @@ describe('TransactionController', () => { typeof mockAddTransactionApprovalRequest >[1]; }; + selectedAccount?: InternalAccount; } = {}) { const unrestrictedMessenger: UnrestrictedControllerMessenger = new ControllerMessenger(); @@ -587,7 +606,6 @@ describe('TransactionController', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any getNetworkClientRegistry: () => ({} as any), getPermittedAccounts: async () => [ACCOUNT_MOCK], - getSelectedAddress: () => ACCOUNT_MOCK, isMultichainEnabled: false, hooks: {}, onNetworkStateChange: network.subscribe, @@ -605,10 +623,17 @@ describe('TransactionController', () => { 'ApprovalController:addRequest', 'NetworkController:getNetworkClientById', 'NetworkController:findNetworkClientIdByChainId', + 'AccountsController:getSelectedAccount', ], allowedEvents: [], }); + const mockGetSelectedAccount = jest.fn().mockReturnValue(selectedAccount); + unrestrictedMessenger.registerActionHandler( + 'AccountsController:getSelectedAccount', + mockGetSelectedAccount, + ); + const controller = new TransactionController({ ...otherOptions, messenger: restrictedMessenger, @@ -618,6 +643,7 @@ describe('TransactionController', () => { controller, messenger: unrestrictedMessenger, mockTransactionApprovalRequest, + mockGetSelectedAccount, }; } diff --git a/packages/transaction-controller/src/TransactionController.ts b/packages/transaction-controller/src/TransactionController.ts index 06010fc3148..6c1ab6c29bb 100644 --- a/packages/transaction-controller/src/TransactionController.ts +++ b/packages/transaction-controller/src/TransactionController.ts @@ -2,6 +2,7 @@ import { Hardfork, Common, type ChainConfig } from '@ethereumjs/common'; import type { TypedTransaction } from '@ethereumjs/tx'; import { TransactionFactory } from '@ethereumjs/tx'; import { bufferToHex } from '@ethereumjs/util'; +import type { AccountsControllerGetSelectedAccountAction } from '@metamask/accounts-controller'; import type { AcceptResultCallbacks, AddApprovalRequest, @@ -297,7 +298,6 @@ export type TransactionControllerOptions = { getNetworkState: () => NetworkState; getPermittedAccounts: (origin?: string) => Promise; getSavedGasFees?: (chainId: Hex) => SavedGasFees | undefined; - getSelectedAddress: () => string; incomingTransactions?: IncomingTransactionOptions; isMultichainEnabled: boolean; isSimulationEnabled?: () => boolean; @@ -344,7 +344,8 @@ const controllerName = 'TransactionController'; export type AllowedActions = | AddApprovalRequest | NetworkControllerFindNetworkClientIdByChainIdAction - | NetworkControllerGetNetworkClientByIdAction; + | NetworkControllerGetNetworkClientByIdAction + | AccountsControllerGetSelectedAccountAction; /** * The external events available to the {@link TransactionController}. @@ -614,8 +615,6 @@ export class TransactionController extends BaseController< private readonly getPermittedAccounts: (origin?: string) => Promise; - private readonly getSelectedAddress: () => string; - private readonly getExternalPendingTransactions: ( address: string, chainId?: string, @@ -733,7 +732,6 @@ export class TransactionController extends BaseController< * @param options.getNetworkState - Gets the state of the network controller. * @param options.getPermittedAccounts - Get accounts that a given origin has permissions for. * @param options.getSavedGasFees - Gets the saved gas fee config. - * @param options.getSelectedAddress - Gets the address of the currently selected account. * @param options.incomingTransactions - Configuration options for incoming transaction support. * @param options.isMultichainEnabled - Enable multichain support. * @param options.isSimulationEnabled - Whether new transactions will be automatically simulated. @@ -761,7 +759,6 @@ export class TransactionController extends BaseController< getNetworkState, getPermittedAccounts, getSavedGasFees, - getSelectedAddress, incomingTransactions = {}, isMultichainEnabled = false, isSimulationEnabled, @@ -802,7 +799,6 @@ export class TransactionController extends BaseController< this.getGasFeeEstimates = getGasFeeEstimates || (() => Promise.resolve({} as GasFeeState)); this.getPermittedAccounts = getPermittedAccounts; - this.getSelectedAddress = getSelectedAddress; this.getExternalPendingTransactions = getExternalPendingTransactions ?? (() => []); this.securityProviderRequest = securityProviderRequest; @@ -1035,7 +1031,7 @@ export class TransactionController extends BaseController< if (origin) { await validateTransactionOrigin( await this.getPermittedAccounts(origin), - this.getSelectedAddress(), + this.#getSelectedAccount().address, txParams.from, origin, ); @@ -3430,7 +3426,7 @@ export class TransactionController extends BaseController< }): IncomingTransactionHelper { const incomingTransactionHelper = new IncomingTransactionHelper({ blockTracker, - getCurrentAccount: this.getSelectedAddress, + getCurrentAccount: () => this.#getSelectedAccount(), getLastFetchedBlockNumbers: () => this.state.lastFetchedBlockNumbers, getChainId: chainId ? () => chainId : this.getChainId.bind(this), isEnabled: this.#incomingTransactionOptions.isEnabled, @@ -3843,4 +3839,8 @@ export class TransactionController extends BaseController< ).configuration.type === NetworkClientType.Custom ); } + + #getSelectedAccount() { + return this.messagingSystem.call('AccountsController:getSelectedAccount'); + } } diff --git a/packages/transaction-controller/src/TransactionControllerIntegration.test.ts b/packages/transaction-controller/src/TransactionControllerIntegration.test.ts index 979f88c4525..e4ccee1d493 100644 --- a/packages/transaction-controller/src/TransactionControllerIntegration.test.ts +++ b/packages/transaction-controller/src/TransactionControllerIntegration.test.ts @@ -1,4 +1,5 @@ import type { TypedTransaction } from '@ethereumjs/tx'; +import type { AccountsControllerGetSelectedAccountAction } from '@metamask/accounts-controller'; import type { ApprovalControllerActions, ApprovalControllerEvents, @@ -11,6 +12,8 @@ import { InfuraNetworkType, NetworkType, } from '@metamask/controller-utils'; +import type { InternalAccount } from '@metamask/keyring-api'; +import { EthAccountType, EthMethod } from '@metamask/keyring-api'; import { NetworkController, NetworkClientType, @@ -25,6 +28,7 @@ import assert from 'assert'; import nock from 'nock'; import type { SinonFakeTimers } from 'sinon'; import { useFakeTimers } from 'sinon'; +import { v4 } from 'uuid'; import { advanceTime } from '../../../tests/helpers'; import { mockNetwork } from '../../../tests/mock-network'; @@ -58,13 +62,53 @@ import * as etherscanUtils from './utils/etherscan'; type UnrestrictedControllerMessenger = ControllerMessenger< | NetworkControllerActions | ApprovalControllerActions - | TransactionControllerActions, + | TransactionControllerActions + | AccountsControllerGetSelectedAccountAction, | NetworkControllerEvents | ApprovalControllerEvents | TransactionControllerEvents >; +const createMockInternalAccount = ({ + id = v4(), + address = '0x2990079bcdee240329a520d2444386fc119da21a', + name = 'Account 1', + importTime = Date.now(), + lastSelected = Date.now(), +}: { + id?: string; + address?: string; + name?: string; + importTime?: number; + lastSelected?: number; +} = {}): InternalAccount => { + return { + id, + address, + options: {}, + methods: [ + EthMethod.PersonalSign, + EthMethod.Sign, + EthMethod.SignTransaction, + EthMethod.SignTypedDataV1, + EthMethod.SignTypedDataV3, + EthMethod.SignTypedDataV4, + ], + type: EthAccountType.Eoa, + metadata: { + name, + keyring: { type: 'HD Key Tree' }, + importTime, + lastSelected, + }, + } as InternalAccount; +}; + const ACCOUNT_MOCK = '0x6bf137f335ea1b8f193b8f6ea92561a60d23a207'; +const INTERNAL_ACCOUNT_MOCK = createMockInternalAccount({ + address: ACCOUNT_MOCK, +}); + const ACCOUNT_2_MOCK = '0x08f137f335ea1b8f193b8f6ea92561a60d23a211'; const ACCOUNT_3_MOCK = '0xe688b84b23f322a994a53dbf8e15fa82cdb71127'; const infuraProjectId = 'fake-infura-project-id'; @@ -99,6 +143,11 @@ const setupController = async ( givenOptions: Partial< ConstructorParameters[0] > = {}, + mockData: { + selectedAccount?: InternalAccount; + } = { + selectedAccount: createMockInternalAccount({ address: '0xdeadbeef' }), + }, ) => { // Mainnet network must be mocked for NetworkController instantiation mockNetwork({ @@ -146,10 +195,20 @@ const setupController = async ( 'ApprovalController:addRequest', 'NetworkController:getNetworkClientById', 'NetworkController:findNetworkClientIdByChainId', + 'AccountsController:getSelectedAccount', ], allowedEvents: ['NetworkController:stateChange'], }); + const mockGetSelectedAccount = jest + .fn() + .mockReturnValue(mockData.selectedAccount); + + unrestrictedMessenger.registerActionHandler( + 'AccountsController:getSelectedAccount', + mockGetSelectedAccount, + ); + const options = { blockTracker, disableHistory: false, @@ -167,7 +226,6 @@ const setupController = async ( getNetworkClientRegistry: networkController.getNetworkClientRegistry.bind(networkController), getPermittedAccounts: async () => [ACCOUNT_MOCK], - getSelectedAddress: () => '0xdeadbeef', hooks: {}, isMultichainEnabled: false, messenger, @@ -187,6 +245,7 @@ const setupController = async ( approvalController, networkController, messenger, + mockGetSelectedAccount, }; }; @@ -799,11 +858,13 @@ describe('TransactionController Integration', () => { }); const { approvalController, networkController, transactionController } = - await setupController({ - isMultichainEnabled: true, - getPermittedAccounts: async () => [ACCOUNT_MOCK], - getSelectedAddress: () => ACCOUNT_MOCK, - }); + await setupController( + { + isMultichainEnabled: true, + getPermittedAccounts: async () => [ACCOUNT_MOCK], + }, + { selectedAccount: INTERNAL_ACCOUNT_MOCK }, + ); const otherNetworkClientIdOnGoerli = await networkController.upsertNetworkConfiguration( { @@ -880,11 +941,13 @@ describe('TransactionController Integration', () => { ], }); const { approvalController, transactionController } = - await setupController({ - isMultichainEnabled: true, - getPermittedAccounts: async () => [ACCOUNT_MOCK], - getSelectedAddress: () => ACCOUNT_MOCK, - }); + await setupController( + { + isMultichainEnabled: true, + getPermittedAccounts: async () => [ACCOUNT_MOCK], + }, + { selectedAccount: INTERNAL_ACCOUNT_MOCK }, + ); const addTx1 = await transactionController.addTransaction( { @@ -1140,12 +1203,17 @@ describe('TransactionController Integration', () => { }); const selectedAddress = ETHERSCAN_TRANSACTION_BASE_MOCK.to; + const selectedAccountMock = createMockInternalAccount({ + address: selectedAddress, + }); const { networkController, transactionController } = - await setupController({ - getSelectedAddress: () => selectedAddress, - isMultichainEnabled: true, - }); + await setupController( + { + isMultichainEnabled: true, + }, + { selectedAccount: selectedAccountMock }, + ); const expectedLastFetchedBlockNumbers: Record = {}; const expectedTransactions: Partial[] = []; @@ -1209,6 +1277,9 @@ describe('TransactionController Integration', () => { it('should start the global incoming transaction helper when no networkClientIds provided', async () => { const selectedAddress = ETHERSCAN_TRANSACTION_BASE_MOCK.to; + const selectedAccountMock = createMockInternalAccount({ + address: selectedAddress, + }); mockNetwork({ networkClientConfiguration: buildInfuraNetworkClientConfiguration( @@ -1225,9 +1296,10 @@ describe('TransactionController Integration', () => { ) .reply(200, ETHERSCAN_TRANSACTION_RESPONSE_MOCK); - const { transactionController } = await setupController({ - getSelectedAddress: () => selectedAddress, - }); + const { transactionController } = await setupController( + {}, + { selectedAccount: selectedAccountMock }, + ); transactionController.startIncomingTransactionPolling(); @@ -1314,12 +1386,17 @@ describe('TransactionController Integration', () => { }); const selectedAddress = ETHERSCAN_TRANSACTION_BASE_MOCK.to; + const selectedAccountMock = createMockInternalAccount({ + address: selectedAddress, + }); const { networkController, transactionController } = - await setupController({ - getSelectedAddress: () => selectedAddress, - isMultichainEnabled: true, - }); + await setupController( + { + isMultichainEnabled: true, + }, + { selectedAccount: selectedAccountMock }, + ); const otherGoerliClientNetworkClientId = await networkController.upsertNetworkConfiguration( @@ -1410,11 +1487,12 @@ describe('TransactionController Integration', () => { describe('stopIncomingTransactionPolling', () => { it('should not poll for new incoming transactions for the given networkClientId', async () => { const selectedAddress = ETHERSCAN_TRANSACTION_BASE_MOCK.to; + const selectedAccountMock = createMockInternalAccount({ + address: selectedAddress, + }); const { networkController, transactionController } = - await setupController({ - getSelectedAddress: () => selectedAddress, - }); + await setupController({}, { selectedAccount: selectedAccountMock }); const networkClients = networkController.getNetworkClientRegistry(); const networkClientIds = Object.keys(networkClients); @@ -1454,11 +1532,15 @@ describe('TransactionController Integration', () => { it('should stop the global incoming transaction helper when no networkClientIds provided', async () => { const selectedAddress = ETHERSCAN_TRANSACTION_BASE_MOCK.to; - - const { transactionController } = await setupController({ - getSelectedAddress: () => selectedAddress, + const selectedAccountMock = createMockInternalAccount({ + address: selectedAddress, }); + const { transactionController } = await setupController( + {}, + { selectedAccount: selectedAccountMock }, + ); + mockNetwork({ networkClientConfiguration: buildInfuraNetworkClientConfiguration( InfuraNetworkType.mainnet, @@ -1490,11 +1572,12 @@ describe('TransactionController Integration', () => { describe('stopAllIncomingTransactionPolling', () => { it('should not poll for incoming transactions on any network client', async () => { const selectedAddress = ETHERSCAN_TRANSACTION_BASE_MOCK.to; + const selectedAccountMock = createMockInternalAccount({ + address: selectedAddress, + }); const { networkController, transactionController } = - await setupController({ - getSelectedAddress: () => selectedAddress, - }); + await setupController({}, { selectedAccount: selectedAccountMock }); const networkClients = networkController.getNetworkClientRegistry(); const networkClientIds = Object.keys(networkClients); @@ -1534,12 +1617,17 @@ describe('TransactionController Integration', () => { describe('updateIncomingTransactions', () => { it('should add incoming transactions to state with the correct chainId for the given networkClientId without waiting for the next block', async () => { const selectedAddress = ETHERSCAN_TRANSACTION_BASE_MOCK.to; + const selectedAccountMock = createMockInternalAccount({ + address: selectedAddress, + }); const { networkController, transactionController } = - await setupController({ - getSelectedAddress: () => selectedAddress, - isMultichainEnabled: true, - }); + await setupController( + { + isMultichainEnabled: true, + }, + { selectedAccount: selectedAccountMock }, + ); const expectedLastFetchedBlockNumbers: Record = {}; const expectedTransactions: Partial[] = []; @@ -1600,11 +1688,15 @@ describe('TransactionController Integration', () => { it('should update the incoming transactions for the gloablly selected network when no networkClientIds provided', async () => { const selectedAddress = ETHERSCAN_TRANSACTION_BASE_MOCK.to; - - const { transactionController } = await setupController({ - getSelectedAddress: () => selectedAddress, + const selectedAccountMock = createMockInternalAccount({ + address: selectedAddress, }); + const { transactionController } = await setupController( + {}, + { selectedAccount: selectedAccountMock }, + ); + mockNetwork({ networkClientConfiguration: buildInfuraNetworkClientConfiguration( InfuraNetworkType.mainnet, diff --git a/packages/transaction-controller/src/helpers/IncomingTransactionHelper.test.ts b/packages/transaction-controller/src/helpers/IncomingTransactionHelper.test.ts index 49b39c4effc..6e65f7de1c3 100644 --- a/packages/transaction-controller/src/helpers/IncomingTransactionHelper.test.ts +++ b/packages/transaction-controller/src/helpers/IncomingTransactionHelper.test.ts @@ -32,7 +32,21 @@ const BLOCK_TRACKER_MOCK = { const CONTROLLER_ARGS_MOCK = { blockTracker: BLOCK_TRACKER_MOCK, - getCurrentAccount: () => ADDRESS_MOCK, + getCurrentAccount: () => { + return { + id: '58def058-d35f-49a1-a7ab-e2580565f6f5', + address: ADDRESS_MOCK, + type: 'eip155:eoa' as const, + options: {}, + methods: [], + metadata: { + name: 'Account 1', + keyring: { type: 'HD Key Tree' }, + importTime: 1631619180000, + lastSelected: 1631619180000, + }, + }; + }, getLastFetchedBlockNumbers: () => ({}), getChainId: () => CHAIN_ID_MOCK, remoteTransactionSource: {} as RemoteTransactionSource, @@ -546,7 +560,8 @@ describe('IncomingTransactionHelper', () => { remoteTransactionSource: createRemoteTransactionSourceMock([ TRANSACTION_MOCK_2, ]), - getCurrentAccount: () => undefined as unknown as string, + // @ts-expect-error testing undefined + getCurrentAccount: () => undefined, }); const { blockNumberListener } = await emitBlockTrackerLatestEvent( diff --git a/packages/transaction-controller/src/helpers/IncomingTransactionHelper.ts b/packages/transaction-controller/src/helpers/IncomingTransactionHelper.ts index c6600b48931..b39627cc988 100644 --- a/packages/transaction-controller/src/helpers/IncomingTransactionHelper.ts +++ b/packages/transaction-controller/src/helpers/IncomingTransactionHelper.ts @@ -1,3 +1,4 @@ +import type { AccountsController } from '@metamask/accounts-controller'; import type { BlockTracker } from '@metamask/network-controller'; import type { Hex } from '@metamask/utils'; import { Mutex } from 'async-mutex'; @@ -35,7 +36,9 @@ export class IncomingTransactionHelper { #blockTracker: BlockTracker; - #getCurrentAccount: () => string; + #getCurrentAccount: () => ReturnType< + AccountsController['getSelectedAccount'] + >; #getLastFetchedBlockNumbers: () => Record; @@ -72,7 +75,9 @@ export class IncomingTransactionHelper { updateTransactions, }: { blockTracker: BlockTracker; - getCurrentAccount: () => string; + getCurrentAccount: () => ReturnType< + AccountsController['getSelectedAccount'] + >; getLastFetchedBlockNumbers: () => Record; getLocalTransactions?: () => TransactionMeta[]; getChainId: () => Hex; @@ -144,7 +149,7 @@ export class IncomingTransactionHelper { this.#remoteTransactionSource.getLastBlockVariations?.() ?? []; const fromBlock = this.#getFromBlock(latestBlockNumber); - const address = this.#getCurrentAccount(); + const account = this.#getCurrentAccount(); const currentChainId = this.#getChainId(); let remoteTransactions = []; @@ -152,7 +157,7 @@ export class IncomingTransactionHelper { try { remoteTransactions = await this.#remoteTransactionSource.fetchTransactions({ - address, + address: account.address, currentChainId, fromBlock, limit: this.#transactionLimit, @@ -164,8 +169,9 @@ export class IncomingTransactionHelper { return; } if (!this.#updateTransactions) { + const address = account.address.toLowerCase(); remoteTransactions = remoteTransactions.filter( - (tx) => tx.txParams.to?.toLowerCase() === address.toLowerCase(), + (tx) => tx.txParams.to?.toLowerCase() === address, ); } @@ -301,7 +307,7 @@ export class IncomingTransactionHelper { #getBlockNumberKey(additionalKeys: string[]): string { const currentChainId = this.#getChainId(); - const currentAccount = this.#getCurrentAccount()?.toLowerCase(); + const currentAccount = this.#getCurrentAccount()?.address.toLowerCase(); return [currentChainId, currentAccount, ...additionalKeys].join('#'); } diff --git a/packages/transaction-controller/tsconfig.build.json b/packages/transaction-controller/tsconfig.build.json index 9a78dab46ae..648111f91b0 100644 --- a/packages/transaction-controller/tsconfig.build.json +++ b/packages/transaction-controller/tsconfig.build.json @@ -6,6 +6,7 @@ "rootDir": "./src" }, "references": [ + { "path": "../accounts-controller/tsconfig.build.json" }, { "path": "../approval-controller/tsconfig.build.json" }, { "path": "../base-controller/tsconfig.build.json" }, { "path": "../controller-utils/tsconfig.build.json" }, diff --git a/packages/transaction-controller/tsconfig.json b/packages/transaction-controller/tsconfig.json index 52940e55927..bf67c437107 100644 --- a/packages/transaction-controller/tsconfig.json +++ b/packages/transaction-controller/tsconfig.json @@ -5,6 +5,7 @@ "target": "ES2022" }, "references": [ + { "path": "../accounts-controller" }, { "path": "../approval-controller" }, { "path": "../base-controller" }, { "path": "../controller-utils" }, diff --git a/yarn.lock b/yarn.lock index c3f7a314764..af5360d102b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1640,6 +1640,28 @@ __metadata: languageName: unknown linkType: soft +"@metamask/accounts-controller@npm:^16.0.0": + version: 16.0.0 + resolution: "@metamask/accounts-controller@npm:16.0.0" + dependencies: + "@ethereumjs/util": ^8.1.0 + "@metamask/base-controller": ^6.0.0 + "@metamask/eth-snap-keyring": ^4.1.1 + "@metamask/keyring-api": ^6.1.1 + "@metamask/snaps-sdk": ^4.2.0 + "@metamask/snaps-utils": ^7.4.0 + "@metamask/utils": ^8.3.0 + deepmerge: ^4.2.2 + ethereum-cryptography: ^2.1.2 + immer: ^9.0.6 + uuid: ^8.3.2 + peerDependencies: + "@metamask/keyring-controller": ^17.0.0 + "@metamask/snaps-controllers": ^8.1.1 + checksum: 10bfcfcee930c7a2388a61dd1a16bbacca9e5ce7366adace6caeccfb0d1ae6b7edf51828d1f994f990228445bbc3afc4a2fed8c06708ebc574b5a662ca2efedc + languageName: node + linkType: hard + "@metamask/action-utils@npm:^1.0.0": version: 1.1.1 resolution: "@metamask/action-utils@npm:1.1.1" @@ -1810,6 +1832,16 @@ __metadata: languageName: unknown linkType: soft +"@metamask/base-controller@npm:^6.0.0": + version: 6.0.0 + resolution: "@metamask/base-controller@npm:6.0.0" + dependencies: + "@metamask/utils": ^8.3.0 + immer: ^9.0.6 + checksum: ff5c4acedc698e2477f1d719f64363d8763b21836dcea4675214c078457cd47dde068aa336b249663f3c7fb3c0f536ce420870811e00ca3a410646740a9f5934 + languageName: node + linkType: hard + "@metamask/browser-passworder@npm:^4.3.0": version: 4.3.0 resolution: "@metamask/browser-passworder@npm:4.3.0" @@ -2401,19 +2433,19 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-api@npm:^6.1.1": - version: 6.1.1 - resolution: "@metamask/keyring-api@npm:6.1.1" +"@metamask/keyring-api@npm:^6.1.1, @metamask/keyring-api@npm:^6.4.0": + version: 6.4.0 + resolution: "@metamask/keyring-api@npm:6.4.0" dependencies: "@metamask/snaps-sdk": ^4.2.0 - "@metamask/utils": ^8.3.0 - "@types/uuid": ^9.0.1 + "@metamask/utils": ^8.4.0 + "@types/uuid": ^9.0.8 bech32: ^2.0.0 superstruct: ^1.0.3 - uuid: ^9.0.0 + uuid: ^9.0.1 peerDependencies: - "@metamask/providers": ">=15 <17" - checksum: 5a9ed008e19062c84ec8fd019ad29f9ebb7d8d8464bbe5da70ad26e6aceb57e4d98a9762e7cd9fea4ac7de0cdc08bfc0a5bf598770749aa9abdbe6d1840fb627 + "@metamask/providers": ">=15 <18" + checksum: 7845ed5fa73db3165703c2142b6062d03ca5fea329b54d28f424dee2bb393edc1f9a015e771289ef7236c31f30355bf2c52ad74bb47cf531c09c5eec66e06b00 languageName: node linkType: hard @@ -3047,6 +3079,7 @@ __metadata: "@ethersproject/abi": ^5.7.0 "@ethersproject/contracts": ^5.7.0 "@ethersproject/providers": ^5.7.0 + "@metamask/accounts-controller": ^16.0.0 "@metamask/approval-controller": ^6.0.2 "@metamask/auto-changelog": ^3.4.4 "@metamask/base-controller": ^5.0.2 @@ -3055,6 +3088,7 @@ __metadata: "@metamask/eth-query": ^4.0.0 "@metamask/ethjs-provider-http": ^0.3.0 "@metamask/gas-fee-controller": ^16.0.0 + "@metamask/keyring-api": ^6.4.0 "@metamask/metamask-eth-abis": ^3.1.1 "@metamask/network-controller": ^18.1.3 "@metamask/nonce-tracker": ^5.0.0 @@ -3080,6 +3114,7 @@ __metadata: uuid: ^8.3.2 peerDependencies: "@babel/runtime": ^7.23.9 + "@metamask/accounts-controller": ^16.0.0 "@metamask/approval-controller": ^6.0.2 "@metamask/gas-fee-controller": ^16.0.0 "@metamask/network-controller": ^18.1.3 @@ -3907,7 +3942,7 @@ __metadata: languageName: node linkType: hard -"@types/uuid@npm:^9.0.1": +"@types/uuid@npm:^9.0.1, @types/uuid@npm:^9.0.8": version: 9.0.8 resolution: "@types/uuid@npm:9.0.8" checksum: b8c60b7ba8250356b5088302583d1704a4e1a13558d143c549c408bf8920535602ffc12394ede77f8a8083511b023704bc66d1345792714002bfa261b17c5275