@metamask/assets-controllers 42.0.0 → 43.1.0
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 +24 -1
- package/dist/AccountTrackerController.cjs +30 -10
- package/dist/AccountTrackerController.cjs.map +1 -1
- package/dist/AccountTrackerController.d.cts +14 -9
- package/dist/AccountTrackerController.d.cts.map +1 -1
- package/dist/AccountTrackerController.d.mts +14 -9
- package/dist/AccountTrackerController.d.mts.map +1 -1
- package/dist/AccountTrackerController.mjs +30 -10
- package/dist/AccountTrackerController.mjs.map +1 -1
- package/dist/AssetsContractController.cjs +61 -1
- package/dist/AssetsContractController.cjs.map +1 -1
- package/dist/AssetsContractController.d.cts +13 -0
- package/dist/AssetsContractController.d.cts.map +1 -1
- package/dist/AssetsContractController.d.mts +13 -0
- package/dist/AssetsContractController.d.mts.map +1 -1
- package/dist/AssetsContractController.mjs +61 -1
- package/dist/AssetsContractController.mjs.map +1 -1
- package/dist/CurrencyRateController.d.cts +4 -4
- package/dist/CurrencyRateController.d.mts +4 -4
- package/dist/RatesController/RatesController.cjs +12 -1
- package/dist/RatesController/RatesController.cjs.map +1 -1
- package/dist/RatesController/RatesController.d.cts +8 -1
- package/dist/RatesController/RatesController.d.cts.map +1 -1
- package/dist/RatesController/RatesController.d.mts +8 -1
- package/dist/RatesController/RatesController.d.mts.map +1 -1
- package/dist/RatesController/RatesController.mjs +12 -1
- package/dist/RatesController/RatesController.mjs.map +1 -1
- package/dist/TokenDetectionController.cjs +191 -127
- package/dist/TokenDetectionController.cjs.map +1 -1
- package/dist/TokenDetectionController.d.cts +20 -11
- package/dist/TokenDetectionController.d.cts.map +1 -1
- package/dist/TokenDetectionController.d.mts +20 -11
- package/dist/TokenDetectionController.d.mts.map +1 -1
- package/dist/TokenDetectionController.mjs +190 -127
- package/dist/TokenDetectionController.mjs.map +1 -1
- package/dist/TokenListController.cjs +60 -53
- package/dist/TokenListController.cjs.map +1 -1
- package/dist/TokenListController.d.cts +25 -14
- package/dist/TokenListController.d.cts.map +1 -1
- package/dist/TokenListController.d.mts +25 -14
- package/dist/TokenListController.d.mts.map +1 -1
- package/dist/TokenListController.mjs +60 -53
- package/dist/TokenListController.mjs.map +1 -1
- package/dist/TokenRatesController.d.cts +4 -4
- package/dist/TokenRatesController.d.mts +4 -4
- package/dist/TokensController.cjs +7 -4
- package/dist/TokensController.cjs.map +1 -1
- package/dist/TokensController.d.cts.map +1 -1
- package/dist/TokensController.d.mts.map +1 -1
- package/dist/TokensController.mjs +7 -4
- package/dist/TokensController.mjs.map +1 -1
- package/dist/assetsUtil.cjs +13 -1
- package/dist/assetsUtil.cjs.map +1 -1
- package/dist/assetsUtil.d.cts +7 -0
- package/dist/assetsUtil.d.cts.map +1 -1
- package/dist/assetsUtil.d.mts +7 -0
- package/dist/assetsUtil.d.mts.map +1 -1
- package/dist/assetsUtil.mjs +12 -0
- package/dist/assetsUtil.mjs.map +1 -1
- package/dist/multi-chain-accounts-service/mocks/mock-get-balances.cjs +18 -0
- package/dist/multi-chain-accounts-service/mocks/mock-get-balances.cjs.map +1 -1
- package/dist/multi-chain-accounts-service/mocks/mock-get-balances.d.cts.map +1 -1
- package/dist/multi-chain-accounts-service/mocks/mock-get-balances.d.mts.map +1 -1
- package/dist/multi-chain-accounts-service/mocks/mock-get-balances.mjs +18 -0
- package/dist/multi-chain-accounts-service/mocks/mock-get-balances.mjs.map +1 -1
- package/package.json +9 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenListController.d.cts","sourceRoot":"","sources":["../src/TokenListController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,6BAA6B,EAC9B,kCAAkC;AAEnC,OAAO,KAAK,EACV,
|
|
1
|
+
{"version":3,"file":"TokenListController.d.cts","sourceRoot":"","sources":["../src/TokenListController.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ControllerGetStateAction, ControllerStateChangeEvent, RestrictedControllerMessenger } from "@metamask/base-controller";
|
|
2
|
-
import type {
|
|
2
|
+
import type { NetworkControllerStateChangeEvent, NetworkState, NetworkControllerGetNetworkClientByIdAction } from "@metamask/network-controller";
|
|
3
3
|
import type { Hex } from "@metamask/utils";
|
|
4
4
|
declare const name = "TokenListController";
|
|
5
5
|
export type TokenListToken = {
|
|
@@ -34,17 +34,17 @@ export type TokenListControllerMessenger = RestrictedControllerMessenger<typeof
|
|
|
34
34
|
export declare const getDefaultTokenListState: () => TokenListState;
|
|
35
35
|
/** The input to start polling for the {@link TokenListController} */
|
|
36
36
|
type TokenListPollingInput = {
|
|
37
|
-
|
|
37
|
+
chainId: Hex;
|
|
38
38
|
};
|
|
39
39
|
declare const TokenListController_base: (abstract new (...args: any[]) => {
|
|
40
|
-
readonly "__#
|
|
41
|
-
"__#
|
|
40
|
+
readonly "__#787887@#intervalIds": Record<string, NodeJS.Timeout>;
|
|
41
|
+
"__#787887@#intervalLength": number | undefined;
|
|
42
42
|
setIntervalLength(intervalLength: number): void;
|
|
43
43
|
getIntervalLength(): number | undefined;
|
|
44
44
|
_startPolling(input: TokenListPollingInput): void;
|
|
45
45
|
_stopPollingByPollingTokenSetId(key: string): void;
|
|
46
|
-
readonly "__#
|
|
47
|
-
"__#
|
|
46
|
+
readonly "__#787879@#pollingTokenSets": Map<string, Set<string>>;
|
|
47
|
+
"__#787879@#callbacks": Map<string, Set<(input: TokenListPollingInput) => void>>;
|
|
48
48
|
_executePoll(input: TokenListPollingInput): Promise<void>;
|
|
49
49
|
startPolling(input: TokenListPollingInput): string;
|
|
50
50
|
stopAllPolling(): void;
|
|
@@ -85,38 +85,49 @@ export declare class TokenListController extends TokenListController_base<typeof
|
|
|
85
85
|
});
|
|
86
86
|
/**
|
|
87
87
|
* Start polling for the token list.
|
|
88
|
+
* @deprecated This method is deprecated and will be removed in the future.
|
|
89
|
+
* Consider using the new polling approach instead
|
|
88
90
|
*/
|
|
89
91
|
start(): Promise<void>;
|
|
90
92
|
/**
|
|
91
93
|
* Restart polling for the token list.
|
|
94
|
+
* @deprecated This method is deprecated and will be removed in the future.
|
|
95
|
+
* Consider using the new polling approach instead
|
|
92
96
|
*/
|
|
93
97
|
restart(): Promise<void>;
|
|
94
98
|
/**
|
|
95
99
|
* Stop polling for the token list.
|
|
100
|
+
* @deprecated This method is deprecated and will be removed in the future.
|
|
101
|
+
* Consider using the new polling approach instead
|
|
96
102
|
*/
|
|
97
103
|
stop(): void;
|
|
98
104
|
/**
|
|
99
|
-
* Prepare to discard this controller.
|
|
100
|
-
*
|
|
101
105
|
* This stops any active polling.
|
|
106
|
+
* @deprecated This method is deprecated and will be removed in the future.
|
|
107
|
+
* Consider using the new polling approach instead
|
|
102
108
|
*/
|
|
103
109
|
destroy(): void;
|
|
110
|
+
/**
|
|
111
|
+
* This stops any active polling intervals.
|
|
112
|
+
* @deprecated This method is deprecated and will be removed in the future.
|
|
113
|
+
* Consider using the new polling approach instead
|
|
114
|
+
*/
|
|
104
115
|
private stopPolling;
|
|
105
116
|
/**
|
|
106
|
-
*
|
|
117
|
+
* This starts a new polling loop for any given chain. Under the hood it is deduping polls
|
|
107
118
|
*
|
|
108
119
|
* @private
|
|
109
120
|
* @param input - The input for the poll.
|
|
110
|
-
* @param input.
|
|
121
|
+
* @param input.chainId - The chainId of the chain to trigger the fetch.
|
|
111
122
|
* @returns A promise that resolves when this operation completes.
|
|
112
123
|
*/
|
|
113
|
-
_executePoll({
|
|
124
|
+
_executePoll({ chainId }: TokenListPollingInput): Promise<void>;
|
|
114
125
|
/**
|
|
115
|
-
* Fetching token list from the Token Service API.
|
|
126
|
+
* Fetching token list from the Token Service API. This will fetch tokens across chains. It will update tokensChainsCache (scoped across chains), and also the tokenList (scoped for the selected chain)
|
|
116
127
|
*
|
|
117
|
-
* @param
|
|
128
|
+
* @param chainId - The chainId of the current chain triggering the fetch.
|
|
118
129
|
*/
|
|
119
|
-
fetchTokenList(
|
|
130
|
+
fetchTokenList(chainId: Hex): Promise<void>;
|
|
120
131
|
/**
|
|
121
132
|
* Clearing tokenList and tokensChainsCache explicitly.
|
|
122
133
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenListController.d.mts","sourceRoot":"","sources":["../src/TokenListController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,6BAA6B,EAC9B,kCAAkC;AAEnC,OAAO,KAAK,EACV,
|
|
1
|
+
{"version":3,"file":"TokenListController.d.mts","sourceRoot":"","sources":["../src/TokenListController.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
3
3
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
4
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
5
|
};
|
|
6
|
-
var _TokenListController_instances, _TokenListController_onNetworkControllerStateChange,
|
|
6
|
+
var _TokenListController_instances, _TokenListController_onNetworkControllerStateChange, _TokenListController_startDeprecatedPolling, _TokenListController_fetchFromCache;
|
|
7
7
|
import { safelyExecute } from "@metamask/controller-utils";
|
|
8
8
|
import { StaticIntervalPollingController } from "@metamask/polling-controller";
|
|
9
9
|
import { Mutex } from "async-mutex";
|
|
@@ -50,6 +50,7 @@ export class TokenListController extends StaticIntervalPollingController() {
|
|
|
50
50
|
_TokenListController_instances.add(this);
|
|
51
51
|
this.mutex = new Mutex();
|
|
52
52
|
this.intervalDelay = interval;
|
|
53
|
+
this.setIntervalLength(interval);
|
|
53
54
|
this.cacheRefreshThreshold = cacheRefreshThreshold;
|
|
54
55
|
this.chainId = chainId;
|
|
55
56
|
this.updatePreventPollingOnNetworkRestart(preventPollingOnNetworkRestart);
|
|
@@ -70,112 +71,116 @@ export class TokenListController extends StaticIntervalPollingController() {
|
|
|
70
71
|
});
|
|
71
72
|
}
|
|
72
73
|
}
|
|
74
|
+
// Eventually we want to remove start/restart/stop controls in favor of new _executePoll API
|
|
75
|
+
// Maintaining these functions for now until we can safely deprecate them for backwards compatibility
|
|
73
76
|
/**
|
|
74
77
|
* Start polling for the token list.
|
|
78
|
+
* @deprecated This method is deprecated and will be removed in the future.
|
|
79
|
+
* Consider using the new polling approach instead
|
|
75
80
|
*/
|
|
76
81
|
async start() {
|
|
77
82
|
if (!isTokenListSupportedForNetwork(this.chainId)) {
|
|
78
83
|
return;
|
|
79
84
|
}
|
|
80
|
-
await __classPrivateFieldGet(this, _TokenListController_instances, "m",
|
|
85
|
+
await __classPrivateFieldGet(this, _TokenListController_instances, "m", _TokenListController_startDeprecatedPolling).call(this);
|
|
81
86
|
}
|
|
82
87
|
/**
|
|
83
88
|
* Restart polling for the token list.
|
|
89
|
+
* @deprecated This method is deprecated and will be removed in the future.
|
|
90
|
+
* Consider using the new polling approach instead
|
|
84
91
|
*/
|
|
85
92
|
async restart() {
|
|
86
93
|
this.stopPolling();
|
|
87
|
-
await __classPrivateFieldGet(this, _TokenListController_instances, "m",
|
|
94
|
+
await __classPrivateFieldGet(this, _TokenListController_instances, "m", _TokenListController_startDeprecatedPolling).call(this);
|
|
88
95
|
}
|
|
89
96
|
/**
|
|
90
97
|
* Stop polling for the token list.
|
|
98
|
+
* @deprecated This method is deprecated and will be removed in the future.
|
|
99
|
+
* Consider using the new polling approach instead
|
|
91
100
|
*/
|
|
92
101
|
stop() {
|
|
93
102
|
this.stopPolling();
|
|
94
103
|
}
|
|
95
104
|
/**
|
|
96
|
-
* Prepare to discard this controller.
|
|
97
|
-
*
|
|
98
105
|
* This stops any active polling.
|
|
106
|
+
* @deprecated This method is deprecated and will be removed in the future.
|
|
107
|
+
* Consider using the new polling approach instead
|
|
99
108
|
*/
|
|
100
109
|
destroy() {
|
|
101
110
|
super.destroy();
|
|
102
111
|
this.stopPolling();
|
|
103
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* This stops any active polling intervals.
|
|
115
|
+
* @deprecated This method is deprecated and will be removed in the future.
|
|
116
|
+
* Consider using the new polling approach instead
|
|
117
|
+
*/
|
|
104
118
|
stopPolling() {
|
|
105
119
|
if (this.intervalId) {
|
|
106
120
|
clearInterval(this.intervalId);
|
|
107
121
|
}
|
|
108
122
|
}
|
|
109
123
|
/**
|
|
110
|
-
*
|
|
124
|
+
* This starts a new polling loop for any given chain. Under the hood it is deduping polls
|
|
111
125
|
*
|
|
112
126
|
* @private
|
|
113
127
|
* @param input - The input for the poll.
|
|
114
|
-
* @param input.
|
|
128
|
+
* @param input.chainId - The chainId of the chain to trigger the fetch.
|
|
115
129
|
* @returns A promise that resolves when this operation completes.
|
|
116
130
|
*/
|
|
117
|
-
async _executePoll({
|
|
118
|
-
return this.fetchTokenList(
|
|
131
|
+
async _executePoll({ chainId }) {
|
|
132
|
+
return this.fetchTokenList(chainId);
|
|
119
133
|
}
|
|
120
134
|
/**
|
|
121
|
-
* Fetching token list from the Token Service API.
|
|
135
|
+
* Fetching token list from the Token Service API. This will fetch tokens across chains. It will update tokensChainsCache (scoped across chains), and also the tokenList (scoped for the selected chain)
|
|
122
136
|
*
|
|
123
|
-
* @param
|
|
137
|
+
* @param chainId - The chainId of the current chain triggering the fetch.
|
|
124
138
|
*/
|
|
125
|
-
async fetchTokenList(
|
|
139
|
+
async fetchTokenList(chainId) {
|
|
126
140
|
const releaseLock = await this.mutex.acquire();
|
|
127
|
-
let networkClient;
|
|
128
|
-
if (networkClientId) {
|
|
129
|
-
networkClient = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId);
|
|
130
|
-
}
|
|
131
|
-
const chainId = networkClient?.configuration.chainId ?? this.chainId;
|
|
132
141
|
try {
|
|
133
142
|
const { tokensChainsCache } = this.state;
|
|
134
143
|
let tokenList = {};
|
|
144
|
+
// Attempt to fetch cached tokens
|
|
135
145
|
const cachedTokens = await safelyExecute(() => __classPrivateFieldGet(this, _TokenListController_instances, "m", _TokenListController_fetchFromCache).call(this, chainId));
|
|
136
146
|
if (cachedTokens) {
|
|
137
147
|
// Use non-expired cached tokens
|
|
138
148
|
tokenList = { ...cachedTokens };
|
|
139
149
|
}
|
|
140
150
|
else {
|
|
141
|
-
// Fetch fresh token list
|
|
151
|
+
// Fetch fresh token list from the API
|
|
142
152
|
const tokensFromAPI = await safelyExecute(() => fetchTokenListByChainId(chainId, this.abortController.signal));
|
|
143
|
-
if (
|
|
144
|
-
//
|
|
145
|
-
tokenList = {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
...
|
|
149
|
-
|
|
150
|
-
|
|
153
|
+
if (tokensFromAPI) {
|
|
154
|
+
// Format tokens from API (HTTP) and update tokenList
|
|
155
|
+
tokenList = {};
|
|
156
|
+
for (const token of tokensFromAPI) {
|
|
157
|
+
tokenList[token.address] = {
|
|
158
|
+
...token,
|
|
159
|
+
aggregators: formatAggregatorNames(token.aggregators),
|
|
160
|
+
iconUrl: formatIconUrlWithProxy({
|
|
161
|
+
chainId,
|
|
162
|
+
tokenAddress: token.address,
|
|
163
|
+
}),
|
|
151
164
|
};
|
|
152
|
-
}
|
|
153
|
-
return;
|
|
165
|
+
}
|
|
154
166
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
aggregators: formatAggregatorNames(token.aggregators),
|
|
159
|
-
iconUrl: formatIconUrlWithProxy({
|
|
160
|
-
chainId,
|
|
161
|
-
tokenAddress: token.address,
|
|
162
|
-
}),
|
|
163
|
-
};
|
|
164
|
-
tokenList[token.address] = formattedToken;
|
|
167
|
+
else {
|
|
168
|
+
// Fallback to expired cached tokens
|
|
169
|
+
tokenList = { ...(tokensChainsCache[chainId]?.data || {}) };
|
|
165
170
|
}
|
|
166
171
|
}
|
|
167
|
-
|
|
168
|
-
...tokensChainsCache,
|
|
169
|
-
[chainId]: {
|
|
170
|
-
timestamp: Date.now(),
|
|
171
|
-
data: tokenList,
|
|
172
|
-
},
|
|
173
|
-
};
|
|
172
|
+
// Update the state with a single update for both tokenList and tokenChainsCache
|
|
174
173
|
this.update(() => {
|
|
175
174
|
return {
|
|
176
175
|
...this.state,
|
|
177
|
-
tokenList,
|
|
178
|
-
tokensChainsCache:
|
|
176
|
+
tokenList: this.chainId === chainId ? tokenList : this.state.tokenList,
|
|
177
|
+
tokensChainsCache: {
|
|
178
|
+
...tokensChainsCache,
|
|
179
|
+
[chainId]: {
|
|
180
|
+
timestamp: Date.now(),
|
|
181
|
+
data: tokenList,
|
|
182
|
+
},
|
|
183
|
+
},
|
|
179
184
|
};
|
|
180
185
|
});
|
|
181
186
|
}
|
|
@@ -234,19 +239,21 @@ async function _TokenListController_onNetworkControllerStateChange(networkContro
|
|
|
234
239
|
tokenList: this.state.tokensChainsCache[this.chainId]?.data || {},
|
|
235
240
|
};
|
|
236
241
|
});
|
|
237
|
-
await this.restart();
|
|
238
242
|
}
|
|
239
243
|
}
|
|
240
|
-
},
|
|
244
|
+
}, _TokenListController_startDeprecatedPolling =
|
|
241
245
|
/**
|
|
242
|
-
* Starts a new polling interval
|
|
246
|
+
* Starts a new polling interval for a given chainId (this should be deprecated in favor of _executePoll)
|
|
247
|
+
* @deprecated This method is deprecated and will be removed in the future.
|
|
248
|
+
* Consider using the new polling approach instead
|
|
243
249
|
*/
|
|
244
|
-
async function
|
|
245
|
-
|
|
250
|
+
async function _TokenListController_startDeprecatedPolling() {
|
|
251
|
+
// renaming this to avoid collision with base class
|
|
252
|
+
await safelyExecute(() => this.fetchTokenList(this.chainId));
|
|
246
253
|
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
|
|
247
254
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
248
255
|
this.intervalId = setInterval(async () => {
|
|
249
|
-
await safelyExecute(() => this.fetchTokenList());
|
|
256
|
+
await safelyExecute(() => this.fetchTokenList(this.chainId));
|
|
250
257
|
}, this.intervalDelay);
|
|
251
258
|
}, _TokenListController_fetchFromCache =
|
|
252
259
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenListController.mjs","sourceRoot":"","sources":["../src/TokenListController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { safelyExecute } from '@metamask/controller-utils';\nimport type {\n NetworkClientId,\n NetworkControllerStateChangeEvent,\n NetworkState,\n NetworkControllerGetNetworkClientByIdAction,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\n\nimport {\n isTokenListSupportedForNetwork,\n formatAggregatorNames,\n formatIconUrlWithProxy,\n} from './assetsUtil';\nimport { fetchTokenListByChainId } from './token-service';\n\nconst DEFAULT_INTERVAL = 24 * 60 * 60 * 1000;\nconst DEFAULT_THRESHOLD = 24 * 60 * 60 * 1000;\n\nconst name = 'TokenListController';\n\nexport type TokenListToken = {\n name: string;\n symbol: string;\n decimals: number;\n address: string;\n occurrences: number;\n aggregators: string[];\n iconUrl: string;\n};\n\nexport type TokenListMap = Record<string, TokenListToken>;\n\ntype DataCache = {\n timestamp: number;\n data: TokenListMap;\n};\nexport type TokensChainsCache = {\n [chainId: Hex]: DataCache;\n};\n\nexport type TokenListState = {\n tokenList: TokenListMap;\n tokensChainsCache: TokensChainsCache;\n preventPollingOnNetworkRestart: boolean;\n};\n\nexport type TokenListStateChange = ControllerStateChangeEvent<\n typeof name,\n TokenListState\n>;\n\nexport type TokenListControllerEvents = TokenListStateChange;\n\nexport type GetTokenListState = ControllerGetStateAction<\n typeof name,\n TokenListState\n>;\n\nexport type TokenListControllerActions = GetTokenListState;\n\ntype AllowedActions = NetworkControllerGetNetworkClientByIdAction;\n\ntype AllowedEvents = NetworkControllerStateChangeEvent;\n\nexport type TokenListControllerMessenger = RestrictedControllerMessenger<\n typeof name,\n TokenListControllerActions | AllowedActions,\n TokenListControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\nconst metadata = {\n tokenList: { persist: true, anonymous: true },\n tokensChainsCache: { persist: true, anonymous: true },\n preventPollingOnNetworkRestart: { persist: true, anonymous: true },\n};\n\nexport const getDefaultTokenListState = (): TokenListState => {\n return {\n tokenList: {},\n tokensChainsCache: {},\n preventPollingOnNetworkRestart: false,\n };\n};\n\n/** The input to start polling for the {@link TokenListController} */\ntype TokenListPollingInput = {\n networkClientId: NetworkClientId;\n};\n\n/**\n * Controller that passively polls on a set interval for the list of tokens from metaswaps api\n */\nexport class TokenListController extends StaticIntervalPollingController<TokenListPollingInput>()<\n typeof name,\n TokenListState,\n TokenListControllerMessenger\n> {\n private readonly mutex = new Mutex();\n\n private intervalId?: ReturnType<typeof setTimeout>;\n\n private readonly intervalDelay: number;\n\n private readonly cacheRefreshThreshold: number;\n\n private chainId: Hex;\n\n private abortController: AbortController;\n\n /**\n * Creates a TokenListController instance.\n *\n * @param options - The controller options.\n * @param options.chainId - The chain ID of the current network.\n * @param options.onNetworkStateChange - A function for registering an event handler for network state changes.\n * @param options.interval - The polling interval, in milliseconds.\n * @param options.cacheRefreshThreshold - The token cache expiry time, in milliseconds.\n * @param options.messenger - A restricted controller messenger.\n * @param options.state - Initial state to set on this controller.\n * @param options.preventPollingOnNetworkRestart - Determines whether to prevent poilling on network restart in extension.\n */\n constructor({\n chainId,\n preventPollingOnNetworkRestart = false,\n onNetworkStateChange,\n interval = DEFAULT_INTERVAL,\n cacheRefreshThreshold = DEFAULT_THRESHOLD,\n messenger,\n state,\n }: {\n chainId: Hex;\n preventPollingOnNetworkRestart?: boolean;\n onNetworkStateChange?: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n interval?: number;\n cacheRefreshThreshold?: number;\n messenger: TokenListControllerMessenger;\n state?: Partial<TokenListState>;\n }) {\n super({\n name,\n metadata,\n messenger,\n state: { ...getDefaultTokenListState(), ...state },\n });\n this.intervalDelay = interval;\n this.cacheRefreshThreshold = cacheRefreshThreshold;\n this.chainId = chainId;\n this.updatePreventPollingOnNetworkRestart(preventPollingOnNetworkRestart);\n this.abortController = new AbortController();\n if (onNetworkStateChange) {\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n onNetworkStateChange(async (networkControllerState) => {\n await this.#onNetworkControllerStateChange(networkControllerState);\n });\n } else {\n this.messagingSystem.subscribe(\n 'NetworkController:stateChange',\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async (networkControllerState) => {\n await this.#onNetworkControllerStateChange(networkControllerState);\n },\n );\n }\n }\n\n /**\n * Updates state and restarts polling on changes to the network controller\n * state.\n *\n * @param networkControllerState - The updated network controller state.\n */\n async #onNetworkControllerStateChange(networkControllerState: NetworkState) {\n const selectedNetworkClient = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkControllerState.selectedNetworkClientId,\n );\n const { chainId } = selectedNetworkClient.configuration;\n\n if (this.chainId !== chainId) {\n this.abortController.abort();\n this.abortController = new AbortController();\n this.chainId = chainId;\n if (this.state.preventPollingOnNetworkRestart) {\n this.clearingTokenListData();\n } else {\n // Ensure tokenList is referencing data from correct network\n this.update(() => {\n return {\n ...this.state,\n tokenList: this.state.tokensChainsCache[this.chainId]?.data || {},\n };\n });\n await this.restart();\n }\n }\n }\n\n /**\n * Start polling for the token list.\n */\n async start() {\n if (!isTokenListSupportedForNetwork(this.chainId)) {\n return;\n }\n await this.#startPolling();\n }\n\n /**\n * Restart polling for the token list.\n */\n async restart() {\n this.stopPolling();\n await this.#startPolling();\n }\n\n /**\n * Stop polling for the token list.\n */\n stop() {\n this.stopPolling();\n }\n\n /**\n * Prepare to discard this controller.\n *\n * This stops any active polling.\n */\n override destroy() {\n super.destroy();\n this.stopPolling();\n }\n\n private stopPolling() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n }\n\n /**\n * Starts a new polling interval.\n */\n async #startPolling(): Promise<void> {\n await safelyExecute(() => this.fetchTokenList());\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.intervalId = setInterval(async () => {\n await safelyExecute(() => this.fetchTokenList());\n }, this.intervalDelay);\n }\n\n /**\n * Fetching token list from the Token Service API.\n *\n * @private\n * @param input - The input for the poll.\n * @param input.networkClientId - The ID of the network client triggering the fetch.\n * @returns A promise that resolves when this operation completes.\n */\n async _executePoll({\n networkClientId,\n }: TokenListPollingInput): Promise<void> {\n return this.fetchTokenList(networkClientId);\n }\n\n /**\n * Fetching token list from the Token Service API.\n *\n * @param networkClientId - The ID of the network client triggering the fetch.\n */\n async fetchTokenList(networkClientId?: NetworkClientId): Promise<void> {\n const releaseLock = await this.mutex.acquire();\n let networkClient;\n if (networkClientId) {\n networkClient = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n }\n const chainId = networkClient?.configuration.chainId ?? this.chainId;\n try {\n const { tokensChainsCache } = this.state;\n let tokenList: TokenListMap = {};\n const cachedTokens = await safelyExecute(() =>\n this.#fetchFromCache(chainId),\n );\n if (cachedTokens) {\n // Use non-expired cached tokens\n tokenList = { ...cachedTokens };\n } else {\n // Fetch fresh token list\n const tokensFromAPI = await safelyExecute(\n () =>\n fetchTokenListByChainId(\n chainId,\n this.abortController.signal,\n ) as Promise<TokenListToken[]>,\n );\n\n if (!tokensFromAPI) {\n // Fallback to expired cached tokens\n tokenList = { ...(tokensChainsCache[chainId]?.data || {}) };\n this.update(() => {\n return {\n ...this.state,\n tokenList,\n tokensChainsCache,\n };\n });\n return;\n }\n for (const token of tokensFromAPI) {\n const formattedToken: TokenListToken = {\n ...token,\n aggregators: formatAggregatorNames(token.aggregators),\n iconUrl: formatIconUrlWithProxy({\n chainId,\n tokenAddress: token.address,\n }),\n };\n tokenList[token.address] = formattedToken;\n }\n }\n const updatedTokensChainsCache: TokensChainsCache = {\n ...tokensChainsCache,\n [chainId]: {\n timestamp: Date.now(),\n data: tokenList,\n },\n };\n this.update(() => {\n return {\n ...this.state,\n tokenList,\n tokensChainsCache: updatedTokensChainsCache,\n };\n });\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Checks if the Cache timestamp is valid,\n * if yes data in cache will be returned\n * otherwise null will be returned.\n * @param chainId - The chain ID of the network for which to fetch the cache.\n * @returns The cached data, or `null` if the cache was expired.\n */\n async #fetchFromCache(chainId: Hex): Promise<TokenListMap | null> {\n const { tokensChainsCache }: TokenListState = this.state;\n const dataCache = tokensChainsCache[chainId];\n const now = Date.now();\n if (\n dataCache?.data &&\n now - dataCache?.timestamp < this.cacheRefreshThreshold\n ) {\n return dataCache.data;\n }\n return null;\n }\n\n /**\n * Clearing tokenList and tokensChainsCache explicitly.\n */\n clearingTokenListData(): void {\n this.update(() => {\n return {\n ...this.state,\n tokenList: {},\n tokensChainsCache: {},\n };\n });\n }\n\n /**\n * Updates preventPollingOnNetworkRestart from extension.\n *\n * @param shouldPreventPolling - Determine whether to prevent polling on network change\n */\n updatePreventPollingOnNetworkRestart(shouldPreventPolling: boolean): void {\n this.update(() => {\n return {\n ...this.state,\n preventPollingOnNetworkRestart: shouldPreventPolling,\n };\n });\n }\n}\n\nexport default TokenListController;\n"]}
|
|
1
|
+
{"version":3,"file":"TokenListController.mjs","sourceRoot":"","sources":["../src/TokenListController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { safelyExecute } from '@metamask/controller-utils';\nimport type {\n NetworkControllerStateChangeEvent,\n NetworkState,\n NetworkControllerGetNetworkClientByIdAction,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\n\nimport {\n isTokenListSupportedForNetwork,\n formatAggregatorNames,\n formatIconUrlWithProxy,\n} from './assetsUtil';\nimport { fetchTokenListByChainId } from './token-service';\n\nconst DEFAULT_INTERVAL = 24 * 60 * 60 * 1000;\nconst DEFAULT_THRESHOLD = 24 * 60 * 60 * 1000;\n\nconst name = 'TokenListController';\n\nexport type TokenListToken = {\n name: string;\n symbol: string;\n decimals: number;\n address: string;\n occurrences: number;\n aggregators: string[];\n iconUrl: string;\n};\n\nexport type TokenListMap = Record<string, TokenListToken>;\n\ntype DataCache = {\n timestamp: number;\n data: TokenListMap;\n};\nexport type TokensChainsCache = {\n [chainId: Hex]: DataCache;\n};\n\nexport type TokenListState = {\n tokenList: TokenListMap;\n tokensChainsCache: TokensChainsCache;\n preventPollingOnNetworkRestart: boolean;\n};\n\nexport type TokenListStateChange = ControllerStateChangeEvent<\n typeof name,\n TokenListState\n>;\n\nexport type TokenListControllerEvents = TokenListStateChange;\n\nexport type GetTokenListState = ControllerGetStateAction<\n typeof name,\n TokenListState\n>;\n\nexport type TokenListControllerActions = GetTokenListState;\n\ntype AllowedActions = NetworkControllerGetNetworkClientByIdAction;\n\ntype AllowedEvents = NetworkControllerStateChangeEvent;\n\nexport type TokenListControllerMessenger = RestrictedControllerMessenger<\n typeof name,\n TokenListControllerActions | AllowedActions,\n TokenListControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\nconst metadata = {\n tokenList: { persist: true, anonymous: true },\n tokensChainsCache: { persist: true, anonymous: true },\n preventPollingOnNetworkRestart: { persist: true, anonymous: true },\n};\n\nexport const getDefaultTokenListState = (): TokenListState => {\n return {\n tokenList: {},\n tokensChainsCache: {},\n preventPollingOnNetworkRestart: false,\n };\n};\n\n/** The input to start polling for the {@link TokenListController} */\ntype TokenListPollingInput = {\n chainId: Hex;\n};\n\n/**\n * Controller that passively polls on a set interval for the list of tokens from metaswaps api\n */\nexport class TokenListController extends StaticIntervalPollingController<TokenListPollingInput>()<\n typeof name,\n TokenListState,\n TokenListControllerMessenger\n> {\n private readonly mutex = new Mutex();\n\n private intervalId?: ReturnType<typeof setTimeout>;\n\n private readonly intervalDelay: number;\n\n private readonly cacheRefreshThreshold: number;\n\n private chainId: Hex;\n\n private abortController: AbortController;\n\n /**\n * Creates a TokenListController instance.\n *\n * @param options - The controller options.\n * @param options.chainId - The chain ID of the current network.\n * @param options.onNetworkStateChange - A function for registering an event handler for network state changes.\n * @param options.interval - The polling interval, in milliseconds.\n * @param options.cacheRefreshThreshold - The token cache expiry time, in milliseconds.\n * @param options.messenger - A restricted controller messenger.\n * @param options.state - Initial state to set on this controller.\n * @param options.preventPollingOnNetworkRestart - Determines whether to prevent poilling on network restart in extension.\n */\n constructor({\n chainId,\n preventPollingOnNetworkRestart = false,\n onNetworkStateChange,\n interval = DEFAULT_INTERVAL,\n cacheRefreshThreshold = DEFAULT_THRESHOLD,\n messenger,\n state,\n }: {\n chainId: Hex;\n preventPollingOnNetworkRestart?: boolean;\n onNetworkStateChange?: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n interval?: number;\n cacheRefreshThreshold?: number;\n messenger: TokenListControllerMessenger;\n state?: Partial<TokenListState>;\n }) {\n super({\n name,\n metadata,\n messenger,\n state: { ...getDefaultTokenListState(), ...state },\n });\n this.intervalDelay = interval;\n this.setIntervalLength(interval);\n this.cacheRefreshThreshold = cacheRefreshThreshold;\n this.chainId = chainId;\n this.updatePreventPollingOnNetworkRestart(preventPollingOnNetworkRestart);\n this.abortController = new AbortController();\n if (onNetworkStateChange) {\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n onNetworkStateChange(async (networkControllerState) => {\n await this.#onNetworkControllerStateChange(networkControllerState);\n });\n } else {\n this.messagingSystem.subscribe(\n 'NetworkController:stateChange',\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async (networkControllerState) => {\n await this.#onNetworkControllerStateChange(networkControllerState);\n },\n );\n }\n }\n\n /**\n * Updates state and restarts polling on changes to the network controller\n * state.\n *\n * @param networkControllerState - The updated network controller state.\n */\n async #onNetworkControllerStateChange(networkControllerState: NetworkState) {\n const selectedNetworkClient = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkControllerState.selectedNetworkClientId,\n );\n const { chainId } = selectedNetworkClient.configuration;\n\n if (this.chainId !== chainId) {\n this.abortController.abort();\n this.abortController = new AbortController();\n this.chainId = chainId;\n if (this.state.preventPollingOnNetworkRestart) {\n this.clearingTokenListData();\n } else {\n // Ensure tokenList is referencing data from correct network\n this.update(() => {\n return {\n ...this.state,\n tokenList: this.state.tokensChainsCache[this.chainId]?.data || {},\n };\n });\n }\n }\n }\n\n // Eventually we want to remove start/restart/stop controls in favor of new _executePoll API\n // Maintaining these functions for now until we can safely deprecate them for backwards compatibility\n /**\n * Start polling for the token list.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n async start() {\n if (!isTokenListSupportedForNetwork(this.chainId)) {\n return;\n }\n await this.#startDeprecatedPolling();\n }\n\n /**\n * Restart polling for the token list.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n async restart() {\n this.stopPolling();\n await this.#startDeprecatedPolling();\n }\n\n /**\n * Stop polling for the token list.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n stop() {\n this.stopPolling();\n }\n\n /**\n * This stops any active polling.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n override destroy() {\n super.destroy();\n this.stopPolling();\n }\n\n /**\n * This stops any active polling intervals.\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n private stopPolling() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n }\n\n /**\n * Starts a new polling interval for a given chainId (this should be deprecated in favor of _executePoll)\n * @deprecated This method is deprecated and will be removed in the future.\n * Consider using the new polling approach instead\n */\n async #startDeprecatedPolling(): Promise<void> {\n // renaming this to avoid collision with base class\n await safelyExecute(() => this.fetchTokenList(this.chainId));\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.intervalId = setInterval(async () => {\n await safelyExecute(() => this.fetchTokenList(this.chainId));\n }, this.intervalDelay);\n }\n\n /**\n * This starts a new polling loop for any given chain. Under the hood it is deduping polls\n *\n * @private\n * @param input - The input for the poll.\n * @param input.chainId - The chainId of the chain to trigger the fetch.\n * @returns A promise that resolves when this operation completes.\n */\n async _executePoll({ chainId }: TokenListPollingInput): Promise<void> {\n return this.fetchTokenList(chainId);\n }\n\n /**\n * Fetching token list from the Token Service API. This will fetch tokens across chains. It will update tokensChainsCache (scoped across chains), and also the tokenList (scoped for the selected chain)\n *\n * @param chainId - The chainId of the current chain triggering the fetch.\n */\n async fetchTokenList(chainId: Hex): Promise<void> {\n const releaseLock = await this.mutex.acquire();\n try {\n const { tokensChainsCache } = this.state;\n let tokenList: TokenListMap = {};\n // Attempt to fetch cached tokens\n const cachedTokens = await safelyExecute(() =>\n this.#fetchFromCache(chainId),\n );\n if (cachedTokens) {\n // Use non-expired cached tokens\n tokenList = { ...cachedTokens };\n } else {\n // Fetch fresh token list from the API\n const tokensFromAPI = await safelyExecute(\n () =>\n fetchTokenListByChainId(\n chainId,\n this.abortController.signal,\n ) as Promise<TokenListToken[]>,\n );\n\n if (tokensFromAPI) {\n // Format tokens from API (HTTP) and update tokenList\n tokenList = {};\n for (const token of tokensFromAPI) {\n tokenList[token.address] = {\n ...token,\n aggregators: formatAggregatorNames(token.aggregators),\n iconUrl: formatIconUrlWithProxy({\n chainId,\n tokenAddress: token.address,\n }),\n };\n }\n } else {\n // Fallback to expired cached tokens\n tokenList = { ...(tokensChainsCache[chainId]?.data || {}) };\n }\n }\n\n // Update the state with a single update for both tokenList and tokenChainsCache\n this.update(() => {\n return {\n ...this.state,\n tokenList:\n this.chainId === chainId ? tokenList : this.state.tokenList,\n tokensChainsCache: {\n ...tokensChainsCache,\n [chainId]: {\n timestamp: Date.now(),\n data: tokenList,\n },\n },\n };\n });\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Checks if the Cache timestamp is valid,\n * if yes data in cache will be returned\n * otherwise null will be returned.\n * @param chainId - The chain ID of the network for which to fetch the cache.\n * @returns The cached data, or `null` if the cache was expired.\n */\n async #fetchFromCache(chainId: Hex): Promise<TokenListMap | null> {\n const { tokensChainsCache }: TokenListState = this.state;\n const dataCache = tokensChainsCache[chainId];\n const now = Date.now();\n if (\n dataCache?.data &&\n now - dataCache?.timestamp < this.cacheRefreshThreshold\n ) {\n return dataCache.data;\n }\n return null;\n }\n\n /**\n * Clearing tokenList and tokensChainsCache explicitly.\n */\n clearingTokenListData(): void {\n this.update(() => {\n return {\n ...this.state,\n tokenList: {},\n tokensChainsCache: {},\n };\n });\n }\n\n /**\n * Updates preventPollingOnNetworkRestart from extension.\n *\n * @param shouldPreventPolling - Determine whether to prevent polling on network change\n */\n updatePreventPollingOnNetworkRestart(shouldPreventPolling: boolean): void {\n this.update(() => {\n return {\n ...this.state,\n preventPollingOnNetworkRestart: shouldPreventPolling,\n };\n });\n }\n}\n\nexport default TokenListController;\n"]}
|
|
@@ -108,14 +108,14 @@ export type TokenRatesPollingInput = {
|
|
|
108
108
|
chainId: Hex;
|
|
109
109
|
};
|
|
110
110
|
declare const TokenRatesController_base: (abstract new (...args: any[]) => {
|
|
111
|
-
readonly "__#
|
|
112
|
-
"__#
|
|
111
|
+
readonly "__#787887@#intervalIds": Record<string, NodeJS.Timeout>;
|
|
112
|
+
"__#787887@#intervalLength": number | undefined;
|
|
113
113
|
setIntervalLength(intervalLength: number): void;
|
|
114
114
|
getIntervalLength(): number | undefined;
|
|
115
115
|
_startPolling(input: TokenRatesPollingInput): void;
|
|
116
116
|
_stopPollingByPollingTokenSetId(key: string): void;
|
|
117
|
-
readonly "__#
|
|
118
|
-
"__#
|
|
117
|
+
readonly "__#787879@#pollingTokenSets": Map<string, Set<string>>;
|
|
118
|
+
"__#787879@#callbacks": Map<string, Set<(input: TokenRatesPollingInput) => void>>;
|
|
119
119
|
_executePoll(input: TokenRatesPollingInput): Promise<void>;
|
|
120
120
|
startPolling(input: TokenRatesPollingInput): string;
|
|
121
121
|
stopAllPolling(): void;
|
|
@@ -108,14 +108,14 @@ export type TokenRatesPollingInput = {
|
|
|
108
108
|
chainId: Hex;
|
|
109
109
|
};
|
|
110
110
|
declare const TokenRatesController_base: (abstract new (...args: any[]) => {
|
|
111
|
-
readonly "__#
|
|
112
|
-
"__#
|
|
111
|
+
readonly "__#787887@#intervalIds": Record<string, NodeJS.Timeout>;
|
|
112
|
+
"__#787887@#intervalLength": number | undefined;
|
|
113
113
|
setIntervalLength(intervalLength: number): void;
|
|
114
114
|
getIntervalLength(): number | undefined;
|
|
115
115
|
_startPolling(input: TokenRatesPollingInput): void;
|
|
116
116
|
_stopPollingByPollingTokenSetId(key: string): void;
|
|
117
|
-
readonly "__#
|
|
118
|
-
"__#
|
|
117
|
+
readonly "__#787879@#pollingTokenSets": Map<string, Set<string>>;
|
|
118
|
+
"__#787879@#callbacks": Map<string, Set<(input: TokenRatesPollingInput) => void>>;
|
|
119
119
|
_executePoll(input: TokenRatesPollingInput): Promise<void>;
|
|
120
120
|
startPolling(input: TokenRatesPollingInput): string;
|
|
121
121
|
stopAllPolling(): void;
|
|
@@ -207,11 +207,11 @@ class TokensController extends base_controller_1.BaseController {
|
|
|
207
207
|
*/
|
|
208
208
|
async addTokens(tokensToImport, networkClientId) {
|
|
209
209
|
const releaseLock = await __classPrivateFieldGet(this, _TokensController_mutex, "f").acquire();
|
|
210
|
-
const {
|
|
210
|
+
const { ignoredTokens, allDetectedTokens } = this.state;
|
|
211
211
|
const importedTokensMap = {};
|
|
212
212
|
// Used later to dedupe imported tokens
|
|
213
|
-
const newTokensMap =
|
|
214
|
-
output[
|
|
213
|
+
const newTokensMap = Object.values(tokensToImport).reduce((output, token) => {
|
|
214
|
+
output[token.address] = token;
|
|
215
215
|
return output;
|
|
216
216
|
}, {});
|
|
217
217
|
try {
|
|
@@ -231,12 +231,15 @@ class TokensController extends base_controller_1.BaseController {
|
|
|
231
231
|
return formattedToken;
|
|
232
232
|
});
|
|
233
233
|
const newTokens = Object.values(newTokensMap);
|
|
234
|
-
const newDetectedTokens = detectedTokens.filter((token) => !importedTokensMap[token.address.toLowerCase()]);
|
|
235
234
|
const newIgnoredTokens = ignoredTokens.filter((tokenAddress) => !newTokensMap[tokenAddress.toLowerCase()]);
|
|
236
235
|
let interactingChainId;
|
|
237
236
|
if (networkClientId) {
|
|
238
237
|
interactingChainId = this.messagingSystem.call('NetworkController:getNetworkClientById', networkClientId).configuration.chainId;
|
|
239
238
|
}
|
|
239
|
+
const detectedTokensForGivenChain = interactingChainId
|
|
240
|
+
? allDetectedTokens?.[interactingChainId]?.[__classPrivateFieldGet(this, _TokensController_instances, "m", _TokensController_getSelectedAddress).call(this)]
|
|
241
|
+
: [];
|
|
242
|
+
const newDetectedTokens = detectedTokensForGivenChain?.filter((t) => !importedTokensMap[t.address.toLowerCase()]);
|
|
240
243
|
const { newAllTokens, newAllDetectedTokens, newAllIgnoredTokens } = __classPrivateFieldGet(this, _TokensController_instances, "m", _TokensController_getNewAllTokensState).call(this, {
|
|
241
244
|
newTokens,
|
|
242
245
|
newDetectedTokens,
|