@metamask-previews/assets-controllers 113.2.0-preview-622cd8571 → 113.3.0-preview-a553ac65f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -1
- package/dist/AccountTrackerController.d.ts +11 -0
- package/dist/AccountTrackerController.d.ts.map +1 -1
- package/dist/AccountTrackerController.js +32 -7
- package/dist/AccountTrackerController.js.map +1 -1
- package/dist/MultichainAssetsController/MultichainAssetsController.d.ts +10 -0
- package/dist/MultichainAssetsController/MultichainAssetsController.d.ts.map +1 -1
- package/dist/MultichainAssetsController/MultichainAssetsController.js +26 -4
- package/dist/MultichainAssetsController/MultichainAssetsController.js.map +1 -1
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.ts +10 -0
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.ts.map +1 -1
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.js +18 -2
- package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.js.map +1 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.d.ts +9 -0
- package/dist/MultichainBalancesController/MultichainBalancesController.d.ts.map +1 -1
- package/dist/MultichainBalancesController/MultichainBalancesController.js +25 -8
- package/dist/MultichainBalancesController/MultichainBalancesController.js.map +1 -1
- package/dist/NftController-method-action-types.d.ts +16 -1
- package/dist/NftController-method-action-types.d.ts.map +1 -1
- package/dist/NftController-method-action-types.js.map +1 -1
- package/dist/NftController.d.ts +10 -0
- package/dist/NftController.d.ts.map +1 -1
- package/dist/NftController.js +21 -2
- package/dist/NftController.js.map +1 -1
- package/dist/TokenBalancesController.d.ts +10 -0
- package/dist/TokenBalancesController.d.ts.map +1 -1
- package/dist/TokenBalancesController.js +22 -6
- package/dist/TokenBalancesController.js.map +1 -1
- package/dist/TokenDetectionController.d.ts +15 -0
- package/dist/TokenDetectionController.d.ts.map +1 -1
- package/dist/TokenDetectionController.js +60 -9
- package/dist/TokenDetectionController.js.map +1 -1
- package/dist/TokenListController.d.ts +8 -0
- package/dist/TokenListController.d.ts.map +1 -1
- package/dist/TokenListController.js +12 -0
- package/dist/TokenListController.js.map +1 -1
- package/dist/TokenRatesController.d.ts +16 -2
- package/dist/TokenRatesController.d.ts.map +1 -1
- package/dist/TokenRatesController.js +72 -12
- package/dist/TokenRatesController.js.map +1 -1
- package/dist/TokensController.d.ts +18 -5
- package/dist/TokensController.d.ts.map +1 -1
- package/dist/TokensController.js +42 -10
- package/dist/TokensController.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/token-prices-service/codefi-v2.d.ts +2 -0
- package/dist/token-prices-service/codefi-v2.d.ts.map +1 -1
- package/dist/token-prices-service/codefi-v2.js +2 -0
- package/dist/token-prices-service/codefi-v2.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Add `init` method to `TokensController`, `TokenBalancesController`, `TokenDetectionController`, `TokenRatesController`, `AccountTrackerController`, `NftController`, `MultichainBalancesController`, `MultichainAssetsRatesController`, `MultichainAssetsController` and `TokenListController` ([#11315](https://github.com/MetaMask/core/pull/11315))
|
|
13
|
+
- `init` reads the other controllers that the constructor used to read. Calling it more than once has no effect.
|
|
14
|
+
- `TokenListController.init` calls `initialize` once.
|
|
15
|
+
- Expose `addNfts` through the `NftController` messenger ([#11315](https://github.com/MetaMask/core/pull/11315))
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- **BREAKING:** The constructors of `TokensController`, `TokenBalancesController`, `TokenDetectionController`, `TokenRatesController`, `AccountTrackerController`, `NftController`, `MultichainBalancesController`, `MultichainAssetsRatesController` and `MultichainAssetsController` no longer call other controllers or start background work, so they can be constructed in any order ([#11315](https://github.com/MetaMask/core/pull/11315))
|
|
20
|
+
- Call `init` on each of them once the controllers they read from are registered. Until then:
|
|
21
|
+
- `TokensController` does not enrich persisted tokens from the token list, and reads the selected account on demand.
|
|
22
|
+
- `TokenBalancesController`, `TokenDetectionController` and `AccountTrackerController` treat the keyring as locked, and `TokenBalancesController` knows of no tokens.
|
|
23
|
+
- `TokenRatesController` knows of no tokens and does not pass native asset identifiers to the token prices service. After `init`, identifiers that `NetworkEnablementController` fills or changes are passed to the token prices service on `NetworkEnablementController:stateChange` and again before each rate lookup.
|
|
24
|
+
- `AccountTrackerController` starts with an empty `accountsByChainId`; `init` adds an empty entry for the selected network's chain when no `accountsByChainId` state was provided.
|
|
25
|
+
- `NftController` reads the selected account on demand.
|
|
26
|
+
- `MultichainBalancesController` does not fetch the initial non-EVM balances.
|
|
27
|
+
- `MultichainAssetsRatesController` uses `usd` as the current currency.
|
|
28
|
+
- `MultichainAssetsController` does not start the periodic Blockaid re-scan.
|
|
29
|
+
- `TokenDetectionController.init` reports a failure to read `PreferencesController:getState` through `messenger.captureException` instead of throwing. The preference stays unset after a failed read and is read again the next time detection runs. While it is still unset, non-mainnet detection is skipped and mainnet uses the static token list. `PreferencesController:stateChange` also updates the preference.
|
|
30
|
+
- **BREAKING:** `TokensControllerMessenger` must allow the `NetworkController:getSelectedNetworkClient` action ([#11315](https://github.com/MetaMask/core/pull/11315))
|
|
31
|
+
- **BREAKING:** `TokenRatesControllerMessenger` must allow the `NetworkEnablementController:stateChange` event ([#11315](https://github.com/MetaMask/core/pull/11315))
|
|
32
|
+
- The controller subscribes to it and passes updated `nativeAssetIdentifiers` to the token prices service. It also re-reads them before each rate lookup.
|
|
33
|
+
- `TokensController` no longer requires the `chainId` and `provider` options ([#11315](https://github.com/MetaMask/core/pull/11315))
|
|
34
|
+
- When `provider` is omitted, the provider of the selected network client (`NetworkController:getSelectedNetworkClient`) is used.
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- `TokenRatesController` applies `nativeAssetIdentifiers` that `NetworkEnablementController` fills or updates after `init`, so CAIP-19 native token rate lookups are not left on the map captured during `init` ([#11315](https://github.com/MetaMask/core/pull/11315))
|
|
39
|
+
- `TokenDetectionController` reads `useTokenDetection` again when detection runs if that preference is still unset, so a `PreferencesController` registered after `init` does not leave non-mainnet detection skipped ([#11315](https://github.com/MetaMask/core/pull/11315))
|
|
40
|
+
|
|
41
|
+
## [113.3.0]
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
|
|
45
|
+
- Add Matchain (`0x2ba`, `eip155:698/slip44:714`) and Nomina (`0xa6`, `eip155:166/slip44:11111166`) to `SPOT_PRICES_SUPPORT_INFO` so the token prices service requests their native prices ([#11383](https://github.com/MetaMask/core/pull/11383))
|
|
46
|
+
- Nomina has no registered SLIP-44 coin type, so it uses the synthetic `slip44:11111<chainId>` form, matching the Price API.
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
|
|
50
|
+
- Bump `@metamask/abi-utils` from `^2.0.4` to `^3.0.0` ([#11356](https://github.com/MetaMask/core/pull/11356))
|
|
51
|
+
|
|
10
52
|
## [113.2.0]
|
|
11
53
|
|
|
12
54
|
### Added
|
|
@@ -3668,7 +3710,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
3668
3710
|
|
|
3669
3711
|
- Use Ethers for AssetsContractController ([#845](https://github.com/MetaMask/core/pull/845))
|
|
3670
3712
|
|
|
3671
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@113.
|
|
3713
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@113.3.0...HEAD
|
|
3714
|
+
[113.3.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@113.2.0...@metamask/assets-controllers@113.3.0
|
|
3672
3715
|
[113.2.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@113.1.1...@metamask/assets-controllers@113.2.0
|
|
3673
3716
|
[113.1.1]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@113.1.0...@metamask/assets-controllers@113.1.1
|
|
3674
3717
|
[113.1.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@113.0.1...@metamask/assets-controllers@113.1.0
|
|
@@ -131,6 +131,17 @@ export declare class AccountTrackerController extends AccountTrackerController_b
|
|
|
131
131
|
isOnboarded?: () => boolean;
|
|
132
132
|
isDeprecated?: () => boolean;
|
|
133
133
|
});
|
|
134
|
+
/**
|
|
135
|
+
* Complete initialization once the controllers this controller reads from
|
|
136
|
+
* have been constructed: read the lock state from `KeyringController` and,
|
|
137
|
+
* when no `accountsByChainId` state was provided, add an empty entry for the
|
|
138
|
+
* chain of the selected network.
|
|
139
|
+
*
|
|
140
|
+
* The constructor does not call other controllers, so it can run before they
|
|
141
|
+
* are constructed. Until this is called, the controller treats the keyring as
|
|
142
|
+
* locked. Calling it more than once has no effect.
|
|
143
|
+
*/
|
|
144
|
+
init(): void;
|
|
134
145
|
/**
|
|
135
146
|
* Whether the controller is active (keyring is unlocked and user is onboarded).
|
|
136
147
|
* When locked or not onboarded, balance updates should be skipped.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccountTrackerController.d.ts","sourceRoot":"","sources":["../src/AccountTrackerController.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,+CAA+C,EAC/C,0CAA0C,EAC1C,oCAAoC,EACrC,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EACV,0BAA0B,EAC1B,wBAAwB,EAEzB,MAAM,2BAA2B,CAAC;AAOnC,OAAO,KAAK,EACV,+BAA+B,EAC/B,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAEV,eAAe,EACf,2CAA2C,EAC3C,+BAA+B,EAC/B,kCAAkC,EACnC,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EACV,yCAAyC,EACzC,uDAAuD,EACxD,MAAM,yCAAyC,CAAC;AAEjD,OAAO,KAAK,EACV,8CAA8C,EAC9C,oDAAoD,EAErD,MAAM,kCAAkC,CAAC;AAE1C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAI3C,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,mDAAmD,CAAC;AAE/G,OAAO,KAAK,EACV,wBAAwB,EACxB,aAAa,EACd,MAAM,+BAA+B,CAAC;AAUvC;;GAEG;AACH,QAAA,MAAM,cAAc,6BAA6B,CAAC;AAElD,MAAM,MAAM,UAAU,GAAG,GAAG,CAAC;AAC7B,MAAM,MAAM,eAAe,GAAG,GAAG,CAAC;AA4DlC;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,6BAA6B,GAAG;IAC1C,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,CAAA;KAAE,CAAC,CAAC;CAC9E,CAAC;AAWF;;GAEG;AACH,MAAM,MAAM,sCAAsC,GAAG,wBAAwB,CAC3E,OAAO,cAAc,EACrB,6BAA6B,CAC9B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,+BAA+B,GACvC,sCAAsC,GACtC,qCAAqC,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,oCAAoC,GACpC;IACE,IAAI,EAAE,gCAAgC,CAAC;IACvC,OAAO,EAAE,MAAM;QAAE,6BAA6B,EAAE,OAAO,CAAA;KAAE,CAAC;CAC3D,GACD,0CAA0C,GAC1C,+BAA+B,GAC/B,2CAA2C,GAC3C,yCAAyC,GACzC,uDAAuD,GACvD,+BAA+B,CAAC;AAEpC;;GAEG;AACH,MAAM,MAAM,wCAAwC,GAClD,0BAA0B,CACxB,OAAO,cAAc,EACrB,6BAA6B,CAC9B,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,8BAA8B,GACxC,wCAAwC,CAAC;AAE3C;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,+CAA+C,GAC/C,oDAAoD,GACpD,8CAA8C,GAC9C,kCAAkC,GAClC,0BAA0B,GAC1B,4BAA4B,CAAC;AAEjC;;GAEG;AACH,MAAM,MAAM,iCAAiC,GAAG,SAAS,CACvD,OAAO,cAAc,EACrB,+BAA+B,GAAG,cAAc,EAChD,8BAA8B,GAAG,aAAa,CAC/C,CAAC;AAEF,0EAA0E;AAC1E,KAAK,0BAA0B,GAAG;IAChC,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;;;;;;;;;;;;;;;;AASF;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,8BAC5C,OAAO,cAAc,EACrB,6BAA6B,EAC7B,iCAAiC,CAClC;;
|
|
1
|
+
{"version":3,"file":"AccountTrackerController.d.ts","sourceRoot":"","sources":["../src/AccountTrackerController.ts"],"names":[],"mappings":"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"}
|
|
@@ -77,6 +77,8 @@ export class AccountTrackerController extends StaticIntervalPollingController()
|
|
|
77
77
|
#isDeprecated;
|
|
78
78
|
/** Track if the keyring is locked */
|
|
79
79
|
#isLocked = true;
|
|
80
|
+
#seedSelectedChain;
|
|
81
|
+
#initialized = false;
|
|
80
82
|
/**
|
|
81
83
|
* Creates an AccountTracker instance.
|
|
82
84
|
*
|
|
@@ -99,19 +101,16 @@ export class AccountTrackerController extends StaticIntervalPollingController()
|
|
|
99
101
|
* use when a higher-level controller (e.g. AssetsController) supersedes this one.
|
|
100
102
|
*/
|
|
101
103
|
constructor({ interval = 10000, state, messenger, getStakedBalanceForChain, includeStakedAssets = false, accountsApiChainIds = () => [], allowExternalServices = () => true, fetchingEnabled = () => true, isOnboarded = () => true, isHomepageSectionsV1Enabled = () => false, isDeprecated = () => false, }) {
|
|
102
|
-
const { selectedNetworkClientId } = messenger.call('NetworkController:getState');
|
|
103
|
-
const { configuration: { chainId }, } = messenger.call('NetworkController:getNetworkClientById', selectedNetworkClientId);
|
|
104
104
|
super({
|
|
105
105
|
name: controllerName,
|
|
106
106
|
messenger,
|
|
107
107
|
state: {
|
|
108
|
-
accountsByChainId: {
|
|
109
|
-
[chainId]: {},
|
|
110
|
-
},
|
|
108
|
+
accountsByChainId: {},
|
|
111
109
|
...state,
|
|
112
110
|
},
|
|
113
111
|
metadata: accountTrackerMetadata,
|
|
114
112
|
});
|
|
113
|
+
this.#seedSelectedChain = state?.accountsByChainId === undefined;
|
|
115
114
|
this.#getStakedBalanceForChain = getStakedBalanceForChain;
|
|
116
115
|
this.#includeStakedAssets = includeStakedAssets;
|
|
117
116
|
this.#accountsApiChainIds = accountsApiChainIds;
|
|
@@ -129,8 +128,6 @@ export class AccountTrackerController extends StaticIntervalPollingController()
|
|
|
129
128
|
if (this.#isDeprecated()) {
|
|
130
129
|
this.#enforceDisabledState();
|
|
131
130
|
}
|
|
132
|
-
const { isUnlocked } = this.messenger.call('KeyringController:getState');
|
|
133
|
-
this.#isLocked = !isUnlocked;
|
|
134
131
|
this.setIntervalLength(interval);
|
|
135
132
|
this.messenger.subscribe('AccountsController:selectedEvmAccountChange', (newAddress, prevAddress) => {
|
|
136
133
|
if (newAddress !== prevAddress) {
|
|
@@ -181,6 +178,34 @@ export class AccountTrackerController extends StaticIntervalPollingController()
|
|
|
181
178
|
});
|
|
182
179
|
messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
183
180
|
}
|
|
181
|
+
/**
|
|
182
|
+
* Complete initialization once the controllers this controller reads from
|
|
183
|
+
* have been constructed: read the lock state from `KeyringController` and,
|
|
184
|
+
* when no `accountsByChainId` state was provided, add an empty entry for the
|
|
185
|
+
* chain of the selected network.
|
|
186
|
+
*
|
|
187
|
+
* The constructor does not call other controllers, so it can run before they
|
|
188
|
+
* are constructed. Until this is called, the controller treats the keyring as
|
|
189
|
+
* locked. Calling it more than once has no effect.
|
|
190
|
+
*/
|
|
191
|
+
init() {
|
|
192
|
+
if (this.#initialized) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
this.#initialized = true;
|
|
196
|
+
const { isUnlocked } = this.messenger.call('KeyringController:getState');
|
|
197
|
+
this.#isLocked = !isUnlocked;
|
|
198
|
+
if (!this.#seedSelectedChain || this.#isDeprecated()) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const { selectedNetworkClientId } = this.messenger.call('NetworkController:getState');
|
|
202
|
+
const { configuration: { chainId }, } = this.messenger.call('NetworkController:getNetworkClientById', selectedNetworkClientId);
|
|
203
|
+
if (this.state.accountsByChainId[chainId] === undefined) {
|
|
204
|
+
this.update((state) => {
|
|
205
|
+
state.accountsByChainId[chainId] = {};
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
184
209
|
/**
|
|
185
210
|
* Whether the controller is active (keyring is unlocked and user is onboarded).
|
|
186
211
|
* When locked or not onboarded, balance updates should be skipped.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccountTrackerController.js","sourceRoot":"","sources":["../src/AccountTrackerController.ts"],"names":[],"mappings":"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","sourcesContent":["import { Web3Provider } from '@ethersproject/providers';\nimport type {\n AccountsControllerSelectedEvmAccountChangeEvent,\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerListAccountsAction,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n StateMetadata,\n} from '@metamask/base-controller';\nimport {\n query,\n safelyExecuteWithTimeout,\n toChecksumHexAddress,\n} from '@metamask/controller-utils';\nimport EthQuery from '@metamask/eth-query';\nimport type {\n KeyringControllerGetStateAction,\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { Messenger } from '@metamask/messenger';\nimport type {\n NetworkClient,\n NetworkClientId,\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n NetworkControllerNetworkAddedEvent,\n} from '@metamask/network-controller';\nimport type {\n NetworkEnablementControllerGetStateAction,\n NetworkEnablementControllerListPopularEvmNetworksAction,\n} from '@metamask/network-enablement-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type {\n TransactionControllerTransactionConfirmedEvent,\n TransactionControllerUnapprovedTransactionAddedEvent,\n TransactionMeta,\n} from '@metamask/transaction-controller';\nimport { assert, KnownCaipNamespace } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport { cloneDeep, isEqual } from 'lodash-es';\n\nimport type { AccountTrackerControllerMethodActions } from './AccountTrackerController-method-action-types.js';\nimport { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from './AssetsContractController.js';\nimport type {\n AssetsContractController,\n StakedBalance,\n} from './AssetsContractController.js';\nimport { shouldIncludeNativeToken } from './constants.js';\nimport { AccountsApiBalanceFetcher } from './multi-chain-accounts-service/api-balance-fetcher.js';\nimport type {\n BalanceFetcher,\n BalanceFetchResult,\n ProcessedBalance,\n} from './multi-chain-accounts-service/api-balance-fetcher.js';\nimport { RpcBalanceFetcher } from './rpc-service/rpc-balance-fetcher.js';\n\n/**\n * The name of the {@link AccountTrackerController}.\n */\nconst controllerName = 'AccountTrackerController';\n\nexport type ChainIdHex = Hex;\nexport type ChecksumAddress = Hex;\n\nconst ZERO_ADDRESS =\n '0x0000000000000000000000000000000000000000' as ChecksumAddress;\n\n/**\n * Creates an RPC balance fetcher configured for AccountTracker use case.\n * Returns only native balances and staked balances (no token balances).\n *\n * @param getProvider - Function to get Web3Provider for a given chain ID\n * @param getNetworkClient - Function to get NetworkClient for a given chain ID\n * @param includeStakedAssets - Whether to include staked assets in the fetch\n * @returns BalanceFetcher configured to fetch only native and optionally staked balances\n */\nfunction createAccountTrackerRpcBalanceFetcher(\n getProvider: (chainId: Hex) => Web3Provider,\n getNetworkClient: (chainId: Hex) => NetworkClient,\n includeStakedAssets: boolean,\n): BalanceFetcher {\n // Provide empty tokens state to ensure only native and staked balances are fetched\n const getEmptyTokensState = (): {\n allTokens: Record<string, never>;\n allDetectedTokens: Record<string, never>;\n } => ({\n allTokens: {},\n allDetectedTokens: {},\n });\n\n const rpcBalanceFetcher = new RpcBalanceFetcher(\n getProvider,\n getNetworkClient,\n getEmptyTokensState,\n );\n\n // Wrap the RpcBalanceFetcher to filter staked balances when not needed\n return {\n supports(_chainId: ChainIdHex): boolean {\n return rpcBalanceFetcher.supports();\n },\n\n async fetch(\n params: Parameters<BalanceFetcher['fetch']>[0],\n ): Promise<BalanceFetchResult> {\n const result = await rpcBalanceFetcher.fetch(params);\n\n if (!includeStakedAssets) {\n // Filter out staked balances from the results\n return {\n balances: result.balances.filter(\n (balance) => balance.token === ZERO_ADDRESS,\n ),\n unprocessedChainIds: result.unprocessedChainIds,\n };\n }\n\n return result;\n },\n };\n}\n\n/**\n * AccountInformation\n *\n * Account information object\n *\n * balance - Hex string of an account balance in wei\n *\n * stakedBalance - Hex string of an account staked balance in wei\n */\nexport type AccountInformation = {\n balance: string;\n stakedBalance?: string;\n};\n\n/**\n * AccountTrackerControllerState\n *\n * Account tracker controller state\n *\n * accountsByChainId - Map of addresses to account information by chain\n */\nexport type AccountTrackerControllerState = {\n accountsByChainId: Record<string, { [address: string]: AccountInformation }>;\n};\n\nconst accountTrackerMetadata: StateMetadata<AccountTrackerControllerState> = {\n accountsByChainId: {\n includeInStateLogs: false,\n persist: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n};\n\n/**\n * The action that can be performed to get the state of the {@link AccountTrackerController}.\n */\nexport type AccountTrackerControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AccountTrackerControllerState\n>;\n\n/**\n * The actions that can be performed using the {@link AccountTrackerController}.\n */\nexport type AccountTrackerControllerActions =\n | AccountTrackerControllerGetStateAction\n | AccountTrackerControllerMethodActions;\n\n/**\n * The messenger of the {@link AccountTrackerController} for communication.\n */\nexport type AllowedActions =\n | AccountsControllerListAccountsAction\n | {\n type: 'PreferencesController:getState';\n handler: () => { isMultiAccountBalancesEnabled: boolean };\n }\n | AccountsControllerGetSelectedAccountAction\n | NetworkControllerGetStateAction\n | NetworkControllerGetNetworkClientByIdAction\n | NetworkEnablementControllerGetStateAction\n | NetworkEnablementControllerListPopularEvmNetworksAction\n | KeyringControllerGetStateAction;\n\n/**\n * The event that {@link AccountTrackerController} can emit.\n */\nexport type AccountTrackerControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n AccountTrackerControllerState\n >;\n\n/**\n * The events that {@link AccountTrackerController} can emit.\n */\nexport type AccountTrackerControllerEvents =\n AccountTrackerControllerStateChangeEvent;\n\n/**\n * The external events available to the {@link AccountTrackerController}.\n */\nexport type AllowedEvents =\n | AccountsControllerSelectedEvmAccountChangeEvent\n | TransactionControllerUnapprovedTransactionAddedEvent\n | TransactionControllerTransactionConfirmedEvent\n | NetworkControllerNetworkAddedEvent\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent;\n\n/**\n * The messenger of the {@link AccountTrackerController}.\n */\nexport type AccountTrackerControllerMessenger = Messenger<\n typeof controllerName,\n AccountTrackerControllerActions | AllowedActions,\n AccountTrackerControllerEvents | AllowedEvents\n>;\n\n/** The input to start polling for the {@link AccountTrackerController} */\ntype AccountTrackerPollingInput = {\n networkClientIds: NetworkClientId[];\n queryAllAccounts?: boolean;\n};\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'updateNativeBalances',\n 'updateStakedBalances',\n 'refresh',\n 'syncBalanceWithAddresses',\n] as const;\n\n/**\n * Controller that tracks the network balances for all user accounts.\n */\nexport class AccountTrackerController extends StaticIntervalPollingController<AccountTrackerPollingInput>()<\n typeof controllerName,\n AccountTrackerControllerState,\n AccountTrackerControllerMessenger\n> {\n readonly #refreshMutex = new Mutex();\n\n readonly #includeStakedAssets: boolean;\n\n readonly #accountsApiChainIds: () => ChainIdHex[];\n\n readonly #getStakedBalanceForChain: AssetsContractController['getStakedBalanceForChain'];\n\n readonly #balanceFetchers: BalanceFetcher[];\n\n readonly #fetchingEnabled: () => boolean;\n\n readonly #isOnboarded: () => boolean;\n\n readonly #isHomepageSectionsV1Enabled: () => boolean;\n\n readonly #isDeprecated: () => boolean;\n\n /** Track if the keyring is locked */\n #isLocked = true;\n\n /**\n * Creates an AccountTracker instance.\n *\n * @param options - The controller options.\n * @param options.interval - Polling interval used to fetch new account balances.\n * @param options.state - Initial state to set on this controller.\n * @param options.messenger - The controller messenger.\n * @param options.getStakedBalanceForChain - The function to get the staked native asset balance for a chain.\n * @param options.includeStakedAssets - Whether to include staked assets in the account balances.\n * @param options.accountsApiChainIds - Function that returns array of chainIds that should use Accounts-API strategy (if supported by API).\n * @param options.allowExternalServices - Disable external HTTP calls (privacy / offline mode).\n * @param options.fetchingEnabled - Function that returns whether the controller is fetching enabled.\n * @param options.isOnboarded - Whether the user has completed onboarding. If false, balance updates are skipped.\n * @param options.isHomepageSectionsV1Enabled - Whether the homepage sections v1 is enabled.\n * @param options.isDeprecated - Optional function that returns true to completely\n * disable this controller (no requests, no state updates). When it returns\n * `true`, `accountsByChainId` is reset to `{}` at construction and at every\n * entry point, so no stale balances remain in state. The function is evaluated\n * dynamically on each entry point so it can be toggled at runtime. Intended for\n * use when a higher-level controller (e.g. AssetsController) supersedes this one.\n */\n constructor({\n interval = 10000,\n state,\n messenger,\n getStakedBalanceForChain,\n includeStakedAssets = false,\n accountsApiChainIds = (): ChainIdHex[] => [],\n allowExternalServices = (): boolean => true,\n fetchingEnabled = (): boolean => true,\n isOnboarded = (): boolean => true,\n isHomepageSectionsV1Enabled = (): boolean => false,\n isDeprecated = (): boolean => false,\n }: {\n interval?: number;\n state?: Partial<AccountTrackerControllerState>;\n messenger: AccountTrackerControllerMessenger;\n getStakedBalanceForChain: AssetsContractController['getStakedBalanceForChain'];\n includeStakedAssets?: boolean;\n accountsApiChainIds?: () => ChainIdHex[];\n isHomepageSectionsV1Enabled?: () => boolean;\n allowExternalServices?: () => boolean;\n fetchingEnabled?: () => boolean;\n isOnboarded?: () => boolean;\n isDeprecated?: () => boolean;\n }) {\n const { selectedNetworkClientId } = messenger.call(\n 'NetworkController:getState',\n );\n const {\n configuration: { chainId },\n } = messenger.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n super({\n name: controllerName,\n messenger,\n state: {\n accountsByChainId: {\n [chainId]: {},\n },\n ...state,\n },\n metadata: accountTrackerMetadata,\n });\n this.#getStakedBalanceForChain = getStakedBalanceForChain;\n\n this.#includeStakedAssets = includeStakedAssets;\n this.#accountsApiChainIds = accountsApiChainIds;\n this.#isHomepageSectionsV1Enabled = isHomepageSectionsV1Enabled;\n\n // Initialize balance fetchers - Strategy order: API first, then RPC fallback\n this.#balanceFetchers = [\n ...(accountsApiChainIds().length > 0 && allowExternalServices()\n ? [this.#createAccountsApiFetcher()]\n : []),\n createAccountTrackerRpcBalanceFetcher(\n this.#getProvider,\n this.#getNetworkClient,\n this.#includeStakedAssets,\n ),\n ];\n\n this.#fetchingEnabled = fetchingEnabled;\n this.#isOnboarded = isOnboarded;\n this.#isDeprecated = isDeprecated;\n\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n }\n\n const { isUnlocked } = this.messenger.call('KeyringController:getState');\n this.#isLocked = !isUnlocked;\n\n this.setIntervalLength(interval);\n\n this.messenger.subscribe(\n 'AccountsController:selectedEvmAccountChange',\n (newAddress, prevAddress) => {\n if (newAddress !== prevAddress) {\n // Making an async call for this new event\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.refresh(this.#getNetworkClientIds());\n }\n },\n (event): string => event.address,\n );\n\n this.messenger.subscribe(\n 'NetworkController:networkAdded',\n (networkConfiguration) => {\n const { networkClientId } =\n networkConfiguration.rpcEndpoints[\n networkConfiguration.defaultRpcEndpointIndex\n ];\n this.refresh([networkClientId]).catch(() => {\n // Silently handle refresh errors\n });\n },\n );\n\n this.messenger.subscribe('KeyringController:unlock', () => {\n this.#isLocked = false;\n const networkClientIds = this.#getNetworkClientIds();\n this.refresh(networkClientIds).catch((error) => {\n console.error('Error refreshing balances after keyring unlock:', error);\n });\n });\n\n this.messenger.subscribe('KeyringController:lock', () => {\n this.#isLocked = true;\n });\n\n this.messenger.subscribe(\n 'TransactionController:unapprovedTransactionAdded',\n (transactionMeta: TransactionMeta) => {\n const addresses = [transactionMeta.txParams.from];\n if (transactionMeta.txParams.to) {\n addresses.push(transactionMeta.txParams.to);\n }\n this.refreshAddresses({\n networkClientIds: [transactionMeta.networkClientId],\n addresses,\n }).catch(() => {\n // Silently handle refresh errors\n });\n },\n );\n\n this.messenger.subscribe(\n 'TransactionController:transactionConfirmed',\n (transactionMeta: TransactionMeta) => {\n const addresses = [transactionMeta.txParams.from];\n if (transactionMeta.txParams.to) {\n addresses.push(transactionMeta.txParams.to);\n }\n this.refreshAddresses({\n networkClientIds: [transactionMeta.networkClientId],\n addresses,\n }).catch(() => {\n // Silently handle refresh errors\n });\n },\n );\n\n messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);\n }\n\n /**\n * Whether the controller is active (keyring is unlocked and user is onboarded).\n * When locked or not onboarded, balance updates should be skipped.\n *\n * @returns Whether the controller should perform balance updates.\n */\n get isActive(): boolean {\n return !this.#isLocked && this.#isOnboarded();\n }\n\n /**\n * Clears all persisted `accountsByChainId` so that no stale balances remain in\n * state.\n *\n * Called from every entry point when `isDeprecated()` is true so that a runtime\n * toggle propagates to state immediately, even if the controller was originally\n * constructed while it was enabled. The update is skipped when\n * `accountsByChainId` is already empty to avoid emitting redundant state\n * changes.\n */\n #enforceDisabledState(): void {\n if (Object.keys(this.state.accountsByChainId).length === 0) {\n return;\n }\n this.update((state) => {\n state.accountsByChainId = {};\n });\n }\n\n #syncAccounts(newChainIds: string[]): void {\n const accountsByChainId = cloneDeep(this.state.accountsByChainId);\n const { selectedNetworkClientId } = this.messenger.call(\n 'NetworkController:getState',\n );\n const {\n configuration: { chainId: currentChainId },\n } = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n\n const existing = Object.keys(accountsByChainId?.[currentChainId] ?? {});\n\n // Initialize new chain IDs if they don't exist\n newChainIds.forEach((newChainId) => {\n if (!accountsByChainId[newChainId]) {\n accountsByChainId[newChainId] = {};\n existing.forEach((address) => {\n accountsByChainId[newChainId][address] = { balance: '0x0' };\n });\n }\n });\n\n // Note: The address from the preferences controller are checksummed\n // The addresses from the accounts controller are lowercased\n const addresses = Object.values(\n this.messenger\n .call('AccountsController:listAccounts')\n .map((internalAccount) =>\n toChecksumHexAddress(internalAccount.address),\n ),\n );\n const newAddresses = addresses.filter(\n (address) => !existing.includes(address),\n );\n const oldAddresses = existing.filter(\n (address) => !addresses.includes(address),\n );\n Object.keys(accountsByChainId).forEach((chainId) => {\n newAddresses.forEach((address) => {\n if (!accountsByChainId[chainId][address]) {\n accountsByChainId[chainId][address] = {\n balance: '0x0',\n };\n }\n });\n });\n\n Object.keys(accountsByChainId).forEach((chainId) => {\n oldAddresses.forEach((address) => {\n delete accountsByChainId[chainId][address];\n });\n });\n\n if (!isEqual(this.state.accountsByChainId, accountsByChainId)) {\n this.update((state) => {\n state.accountsByChainId = accountsByChainId;\n });\n }\n }\n\n readonly #getProvider = (chainId: Hex): Web3Provider => {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n const networkConfig = networkConfigurationsByChainId[chainId];\n const { networkClientId } =\n networkConfig.rpcEndpoints[networkConfig.defaultRpcEndpointIndex];\n const client = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n return new Web3Provider(client.provider);\n };\n\n readonly #getNetworkClient = (chainId: Hex): NetworkClient => {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n const networkConfig = networkConfigurationsByChainId[chainId];\n const { networkClientId } =\n networkConfig.rpcEndpoints[networkConfig.defaultRpcEndpointIndex];\n return this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n };\n\n /**\n * Creates an AccountsApiBalanceFetcher that only supports chains in the accountsApiChainIds array\n *\n * @returns A BalanceFetcher that wraps AccountsApiBalanceFetcher with chainId filtering\n */\n readonly #createAccountsApiFetcher = (): BalanceFetcher => {\n const originalFetcher = new AccountsApiBalanceFetcher(\n 'extension',\n this.#getProvider,\n );\n\n return {\n supports: (chainId: ChainIdHex): boolean => {\n // Only support chains that are both:\n // 1. In our specified accountsApiChainIds array\n // 2. Actually supported by the AccountsApi\n return (\n this.#accountsApiChainIds().includes(chainId) &&\n originalFetcher.supports(chainId)\n );\n },\n fetch: originalFetcher.fetch.bind(originalFetcher),\n };\n };\n\n /**\n * Resolves a networkClientId to a network client config\n * or globally selected network config if not provided\n *\n * @param networkClientId - Optional networkClientId to fetch a network client with\n * @returns network client config\n */\n #getCorrectNetworkClient(networkClientId?: NetworkClientId): {\n chainId: Hex;\n provider: NetworkClient['provider'];\n ethQuery: EthQuery;\n blockTracker: NetworkClient['blockTracker'];\n } {\n const selectedNetworkClientId =\n networkClientId ??\n this.messenger.call('NetworkController:getState').selectedNetworkClientId;\n const {\n configuration: { chainId },\n provider,\n blockTracker,\n } = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n\n return {\n chainId,\n provider,\n ethQuery: new EthQuery(provider),\n blockTracker,\n };\n }\n\n /**\n * Retrieves the list of network client IDs.\n *\n * @returns An array of network client IDs.\n */\n #getNetworkClientIds(): NetworkClientId[] {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n\n if (this.#isHomepageSectionsV1Enabled()) {\n const popularEvmChainIds = this.messenger.call(\n 'NetworkEnablementController:listPopularEvmNetworks',\n );\n return popularEvmChainIds\n .map((hexChainId) => {\n const networkConfig = networkConfigurationsByChainId[hexChainId];\n return networkConfig?.rpcEndpoints[\n networkConfig.defaultRpcEndpointIndex\n ]?.networkClientId;\n })\n .filter((id): id is NetworkClientId => id !== undefined);\n }\n\n const { enabledNetworkMap } = this.messenger.call(\n 'NetworkEnablementController:getState',\n );\n\n const evmEnabledStorageKeys = enabledNetworkMap[KnownCaipNamespace.Eip155]\n ? Object.keys(enabledNetworkMap[KnownCaipNamespace.Eip155])\n : [];\n\n return evmEnabledStorageKeys\n .map((hexChainId) => {\n const networkConfig = networkConfigurationsByChainId[hexChainId as Hex];\n return networkConfig?.rpcEndpoints[\n networkConfig.defaultRpcEndpointIndex\n ]?.networkClientId;\n })\n .filter((id): id is NetworkClientId => id !== undefined);\n }\n\n /**\n * Refreshes the balances of the accounts using the networkClientId\n *\n * @param input - The input for the poll.\n * @param input.networkClientIds - The network client IDs used to get balances.\n * @param input.queryAllAccounts - Whether to query all accounts or just the selected account\n */\n async _executePoll({\n networkClientIds,\n queryAllAccounts = false,\n }: AccountTrackerPollingInput): Promise<void> {\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n return;\n }\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.refresh(networkClientIds, queryAllAccounts);\n }\n\n /**\n * Refreshes the balances of the accounts depending on the multi-account setting.\n * If multi-account is disabled, only updates the selected account balance.\n * If multi-account is enabled, updates balances for all accounts.\n *\n * @param networkClientIds - Optional network client IDs to fetch a network client with\n * @param queryAllAccounts - Whether to query all accounts or just the selected account\n */\n async refresh(\n networkClientIds: NetworkClientId[],\n queryAllAccounts: boolean = false,\n ): Promise<void> {\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n return;\n }\n const selectedAccount = this.messenger.call(\n 'AccountsController:getSelectedAccount',\n );\n const allAccounts = this.messenger.call('AccountsController:listAccounts');\n const { isMultiAccountBalancesEnabled } = this.messenger.call(\n 'PreferencesController:getState',\n );\n\n await this.#refreshAccounts({\n networkClientIds,\n queryAllAccounts: queryAllAccounts ?? isMultiAccountBalancesEnabled,\n selectedAccount: toChecksumHexAddress(\n selectedAccount.address,\n ) as ChecksumAddress,\n allAccounts,\n });\n }\n\n async refreshAddresses({\n networkClientIds,\n addresses,\n }: {\n networkClientIds: NetworkClientId[];\n addresses: string[];\n }): Promise<void> {\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n return;\n }\n const checksummedAddresses = addresses.map((address) =>\n toChecksumHexAddress(address),\n );\n\n const accounts = this.messenger\n .call('AccountsController:listAccounts')\n .filter((account) =>\n checksummedAddresses.includes(toChecksumHexAddress(account.address)),\n );\n\n await this.#refreshAccounts({\n networkClientIds,\n queryAllAccounts: true,\n selectedAccount: '0x0',\n allAccounts: accounts,\n });\n }\n\n async #refreshAccounts({\n networkClientIds,\n queryAllAccounts,\n selectedAccount,\n allAccounts,\n }: {\n networkClientIds: NetworkClientId[];\n queryAllAccounts: boolean;\n selectedAccount: ChecksumAddress;\n allAccounts: InternalAccount[];\n }): Promise<void> {\n const releaseLock = await this.#refreshMutex.acquire();\n try {\n const chainIds = networkClientIds.map((networkClientId) => {\n const { chainId } = this.#getCorrectNetworkClient(networkClientId);\n return chainId;\n });\n\n this.#syncAccounts(chainIds);\n\n if (!this.#fetchingEnabled() || !this.isActive) {\n return;\n }\n\n // Use balance fetchers with fallback strategy\n const aggregated: ProcessedBalance[] = [];\n let remainingChains = [...chainIds] as ChainIdHex[];\n\n // Temporary normalization to lowercase for balance fetching to match TokenBalancesController and enable HTTP caching\n const lowerCaseSelectedAccount =\n selectedAccount.toLowerCase() as ChecksumAddress;\n const lowerCaseAllAccounts = allAccounts.map((account) => ({\n ...account,\n address: account.address.toLowerCase(),\n }));\n\n // Try each fetcher in order, removing successfully processed chains\n for (const fetcher of this.#balanceFetchers) {\n const supportedChains = remainingChains.filter((chainId) =>\n fetcher.supports(chainId),\n );\n if (!supportedChains.length) {\n continue;\n }\n\n try {\n const result = await fetcher.fetch({\n chainIds: supportedChains,\n queryAllAccounts,\n selectedAccount: lowerCaseSelectedAccount,\n allAccounts: lowerCaseAllAccounts,\n });\n\n if (result.balances && result.balances.length > 0) {\n aggregated.push(...result.balances);\n // Remove chains that were successfully processed\n const processedChains = new Set(\n result.balances.map((b) => b.chainId),\n );\n remainingChains = remainingChains.filter(\n (chain) => !processedChains.has(chain),\n );\n }\n\n // Add unprocessed chains back to remainingChains for next fetcher\n if (\n result.unprocessedChainIds &&\n result.unprocessedChainIds.length > 0\n ) {\n // Only add chains that were originally requested and aren't already in remainingChains\n const currentRemainingChains = remainingChains;\n const chainsToAdd = result.unprocessedChainIds.filter(\n (chainId) =>\n supportedChains.includes(chainId) &&\n !currentRemainingChains.includes(chainId),\n );\n remainingChains.push(...chainsToAdd);\n }\n } catch (error) {\n console.warn(\n `Balance fetcher failed for chains ${supportedChains.join(', ')}: ${String(error)}`,\n );\n // Continue to next fetcher (fallback)\n }\n\n // If all chains have been processed, break early\n if (remainingChains.length === 0) {\n break;\n }\n }\n\n // Build a _copy_ of the current state and track whether anything changed\n const nextAccountsByChainId: AccountTrackerControllerState['accountsByChainId'] =\n cloneDeep(this.state.accountsByChainId);\n let hasChanges = false;\n\n // Process the aggregated balance results\n const stakedBalancesByChainAndAddress: Record<\n string,\n Record<string, string>\n > = {};\n\n aggregated.forEach(({ success, value, account, token, chainId }) => {\n if (success && value !== undefined) {\n const checksumAddress = toChecksumHexAddress(account);\n const hexValue = `0x${value.toString(16)}`;\n\n if (token === ZERO_ADDRESS) {\n // Native balance\n // Ensure the account entry exists before accessing it\n if (!nextAccountsByChainId[chainId]) {\n nextAccountsByChainId[chainId] = {};\n }\n if (!nextAccountsByChainId[chainId][checksumAddress]) {\n nextAccountsByChainId[chainId][checksumAddress] = {\n balance: '0x0',\n };\n }\n\n if (\n nextAccountsByChainId[chainId][checksumAddress].balance !==\n hexValue\n ) {\n nextAccountsByChainId[chainId][checksumAddress].balance =\n hexValue;\n hasChanges = true;\n }\n } else if (\n STAKING_CONTRACT_ADDRESS_BY_CHAINID[chainId]?.toLowerCase() ===\n token.toLowerCase()\n ) {\n // Staked balance (from staking contract address)\n if (!stakedBalancesByChainAndAddress[chainId]) {\n stakedBalancesByChainAndAddress[chainId] = {};\n }\n stakedBalancesByChainAndAddress[chainId][checksumAddress] =\n hexValue;\n }\n }\n });\n\n // Apply staked balances\n Object.entries(stakedBalancesByChainAndAddress).forEach(\n ([chainId, balancesByAddress]) => {\n Object.entries(balancesByAddress).forEach(\n ([address, stakedBalance]) => {\n // Ensure account structure exists\n if (!nextAccountsByChainId[chainId]) {\n nextAccountsByChainId[chainId] = {};\n }\n if (!nextAccountsByChainId[chainId][address]) {\n nextAccountsByChainId[chainId][address] = { balance: '0x0' };\n }\n if (\n nextAccountsByChainId[chainId][address].stakedBalance !==\n stakedBalance\n ) {\n nextAccountsByChainId[chainId][address].stakedBalance =\n stakedBalance;\n hasChanges = true;\n }\n },\n );\n },\n );\n\n // Only update state if something changed\n if (hasChanges) {\n this.update((state) => {\n state.accountsByChainId = nextAccountsByChainId;\n });\n }\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Sync accounts balances with some additional addresses.\n *\n * @param addresses - the additional addresses, may be hardware wallet addresses.\n * @param networkClientId - Optional networkClientId to fetch a network client with.\n * @returns accounts - addresses with synced balance\n */\n async syncBalanceWithAddresses(\n addresses: string[],\n networkClientId?: NetworkClientId,\n ): Promise<\n Record<string, { balance: string; stakedBalance?: StakedBalance }>\n > {\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n return {};\n }\n // Skip balance fetching if locked or not onboarded to avoid unnecessary RPC calls\n if (!this.isActive) {\n return {};\n }\n\n const { ethQuery, chainId } =\n this.#getCorrectNetworkClient(networkClientId);\n\n // Skip native token fetching for chains that return arbitrary large numbers\n if (!shouldIncludeNativeToken(chainId)) {\n // Return empty balances for chains that skip native token fetching\n return addresses.reduce<\n Record<string, { balance: string; stakedBalance?: StakedBalance }>\n >((acc, address) => {\n acc[address] = { balance: '0x0' };\n return acc;\n }, {});\n }\n\n // TODO: This should use multicall when enabled by the user.\n return await Promise.all(\n addresses.map(\n (address): Promise<[string, string, StakedBalance] | undefined> => {\n return safelyExecuteWithTimeout(async () => {\n assert(ethQuery, 'Provider not set.');\n const balance = await query(ethQuery, 'getBalance', [address]);\n\n let stakedBalance: StakedBalance;\n if (this.#includeStakedAssets) {\n stakedBalance = (\n await this.#getStakedBalanceForChain([address], networkClientId)\n )[address];\n }\n return [address, balance, stakedBalance];\n });\n },\n ),\n ).then((value) => {\n return value.reduce((obj, item) => {\n if (!item) {\n return obj;\n }\n\n const [address, balance, stakedBalance] = item;\n return {\n ...obj,\n [address]: {\n balance,\n stakedBalance,\n },\n };\n }, {});\n });\n }\n\n /**\n * Updates the balances of multiple native tokens in a single batch operation.\n * This is more efficient than calling updateNativeToken multiple times as it\n * triggers only one state update.\n *\n * @param balances - Array of balance updates, each containing address, chainId, and balance.\n */\n updateNativeBalances(\n balances: { address: string; chainId: Hex; balance: Hex }[],\n ): void {\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n return;\n }\n const nextAccountsByChainId = cloneDeep(this.state.accountsByChainId);\n let hasChanges = false;\n\n balances.forEach(({ address, chainId, balance }) => {\n const checksumAddress = toChecksumHexAddress(address);\n\n // Ensure the chainId exists in the state\n if (!nextAccountsByChainId[chainId]) {\n nextAccountsByChainId[chainId] = {};\n hasChanges = true;\n }\n\n // Check if the address exists for this chain\n const accountExists = Boolean(\n nextAccountsByChainId[chainId][checksumAddress],\n );\n\n // Ensure the address exists for this chain\n if (!accountExists) {\n nextAccountsByChainId[chainId][checksumAddress] = {\n balance: '0x0',\n };\n hasChanges = true;\n }\n\n // Only update the balance if it has changed, or if this is a new account\n const currentBalance =\n nextAccountsByChainId[chainId][checksumAddress].balance;\n if (!accountExists || currentBalance !== balance) {\n nextAccountsByChainId[chainId][checksumAddress].balance = balance;\n hasChanges = true;\n }\n });\n\n // Only call update if there are actual changes\n if (hasChanges) {\n this.update((state) => {\n state.accountsByChainId = nextAccountsByChainId;\n });\n }\n }\n\n /**\n * Updates the staked balances of multiple accounts in a single batch operation.\n * This is more efficient than updating staked balances individually as it\n * triggers only one state update.\n *\n * @param stakedBalances - Array of staked balance updates, each containing address, chainId, and stakedBalance.\n */\n updateStakedBalances(\n stakedBalances: {\n address: string;\n chainId: Hex;\n stakedBalance: StakedBalance;\n }[],\n ): void {\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n return;\n }\n const nextAccountsByChainId = cloneDeep(this.state.accountsByChainId);\n let hasChanges = false;\n\n stakedBalances.forEach(({ address, chainId, stakedBalance }) => {\n const checksumAddress = toChecksumHexAddress(address);\n\n // Ensure the chainId exists in the state\n if (!nextAccountsByChainId[chainId]) {\n nextAccountsByChainId[chainId] = {};\n hasChanges = true;\n }\n\n // Check if the address exists for this chain\n const accountExists = Boolean(\n nextAccountsByChainId[chainId][checksumAddress],\n );\n\n // Ensure the address exists for this chain\n if (!accountExists) {\n nextAccountsByChainId[chainId][checksumAddress] = {\n balance: '0x0',\n };\n hasChanges = true;\n }\n\n // Only update the staked balance if it has changed, or if this is a new account\n const currentStakedBalance =\n nextAccountsByChainId[chainId][checksumAddress].stakedBalance;\n if (!accountExists || !isEqual(currentStakedBalance, stakedBalance)) {\n nextAccountsByChainId[chainId][checksumAddress].stakedBalance =\n stakedBalance;\n hasChanges = true;\n }\n });\n\n // Only call update if there are actual changes\n if (hasChanges) {\n this.update((state) => {\n state.accountsByChainId = nextAccountsByChainId;\n });\n }\n }\n}\n\nexport default AccountTrackerController;\n"]}
|
|
1
|
+
{"version":3,"file":"AccountTrackerController.js","sourceRoot":"","sources":["../src/AccountTrackerController.ts"],"names":[],"mappings":"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","sourcesContent":["import { Web3Provider } from '@ethersproject/providers';\nimport type {\n AccountsControllerSelectedEvmAccountChangeEvent,\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerListAccountsAction,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerStateChangeEvent,\n ControllerGetStateAction,\n StateMetadata,\n} from '@metamask/base-controller';\nimport {\n query,\n safelyExecuteWithTimeout,\n toChecksumHexAddress,\n} from '@metamask/controller-utils';\nimport EthQuery from '@metamask/eth-query';\nimport type {\n KeyringControllerGetStateAction,\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { Messenger } from '@metamask/messenger';\nimport type {\n NetworkClient,\n NetworkClientId,\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n NetworkControllerNetworkAddedEvent,\n} from '@metamask/network-controller';\nimport type {\n NetworkEnablementControllerGetStateAction,\n NetworkEnablementControllerListPopularEvmNetworksAction,\n} from '@metamask/network-enablement-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type {\n TransactionControllerTransactionConfirmedEvent,\n TransactionControllerUnapprovedTransactionAddedEvent,\n TransactionMeta,\n} from '@metamask/transaction-controller';\nimport { assert, KnownCaipNamespace } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport { cloneDeep, isEqual } from 'lodash-es';\n\nimport type { AccountTrackerControllerMethodActions } from './AccountTrackerController-method-action-types.js';\nimport { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from './AssetsContractController.js';\nimport type {\n AssetsContractController,\n StakedBalance,\n} from './AssetsContractController.js';\nimport { shouldIncludeNativeToken } from './constants.js';\nimport { AccountsApiBalanceFetcher } from './multi-chain-accounts-service/api-balance-fetcher.js';\nimport type {\n BalanceFetcher,\n BalanceFetchResult,\n ProcessedBalance,\n} from './multi-chain-accounts-service/api-balance-fetcher.js';\nimport { RpcBalanceFetcher } from './rpc-service/rpc-balance-fetcher.js';\n\n/**\n * The name of the {@link AccountTrackerController}.\n */\nconst controllerName = 'AccountTrackerController';\n\nexport type ChainIdHex = Hex;\nexport type ChecksumAddress = Hex;\n\nconst ZERO_ADDRESS =\n '0x0000000000000000000000000000000000000000' as ChecksumAddress;\n\n/**\n * Creates an RPC balance fetcher configured for AccountTracker use case.\n * Returns only native balances and staked balances (no token balances).\n *\n * @param getProvider - Function to get Web3Provider for a given chain ID\n * @param getNetworkClient - Function to get NetworkClient for a given chain ID\n * @param includeStakedAssets - Whether to include staked assets in the fetch\n * @returns BalanceFetcher configured to fetch only native and optionally staked balances\n */\nfunction createAccountTrackerRpcBalanceFetcher(\n getProvider: (chainId: Hex) => Web3Provider,\n getNetworkClient: (chainId: Hex) => NetworkClient,\n includeStakedAssets: boolean,\n): BalanceFetcher {\n // Provide empty tokens state to ensure only native and staked balances are fetched\n const getEmptyTokensState = (): {\n allTokens: Record<string, never>;\n allDetectedTokens: Record<string, never>;\n } => ({\n allTokens: {},\n allDetectedTokens: {},\n });\n\n const rpcBalanceFetcher = new RpcBalanceFetcher(\n getProvider,\n getNetworkClient,\n getEmptyTokensState,\n );\n\n // Wrap the RpcBalanceFetcher to filter staked balances when not needed\n return {\n supports(_chainId: ChainIdHex): boolean {\n return rpcBalanceFetcher.supports();\n },\n\n async fetch(\n params: Parameters<BalanceFetcher['fetch']>[0],\n ): Promise<BalanceFetchResult> {\n const result = await rpcBalanceFetcher.fetch(params);\n\n if (!includeStakedAssets) {\n // Filter out staked balances from the results\n return {\n balances: result.balances.filter(\n (balance) => balance.token === ZERO_ADDRESS,\n ),\n unprocessedChainIds: result.unprocessedChainIds,\n };\n }\n\n return result;\n },\n };\n}\n\n/**\n * AccountInformation\n *\n * Account information object\n *\n * balance - Hex string of an account balance in wei\n *\n * stakedBalance - Hex string of an account staked balance in wei\n */\nexport type AccountInformation = {\n balance: string;\n stakedBalance?: string;\n};\n\n/**\n * AccountTrackerControllerState\n *\n * Account tracker controller state\n *\n * accountsByChainId - Map of addresses to account information by chain\n */\nexport type AccountTrackerControllerState = {\n accountsByChainId: Record<string, { [address: string]: AccountInformation }>;\n};\n\nconst accountTrackerMetadata: StateMetadata<AccountTrackerControllerState> = {\n accountsByChainId: {\n includeInStateLogs: false,\n persist: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n};\n\n/**\n * The action that can be performed to get the state of the {@link AccountTrackerController}.\n */\nexport type AccountTrackerControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AccountTrackerControllerState\n>;\n\n/**\n * The actions that can be performed using the {@link AccountTrackerController}.\n */\nexport type AccountTrackerControllerActions =\n | AccountTrackerControllerGetStateAction\n | AccountTrackerControllerMethodActions;\n\n/**\n * The messenger of the {@link AccountTrackerController} for communication.\n */\nexport type AllowedActions =\n | AccountsControllerListAccountsAction\n | {\n type: 'PreferencesController:getState';\n handler: () => { isMultiAccountBalancesEnabled: boolean };\n }\n | AccountsControllerGetSelectedAccountAction\n | NetworkControllerGetStateAction\n | NetworkControllerGetNetworkClientByIdAction\n | NetworkEnablementControllerGetStateAction\n | NetworkEnablementControllerListPopularEvmNetworksAction\n | KeyringControllerGetStateAction;\n\n/**\n * The event that {@link AccountTrackerController} can emit.\n */\nexport type AccountTrackerControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n AccountTrackerControllerState\n >;\n\n/**\n * The events that {@link AccountTrackerController} can emit.\n */\nexport type AccountTrackerControllerEvents =\n AccountTrackerControllerStateChangeEvent;\n\n/**\n * The external events available to the {@link AccountTrackerController}.\n */\nexport type AllowedEvents =\n | AccountsControllerSelectedEvmAccountChangeEvent\n | TransactionControllerUnapprovedTransactionAddedEvent\n | TransactionControllerTransactionConfirmedEvent\n | NetworkControllerNetworkAddedEvent\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent;\n\n/**\n * The messenger of the {@link AccountTrackerController}.\n */\nexport type AccountTrackerControllerMessenger = Messenger<\n typeof controllerName,\n AccountTrackerControllerActions | AllowedActions,\n AccountTrackerControllerEvents | AllowedEvents\n>;\n\n/** The input to start polling for the {@link AccountTrackerController} */\ntype AccountTrackerPollingInput = {\n networkClientIds: NetworkClientId[];\n queryAllAccounts?: boolean;\n};\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'updateNativeBalances',\n 'updateStakedBalances',\n 'refresh',\n 'syncBalanceWithAddresses',\n] as const;\n\n/**\n * Controller that tracks the network balances for all user accounts.\n */\nexport class AccountTrackerController extends StaticIntervalPollingController<AccountTrackerPollingInput>()<\n typeof controllerName,\n AccountTrackerControllerState,\n AccountTrackerControllerMessenger\n> {\n readonly #refreshMutex = new Mutex();\n\n readonly #includeStakedAssets: boolean;\n\n readonly #accountsApiChainIds: () => ChainIdHex[];\n\n readonly #getStakedBalanceForChain: AssetsContractController['getStakedBalanceForChain'];\n\n readonly #balanceFetchers: BalanceFetcher[];\n\n readonly #fetchingEnabled: () => boolean;\n\n readonly #isOnboarded: () => boolean;\n\n readonly #isHomepageSectionsV1Enabled: () => boolean;\n\n readonly #isDeprecated: () => boolean;\n\n /** Track if the keyring is locked */\n #isLocked = true;\n\n readonly #seedSelectedChain: boolean;\n\n #initialized = false;\n\n /**\n * Creates an AccountTracker instance.\n *\n * @param options - The controller options.\n * @param options.interval - Polling interval used to fetch new account balances.\n * @param options.state - Initial state to set on this controller.\n * @param options.messenger - The controller messenger.\n * @param options.getStakedBalanceForChain - The function to get the staked native asset balance for a chain.\n * @param options.includeStakedAssets - Whether to include staked assets in the account balances.\n * @param options.accountsApiChainIds - Function that returns array of chainIds that should use Accounts-API strategy (if supported by API).\n * @param options.allowExternalServices - Disable external HTTP calls (privacy / offline mode).\n * @param options.fetchingEnabled - Function that returns whether the controller is fetching enabled.\n * @param options.isOnboarded - Whether the user has completed onboarding. If false, balance updates are skipped.\n * @param options.isHomepageSectionsV1Enabled - Whether the homepage sections v1 is enabled.\n * @param options.isDeprecated - Optional function that returns true to completely\n * disable this controller (no requests, no state updates). When it returns\n * `true`, `accountsByChainId` is reset to `{}` at construction and at every\n * entry point, so no stale balances remain in state. The function is evaluated\n * dynamically on each entry point so it can be toggled at runtime. Intended for\n * use when a higher-level controller (e.g. AssetsController) supersedes this one.\n */\n constructor({\n interval = 10000,\n state,\n messenger,\n getStakedBalanceForChain,\n includeStakedAssets = false,\n accountsApiChainIds = (): ChainIdHex[] => [],\n allowExternalServices = (): boolean => true,\n fetchingEnabled = (): boolean => true,\n isOnboarded = (): boolean => true,\n isHomepageSectionsV1Enabled = (): boolean => false,\n isDeprecated = (): boolean => false,\n }: {\n interval?: number;\n state?: Partial<AccountTrackerControllerState>;\n messenger: AccountTrackerControllerMessenger;\n getStakedBalanceForChain: AssetsContractController['getStakedBalanceForChain'];\n includeStakedAssets?: boolean;\n accountsApiChainIds?: () => ChainIdHex[];\n isHomepageSectionsV1Enabled?: () => boolean;\n allowExternalServices?: () => boolean;\n fetchingEnabled?: () => boolean;\n isOnboarded?: () => boolean;\n isDeprecated?: () => boolean;\n }) {\n super({\n name: controllerName,\n messenger,\n state: {\n accountsByChainId: {},\n ...state,\n },\n metadata: accountTrackerMetadata,\n });\n this.#seedSelectedChain = state?.accountsByChainId === undefined;\n this.#getStakedBalanceForChain = getStakedBalanceForChain;\n\n this.#includeStakedAssets = includeStakedAssets;\n this.#accountsApiChainIds = accountsApiChainIds;\n this.#isHomepageSectionsV1Enabled = isHomepageSectionsV1Enabled;\n\n // Initialize balance fetchers - Strategy order: API first, then RPC fallback\n this.#balanceFetchers = [\n ...(accountsApiChainIds().length > 0 && allowExternalServices()\n ? [this.#createAccountsApiFetcher()]\n : []),\n createAccountTrackerRpcBalanceFetcher(\n this.#getProvider,\n this.#getNetworkClient,\n this.#includeStakedAssets,\n ),\n ];\n\n this.#fetchingEnabled = fetchingEnabled;\n this.#isOnboarded = isOnboarded;\n this.#isDeprecated = isDeprecated;\n\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n }\n\n this.setIntervalLength(interval);\n\n this.messenger.subscribe(\n 'AccountsController:selectedEvmAccountChange',\n (newAddress, prevAddress) => {\n if (newAddress !== prevAddress) {\n // Making an async call for this new event\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.refresh(this.#getNetworkClientIds());\n }\n },\n (event): string => event.address,\n );\n\n this.messenger.subscribe(\n 'NetworkController:networkAdded',\n (networkConfiguration) => {\n const { networkClientId } =\n networkConfiguration.rpcEndpoints[\n networkConfiguration.defaultRpcEndpointIndex\n ];\n this.refresh([networkClientId]).catch(() => {\n // Silently handle refresh errors\n });\n },\n );\n\n this.messenger.subscribe('KeyringController:unlock', () => {\n this.#isLocked = false;\n const networkClientIds = this.#getNetworkClientIds();\n this.refresh(networkClientIds).catch((error) => {\n console.error('Error refreshing balances after keyring unlock:', error);\n });\n });\n\n this.messenger.subscribe('KeyringController:lock', () => {\n this.#isLocked = true;\n });\n\n this.messenger.subscribe(\n 'TransactionController:unapprovedTransactionAdded',\n (transactionMeta: TransactionMeta) => {\n const addresses = [transactionMeta.txParams.from];\n if (transactionMeta.txParams.to) {\n addresses.push(transactionMeta.txParams.to);\n }\n this.refreshAddresses({\n networkClientIds: [transactionMeta.networkClientId],\n addresses,\n }).catch(() => {\n // Silently handle refresh errors\n });\n },\n );\n\n this.messenger.subscribe(\n 'TransactionController:transactionConfirmed',\n (transactionMeta: TransactionMeta) => {\n const addresses = [transactionMeta.txParams.from];\n if (transactionMeta.txParams.to) {\n addresses.push(transactionMeta.txParams.to);\n }\n this.refreshAddresses({\n networkClientIds: [transactionMeta.networkClientId],\n addresses,\n }).catch(() => {\n // Silently handle refresh errors\n });\n },\n );\n\n messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);\n }\n\n /**\n * Complete initialization once the controllers this controller reads from\n * have been constructed: read the lock state from `KeyringController` and,\n * when no `accountsByChainId` state was provided, add an empty entry for the\n * chain of the selected network.\n *\n * The constructor does not call other controllers, so it can run before they\n * are constructed. Until this is called, the controller treats the keyring as\n * locked. Calling it more than once has no effect.\n */\n init(): void {\n if (this.#initialized) {\n return;\n }\n this.#initialized = true;\n\n const { isUnlocked } = this.messenger.call('KeyringController:getState');\n this.#isLocked = !isUnlocked;\n\n if (!this.#seedSelectedChain || this.#isDeprecated()) {\n return;\n }\n\n const { selectedNetworkClientId } = this.messenger.call(\n 'NetworkController:getState',\n );\n const {\n configuration: { chainId },\n } = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n if (this.state.accountsByChainId[chainId] === undefined) {\n this.update((state) => {\n state.accountsByChainId[chainId] = {};\n });\n }\n }\n\n /**\n * Whether the controller is active (keyring is unlocked and user is onboarded).\n * When locked or not onboarded, balance updates should be skipped.\n *\n * @returns Whether the controller should perform balance updates.\n */\n get isActive(): boolean {\n return !this.#isLocked && this.#isOnboarded();\n }\n\n /**\n * Clears all persisted `accountsByChainId` so that no stale balances remain in\n * state.\n *\n * Called from every entry point when `isDeprecated()` is true so that a runtime\n * toggle propagates to state immediately, even if the controller was originally\n * constructed while it was enabled. The update is skipped when\n * `accountsByChainId` is already empty to avoid emitting redundant state\n * changes.\n */\n #enforceDisabledState(): void {\n if (Object.keys(this.state.accountsByChainId).length === 0) {\n return;\n }\n this.update((state) => {\n state.accountsByChainId = {};\n });\n }\n\n #syncAccounts(newChainIds: string[]): void {\n const accountsByChainId = cloneDeep(this.state.accountsByChainId);\n const { selectedNetworkClientId } = this.messenger.call(\n 'NetworkController:getState',\n );\n const {\n configuration: { chainId: currentChainId },\n } = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n\n const existing = Object.keys(accountsByChainId?.[currentChainId] ?? {});\n\n // Initialize new chain IDs if they don't exist\n newChainIds.forEach((newChainId) => {\n if (!accountsByChainId[newChainId]) {\n accountsByChainId[newChainId] = {};\n existing.forEach((address) => {\n accountsByChainId[newChainId][address] = { balance: '0x0' };\n });\n }\n });\n\n // Note: The address from the preferences controller are checksummed\n // The addresses from the accounts controller are lowercased\n const addresses = Object.values(\n this.messenger\n .call('AccountsController:listAccounts')\n .map((internalAccount) =>\n toChecksumHexAddress(internalAccount.address),\n ),\n );\n const newAddresses = addresses.filter(\n (address) => !existing.includes(address),\n );\n const oldAddresses = existing.filter(\n (address) => !addresses.includes(address),\n );\n Object.keys(accountsByChainId).forEach((chainId) => {\n newAddresses.forEach((address) => {\n if (!accountsByChainId[chainId][address]) {\n accountsByChainId[chainId][address] = {\n balance: '0x0',\n };\n }\n });\n });\n\n Object.keys(accountsByChainId).forEach((chainId) => {\n oldAddresses.forEach((address) => {\n delete accountsByChainId[chainId][address];\n });\n });\n\n if (!isEqual(this.state.accountsByChainId, accountsByChainId)) {\n this.update((state) => {\n state.accountsByChainId = accountsByChainId;\n });\n }\n }\n\n readonly #getProvider = (chainId: Hex): Web3Provider => {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n const networkConfig = networkConfigurationsByChainId[chainId];\n const { networkClientId } =\n networkConfig.rpcEndpoints[networkConfig.defaultRpcEndpointIndex];\n const client = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n return new Web3Provider(client.provider);\n };\n\n readonly #getNetworkClient = (chainId: Hex): NetworkClient => {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n const networkConfig = networkConfigurationsByChainId[chainId];\n const { networkClientId } =\n networkConfig.rpcEndpoints[networkConfig.defaultRpcEndpointIndex];\n return this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n };\n\n /**\n * Creates an AccountsApiBalanceFetcher that only supports chains in the accountsApiChainIds array\n *\n * @returns A BalanceFetcher that wraps AccountsApiBalanceFetcher with chainId filtering\n */\n readonly #createAccountsApiFetcher = (): BalanceFetcher => {\n const originalFetcher = new AccountsApiBalanceFetcher(\n 'extension',\n this.#getProvider,\n );\n\n return {\n supports: (chainId: ChainIdHex): boolean => {\n // Only support chains that are both:\n // 1. In our specified accountsApiChainIds array\n // 2. Actually supported by the AccountsApi\n return (\n this.#accountsApiChainIds().includes(chainId) &&\n originalFetcher.supports(chainId)\n );\n },\n fetch: originalFetcher.fetch.bind(originalFetcher),\n };\n };\n\n /**\n * Resolves a networkClientId to a network client config\n * or globally selected network config if not provided\n *\n * @param networkClientId - Optional networkClientId to fetch a network client with\n * @returns network client config\n */\n #getCorrectNetworkClient(networkClientId?: NetworkClientId): {\n chainId: Hex;\n provider: NetworkClient['provider'];\n ethQuery: EthQuery;\n blockTracker: NetworkClient['blockTracker'];\n } {\n const selectedNetworkClientId =\n networkClientId ??\n this.messenger.call('NetworkController:getState').selectedNetworkClientId;\n const {\n configuration: { chainId },\n provider,\n blockTracker,\n } = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n\n return {\n chainId,\n provider,\n ethQuery: new EthQuery(provider),\n blockTracker,\n };\n }\n\n /**\n * Retrieves the list of network client IDs.\n *\n * @returns An array of network client IDs.\n */\n #getNetworkClientIds(): NetworkClientId[] {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n\n if (this.#isHomepageSectionsV1Enabled()) {\n const popularEvmChainIds = this.messenger.call(\n 'NetworkEnablementController:listPopularEvmNetworks',\n );\n return popularEvmChainIds\n .map((hexChainId) => {\n const networkConfig = networkConfigurationsByChainId[hexChainId];\n return networkConfig?.rpcEndpoints[\n networkConfig.defaultRpcEndpointIndex\n ]?.networkClientId;\n })\n .filter((id): id is NetworkClientId => id !== undefined);\n }\n\n const { enabledNetworkMap } = this.messenger.call(\n 'NetworkEnablementController:getState',\n );\n\n const evmEnabledStorageKeys = enabledNetworkMap[KnownCaipNamespace.Eip155]\n ? Object.keys(enabledNetworkMap[KnownCaipNamespace.Eip155])\n : [];\n\n return evmEnabledStorageKeys\n .map((hexChainId) => {\n const networkConfig = networkConfigurationsByChainId[hexChainId as Hex];\n return networkConfig?.rpcEndpoints[\n networkConfig.defaultRpcEndpointIndex\n ]?.networkClientId;\n })\n .filter((id): id is NetworkClientId => id !== undefined);\n }\n\n /**\n * Refreshes the balances of the accounts using the networkClientId\n *\n * @param input - The input for the poll.\n * @param input.networkClientIds - The network client IDs used to get balances.\n * @param input.queryAllAccounts - Whether to query all accounts or just the selected account\n */\n async _executePoll({\n networkClientIds,\n queryAllAccounts = false,\n }: AccountTrackerPollingInput): Promise<void> {\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n return;\n }\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.refresh(networkClientIds, queryAllAccounts);\n }\n\n /**\n * Refreshes the balances of the accounts depending on the multi-account setting.\n * If multi-account is disabled, only updates the selected account balance.\n * If multi-account is enabled, updates balances for all accounts.\n *\n * @param networkClientIds - Optional network client IDs to fetch a network client with\n * @param queryAllAccounts - Whether to query all accounts or just the selected account\n */\n async refresh(\n networkClientIds: NetworkClientId[],\n queryAllAccounts: boolean = false,\n ): Promise<void> {\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n return;\n }\n const selectedAccount = this.messenger.call(\n 'AccountsController:getSelectedAccount',\n );\n const allAccounts = this.messenger.call('AccountsController:listAccounts');\n const { isMultiAccountBalancesEnabled } = this.messenger.call(\n 'PreferencesController:getState',\n );\n\n await this.#refreshAccounts({\n networkClientIds,\n queryAllAccounts: queryAllAccounts ?? isMultiAccountBalancesEnabled,\n selectedAccount: toChecksumHexAddress(\n selectedAccount.address,\n ) as ChecksumAddress,\n allAccounts,\n });\n }\n\n async refreshAddresses({\n networkClientIds,\n addresses,\n }: {\n networkClientIds: NetworkClientId[];\n addresses: string[];\n }): Promise<void> {\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n return;\n }\n const checksummedAddresses = addresses.map((address) =>\n toChecksumHexAddress(address),\n );\n\n const accounts = this.messenger\n .call('AccountsController:listAccounts')\n .filter((account) =>\n checksummedAddresses.includes(toChecksumHexAddress(account.address)),\n );\n\n await this.#refreshAccounts({\n networkClientIds,\n queryAllAccounts: true,\n selectedAccount: '0x0',\n allAccounts: accounts,\n });\n }\n\n async #refreshAccounts({\n networkClientIds,\n queryAllAccounts,\n selectedAccount,\n allAccounts,\n }: {\n networkClientIds: NetworkClientId[];\n queryAllAccounts: boolean;\n selectedAccount: ChecksumAddress;\n allAccounts: InternalAccount[];\n }): Promise<void> {\n const releaseLock = await this.#refreshMutex.acquire();\n try {\n const chainIds = networkClientIds.map((networkClientId) => {\n const { chainId } = this.#getCorrectNetworkClient(networkClientId);\n return chainId;\n });\n\n this.#syncAccounts(chainIds);\n\n if (!this.#fetchingEnabled() || !this.isActive) {\n return;\n }\n\n // Use balance fetchers with fallback strategy\n const aggregated: ProcessedBalance[] = [];\n let remainingChains = [...chainIds] as ChainIdHex[];\n\n // Temporary normalization to lowercase for balance fetching to match TokenBalancesController and enable HTTP caching\n const lowerCaseSelectedAccount =\n selectedAccount.toLowerCase() as ChecksumAddress;\n const lowerCaseAllAccounts = allAccounts.map((account) => ({\n ...account,\n address: account.address.toLowerCase(),\n }));\n\n // Try each fetcher in order, removing successfully processed chains\n for (const fetcher of this.#balanceFetchers) {\n const supportedChains = remainingChains.filter((chainId) =>\n fetcher.supports(chainId),\n );\n if (!supportedChains.length) {\n continue;\n }\n\n try {\n const result = await fetcher.fetch({\n chainIds: supportedChains,\n queryAllAccounts,\n selectedAccount: lowerCaseSelectedAccount,\n allAccounts: lowerCaseAllAccounts,\n });\n\n if (result.balances && result.balances.length > 0) {\n aggregated.push(...result.balances);\n // Remove chains that were successfully processed\n const processedChains = new Set(\n result.balances.map((b) => b.chainId),\n );\n remainingChains = remainingChains.filter(\n (chain) => !processedChains.has(chain),\n );\n }\n\n // Add unprocessed chains back to remainingChains for next fetcher\n if (\n result.unprocessedChainIds &&\n result.unprocessedChainIds.length > 0\n ) {\n // Only add chains that were originally requested and aren't already in remainingChains\n const currentRemainingChains = remainingChains;\n const chainsToAdd = result.unprocessedChainIds.filter(\n (chainId) =>\n supportedChains.includes(chainId) &&\n !currentRemainingChains.includes(chainId),\n );\n remainingChains.push(...chainsToAdd);\n }\n } catch (error) {\n console.warn(\n `Balance fetcher failed for chains ${supportedChains.join(', ')}: ${String(error)}`,\n );\n // Continue to next fetcher (fallback)\n }\n\n // If all chains have been processed, break early\n if (remainingChains.length === 0) {\n break;\n }\n }\n\n // Build a _copy_ of the current state and track whether anything changed\n const nextAccountsByChainId: AccountTrackerControllerState['accountsByChainId'] =\n cloneDeep(this.state.accountsByChainId);\n let hasChanges = false;\n\n // Process the aggregated balance results\n const stakedBalancesByChainAndAddress: Record<\n string,\n Record<string, string>\n > = {};\n\n aggregated.forEach(({ success, value, account, token, chainId }) => {\n if (success && value !== undefined) {\n const checksumAddress = toChecksumHexAddress(account);\n const hexValue = `0x${value.toString(16)}`;\n\n if (token === ZERO_ADDRESS) {\n // Native balance\n // Ensure the account entry exists before accessing it\n if (!nextAccountsByChainId[chainId]) {\n nextAccountsByChainId[chainId] = {};\n }\n if (!nextAccountsByChainId[chainId][checksumAddress]) {\n nextAccountsByChainId[chainId][checksumAddress] = {\n balance: '0x0',\n };\n }\n\n if (\n nextAccountsByChainId[chainId][checksumAddress].balance !==\n hexValue\n ) {\n nextAccountsByChainId[chainId][checksumAddress].balance =\n hexValue;\n hasChanges = true;\n }\n } else if (\n STAKING_CONTRACT_ADDRESS_BY_CHAINID[chainId]?.toLowerCase() ===\n token.toLowerCase()\n ) {\n // Staked balance (from staking contract address)\n if (!stakedBalancesByChainAndAddress[chainId]) {\n stakedBalancesByChainAndAddress[chainId] = {};\n }\n stakedBalancesByChainAndAddress[chainId][checksumAddress] =\n hexValue;\n }\n }\n });\n\n // Apply staked balances\n Object.entries(stakedBalancesByChainAndAddress).forEach(\n ([chainId, balancesByAddress]) => {\n Object.entries(balancesByAddress).forEach(\n ([address, stakedBalance]) => {\n // Ensure account structure exists\n if (!nextAccountsByChainId[chainId]) {\n nextAccountsByChainId[chainId] = {};\n }\n if (!nextAccountsByChainId[chainId][address]) {\n nextAccountsByChainId[chainId][address] = { balance: '0x0' };\n }\n if (\n nextAccountsByChainId[chainId][address].stakedBalance !==\n stakedBalance\n ) {\n nextAccountsByChainId[chainId][address].stakedBalance =\n stakedBalance;\n hasChanges = true;\n }\n },\n );\n },\n );\n\n // Only update state if something changed\n if (hasChanges) {\n this.update((state) => {\n state.accountsByChainId = nextAccountsByChainId;\n });\n }\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Sync accounts balances with some additional addresses.\n *\n * @param addresses - the additional addresses, may be hardware wallet addresses.\n * @param networkClientId - Optional networkClientId to fetch a network client with.\n * @returns accounts - addresses with synced balance\n */\n async syncBalanceWithAddresses(\n addresses: string[],\n networkClientId?: NetworkClientId,\n ): Promise<\n Record<string, { balance: string; stakedBalance?: StakedBalance }>\n > {\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n return {};\n }\n // Skip balance fetching if locked or not onboarded to avoid unnecessary RPC calls\n if (!this.isActive) {\n return {};\n }\n\n const { ethQuery, chainId } =\n this.#getCorrectNetworkClient(networkClientId);\n\n // Skip native token fetching for chains that return arbitrary large numbers\n if (!shouldIncludeNativeToken(chainId)) {\n // Return empty balances for chains that skip native token fetching\n return addresses.reduce<\n Record<string, { balance: string; stakedBalance?: StakedBalance }>\n >((acc, address) => {\n acc[address] = { balance: '0x0' };\n return acc;\n }, {});\n }\n\n // TODO: This should use multicall when enabled by the user.\n return await Promise.all(\n addresses.map(\n (address): Promise<[string, string, StakedBalance] | undefined> => {\n return safelyExecuteWithTimeout(async () => {\n assert(ethQuery, 'Provider not set.');\n const balance = await query(ethQuery, 'getBalance', [address]);\n\n let stakedBalance: StakedBalance;\n if (this.#includeStakedAssets) {\n stakedBalance = (\n await this.#getStakedBalanceForChain([address], networkClientId)\n )[address];\n }\n return [address, balance, stakedBalance];\n });\n },\n ),\n ).then((value) => {\n return value.reduce((obj, item) => {\n if (!item) {\n return obj;\n }\n\n const [address, balance, stakedBalance] = item;\n return {\n ...obj,\n [address]: {\n balance,\n stakedBalance,\n },\n };\n }, {});\n });\n }\n\n /**\n * Updates the balances of multiple native tokens in a single batch operation.\n * This is more efficient than calling updateNativeToken multiple times as it\n * triggers only one state update.\n *\n * @param balances - Array of balance updates, each containing address, chainId, and balance.\n */\n updateNativeBalances(\n balances: { address: string; chainId: Hex; balance: Hex }[],\n ): void {\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n return;\n }\n const nextAccountsByChainId = cloneDeep(this.state.accountsByChainId);\n let hasChanges = false;\n\n balances.forEach(({ address, chainId, balance }) => {\n const checksumAddress = toChecksumHexAddress(address);\n\n // Ensure the chainId exists in the state\n if (!nextAccountsByChainId[chainId]) {\n nextAccountsByChainId[chainId] = {};\n hasChanges = true;\n }\n\n // Check if the address exists for this chain\n const accountExists = Boolean(\n nextAccountsByChainId[chainId][checksumAddress],\n );\n\n // Ensure the address exists for this chain\n if (!accountExists) {\n nextAccountsByChainId[chainId][checksumAddress] = {\n balance: '0x0',\n };\n hasChanges = true;\n }\n\n // Only update the balance if it has changed, or if this is a new account\n const currentBalance =\n nextAccountsByChainId[chainId][checksumAddress].balance;\n if (!accountExists || currentBalance !== balance) {\n nextAccountsByChainId[chainId][checksumAddress].balance = balance;\n hasChanges = true;\n }\n });\n\n // Only call update if there are actual changes\n if (hasChanges) {\n this.update((state) => {\n state.accountsByChainId = nextAccountsByChainId;\n });\n }\n }\n\n /**\n * Updates the staked balances of multiple accounts in a single batch operation.\n * This is more efficient than updating staked balances individually as it\n * triggers only one state update.\n *\n * @param stakedBalances - Array of staked balance updates, each containing address, chainId, and stakedBalance.\n */\n updateStakedBalances(\n stakedBalances: {\n address: string;\n chainId: Hex;\n stakedBalance: StakedBalance;\n }[],\n ): void {\n if (this.#isDeprecated()) {\n this.#enforceDisabledState();\n return;\n }\n const nextAccountsByChainId = cloneDeep(this.state.accountsByChainId);\n let hasChanges = false;\n\n stakedBalances.forEach(({ address, chainId, stakedBalance }) => {\n const checksumAddress = toChecksumHexAddress(address);\n\n // Ensure the chainId exists in the state\n if (!nextAccountsByChainId[chainId]) {\n nextAccountsByChainId[chainId] = {};\n hasChanges = true;\n }\n\n // Check if the address exists for this chain\n const accountExists = Boolean(\n nextAccountsByChainId[chainId][checksumAddress],\n );\n\n // Ensure the address exists for this chain\n if (!accountExists) {\n nextAccountsByChainId[chainId][checksumAddress] = {\n balance: '0x0',\n };\n hasChanges = true;\n }\n\n // Only update the staked balance if it has changed, or if this is a new account\n const currentStakedBalance =\n nextAccountsByChainId[chainId][checksumAddress].stakedBalance;\n if (!accountExists || !isEqual(currentStakedBalance, stakedBalance)) {\n nextAccountsByChainId[chainId][checksumAddress].stakedBalance =\n stakedBalance;\n hasChanges = true;\n }\n });\n\n // Only call update if there are actual changes\n if (hasChanges) {\n this.update((state) => {\n state.accountsByChainId = nextAccountsByChainId;\n });\n }\n }\n}\n\nexport default AccountTrackerController;\n"]}
|
|
@@ -89,6 +89,16 @@ export declare class MultichainAssetsController extends MultichainAssetsControll
|
|
|
89
89
|
blockaidTokenRescanInterval?: number;
|
|
90
90
|
isDeprecated?: () => boolean;
|
|
91
91
|
});
|
|
92
|
+
/**
|
|
93
|
+
* Complete initialization once the controllers this controller reads from
|
|
94
|
+
* have been constructed: start the periodic Blockaid re-scan of stored
|
|
95
|
+
* tokens, unless it is disabled.
|
|
96
|
+
*
|
|
97
|
+
* The constructor does not call other controllers or start polling, so it
|
|
98
|
+
* can run before they are constructed. Calling it more than once has no
|
|
99
|
+
* effect.
|
|
100
|
+
*/
|
|
101
|
+
init(): void;
|
|
92
102
|
_executePoll(_input: null): Promise<void>;
|
|
93
103
|
/**
|
|
94
104
|
* Returns the metadata for the given asset
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultichainAssetsController.d.ts","sourceRoot":"","sources":["../../src/MultichainAssetsController/MultichainAssetsController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mCAAmC,EACnC,8CAA8C,EAC9C,qCAAqC,EACrC,8CAA8C,EAC/C,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAE3B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,KAAK,EAEV,aAAa,EAEd,MAAM,uBAAuB,CAAC;AAG/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAEV,sCAAsC,EACvC,MAAM,+BAA+B,CAAC;AAGvC,OAAO,KAAK,EACV,oCAAoC,EACpC,iCAAiC,EAClC,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,qBAAqB,EAAgB,MAAM,qBAAqB,CAAC;AAQ/E,OAAO,KAAK,EAAE,uCAAuC,EAAE,MAAM,qDAAqD,CAAC;AAGnH,QAAA,MAAM,cAAc,+BAA+B,CAAC;AAEpD,MAAM,MAAM,+BAA+B,GAAG;IAC5C,cAAc,EAAE;QACd,CAAC,KAAK,EAAE,aAAa,GAAG,qBAAqB,CAAC;KAC/C,CAAC;IACF,cAAc,EAAE;QAAE,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAAA;KAAE,CAAC;IACvD,gBAAgB,EAAE;QAAE,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAAA;KAAE,CAAC;CAC1D,CAAC;AAGF,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE;QACN,CAAC,KAAK,EAAE,aAAa,GAAG,qBAAqB,CAAC;KAC/C,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,sDAAsD,GAAG;IACnE,IAAI,EAAE,GAAG,OAAO,cAAc,0BAA0B,CAAC;IACzD,OAAO,EAAE,8CAA8C,CAAC,SAAS,CAAC,CAAC;CACpE,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,yCAAyC,IAAI,+BAA+B,CAE3F;AAED;;GAEG;AACH,MAAM,MAAM,wCAAwC,GAAG,wBAAwB,CAC7E,OAAO,cAAc,EACrB,+BAA+B,CAChC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,0CAA0C,GACpD,0BAA0B,CACxB,OAAO,cAAc,EACrB,+BAA+B,CAChC,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,iCAAiC,GACzC,wCAAwC,GACxC,uCAAuC,CAAC;AAE5C;;GAEG;AACH,MAAM,MAAM,gCAAgC,GACxC,0CAA0C,GAC1C,sDAAsD,CAAC;AAc3D;;GAEG;AACH,KAAK,cAAc,GACf,oCAAoC,GACpC,iCAAiC,GACjC,cAAc,GACd,8CAA8C,GAC9C,sCAAsC,CAAC;AAE3C;;GAEG;AACH,KAAK,aAAa,GACd,mCAAmC,GACnC,qCAAqC,GACrC,8CAA8C,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,mCAAmC,GAAG,SAAS,CACzD,OAAO,cAAc,EACrB,iCAAiC,GAAG,cAAc,EAClD,gCAAgC,GAAG,aAAa,CACjD,CAAC;;;;;;;;;;;;;;;;AAwDF,qBAAa,0BAA2B,SAAQ,gCAC9C,OAAO,cAAc,EACrB,+BAA+B,EAC/B,mCAAmC,CACpC;;
|
|
1
|
+
{"version":3,"file":"MultichainAssetsController.d.ts","sourceRoot":"","sources":["../../src/MultichainAssetsController/MultichainAssetsController.ts"],"names":[],"mappings":"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"}
|
|
@@ -62,6 +62,8 @@ export class MultichainAssetsController extends StaticIntervalPollingController(
|
|
|
62
62
|
#snaps;
|
|
63
63
|
#controllerOperationMutex = new Mutex();
|
|
64
64
|
#isDeprecated;
|
|
65
|
+
#blockaidTokenRescanInterval;
|
|
66
|
+
#initialized = false;
|
|
65
67
|
constructor({ messenger, state = {}, blockaidTokenRescanInterval = DEFAULT_BLOCKAID_TOKEN_RESCAN_INTERVAL_MS, isDeprecated = () => false, }) {
|
|
66
68
|
super({
|
|
67
69
|
messenger,
|
|
@@ -74,13 +76,10 @@ export class MultichainAssetsController extends StaticIntervalPollingController(
|
|
|
74
76
|
});
|
|
75
77
|
this.#snaps = {};
|
|
76
78
|
this.#isDeprecated = isDeprecated;
|
|
79
|
+
this.#blockaidTokenRescanInterval = blockaidTokenRescanInterval;
|
|
77
80
|
if (this.#isDeprecated()) {
|
|
78
81
|
this.#enforceDisabledState();
|
|
79
82
|
}
|
|
80
|
-
else if (blockaidTokenRescanInterval > 0) {
|
|
81
|
-
this.setIntervalLength(blockaidTokenRescanInterval);
|
|
82
|
-
this.startPolling(null);
|
|
83
|
-
}
|
|
84
83
|
this.messenger.subscribe('AccountsController:accountAdded',
|
|
85
84
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
86
85
|
async (account) => await this.#handleOnAccountAddedEvent(account));
|
|
@@ -92,6 +91,29 @@ export class MultichainAssetsController extends StaticIntervalPollingController(
|
|
|
92
91
|
async (event) => await this.#handleAccountAssetListUpdatedEvent(event));
|
|
93
92
|
messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
94
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Complete initialization once the controllers this controller reads from
|
|
96
|
+
* have been constructed: start the periodic Blockaid re-scan of stored
|
|
97
|
+
* tokens, unless it is disabled.
|
|
98
|
+
*
|
|
99
|
+
* The constructor does not call other controllers or start polling, so it
|
|
100
|
+
* can run before they are constructed. Calling it more than once has no
|
|
101
|
+
* effect.
|
|
102
|
+
*/
|
|
103
|
+
init() {
|
|
104
|
+
if (this.#initialized) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
this.#initialized = true;
|
|
108
|
+
if (this.#isDeprecated()) {
|
|
109
|
+
this.#enforceDisabledState();
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (this.#blockaidTokenRescanInterval > 0) {
|
|
113
|
+
this.setIntervalLength(this.#blockaidTokenRescanInterval);
|
|
114
|
+
this.startPolling(null);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
95
117
|
/**
|
|
96
118
|
* Clears all persisted `accountsAssets`, `assetsMetadata`, and
|
|
97
119
|
* `allIgnoredAssets` so that no stale asset data remains in state.
|