@metamask-previews/assets-controllers 91.0.0-preview-0e8737f → 91.0.0-preview-fe83443
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 +22 -4
- package/dist/TokenCacheService.cjs +101 -0
- package/dist/TokenCacheService.cjs.map +1 -0
- package/dist/TokenCacheService.d.cts +90 -0
- package/dist/TokenCacheService.d.cts.map +1 -0
- package/dist/TokenCacheService.d.mts +90 -0
- package/dist/TokenCacheService.d.mts.map +1 -0
- package/dist/TokenCacheService.mjs +97 -0
- package/dist/TokenCacheService.mjs.map +1 -0
- package/dist/TokenDetectionController.cjs +4 -7
- package/dist/TokenDetectionController.cjs.map +1 -1
- package/dist/TokenDetectionController.d.cts +3 -3
- package/dist/TokenDetectionController.d.cts.map +1 -1
- package/dist/TokenDetectionController.d.mts +3 -3
- package/dist/TokenDetectionController.d.mts.map +1 -1
- package/dist/TokenDetectionController.mjs +4 -7
- package/dist/TokenDetectionController.mjs.map +1 -1
- package/dist/TokenListController.cjs +22 -35
- package/dist/TokenListController.cjs.map +1 -1
- package/dist/TokenListController.d.cts +17 -5
- package/dist/TokenListController.d.cts.map +1 -1
- package/dist/TokenListController.d.mts +17 -5
- package/dist/TokenListController.d.mts.map +1 -1
- package/dist/TokenListController.mjs +22 -35
- package/dist/TokenListController.mjs.map +1 -1
- package/dist/TokensController.cjs +1 -1
- package/dist/TokensController.cjs.map +1 -1
- package/dist/TokensController.d.cts +2 -2
- package/dist/TokensController.d.cts.map +1 -1
- package/dist/TokensController.d.mts +2 -2
- package/dist/TokensController.d.mts.map +1 -1
- package/dist/TokensController.mjs +1 -1
- package/dist/TokensController.mjs.map +1 -1
- package/dist/index.cjs +3 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +14 -26
package/CHANGELOG.md
CHANGED
|
@@ -7,10 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
-
### Fixed
|
|
11
|
-
|
|
12
|
-
- Fix `TokenBalancesController` state that store both lowercase and checksum account addresses ([#7216](https://github.com/MetaMask/core/pull/7216))
|
|
13
|
-
|
|
14
10
|
### Added
|
|
15
11
|
|
|
16
12
|
- **BREAKING:** Add optional JWT token authentication to multi-chain accounts API calls ([#7165](https://github.com/MetaMask/core/pull/7165))
|
|
@@ -20,8 +16,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
20
16
|
- JWT token is included in `Authorization: Bearer <token>` header when provided
|
|
21
17
|
- Backward compatible: token parameter is optional and APIs work without authentication
|
|
22
18
|
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- Move peer dependencies for controller and service packages to direct dependencies ([#7209](https://github.com/MetaMask/core/pull/7209), [#7220](https://github.com/MetaMask/core/pull/7220))
|
|
22
|
+
- The dependencies moved are:
|
|
23
|
+
- `@metamask/account-tree-controller` (^4.0.0)
|
|
24
|
+
- `@metamask/accounts-controller` (^35.0.0)
|
|
25
|
+
- `@metamask/approval-controller` (^8.0.0)
|
|
26
|
+
- `@metamask/core-backend` (^5.0.0)
|
|
27
|
+
- `@metamask/keyring-controller` (^25.0.0)
|
|
28
|
+
- `@metamask/multichain-account-service` (^4.0.0)
|
|
29
|
+
- `@metamask/network-controller` (^26.0.0)
|
|
30
|
+
- `@metamask/permission-controller` (^12.1.1)
|
|
31
|
+
- `@metamask/phishing-controller` (^16.1.0)
|
|
32
|
+
- `@metamask/preferences-controller` (^22.0.0)
|
|
33
|
+
- `@metamask/profile-sync-controller` (^27.0.0)
|
|
34
|
+
- `@metamask/snaps-controllers` (^14.0.1)
|
|
35
|
+
- `@metamask/transaction-controller` (^62.2.0)
|
|
36
|
+
- In clients, it is now possible for multiple versions of these packages to exist in the dependency tree.
|
|
37
|
+
- For example, this scenario would be valid: a client relies on `@metamask/controller-a` 1.0.0 and `@metamask/controller-b` 1.0.0, and `@metamask/controller-b` depends on `@metamask/controller-a` 1.1.0.
|
|
38
|
+
- Note, however, that the versions specified in the client's `package.json` always "win", and you are expected to keep them up to date so as not to break controller and service intercommunication.
|
|
39
|
+
|
|
23
40
|
### Fixed
|
|
24
41
|
|
|
42
|
+
- Fix `TokenBalancesController` state that store both lowercase and checksum account addresses ([#7217](https://github.com/MetaMask/core/pull/7217))
|
|
25
43
|
- `TokenBalancesController`: state inconsistency by ensuring all account addresses are stored in lowercase format ([#7216](https://github.com/MetaMask/core/pull/7216))
|
|
26
44
|
|
|
27
45
|
## [91.0.0]
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
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");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var _TokenCacheService_cache, _TokenCacheService_cacheThreshold;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.TokenCacheService = void 0;
|
|
16
|
+
/**
|
|
17
|
+
* Service for managing token list cache outside of controller state
|
|
18
|
+
* This provides in-memory token metadata storage without persisting to disk
|
|
19
|
+
*/
|
|
20
|
+
class TokenCacheService {
|
|
21
|
+
/**
|
|
22
|
+
* Creates a new TokenCacheService instance
|
|
23
|
+
*
|
|
24
|
+
* @param cacheThreshold - Time in milliseconds before cache is considered stale (default: 24 hours)
|
|
25
|
+
*/
|
|
26
|
+
constructor(cacheThreshold = 24 * 60 * 60 * 1000) {
|
|
27
|
+
_TokenCacheService_cache.set(this, new Map());
|
|
28
|
+
_TokenCacheService_cacheThreshold.set(this, void 0);
|
|
29
|
+
__classPrivateFieldSet(this, _TokenCacheService_cacheThreshold, cacheThreshold, "f");
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get cache entry for a specific chain
|
|
33
|
+
*
|
|
34
|
+
* @param chainId - Chain ID in hex format
|
|
35
|
+
* @returns Cache entry with token list data and timestamp, or undefined if not cached
|
|
36
|
+
*/
|
|
37
|
+
get(chainId) {
|
|
38
|
+
return __classPrivateFieldGet(this, _TokenCacheService_cache, "f").get(chainId);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Set cache entry for a specific chain
|
|
42
|
+
*
|
|
43
|
+
* @param chainId - Chain ID in hex format
|
|
44
|
+
* @param data - Token list data to cache
|
|
45
|
+
* @param timestamp - Optional timestamp (defaults to current time)
|
|
46
|
+
*/
|
|
47
|
+
set(chainId, data, timestamp = Date.now()) {
|
|
48
|
+
__classPrivateFieldGet(this, _TokenCacheService_cache, "f").set(chainId, { data, timestamp });
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Check if cache entry for a chain is still valid (not expired)
|
|
52
|
+
*
|
|
53
|
+
* @param chainId - Chain ID in hex format
|
|
54
|
+
* @returns True if cache exists and is not expired
|
|
55
|
+
*/
|
|
56
|
+
isValid(chainId) {
|
|
57
|
+
const entry = __classPrivateFieldGet(this, _TokenCacheService_cache, "f").get(chainId);
|
|
58
|
+
if (!entry) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
return Date.now() - entry.timestamp < __classPrivateFieldGet(this, _TokenCacheService_cacheThreshold, "f");
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get all cached token lists across all chains
|
|
65
|
+
*
|
|
66
|
+
* @returns Complete cache structure with all chains
|
|
67
|
+
*/
|
|
68
|
+
getAll() {
|
|
69
|
+
const result = {};
|
|
70
|
+
__classPrivateFieldGet(this, _TokenCacheService_cache, "f").forEach((value, key) => {
|
|
71
|
+
result[key] = value;
|
|
72
|
+
});
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Clear all cached token lists
|
|
77
|
+
*/
|
|
78
|
+
clear() {
|
|
79
|
+
__classPrivateFieldGet(this, _TokenCacheService_cache, "f").clear();
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Remove cache entry for a specific chain
|
|
83
|
+
*
|
|
84
|
+
* @param chainId - Chain ID in hex format
|
|
85
|
+
* @returns True if an entry was removed
|
|
86
|
+
*/
|
|
87
|
+
delete(chainId) {
|
|
88
|
+
return __classPrivateFieldGet(this, _TokenCacheService_cache, "f").delete(chainId);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get number of cached chains
|
|
92
|
+
*
|
|
93
|
+
* @returns Count of cached chains
|
|
94
|
+
*/
|
|
95
|
+
get size() {
|
|
96
|
+
return __classPrivateFieldGet(this, _TokenCacheService_cache, "f").size;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
exports.TokenCacheService = TokenCacheService;
|
|
100
|
+
_TokenCacheService_cache = new WeakMap(), _TokenCacheService_cacheThreshold = new WeakMap();
|
|
101
|
+
//# sourceMappingURL=TokenCacheService.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenCacheService.cjs","sourceRoot":"","sources":["../src/TokenCacheService.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAmCA;;;GAGG;AACH,MAAa,iBAAiB;IAK5B;;;;OAIG;IACH,YAAY,iBAAyB,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;QAT/C,mCAA8B,IAAI,GAAG,EAAE,EAAC;QAExC,oDAAwB;QAQ/B,uBAAA,IAAI,qCAAmB,cAAc,MAAA,CAAC;IACxC,CAAC;IAED;;;;;OAKG;IACH,GAAG,CAAC,OAAY;QACd,OAAO,uBAAA,IAAI,gCAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAED;;;;;;OAMG;IACH,GAAG,CAAC,OAAY,EAAE,IAAkB,EAAE,YAAoB,IAAI,CAAC,GAAG,EAAE;QAClE,uBAAA,IAAI,gCAAO,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IAChD,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,OAAY;QAClB,MAAM,KAAK,GAAG,uBAAA,IAAI,gCAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,GAAG,uBAAA,IAAI,yCAAgB,CAAC;IAC7D,CAAC;IAED;;;;OAIG;IACH,MAAM;QACJ,MAAM,MAAM,GAAsB,EAAE,CAAC;QACrC,uBAAA,IAAI,gCAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACjC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,KAAK;QACH,uBAAA,IAAI,gCAAO,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,OAAY;QACjB,OAAO,uBAAA,IAAI,gCAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED;;;;OAIG;IACH,IAAI,IAAI;QACN,OAAO,uBAAA,IAAI,gCAAO,CAAC,IAAI,CAAC;IAC1B,CAAC;CACF;AAvFD,8CAuFC","sourcesContent":["import type { Hex } from '@metamask/utils';\n\n/**\n * Token metadata for a single token\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\n/**\n * Map of token addresses to token metadata\n */\nexport type TokenListMap = Record<string, TokenListToken>;\n\n/**\n * Cache entry containing token list data and timestamp\n */\ntype DataCache = {\n timestamp: number;\n data: TokenListMap;\n};\n\n/**\n * Cache structure mapping chain IDs to token lists\n */\nexport type TokensChainsCache = {\n [chainId: Hex]: DataCache;\n};\n\n/**\n * Service for managing token list cache outside of controller state\n * This provides in-memory token metadata storage without persisting to disk\n */\nexport class TokenCacheService {\n readonly #cache: Map<Hex, DataCache> = new Map();\n\n readonly #cacheThreshold: number;\n\n /**\n * Creates a new TokenCacheService instance\n *\n * @param cacheThreshold - Time in milliseconds before cache is considered stale (default: 24 hours)\n */\n constructor(cacheThreshold: number = 24 * 60 * 60 * 1000) {\n this.#cacheThreshold = cacheThreshold;\n }\n\n /**\n * Get cache entry for a specific chain\n *\n * @param chainId - Chain ID in hex format\n * @returns Cache entry with token list data and timestamp, or undefined if not cached\n */\n get(chainId: Hex): DataCache | undefined {\n return this.#cache.get(chainId);\n }\n\n /**\n * Set cache entry for a specific chain\n *\n * @param chainId - Chain ID in hex format\n * @param data - Token list data to cache\n * @param timestamp - Optional timestamp (defaults to current time)\n */\n set(chainId: Hex, data: TokenListMap, timestamp: number = Date.now()): void {\n this.#cache.set(chainId, { data, timestamp });\n }\n\n /**\n * Check if cache entry for a chain is still valid (not expired)\n *\n * @param chainId - Chain ID in hex format\n * @returns True if cache exists and is not expired\n */\n isValid(chainId: Hex): boolean {\n const entry = this.#cache.get(chainId);\n if (!entry) {\n return false;\n }\n return Date.now() - entry.timestamp < this.#cacheThreshold;\n }\n\n /**\n * Get all cached token lists across all chains\n *\n * @returns Complete cache structure with all chains\n */\n getAll(): TokensChainsCache {\n const result: TokensChainsCache = {};\n this.#cache.forEach((value, key) => {\n result[key] = value;\n });\n return result;\n }\n\n /**\n * Clear all cached token lists\n */\n clear(): void {\n this.#cache.clear();\n }\n\n /**\n * Remove cache entry for a specific chain\n *\n * @param chainId - Chain ID in hex format\n * @returns True if an entry was removed\n */\n delete(chainId: Hex): boolean {\n return this.#cache.delete(chainId);\n }\n\n /**\n * Get number of cached chains\n *\n * @returns Count of cached chains\n */\n get size(): number {\n return this.#cache.size;\n }\n}\n"]}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { Hex } from "@metamask/utils";
|
|
2
|
+
/**
|
|
3
|
+
* Token metadata for a single token
|
|
4
|
+
*/
|
|
5
|
+
export type TokenListToken = {
|
|
6
|
+
name: string;
|
|
7
|
+
symbol: string;
|
|
8
|
+
decimals: number;
|
|
9
|
+
address: string;
|
|
10
|
+
occurrences: number;
|
|
11
|
+
aggregators: string[];
|
|
12
|
+
iconUrl: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Map of token addresses to token metadata
|
|
16
|
+
*/
|
|
17
|
+
export type TokenListMap = Record<string, TokenListToken>;
|
|
18
|
+
/**
|
|
19
|
+
* Cache entry containing token list data and timestamp
|
|
20
|
+
*/
|
|
21
|
+
type DataCache = {
|
|
22
|
+
timestamp: number;
|
|
23
|
+
data: TokenListMap;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Cache structure mapping chain IDs to token lists
|
|
27
|
+
*/
|
|
28
|
+
export type TokensChainsCache = {
|
|
29
|
+
[chainId: Hex]: DataCache;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Service for managing token list cache outside of controller state
|
|
33
|
+
* This provides in-memory token metadata storage without persisting to disk
|
|
34
|
+
*/
|
|
35
|
+
export declare class TokenCacheService {
|
|
36
|
+
#private;
|
|
37
|
+
/**
|
|
38
|
+
* Creates a new TokenCacheService instance
|
|
39
|
+
*
|
|
40
|
+
* @param cacheThreshold - Time in milliseconds before cache is considered stale (default: 24 hours)
|
|
41
|
+
*/
|
|
42
|
+
constructor(cacheThreshold?: number);
|
|
43
|
+
/**
|
|
44
|
+
* Get cache entry for a specific chain
|
|
45
|
+
*
|
|
46
|
+
* @param chainId - Chain ID in hex format
|
|
47
|
+
* @returns Cache entry with token list data and timestamp, or undefined if not cached
|
|
48
|
+
*/
|
|
49
|
+
get(chainId: Hex): DataCache | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Set cache entry for a specific chain
|
|
52
|
+
*
|
|
53
|
+
* @param chainId - Chain ID in hex format
|
|
54
|
+
* @param data - Token list data to cache
|
|
55
|
+
* @param timestamp - Optional timestamp (defaults to current time)
|
|
56
|
+
*/
|
|
57
|
+
set(chainId: Hex, data: TokenListMap, timestamp?: number): void;
|
|
58
|
+
/**
|
|
59
|
+
* Check if cache entry for a chain is still valid (not expired)
|
|
60
|
+
*
|
|
61
|
+
* @param chainId - Chain ID in hex format
|
|
62
|
+
* @returns True if cache exists and is not expired
|
|
63
|
+
*/
|
|
64
|
+
isValid(chainId: Hex): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Get all cached token lists across all chains
|
|
67
|
+
*
|
|
68
|
+
* @returns Complete cache structure with all chains
|
|
69
|
+
*/
|
|
70
|
+
getAll(): TokensChainsCache;
|
|
71
|
+
/**
|
|
72
|
+
* Clear all cached token lists
|
|
73
|
+
*/
|
|
74
|
+
clear(): void;
|
|
75
|
+
/**
|
|
76
|
+
* Remove cache entry for a specific chain
|
|
77
|
+
*
|
|
78
|
+
* @param chainId - Chain ID in hex format
|
|
79
|
+
* @returns True if an entry was removed
|
|
80
|
+
*/
|
|
81
|
+
delete(chainId: Hex): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Get number of cached chains
|
|
84
|
+
*
|
|
85
|
+
* @returns Count of cached chains
|
|
86
|
+
*/
|
|
87
|
+
get size(): number;
|
|
88
|
+
}
|
|
89
|
+
export {};
|
|
90
|
+
//# sourceMappingURL=TokenCacheService.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenCacheService.d.cts","sourceRoot":"","sources":["../src/TokenCacheService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAE1D;;GAEG;AACH,KAAK,SAAS,GAAG;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,YAAY,CAAC;CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,CAAC,OAAO,EAAE,GAAG,GAAG,SAAS,CAAC;CAC3B,CAAC;AAEF;;;GAGG;AACH,qBAAa,iBAAiB;;IAK5B;;;;OAIG;gBACS,cAAc,GAAE,MAA4B;IAIxD;;;;;OAKG;IACH,GAAG,CAAC,OAAO,EAAE,GAAG,GAAG,SAAS,GAAG,SAAS;IAIxC;;;;;;OAMG;IACH,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,GAAE,MAAmB,GAAG,IAAI;IAI3E;;;;;OAKG;IACH,OAAO,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO;IAQ9B;;;;OAIG;IACH,MAAM,IAAI,iBAAiB;IAQ3B;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;;;;OAKG;IACH,MAAM,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO;IAI7B;;;;OAIG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { Hex } from "@metamask/utils";
|
|
2
|
+
/**
|
|
3
|
+
* Token metadata for a single token
|
|
4
|
+
*/
|
|
5
|
+
export type TokenListToken = {
|
|
6
|
+
name: string;
|
|
7
|
+
symbol: string;
|
|
8
|
+
decimals: number;
|
|
9
|
+
address: string;
|
|
10
|
+
occurrences: number;
|
|
11
|
+
aggregators: string[];
|
|
12
|
+
iconUrl: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Map of token addresses to token metadata
|
|
16
|
+
*/
|
|
17
|
+
export type TokenListMap = Record<string, TokenListToken>;
|
|
18
|
+
/**
|
|
19
|
+
* Cache entry containing token list data and timestamp
|
|
20
|
+
*/
|
|
21
|
+
type DataCache = {
|
|
22
|
+
timestamp: number;
|
|
23
|
+
data: TokenListMap;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Cache structure mapping chain IDs to token lists
|
|
27
|
+
*/
|
|
28
|
+
export type TokensChainsCache = {
|
|
29
|
+
[chainId: Hex]: DataCache;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Service for managing token list cache outside of controller state
|
|
33
|
+
* This provides in-memory token metadata storage without persisting to disk
|
|
34
|
+
*/
|
|
35
|
+
export declare class TokenCacheService {
|
|
36
|
+
#private;
|
|
37
|
+
/**
|
|
38
|
+
* Creates a new TokenCacheService instance
|
|
39
|
+
*
|
|
40
|
+
* @param cacheThreshold - Time in milliseconds before cache is considered stale (default: 24 hours)
|
|
41
|
+
*/
|
|
42
|
+
constructor(cacheThreshold?: number);
|
|
43
|
+
/**
|
|
44
|
+
* Get cache entry for a specific chain
|
|
45
|
+
*
|
|
46
|
+
* @param chainId - Chain ID in hex format
|
|
47
|
+
* @returns Cache entry with token list data and timestamp, or undefined if not cached
|
|
48
|
+
*/
|
|
49
|
+
get(chainId: Hex): DataCache | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Set cache entry for a specific chain
|
|
52
|
+
*
|
|
53
|
+
* @param chainId - Chain ID in hex format
|
|
54
|
+
* @param data - Token list data to cache
|
|
55
|
+
* @param timestamp - Optional timestamp (defaults to current time)
|
|
56
|
+
*/
|
|
57
|
+
set(chainId: Hex, data: TokenListMap, timestamp?: number): void;
|
|
58
|
+
/**
|
|
59
|
+
* Check if cache entry for a chain is still valid (not expired)
|
|
60
|
+
*
|
|
61
|
+
* @param chainId - Chain ID in hex format
|
|
62
|
+
* @returns True if cache exists and is not expired
|
|
63
|
+
*/
|
|
64
|
+
isValid(chainId: Hex): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Get all cached token lists across all chains
|
|
67
|
+
*
|
|
68
|
+
* @returns Complete cache structure with all chains
|
|
69
|
+
*/
|
|
70
|
+
getAll(): TokensChainsCache;
|
|
71
|
+
/**
|
|
72
|
+
* Clear all cached token lists
|
|
73
|
+
*/
|
|
74
|
+
clear(): void;
|
|
75
|
+
/**
|
|
76
|
+
* Remove cache entry for a specific chain
|
|
77
|
+
*
|
|
78
|
+
* @param chainId - Chain ID in hex format
|
|
79
|
+
* @returns True if an entry was removed
|
|
80
|
+
*/
|
|
81
|
+
delete(chainId: Hex): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Get number of cached chains
|
|
84
|
+
*
|
|
85
|
+
* @returns Count of cached chains
|
|
86
|
+
*/
|
|
87
|
+
get size(): number;
|
|
88
|
+
}
|
|
89
|
+
export {};
|
|
90
|
+
//# sourceMappingURL=TokenCacheService.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenCacheService.d.mts","sourceRoot":"","sources":["../src/TokenCacheService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAE1D;;GAEG;AACH,KAAK,SAAS,GAAG;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,YAAY,CAAC;CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,CAAC,OAAO,EAAE,GAAG,GAAG,SAAS,CAAC;CAC3B,CAAC;AAEF;;;GAGG;AACH,qBAAa,iBAAiB;;IAK5B;;;;OAIG;gBACS,cAAc,GAAE,MAA4B;IAIxD;;;;;OAKG;IACH,GAAG,CAAC,OAAO,EAAE,GAAG,GAAG,SAAS,GAAG,SAAS;IAIxC;;;;;;OAMG;IACH,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,GAAE,MAAmB,GAAG,IAAI;IAI3E;;;;;OAKG;IACH,OAAO,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO;IAQ9B;;;;OAIG;IACH,MAAM,IAAI,iBAAiB;IAQ3B;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;;;;OAKG;IACH,MAAM,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO;IAI7B;;;;OAIG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
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");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _TokenCacheService_cache, _TokenCacheService_cacheThreshold;
|
|
13
|
+
/**
|
|
14
|
+
* Service for managing token list cache outside of controller state
|
|
15
|
+
* This provides in-memory token metadata storage without persisting to disk
|
|
16
|
+
*/
|
|
17
|
+
export class TokenCacheService {
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new TokenCacheService instance
|
|
20
|
+
*
|
|
21
|
+
* @param cacheThreshold - Time in milliseconds before cache is considered stale (default: 24 hours)
|
|
22
|
+
*/
|
|
23
|
+
constructor(cacheThreshold = 24 * 60 * 60 * 1000) {
|
|
24
|
+
_TokenCacheService_cache.set(this, new Map());
|
|
25
|
+
_TokenCacheService_cacheThreshold.set(this, void 0);
|
|
26
|
+
__classPrivateFieldSet(this, _TokenCacheService_cacheThreshold, cacheThreshold, "f");
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get cache entry for a specific chain
|
|
30
|
+
*
|
|
31
|
+
* @param chainId - Chain ID in hex format
|
|
32
|
+
* @returns Cache entry with token list data and timestamp, or undefined if not cached
|
|
33
|
+
*/
|
|
34
|
+
get(chainId) {
|
|
35
|
+
return __classPrivateFieldGet(this, _TokenCacheService_cache, "f").get(chainId);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Set cache entry for a specific chain
|
|
39
|
+
*
|
|
40
|
+
* @param chainId - Chain ID in hex format
|
|
41
|
+
* @param data - Token list data to cache
|
|
42
|
+
* @param timestamp - Optional timestamp (defaults to current time)
|
|
43
|
+
*/
|
|
44
|
+
set(chainId, data, timestamp = Date.now()) {
|
|
45
|
+
__classPrivateFieldGet(this, _TokenCacheService_cache, "f").set(chainId, { data, timestamp });
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Check if cache entry for a chain is still valid (not expired)
|
|
49
|
+
*
|
|
50
|
+
* @param chainId - Chain ID in hex format
|
|
51
|
+
* @returns True if cache exists and is not expired
|
|
52
|
+
*/
|
|
53
|
+
isValid(chainId) {
|
|
54
|
+
const entry = __classPrivateFieldGet(this, _TokenCacheService_cache, "f").get(chainId);
|
|
55
|
+
if (!entry) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
return Date.now() - entry.timestamp < __classPrivateFieldGet(this, _TokenCacheService_cacheThreshold, "f");
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get all cached token lists across all chains
|
|
62
|
+
*
|
|
63
|
+
* @returns Complete cache structure with all chains
|
|
64
|
+
*/
|
|
65
|
+
getAll() {
|
|
66
|
+
const result = {};
|
|
67
|
+
__classPrivateFieldGet(this, _TokenCacheService_cache, "f").forEach((value, key) => {
|
|
68
|
+
result[key] = value;
|
|
69
|
+
});
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Clear all cached token lists
|
|
74
|
+
*/
|
|
75
|
+
clear() {
|
|
76
|
+
__classPrivateFieldGet(this, _TokenCacheService_cache, "f").clear();
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Remove cache entry for a specific chain
|
|
80
|
+
*
|
|
81
|
+
* @param chainId - Chain ID in hex format
|
|
82
|
+
* @returns True if an entry was removed
|
|
83
|
+
*/
|
|
84
|
+
delete(chainId) {
|
|
85
|
+
return __classPrivateFieldGet(this, _TokenCacheService_cache, "f").delete(chainId);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get number of cached chains
|
|
89
|
+
*
|
|
90
|
+
* @returns Count of cached chains
|
|
91
|
+
*/
|
|
92
|
+
get size() {
|
|
93
|
+
return __classPrivateFieldGet(this, _TokenCacheService_cache, "f").size;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
_TokenCacheService_cache = new WeakMap(), _TokenCacheService_cacheThreshold = new WeakMap();
|
|
97
|
+
//# sourceMappingURL=TokenCacheService.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenCacheService.mjs","sourceRoot":"","sources":["../src/TokenCacheService.ts"],"names":[],"mappings":";;;;;;;;;;;;AAmCA;;;GAGG;AACH,MAAM,OAAO,iBAAiB;IAK5B;;;;OAIG;IACH,YAAY,iBAAyB,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;QAT/C,mCAA8B,IAAI,GAAG,EAAE,EAAC;QAExC,oDAAwB;QAQ/B,uBAAA,IAAI,qCAAmB,cAAc,MAAA,CAAC;IACxC,CAAC;IAED;;;;;OAKG;IACH,GAAG,CAAC,OAAY;QACd,OAAO,uBAAA,IAAI,gCAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAED;;;;;;OAMG;IACH,GAAG,CAAC,OAAY,EAAE,IAAkB,EAAE,YAAoB,IAAI,CAAC,GAAG,EAAE;QAClE,uBAAA,IAAI,gCAAO,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IAChD,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,OAAY;QAClB,MAAM,KAAK,GAAG,uBAAA,IAAI,gCAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,GAAG,uBAAA,IAAI,yCAAgB,CAAC;IAC7D,CAAC;IAED;;;;OAIG;IACH,MAAM;QACJ,MAAM,MAAM,GAAsB,EAAE,CAAC;QACrC,uBAAA,IAAI,gCAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACjC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,KAAK;QACH,uBAAA,IAAI,gCAAO,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,OAAY;QACjB,OAAO,uBAAA,IAAI,gCAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED;;;;OAIG;IACH,IAAI,IAAI;QACN,OAAO,uBAAA,IAAI,gCAAO,CAAC,IAAI,CAAC;IAC1B,CAAC;CACF","sourcesContent":["import type { Hex } from '@metamask/utils';\n\n/**\n * Token metadata for a single token\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\n/**\n * Map of token addresses to token metadata\n */\nexport type TokenListMap = Record<string, TokenListToken>;\n\n/**\n * Cache entry containing token list data and timestamp\n */\ntype DataCache = {\n timestamp: number;\n data: TokenListMap;\n};\n\n/**\n * Cache structure mapping chain IDs to token lists\n */\nexport type TokensChainsCache = {\n [chainId: Hex]: DataCache;\n};\n\n/**\n * Service for managing token list cache outside of controller state\n * This provides in-memory token metadata storage without persisting to disk\n */\nexport class TokenCacheService {\n readonly #cache: Map<Hex, DataCache> = new Map();\n\n readonly #cacheThreshold: number;\n\n /**\n * Creates a new TokenCacheService instance\n *\n * @param cacheThreshold - Time in milliseconds before cache is considered stale (default: 24 hours)\n */\n constructor(cacheThreshold: number = 24 * 60 * 60 * 1000) {\n this.#cacheThreshold = cacheThreshold;\n }\n\n /**\n * Get cache entry for a specific chain\n *\n * @param chainId - Chain ID in hex format\n * @returns Cache entry with token list data and timestamp, or undefined if not cached\n */\n get(chainId: Hex): DataCache | undefined {\n return this.#cache.get(chainId);\n }\n\n /**\n * Set cache entry for a specific chain\n *\n * @param chainId - Chain ID in hex format\n * @param data - Token list data to cache\n * @param timestamp - Optional timestamp (defaults to current time)\n */\n set(chainId: Hex, data: TokenListMap, timestamp: number = Date.now()): void {\n this.#cache.set(chainId, { data, timestamp });\n }\n\n /**\n * Check if cache entry for a chain is still valid (not expired)\n *\n * @param chainId - Chain ID in hex format\n * @returns True if cache exists and is not expired\n */\n isValid(chainId: Hex): boolean {\n const entry = this.#cache.get(chainId);\n if (!entry) {\n return false;\n }\n return Date.now() - entry.timestamp < this.#cacheThreshold;\n }\n\n /**\n * Get all cached token lists across all chains\n *\n * @returns Complete cache structure with all chains\n */\n getAll(): TokensChainsCache {\n const result: TokensChainsCache = {};\n this.#cache.forEach((value, key) => {\n result[key] = value;\n });\n return result;\n }\n\n /**\n * Clear all cached token lists\n */\n clear(): void {\n this.#cache.clear();\n }\n\n /**\n * Remove cache entry for a specific chain\n *\n * @param chainId - Chain ID in hex format\n * @returns True if an entry was removed\n */\n delete(chainId: Hex): boolean {\n return this.#cache.delete(chainId);\n }\n\n /**\n * Get number of cached chains\n *\n * @returns Count of cached chains\n */\n get size(): number {\n return this.#cache.size;\n }\n}\n"]}
|
|
@@ -137,8 +137,7 @@ class TokenDetectionController extends (0, polling_controller_1.StaticIntervalPo
|
|
|
137
137
|
__classPrivateFieldSet(this, _TokenDetectionController_disabled, disabled, "f");
|
|
138
138
|
this.setIntervalLength(interval);
|
|
139
139
|
__classPrivateFieldSet(this, _TokenDetectionController_selectedAccountId, __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getSelectedAccount).call(this).id, "f");
|
|
140
|
-
|
|
141
|
-
__classPrivateFieldSet(this, _TokenDetectionController_tokensChainsCache, tokensChainsCache, "f");
|
|
140
|
+
__classPrivateFieldSet(this, _TokenDetectionController_tokensChainsCache, this.messenger.call('TokenListController:getAllTokenLists'), "f");
|
|
142
141
|
const { useTokenDetection: defaultUseTokenDetection } = this.messenger.call('PreferencesController:getState');
|
|
143
142
|
__classPrivateFieldSet(this, _TokenDetectionController_isDetectionEnabledFromPreferences, defaultUseTokenDetection, "f");
|
|
144
143
|
__classPrivateFieldSet(this, _TokenDetectionController_getBalancesInSingleCall, getBalancesInSingleCall, "f");
|
|
@@ -303,7 +302,7 @@ _TokenDetectionController_intervalId = new WeakMap(), _TokenDetectionController_
|
|
|
303
302
|
__classPrivateFieldSet(this, _TokenDetectionController_isUnlocked, false, "f");
|
|
304
303
|
__classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_stopPolling).call(this);
|
|
305
304
|
});
|
|
306
|
-
this.messenger.subscribe('TokenListController:
|
|
305
|
+
this.messenger.subscribe('TokenListController:cacheUpdate', async (tokensChainsCache) => {
|
|
307
306
|
const isEqualValues = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_compareTokensChainsCache).call(this, tokensChainsCache, __classPrivateFieldGet(this, _TokenDetectionController_tokensChainsCache, "f"));
|
|
308
307
|
if (!isEqualValues) {
|
|
309
308
|
await __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_restartTokenDetection).call(this);
|
|
@@ -442,8 +441,7 @@ async function _TokenDetectionController_restartTokenDetection({ selectedAddress
|
|
|
442
441
|
__classPrivateFieldSet(this, _TokenDetectionController_tokensChainsCache, __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getConvertedStaticMainnetTokenList).call(this), "f");
|
|
443
442
|
}
|
|
444
443
|
else {
|
|
445
|
-
|
|
446
|
-
__classPrivateFieldSet(this, _TokenDetectionController_tokensChainsCache, tokensChainsCache ?? {}, "f");
|
|
444
|
+
__classPrivateFieldSet(this, _TokenDetectionController_tokensChainsCache, this.messenger.call('TokenListController:getAllTokenLists') ?? {}, "f");
|
|
447
445
|
}
|
|
448
446
|
return true;
|
|
449
447
|
}, _TokenDetectionController_detectTokensUsingRpc = async function _TokenDetectionController_detectTokensUsingRpc(chainsToDetectUsingRpc, addressToDetect) {
|
|
@@ -528,10 +526,9 @@ async function _TokenDetectionController_addDetectedTokensViaAPI({ selectedAddre
|
|
|
528
526
|
for (const chainId of chainIds) {
|
|
529
527
|
const isTokenDetectionInactiveInMainnet = !__classPrivateFieldGet(this, _TokenDetectionController_isDetectionEnabledFromPreferences, "f") &&
|
|
530
528
|
chainId === controller_utils_1.ChainId.mainnet;
|
|
531
|
-
const { tokensChainsCache } = this.messenger.call('TokenListController:getState');
|
|
532
529
|
__classPrivateFieldSet(this, _TokenDetectionController_tokensChainsCache, isTokenDetectionInactiveInMainnet
|
|
533
530
|
? __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getConvertedStaticMainnetTokenList).call(this)
|
|
534
|
-
: (
|
|
531
|
+
: (this.messenger.call('TokenListController:getAllTokenLists') ?? {}), "f");
|
|
535
532
|
// Generate token candidates based on chainId and selectedAddress
|
|
536
533
|
const tokenCandidateSlices = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getSlicesOfTokensToDetect).call(this, {
|
|
537
534
|
chainId,
|