From f814c41f66fab4308fa047ee7867ffdfd652be01 Mon Sep 17 00:00:00 2001 From: jiexi Date: Tue, 3 Oct 2023 13:09:45 -0700 Subject: [PATCH] bump `@metamask/assets-controllers` to ^13.0.0 (#20916) ## Explanation Needed to help get us closer to phasing out a single globally selected network. Bumps `@metamask/assets-controllers` to ^13.0.0 and passes networkClientId arg to newly updated `TokenController.addToken()`, `TokenController.addTokens()`, and `TokenController.watchAsset()`. Adopts changes in other asset-related controllers * Fixes https://github.com/MetaMask/MetaMask-planning/issues/1020 * See https://github.com/MetaMask/core/pull/1676 ## Screenshots/Screencaps None. Should be no changes apparent to user. ## Manual Testing Steps ### Via Dapp API * Visit any [coingecko token page](https://www.coingecko.com/en/coins/ethereum-name-service) * On a supported built-in network (switch to mainnet) * Click the metamask icon on the page * Tooltip says: "Add to MetaMask" * Accept * Verify the token shows up in wallet UI ### Via Wallet UI * From wallet ui * Import new token * Fill in token details * Use `0xc18360217d8f7ab5e7c516566761ea12ce7f9d72` contract address for ENS * Verify the token shows up in wallet UI ## Pre-merge author checklist - [x] I've clearly explained: - [x] What problem this PR is solving - [x] How this problem was solved - [x] How reviewers can test my changes - [x] Sufficient automated test coverage has been added ## Pre-merge reviewer checklist - [ ] Manual testing (e.g. pull and build branch, run in browser, test code being changed) - [ ] PR is linked to the appropriate GitHub issue - [ ] **IF** this PR fixes a bug in the release milestone, add this PR to the release milestone If further QA is required (e.g. new feature, complex testing steps, large refactor), add the `Extension QA Board` label. In this case, a QA Engineer approval will be be required. --------- Co-authored-by: MetaMask Bot Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com> --- app/scripts/controllers/detect-tokens.test.js | 11 +++ .../handlers/watch-asset.js | 3 +- .../handlers/watch-asset.test.js | 24 +++--- .../metamask-controller.actions.test.js | 34 +++++++- app/scripts/metamask-controller.js | 71 ++++++++++------ lavamoat/browserify/beta/policy.json | 72 ++++++++++------ lavamoat/browserify/desktop/policy.json | 74 ++++++++++------ lavamoat/browserify/flask/policy.json | 74 ++++++++++------ lavamoat/browserify/main/policy.json | 72 ++++++++++------ lavamoat/browserify/mmi/policy.json | 72 ++++++++++------ package.json | 2 +- .../app/detected-token/detected-token.js | 4 +- ui/components/app/nfts-items/nfts-items.js | 2 +- .../import-tokens-modal.js | 4 +- ui/ducks/swaps/swaps.js | 24 ++++-- ui/store/actions.test.js | 4 +- ui/store/actions.ts | 36 ++++++-- yarn.lock | 85 +++++++++---------- 18 files changed, 442 insertions(+), 226 deletions(-) diff --git a/app/scripts/controllers/detect-tokens.test.js b/app/scripts/controllers/detect-tokens.test.js index 17927cfcfbd2..2ba94dcaebd8 100644 --- a/app/scripts/controllers/detect-tokens.test.js +++ b/app/scripts/controllers/detect-tokens.test.js @@ -217,6 +217,7 @@ describe('DetectTokensController', function () { const tokenListMessenger = new ControllerMessenger().getRestricted({ name: 'TokenListController', + allowedEvents: ['TokenListController:stateChange'], }); tokenListController = new TokenListController({ chainId: toHex(1), @@ -249,6 +250,11 @@ describe('DetectTokensController', function () { networkControllerMessenger, 'NetworkController:stateChange', ), + onTokenListStateChange: (listener) => + tokenListMessenger.subscribe( + `${tokenListController.name}:stateChange`, + listener, + ), }); assetsContractController = new AssetsContractController({ @@ -363,6 +369,7 @@ describe('DetectTokensController', function () { aggregators: undefined, image: undefined, isERC721: undefined, + name: undefined, }, ]); @@ -384,6 +391,7 @@ describe('DetectTokensController', function () { aggregators: undefined, image: undefined, isERC721: undefined, + name: undefined, }, ]); }); @@ -417,6 +425,7 @@ describe('DetectTokensController', function () { aggregators: undefined, image: undefined, isERC721: undefined, + name: undefined, }, ]); const tokenAddressToAdd = erc20ContractAddresses[1]; @@ -435,6 +444,7 @@ describe('DetectTokensController', function () { aggregators: undefined, image: undefined, isERC721: undefined, + name: undefined, }, { address: toChecksumHexAddress(tokenAddressToAdd), @@ -443,6 +453,7 @@ describe('DetectTokensController', function () { aggregators: undefined, image: undefined, isERC721: undefined, + name: undefined, }, ]); }); diff --git a/app/scripts/lib/rpc-method-middleware/handlers/watch-asset.js b/app/scripts/lib/rpc-method-middleware/handlers/watch-asset.js index 2f7fb5d7ab5b..6bce7d7dca18 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/watch-asset.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/watch-asset.js @@ -40,6 +40,7 @@ async function watchAssetHandler( const { params: { options: asset, type }, origin, + networkClientId, } = req; const { tokenId } = asset; @@ -56,7 +57,7 @@ async function watchAssetHandler( ); } - await handleWatchAssetRequest(asset, type, origin); + await handleWatchAssetRequest({ asset, type, origin, networkClientId }); res.result = true; return end(); } catch (error) { diff --git a/app/scripts/lib/rpc-method-middleware/handlers/watch-asset.test.js b/app/scripts/lib/rpc-method-middleware/handlers/watch-asset.test.js index 5af3ad1bd937..eebe8a470ead 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/watch-asset.test.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/watch-asset.test.js @@ -21,6 +21,7 @@ describe('watchAssetHandler', () => { type: ERC721, }, origin: 'testOrigin', + networkClientId: 'networkClientId1', }; const res = { @@ -31,11 +32,12 @@ describe('watchAssetHandler', () => { handleWatchAssetRequest: mockHandleWatchAssetRequest, }); - expect(mockHandleWatchAssetRequest).toHaveBeenCalledWith( - req.params.options, - req.params.type, - req.origin, - ); + expect(mockHandleWatchAssetRequest).toHaveBeenCalledWith({ + asset: req.params.options, + type: req.params.type, + origin: req.origin, + networkClientId: req.networkClientId, + }); expect(res.result).toStrictEqual(true); expect(mockEnd).toHaveBeenCalledWith(); }); @@ -51,6 +53,7 @@ describe('watchAssetHandler', () => { type: ERC20, }, origin: 'testOrigin', + networkClientId: 'networkClientId1', }; const res = { @@ -61,11 +64,12 @@ describe('watchAssetHandler', () => { handleWatchAssetRequest: mockHandleWatchAssetRequest, }); - expect(mockHandleWatchAssetRequest).toHaveBeenCalledWith( - req.params.options, - req.params.type, - req.origin, - ); + expect(mockHandleWatchAssetRequest).toHaveBeenCalledWith({ + asset: req.params.options, + type: req.params.type, + origin: req.origin, + networkClientId: req.networkClientId, + }); expect(res.result).toStrictEqual(true); expect(mockEnd).toHaveBeenCalledWith(); }); diff --git a/app/scripts/metamask-controller.actions.test.js b/app/scripts/metamask-controller.actions.test.js index 51b69a12008f..d0439e48c01e 100644 --- a/app/scripts/metamask-controller.actions.test.js +++ b/app/scripts/metamask-controller.actions.test.js @@ -244,11 +244,41 @@ describe('MetaMaskController', function () { ); const [token1, token2] = await Promise.all([ - metamaskController.getApi().addToken(address, symbol, decimals), - metamaskController.getApi().addToken(address, symbol, decimals), + metamaskController.getApi().addToken({ address, symbol, decimals }), + metamaskController.getApi().addToken({ address, symbol, decimals }), ]); assert.deepEqual(token1, token2); }); + + it('networkClientId is used when provided', async function () { + const supportsInterfaceStub = sinon + .stub() + .returns(Promise.resolve(false)); + sinon + .stub(metamaskController.tokensController, '_createEthersContract') + .callsFake(() => + Promise.resolve({ supportsInterface: supportsInterfaceStub }), + ); + sinon + .stub(metamaskController.tokensController, 'getNetworkClientById') + .callsFake(() => ({ + configuration: { + chainId: '0xa', + }, + })); + + await metamaskController.getApi().addToken({ + address, + symbol, + decimals, + networkClientId: 'networkClientId1', + }); + assert.strictEqual( + metamaskController.tokensController.getNetworkClientById.getCall(0) + .args[0], + 'networkClientId1', + ); + }); }); describe('#removePermissionsFor', function () { diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 1842715640b2..f9dc033a48e8 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -453,25 +453,6 @@ export default class MetamaskController extends EventEmitter { networkConfigurations: this.networkController.state.networkConfigurations, }); - const tokensControllerMessenger = this.controllerMessenger.getRestricted({ - name: 'TokensController', - allowedActions: ['ApprovalController:addRequest'], - allowedEvents: ['NetworkController:stateChange'], - }); - this.tokensController = new TokensController({ - messenger: tokensControllerMessenger, - chainId: this.networkController.state.providerConfig.chainId, - onPreferencesStateChange: this.preferencesController.store.subscribe.bind( - this.preferencesController.store, - ), - onNetworkStateChange: networkControllerMessenger.subscribe.bind( - networkControllerMessenger, - 'NetworkController:stateChange', - ), - config: { provider: this.provider }, - state: initState.TokensController, - }); - this.assetsContractController = new AssetsContractController( { chainId: this.networkController.state.providerConfig.chainId, @@ -493,6 +474,9 @@ export default class MetamaskController extends EventEmitter { return cb(networkState); }, ), + getNetworkClientById: this.networkController.getNetworkClientById.bind( + this.networkController, + ), }, { provider: this.provider, @@ -500,6 +484,36 @@ export default class MetamaskController extends EventEmitter { initState.AssetsContractController, ); + const tokensControllerMessenger = this.controllerMessenger.getRestricted({ + name: 'TokensController', + allowedActions: ['ApprovalController:addRequest'], + allowedEvents: ['NetworkController:stateChange'], + }); + this.tokensController = new TokensController({ + messenger: tokensControllerMessenger, + chainId: this.networkController.state.providerConfig.chainId, + onPreferencesStateChange: this.preferencesController.store.subscribe.bind( + this.preferencesController.store, + ), + onNetworkStateChange: networkControllerMessenger.subscribe.bind( + networkControllerMessenger, + 'NetworkController:stateChange', + ), + onTokenListStateChange: (listener) => + this.controllerMessenger.subscribe( + `${this.tokenListController.name}:stateChange`, + listener, + ), + getNetworkClientById: this.networkController.getNetworkClientById.bind( + this.networkController, + ), + getERC20TokenName: this.assetsContractController.getERC20TokenName.bind( + this.assetsContractController, + ), + config: { provider: this.provider }, + state: initState.TokensController, + }); + const nftControllerMessenger = this.controllerMessenger.getRestricted({ name: 'NftController', allowedActions: [`${this.approvalController.name}:addRequest`], @@ -724,17 +738,18 @@ export default class MetamaskController extends EventEmitter { this.tokenRatesController = new TokenRatesController( { chainId: this.networkController.state.providerConfig.chainId, + ticker: this.networkController.state.providerConfig.ticker, + selectedAddress: this.preferencesController.getSelectedAddress(), onTokensStateChange: (listener) => this.tokensController.subscribe(listener), - onCurrencyRateStateChange: (listener) => - this.controllerMessenger.subscribe( - `${this.currencyRateController.name}:stateChange`, - listener, - ), onNetworkStateChange: networkControllerMessenger.subscribe.bind( networkControllerMessenger, 'NetworkController:stateChange', ), + onPreferencesStateChange: + this.preferencesController.store.subscribe.bind( + this.preferencesController.store, + ), }, { disabled: @@ -3862,10 +3877,14 @@ export default class MetamaskController extends EventEmitter { }); } - handleWatchAssetRequest = (asset, type, origin) => { + handleWatchAssetRequest = ({ asset, type, origin, networkClientId }) => { switch (type) { case ERC20: - return this.tokensController.watchAsset(asset, type); + return this.tokensController.watchAsset({ + asset, + type, + networkClientId, + }); case ERC721: case ERC1155: return this.nftController.watchNft(asset, type, origin); diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index 137d438d31e5..1d5bc4c9562c 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -757,16 +757,16 @@ "@ethersproject/contracts": true, "@ethersproject/providers": true, "@metamask/assets-controllers>@metamask/abi-utils": true, + "@metamask/assets-controllers>@metamask/controller-utils": true, "@metamask/assets-controllers>@metamask/rpc-errors": true, + "@metamask/assets-controllers>@metamask/utils": true, "@metamask/assets-controllers>abort-controller": true, "@metamask/assets-controllers>multiformats": true, "@metamask/base-controller": true, "@metamask/contract-metadata": true, - "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, "@metamask/metamask-eth-abis": true, - "@metamask/utils": true, "eth-json-rpc-filters>async-mutex": true, - "eth-query": true, "ethereumjs-util": true, "single-call-balance-checker-abi": true, "uuid": true, @@ -785,18 +785,61 @@ "TextEncoder": true }, "packages": { + "@metamask/key-tree>@noble/hashes": true, "browserify>buffer": true, "nock>debug": true, "semver": true, "superstruct": true } }, + "@metamask/assets-controllers>@metamask/controller-utils": { + "globals": { + "URL": true, + "console.error": true, + "fetch": true, + "setTimeout": true + }, + "packages": { + "@metamask/assets-controllers>@metamask/utils": true, + "@metamask/controller-utils>@spruceid/siwe-parser": true, + "browserify>buffer": true, + "eslint>fast-deep-equal": true, + "eth-ens-namehash": true, + "ethereumjs-util": true, + "ethjs>ethjs-unit": true + } + }, "@metamask/assets-controllers>@metamask/rpc-errors": { "packages": { - "@metamask/utils": true, + "@metamask/assets-controllers>@metamask/rpc-errors>@metamask/utils": true, "eth-rpc-errors>fast-safe-stringify": true } }, + "@metamask/assets-controllers>@metamask/rpc-errors>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "browserify>buffer": true, + "nock>debug": true, + "semver": true, + "superstruct": true + } + }, + "@metamask/assets-controllers>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/key-tree>@noble/hashes": true, + "browserify>buffer": true, + "nock>debug": true, + "semver": true, + "superstruct": true + } + }, "@metamask/assets-controllers>abort-controller": { "globals": { "AbortController": true @@ -1666,7 +1709,7 @@ "packages": { "@ethereumjs/tx>@ethereumjs/util": true, "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/assets-controllers>@metamask/abi-utils": true, "@metamask/message-manager>@metamask/eth-sig-util>@metamask/utils": true, "browserify>buffer": true, "eth-sig-util>ethereumjs-util>ethjs-util": true, @@ -1674,25 +1717,6 @@ "eth-sig-util>tweetnacl-util": true } }, - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils": { - "packages": { - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": true, - "superstruct": true - } - }, - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/key-tree>@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true, - "superstruct": true - } - }, "@metamask/message-manager>@metamask/eth-sig-util>@metamask/utils": { "globals": { "TextDecoder": true, diff --git a/lavamoat/browserify/desktop/policy.json b/lavamoat/browserify/desktop/policy.json index 5f3e7b1e6a65..c778599726dd 100644 --- a/lavamoat/browserify/desktop/policy.json +++ b/lavamoat/browserify/desktop/policy.json @@ -757,16 +757,16 @@ "@ethersproject/contracts": true, "@ethersproject/providers": true, "@metamask/assets-controllers>@metamask/abi-utils": true, + "@metamask/assets-controllers>@metamask/controller-utils": true, "@metamask/assets-controllers>@metamask/rpc-errors": true, + "@metamask/assets-controllers>@metamask/utils": true, "@metamask/assets-controllers>abort-controller": true, "@metamask/assets-controllers>multiformats": true, "@metamask/base-controller": true, "@metamask/contract-metadata": true, - "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, "@metamask/metamask-eth-abis": true, - "@metamask/utils": true, "eth-json-rpc-filters>async-mutex": true, - "eth-query": true, "ethereumjs-util": true, "single-call-balance-checker-abi": true, "uuid": true, @@ -785,18 +785,61 @@ "TextEncoder": true }, "packages": { + "@metamask/key-tree>@noble/hashes": true, "browserify>buffer": true, "nock>debug": true, "semver": true, "superstruct": true } }, + "@metamask/assets-controllers>@metamask/controller-utils": { + "globals": { + "URL": true, + "console.error": true, + "fetch": true, + "setTimeout": true + }, + "packages": { + "@metamask/assets-controllers>@metamask/utils": true, + "@metamask/controller-utils>@spruceid/siwe-parser": true, + "browserify>buffer": true, + "eslint>fast-deep-equal": true, + "eth-ens-namehash": true, + "ethereumjs-util": true, + "ethjs>ethjs-unit": true + } + }, "@metamask/assets-controllers>@metamask/rpc-errors": { "packages": { - "@metamask/utils": true, + "@metamask/assets-controllers>@metamask/rpc-errors>@metamask/utils": true, "eth-rpc-errors>fast-safe-stringify": true } }, + "@metamask/assets-controllers>@metamask/rpc-errors>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "browserify>buffer": true, + "nock>debug": true, + "semver": true, + "superstruct": true + } + }, + "@metamask/assets-controllers>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/key-tree>@noble/hashes": true, + "browserify>buffer": true, + "nock>debug": true, + "semver": true, + "superstruct": true + } + }, "@metamask/assets-controllers>abort-controller": { "globals": { "AbortController": true @@ -1201,8 +1244,8 @@ "packages": { "@ethereumjs/tx>@ethereumjs/util": true, "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/assets-controllers>@metamask/abi-utils": true, "@metamask/eth-snap-keyring>@metamask/utils": true, - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils": true, "browserify>buffer": true, "eth-sig-util>ethereumjs-util>ethjs-util": true, "eth-sig-util>tweetnacl": true, @@ -1807,7 +1850,7 @@ "packages": { "@ethereumjs/tx>@ethereumjs/util": true, "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/assets-controllers>@metamask/abi-utils": true, "@metamask/message-manager>@metamask/eth-sig-util>@metamask/utils": true, "browserify>buffer": true, "eth-sig-util>ethereumjs-util>ethjs-util": true, @@ -1815,25 +1858,6 @@ "eth-sig-util>tweetnacl-util": true } }, - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils": { - "packages": { - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": true, - "superstruct": true - } - }, - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/key-tree>@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true, - "superstruct": true - } - }, "@metamask/message-manager>@metamask/eth-sig-util>@metamask/utils": { "globals": { "TextDecoder": true, diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index 62ee4d7636f5..259005fc3545 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -757,16 +757,16 @@ "@ethersproject/contracts": true, "@ethersproject/providers": true, "@metamask/assets-controllers>@metamask/abi-utils": true, + "@metamask/assets-controllers>@metamask/controller-utils": true, "@metamask/assets-controllers>@metamask/rpc-errors": true, + "@metamask/assets-controllers>@metamask/utils": true, "@metamask/assets-controllers>abort-controller": true, "@metamask/assets-controllers>multiformats": true, "@metamask/base-controller": true, "@metamask/contract-metadata": true, - "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, "@metamask/metamask-eth-abis": true, - "@metamask/utils": true, "eth-json-rpc-filters>async-mutex": true, - "eth-query": true, "ethereumjs-util": true, "single-call-balance-checker-abi": true, "uuid": true, @@ -785,18 +785,61 @@ "TextEncoder": true }, "packages": { + "@metamask/key-tree>@noble/hashes": true, "browserify>buffer": true, "nock>debug": true, "semver": true, "superstruct": true } }, + "@metamask/assets-controllers>@metamask/controller-utils": { + "globals": { + "URL": true, + "console.error": true, + "fetch": true, + "setTimeout": true + }, + "packages": { + "@metamask/assets-controllers>@metamask/utils": true, + "@metamask/controller-utils>@spruceid/siwe-parser": true, + "browserify>buffer": true, + "eslint>fast-deep-equal": true, + "eth-ens-namehash": true, + "ethereumjs-util": true, + "ethjs>ethjs-unit": true + } + }, "@metamask/assets-controllers>@metamask/rpc-errors": { "packages": { - "@metamask/utils": true, + "@metamask/assets-controllers>@metamask/rpc-errors>@metamask/utils": true, "eth-rpc-errors>fast-safe-stringify": true } }, + "@metamask/assets-controllers>@metamask/rpc-errors>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "browserify>buffer": true, + "nock>debug": true, + "semver": true, + "superstruct": true + } + }, + "@metamask/assets-controllers>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/key-tree>@noble/hashes": true, + "browserify>buffer": true, + "nock>debug": true, + "semver": true, + "superstruct": true + } + }, "@metamask/assets-controllers>abort-controller": { "globals": { "AbortController": true @@ -1201,8 +1244,8 @@ "packages": { "@ethereumjs/tx>@ethereumjs/util": true, "@ethereumjs/tx>ethereum-cryptography": true, + "@metamask/assets-controllers>@metamask/abi-utils": true, "@metamask/eth-snap-keyring>@metamask/utils": true, - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils": true, "browserify>buffer": true, "eth-sig-util>ethereumjs-util>ethjs-util": true, "eth-sig-util>tweetnacl": true, @@ -1807,7 +1850,7 @@ "packages": { "@ethereumjs/tx>@ethereumjs/util": true, "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/assets-controllers>@metamask/abi-utils": true, "@metamask/message-manager>@metamask/eth-sig-util>@metamask/utils": true, "browserify>buffer": true, "eth-sig-util>ethereumjs-util>ethjs-util": true, @@ -1815,25 +1858,6 @@ "eth-sig-util>tweetnacl-util": true } }, - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils": { - "packages": { - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": true, - "superstruct": true - } - }, - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/key-tree>@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true, - "superstruct": true - } - }, "@metamask/message-manager>@metamask/eth-sig-util>@metamask/utils": { "globals": { "TextDecoder": true, diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index 3620f072010a..98db5e952b64 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -757,16 +757,16 @@ "@ethersproject/contracts": true, "@ethersproject/providers": true, "@metamask/assets-controllers>@metamask/abi-utils": true, + "@metamask/assets-controllers>@metamask/controller-utils": true, "@metamask/assets-controllers>@metamask/rpc-errors": true, + "@metamask/assets-controllers>@metamask/utils": true, "@metamask/assets-controllers>abort-controller": true, "@metamask/assets-controllers>multiformats": true, "@metamask/base-controller": true, "@metamask/contract-metadata": true, - "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, "@metamask/metamask-eth-abis": true, - "@metamask/utils": true, "eth-json-rpc-filters>async-mutex": true, - "eth-query": true, "ethereumjs-util": true, "single-call-balance-checker-abi": true, "uuid": true, @@ -785,18 +785,61 @@ "TextEncoder": true }, "packages": { + "@metamask/key-tree>@noble/hashes": true, "browserify>buffer": true, "nock>debug": true, "semver": true, "superstruct": true } }, + "@metamask/assets-controllers>@metamask/controller-utils": { + "globals": { + "URL": true, + "console.error": true, + "fetch": true, + "setTimeout": true + }, + "packages": { + "@metamask/assets-controllers>@metamask/utils": true, + "@metamask/controller-utils>@spruceid/siwe-parser": true, + "browserify>buffer": true, + "eslint>fast-deep-equal": true, + "eth-ens-namehash": true, + "ethereumjs-util": true, + "ethjs>ethjs-unit": true + } + }, "@metamask/assets-controllers>@metamask/rpc-errors": { "packages": { - "@metamask/utils": true, + "@metamask/assets-controllers>@metamask/rpc-errors>@metamask/utils": true, "eth-rpc-errors>fast-safe-stringify": true } }, + "@metamask/assets-controllers>@metamask/rpc-errors>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "browserify>buffer": true, + "nock>debug": true, + "semver": true, + "superstruct": true + } + }, + "@metamask/assets-controllers>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/key-tree>@noble/hashes": true, + "browserify>buffer": true, + "nock>debug": true, + "semver": true, + "superstruct": true + } + }, "@metamask/assets-controllers>abort-controller": { "globals": { "AbortController": true @@ -1666,7 +1709,7 @@ "packages": { "@ethereumjs/tx>@ethereumjs/util": true, "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/assets-controllers>@metamask/abi-utils": true, "@metamask/message-manager>@metamask/eth-sig-util>@metamask/utils": true, "browserify>buffer": true, "eth-sig-util>ethereumjs-util>ethjs-util": true, @@ -1674,25 +1717,6 @@ "eth-sig-util>tweetnacl-util": true } }, - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils": { - "packages": { - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": true, - "superstruct": true - } - }, - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/key-tree>@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true, - "superstruct": true - } - }, "@metamask/message-manager>@metamask/eth-sig-util>@metamask/utils": { "globals": { "TextDecoder": true, diff --git a/lavamoat/browserify/mmi/policy.json b/lavamoat/browserify/mmi/policy.json index da52999e2f72..98c26279a5b0 100644 --- a/lavamoat/browserify/mmi/policy.json +++ b/lavamoat/browserify/mmi/policy.json @@ -897,16 +897,16 @@ "@ethersproject/contracts": true, "@ethersproject/providers": true, "@metamask/assets-controllers>@metamask/abi-utils": true, + "@metamask/assets-controllers>@metamask/controller-utils": true, "@metamask/assets-controllers>@metamask/rpc-errors": true, + "@metamask/assets-controllers>@metamask/utils": true, "@metamask/assets-controllers>abort-controller": true, "@metamask/assets-controllers>multiformats": true, "@metamask/base-controller": true, "@metamask/contract-metadata": true, - "@metamask/controller-utils": true, + "@metamask/controller-utils>@metamask/eth-query": true, "@metamask/metamask-eth-abis": true, - "@metamask/utils": true, "eth-json-rpc-filters>async-mutex": true, - "eth-query": true, "ethereumjs-util": true, "single-call-balance-checker-abi": true, "uuid": true, @@ -925,18 +925,61 @@ "TextEncoder": true }, "packages": { + "@metamask/key-tree>@noble/hashes": true, "browserify>buffer": true, "nock>debug": true, "semver": true, "superstruct": true } }, + "@metamask/assets-controllers>@metamask/controller-utils": { + "globals": { + "URL": true, + "console.error": true, + "fetch": true, + "setTimeout": true + }, + "packages": { + "@metamask/assets-controllers>@metamask/utils": true, + "@metamask/controller-utils>@spruceid/siwe-parser": true, + "browserify>buffer": true, + "eslint>fast-deep-equal": true, + "eth-ens-namehash": true, + "ethereumjs-util": true, + "ethjs>ethjs-unit": true + } + }, "@metamask/assets-controllers>@metamask/rpc-errors": { "packages": { - "@metamask/utils": true, + "@metamask/assets-controllers>@metamask/rpc-errors>@metamask/utils": true, "eth-rpc-errors>fast-safe-stringify": true } }, + "@metamask/assets-controllers>@metamask/rpc-errors>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "browserify>buffer": true, + "nock>debug": true, + "semver": true, + "superstruct": true + } + }, + "@metamask/assets-controllers>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/key-tree>@noble/hashes": true, + "browserify>buffer": true, + "nock>debug": true, + "semver": true, + "superstruct": true + } + }, "@metamask/assets-controllers>abort-controller": { "globals": { "AbortController": true @@ -1806,7 +1849,7 @@ "packages": { "@ethereumjs/tx>@ethereumjs/util": true, "@ethereumjs/tx>ethereum-cryptography": true, - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils": true, + "@metamask/assets-controllers>@metamask/abi-utils": true, "@metamask/message-manager>@metamask/eth-sig-util>@metamask/utils": true, "browserify>buffer": true, "eth-sig-util>ethereumjs-util>ethjs-util": true, @@ -1814,25 +1857,6 @@ "eth-sig-util>tweetnacl-util": true } }, - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils": { - "packages": { - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": true, - "superstruct": true - } - }, - "@metamask/message-manager>@metamask/eth-sig-util>@metamask/abi-utils>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/key-tree>@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true, - "superstruct": true - } - }, "@metamask/message-manager>@metamask/eth-sig-util>@metamask/utils": { "globals": { "TextDecoder": true, diff --git a/package.json b/package.json index c015cb6cff8f..6d4930113db9 100644 --- a/package.json +++ b/package.json @@ -237,7 +237,7 @@ "@metamask/address-book-controller": "^3.0.0", "@metamask/announcement-controller": "^4.0.0", "@metamask/approval-controller": "^3.4.0", - "@metamask/assets-controllers": "^9.2.0", + "@metamask/assets-controllers": "^13.0.0", "@metamask/base-controller": "^3.2.0", "@metamask/browser-passworder": "^4.1.0", "@metamask/contract-metadata": "^2.3.1", diff --git a/ui/components/app/detected-token/detected-token.js b/ui/components/app/detected-token/detected-token.js index 582befda8e9e..3d9038cc52b9 100644 --- a/ui/components/app/detected-token/detected-token.js +++ b/ui/components/app/detected-token/detected-token.js @@ -11,6 +11,7 @@ import { import { getCurrentChainId, getDetectedTokensInCurrentNetwork, + getSelectedNetworkClientId, } from '../../../selectors'; import { MetaMetricsContext } from '../../../contexts/metametrics'; @@ -52,6 +53,7 @@ const DetectedToken = ({ setShowDetectedTokens }) => { const chainId = useSelector(getCurrentChainId); const detectedTokens = useSelector(getDetectedTokensInCurrentNetwork); + const networkClientId = useSelector(getSelectedNetworkClientId); const [tokensListDetected, setTokensListDetected] = useState(() => detectedTokens.reduce((tokenObj, token) => { @@ -81,7 +83,7 @@ const DetectedToken = ({ setShowDetectedTokens }) => { }, }); }); - await dispatch(addImportedTokens(selectedTokens)); + await dispatch(addImportedTokens(selectedTokens, networkClientId)); const tokenSymbols = selectedTokens.map(({ symbol }) => symbol); dispatch(setNewTokensImported(tokenSymbols.join(', '))); }; diff --git a/ui/components/app/nfts-items/nfts-items.js b/ui/components/app/nfts-items/nfts-items.js index d2e5eeb6630d..ced4c8f5a897 100644 --- a/ui/components/app/nfts-items/nfts-items.js +++ b/ui/components/app/nfts-items/nfts-items.js @@ -192,7 +192,7 @@ export default function NftsItems({ ipfsGateway, ); const nftImageAlt = getNftImageAlt(nft); - const isImageHosted = image.startsWith('https:'); + const isImageHosted = image?.startsWith('https:'); const nftImageURL = imageOriginal?.startsWith('ipfs') ? nftImage : image; diff --git a/ui/components/multichain/import-tokens-modal/import-tokens-modal.js b/ui/components/multichain/import-tokens-modal/import-tokens-modal.js index 3bc95be4636f..3239b2cf76f6 100644 --- a/ui/components/multichain/import-tokens-modal/import-tokens-modal.js +++ b/ui/components/multichain/import-tokens-modal/import-tokens-modal.js @@ -21,6 +21,7 @@ import { getMetaMaskIdentities, getRpcPrefsForCurrentProvider, getSelectedAddress, + getSelectedNetworkClientId, getTokenDetectionSupportNetworkByChainId, getTokenList, } from '../../../selectors'; @@ -152,10 +153,11 @@ export const ImportTokensModal = ({ onClose }) => { // CONFIRMATION MODE const trackEvent = useContext(MetaMetricsContext); const pendingTokens = useSelector(getPendingTokens); + const networkClientId = useSelector(getSelectedNetworkClientId); const handleAddTokens = useCallback(async () => { const addedTokenValues = Object.values(pendingTokens); - await dispatch(addImportedTokens(addedTokenValues)); + await dispatch(addImportedTokens(addedTokenValues, networkClientId)); const firstTokenAddress = addedTokenValues?.[0].address?.toLowerCase(); diff --git a/ui/ducks/swaps/swaps.js b/ui/ducks/swaps/swaps.js index 2c50c80253ca..1a055c34e2c7 100644 --- a/ui/ducks/swaps/swaps.js +++ b/ui/ducks/swaps/swaps.js @@ -61,6 +61,7 @@ import { isHardwareWallet, getHardwareWalletType, checkNetworkAndAccountSupports1559, + getSelectedNetworkClientId, } from '../../selectors'; import { @@ -659,6 +660,7 @@ export const fetchQuotesAndSetQuoteState = ( const fetchParams = getFetchParams(state); const selectedAccount = getSelectedAccount(state); + const networkClientId = getSelectedNetworkClientId(state); const balanceError = getBalanceError(state); const swapsDefaultToken = getSwapsDefaultToken(state); const fetchParamsFromToken = @@ -700,10 +702,13 @@ export const fetchQuotesAndSetQuoteState = ( ) { await dispatch( addToken( - toTokenAddress, - toTokenSymbol, - toTokenDecimals, - toTokenIconUrl, + { + address: toTokenAddress, + symbol: toTokenSymbol, + decimals: toTokenDecimals, + image: toTokenIconUrl, + networkClientId, + }, true, ), ); @@ -725,10 +730,13 @@ export const fetchQuotesAndSetQuoteState = ( ) { dispatch( addToken( - fromTokenAddress, - fromTokenSymbol, - fromTokenDecimals, - fromTokenIconUrl, + { + address: fromTokenAddress, + symbol: fromTokenSymbol, + decimals: fromTokenDecimals, + image: fromTokenIconUrl, + networkClientId, + }, true, ), ); diff --git a/ui/store/actions.test.js b/ui/store/actions.test.js index 26550166dd4e..56882e5059e4 100644 --- a/ui/store/actions.test.js +++ b/ui/store/actions.test.js @@ -898,6 +898,7 @@ describe('Actions', () => { address: '0x514910771af9ca656af840dff83e8264ecf986ca', symbol: 'LINK', decimals: 18, + networkClientId: 'networkClientId1', }), ); expect(addTokenStub.callCount).toStrictEqual(1); @@ -914,7 +915,7 @@ describe('Actions', () => { const addTokenStub = sinon .stub() - .callsFake((_, __, ___, ____, cb) => cb(null, tokenDetails)); + .callsFake((_, cb) => cb(null, tokenDetails)); background.getApi.returns({ addToken: addTokenStub, @@ -937,6 +938,7 @@ describe('Actions', () => { address: '0x514910771af9ca656af840dff83e8264ecf986ca', symbol: 'LINK', decimals: 18, + networkClientId: 'networkClientId1', }), ); diff --git a/ui/store/actions.ts b/ui/store/actions.ts index f42cfd34c6dd..6d4875eee20d 100644 --- a/ui/store/actions.ts +++ b/ui/store/actions.ts @@ -21,6 +21,7 @@ import { UpdateProposedNamesRequest, UpdateProposedNamesResult, } from '@metamask/name-controller'; +import { NetworkClientId } from '@metamask/network-controller'; import { getMethodDataAsync } from '../helpers/utils/transactions.util'; import switchDirection from '../../shared/lib/switch-direction'; import { @@ -1777,10 +1778,19 @@ export function showConfTxPage({ id }: Partial = {}) { } export function addToken( - address?: string, - symbol?: string, - decimals?: number, - image?: string, + { + address, + symbol, + decimals, + image, + networkClientId, + }: { + address?: string; + symbol?: string; + decimals?: number; + image?: string; + networkClientId?: NetworkClientId; + }, dontShowLoadingIndicator?: boolean, ): ThunkAction { return async (dispatch: MetaMaskReduxDispatch) => { @@ -1792,10 +1802,13 @@ export function addToken( } try { await submitRequestToBackground('addToken', [ - address, - symbol, - decimals, - image, + { + address, + symbol, + decimals, + image, + networkClientId, + }, ]); } catch (error) { logErrorWithMessage(error); @@ -1811,13 +1824,18 @@ export function addToken( * To add the tokens user selected to state * * @param tokensToImport + * @param networkClientId */ export function addImportedTokens( tokensToImport: Token[], + networkClientId?: NetworkClientId, ): ThunkAction { return async (dispatch: MetaMaskReduxDispatch) => { try { - await submitRequestToBackground('addImportedTokens', [tokensToImport]); + await submitRequestToBackground('addImportedTokens', [ + tokensToImport, + networkClientId, + ]); } catch (error) { logErrorWithMessage(error); } finally { diff --git a/yarn.lock b/yarn.lock index 7b0cb88f0c1f..fcb188b880f3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3752,16 +3752,6 @@ __metadata: languageName: node linkType: hard -"@metamask/abi-utils@npm:^1.2.0": - version: 1.2.0 - resolution: "@metamask/abi-utils@npm:1.2.0" - dependencies: - "@metamask/utils": "npm:^3.4.1" - superstruct: "npm:^1.0.3" - checksum: 94ef4c368adf9e062b90f2851c865ecfc0a8580a774cd5b4e29a382d31f97e51e4d2baf035b5f9f786031b0c1a4536fe2fdd2b7a1d01359a1e24c319debc4eb2 - languageName: node - linkType: hard - "@metamask/abi-utils@npm:^2.0.2": version: 2.0.2 resolution: "@metamask/abi-utils@npm:2.0.2" @@ -3805,39 +3795,38 @@ __metadata: languageName: node linkType: hard -"@metamask/assets-controllers@npm:^9.2.0": - version: 9.2.0 - resolution: "@metamask/assets-controllers@npm:9.2.0" +"@metamask/assets-controllers@npm:^13.0.0": + version: 13.0.0 + resolution: "@metamask/assets-controllers@npm:13.0.0" dependencies: "@ethersproject/address": "npm:^5.7.0" "@ethersproject/bignumber": "npm:^5.7.0" "@ethersproject/contracts": "npm:^5.7.0" "@ethersproject/providers": "npm:^5.7.0" - "@metamask/abi-utils": "npm:^1.2.0" - "@metamask/approval-controller": "npm:^3.3.0" - "@metamask/base-controller": "npm:^3.0.0" + "@metamask/abi-utils": "npm:^2.0.2" + "@metamask/approval-controller": "npm:^3.5.1" + "@metamask/base-controller": "npm:^3.2.1" "@metamask/contract-metadata": "npm:^2.3.1" - "@metamask/controller-utils": "npm:^4.0.1" + "@metamask/controller-utils": "npm:^5.0.0" + "@metamask/eth-query": "npm:^3.0.1" "@metamask/metamask-eth-abis": "npm:3.0.0" - "@metamask/network-controller": "npm:^10.2.0" - "@metamask/preferences-controller": "npm:^4.1.0" + "@metamask/network-controller": "npm:^13.0.0" + "@metamask/preferences-controller": "npm:^4.4.1" "@metamask/rpc-errors": "npm:^5.1.1" - "@metamask/utils": "npm:^5.0.2" + "@metamask/utils": "npm:^6.2.0" "@types/uuid": "npm:^8.3.0" abort-controller: "npm:^3.0.0" async-mutex: "npm:^0.2.6" - babel-runtime: "npm:^6.26.0" - eth-query: "npm:^2.1.2" ethereumjs-util: "npm:^7.0.10" immer: "npm:^9.0.6" multiformats: "npm:^9.5.2" single-call-balance-checker-abi: "npm:^1.0.0" uuid: "npm:^8.3.2" peerDependencies: - "@metamask/approval-controller": ^3.3.0 - "@metamask/network-controller": ^10.2.0 - "@metamask/preferences-controller": ^4.1.0 - checksum: e95ff62b2287fad7969db43ae720c91c4ae7be42f939f54a47365cf2f052ae3a9333e8868fe74df57d10e67afc55bfc7ba10f8a31869a4940b2e542c6fd44710 + "@metamask/approval-controller": ^3.5.1 + "@metamask/network-controller": ^13.0.0 + "@metamask/preferences-controller": ^4.4.1 + checksum: cfb770ac88fa31d2435fe22c58046fc0356884c8981202d8b0b55a3e13387c4f807878941873be204a61a5777fc298ae013382e4948113628d232fbd68c31237 languageName: node linkType: hard @@ -3904,7 +3893,7 @@ __metadata: languageName: node linkType: hard -"@metamask/controller-utils@npm:^4.0.0, @metamask/controller-utils@npm:^4.0.1, @metamask/controller-utils@npm:^4.1.0, @metamask/controller-utils@npm:^4.2.0, @metamask/controller-utils@npm:^4.3.0, @metamask/controller-utils@npm:^4.3.2": +"@metamask/controller-utils@npm:^4.0.0, @metamask/controller-utils@npm:^4.1.0, @metamask/controller-utils@npm:^4.2.0, @metamask/controller-utils@npm:^4.3.0, @metamask/controller-utils@npm:^4.3.2": version: 4.3.2 resolution: "@metamask/controller-utils@npm:4.3.2" dependencies: @@ -3920,7 +3909,7 @@ __metadata: languageName: node linkType: hard -"@metamask/controller-utils@npm:^5.0.1": +"@metamask/controller-utils@npm:^5.0.0, @metamask/controller-utils@npm:^5.0.1": version: 5.0.1 resolution: "@metamask/controller-utils@npm:5.0.1" dependencies: @@ -4385,7 +4374,7 @@ __metadata: languageName: node linkType: hard -"@metamask/network-controller@npm:^10.2.0, @metamask/network-controller@npm:^10.3.0": +"@metamask/network-controller@npm:^10.3.0": version: 10.3.1 resolution: "@metamask/network-controller@npm:10.3.1" dependencies: @@ -4430,6 +4419,28 @@ __metadata: languageName: node linkType: hard +"@metamask/network-controller@npm:^13.0.0": + version: 13.0.0 + resolution: "@metamask/network-controller@npm:13.0.0" + dependencies: + "@metamask/base-controller": "npm:^3.2.1" + "@metamask/controller-utils": "npm:^5.0.0" + "@metamask/eth-json-rpc-infura": "npm:^8.1.1" + "@metamask/eth-json-rpc-middleware": "npm:^11.0.2" + "@metamask/eth-json-rpc-provider": "npm:^1.0.0" + "@metamask/eth-query": "npm:^3.0.1" + "@metamask/swappable-obj-proxy": "npm:^2.1.0" + "@metamask/utils": "npm:^6.2.0" + async-mutex: "npm:^0.2.6" + eth-block-tracker: "npm:^7.0.1" + eth-rpc-errors: "npm:^4.0.2" + immer: "npm:^9.0.6" + json-rpc-engine: "npm:^6.1.0" + uuid: "npm:^8.3.2" + checksum: 42a5fb970ece23219f4a70fb999baacce356a469062f694474b25dd9ce69ec64c88d2c32effc88b915efacfd91bc7b04f0682af6bf4127e504d43caa873b751d + languageName: node + linkType: hard + "@metamask/notification-controller@npm:^3.0.0": version: 3.0.0 resolution: "@metamask/notification-controller@npm:3.0.0" @@ -4587,7 +4598,7 @@ __metadata: languageName: node linkType: hard -"@metamask/preferences-controller@npm:^4.1.0, @metamask/preferences-controller@npm:^4.4.2": +"@metamask/preferences-controller@npm:^4.4.1, @metamask/preferences-controller@npm:^4.4.2": version: 4.4.2 resolution: "@metamask/preferences-controller@npm:4.4.2" dependencies: @@ -4911,18 +4922,6 @@ __metadata: languageName: node linkType: hard -"@metamask/utils@npm:^3.4.1": - version: 3.6.0 - resolution: "@metamask/utils@npm:3.6.0" - dependencies: - "@types/debug": "npm:^4.1.7" - debug: "npm:^4.3.4" - semver: "npm:^7.3.8" - superstruct: "npm:^1.0.3" - checksum: f6a1cf9a2ddbdb9840ed3d93d961d3f7c3feb532361c84a3e54c88034d9a3149a11773948631a25c2b0355712848a6e0b226ad432844703e1f498e9602920879 - languageName: node - linkType: hard - "@metamask/utils@npm:^4.0.0": version: 4.0.0 resolution: "@metamask/utils@npm:4.0.0" @@ -23842,7 +23841,7 @@ __metadata: "@metamask/address-book-controller": "npm:^3.0.0" "@metamask/announcement-controller": "npm:^4.0.0" "@metamask/approval-controller": "npm:^3.4.0" - "@metamask/assets-controllers": "npm:^9.2.0" + "@metamask/assets-controllers": "npm:^13.0.0" "@metamask/auto-changelog": "npm:^2.1.0" "@metamask/base-controller": "npm:^3.2.0" "@metamask/browser-passworder": "npm:^4.1.0"