@exodus/assets-feature 8.5.0 → 8.7.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 +12 -0
- package/module/assets-module.js +35 -14
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [8.7.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/assets-feature@8.6.0...@exodus/assets-feature@8.7.0) (2025-09-24)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- feat: filter out invalid custom token names in addRemoteTokens (#13839)
|
|
11
|
+
|
|
12
|
+
## [8.6.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/assets-feature@8.5.0...@exodus/assets-feature@8.6.0) (2025-09-19)
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
- feat: batch addRemoteTokens requests by 50 (#13858)
|
|
17
|
+
|
|
6
18
|
## [8.5.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/assets-feature@8.4.0...@exodus/assets-feature@8.5.0) (2025-09-18)
|
|
7
19
|
|
|
8
20
|
### Features
|
package/module/assets-module.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
CT_STATUS as STATUS,
|
|
5
5
|
CT_UPDATEABLE_PROPERTIES,
|
|
6
6
|
} from '@exodus/assets'
|
|
7
|
-
import { keyBy, mapValues, partition,
|
|
7
|
+
import { keyBy, mapValues, partition, pickBy, difference } from '@exodus/basic-utils'
|
|
8
8
|
import lodash from 'lodash'
|
|
9
9
|
import assert from 'minimalistic-assert'
|
|
10
10
|
import { memoizeLruCache } from '@exodus/asset-lib'
|
|
@@ -26,7 +26,8 @@ import { validateCustomToken, isValidCustomToken } from '@exodus/asset-schema-va
|
|
|
26
26
|
import makeConcurrent from 'make-concurrent'
|
|
27
27
|
import oldToNewStyleTokenNames from '@exodus/asset-legacy-token-name-mapping'
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
// eslint-disable-next-line @exodus/basic-utils/prefer-basic-utils
|
|
30
|
+
const { get, isEmpty, once, uniq, chunk, pick } = lodash
|
|
30
31
|
|
|
31
32
|
const getFetchCacheKey = (baseAssetName, assetId) => `${assetId}-${baseAssetName}`
|
|
32
33
|
|
|
@@ -110,7 +111,12 @@ export class AssetsModule {
|
|
|
110
111
|
this.#fetchCacheExpiry = config.fetchCacheExpiry ?? CT_FETCH_CACHE_EXPIRY
|
|
111
112
|
this.#fetchival = createFetchival({ fetch })
|
|
112
113
|
this.#logger = logger
|
|
113
|
-
this.#invalidTokenNames = new Set(
|
|
114
|
+
this.#invalidTokenNames = new Set([
|
|
115
|
+
...Object.keys(oldToNewStyleTokenNames).filter(
|
|
116
|
+
(name) => name !== oldToNewStyleTokenNames[name]
|
|
117
|
+
),
|
|
118
|
+
...(config.invalidTokenNames || []),
|
|
119
|
+
])
|
|
114
120
|
}
|
|
115
121
|
|
|
116
122
|
#setRegistry = (registry) => {
|
|
@@ -382,26 +388,26 @@ export class AssetsModule {
|
|
|
382
388
|
|
|
383
389
|
addRemoteTokens = async ({ tokenNames, allowedStatusList }) => {
|
|
384
390
|
this.#assertCustomTokensStorageSupported()
|
|
391
|
+
assert(Array.isArray(tokenNames), 'addRemoteTokens: expected array')
|
|
385
392
|
assert(
|
|
386
393
|
!allowedStatusList || Array.isArray(allowedStatusList),
|
|
387
394
|
'addRemoteTokens: expected `allowedStatusList` to be an array'
|
|
388
395
|
)
|
|
389
396
|
|
|
390
397
|
const assets = this.getAssets()
|
|
398
|
+
const validNames = tokenNames.filter((name) => this.#validCustomTokenName({ name }))
|
|
391
399
|
const [tokenNamesToUpdate, tokenNamesToFetch] = partition(
|
|
392
|
-
|
|
400
|
+
validNames,
|
|
393
401
|
(tokenName) => !!assets[tokenName]
|
|
394
402
|
)
|
|
395
403
|
|
|
396
404
|
const tokens = tokenNamesToUpdate.map((tokenName) => assets[tokenName])
|
|
397
405
|
|
|
398
406
|
if (tokenNamesToFetch.length > 0) {
|
|
399
|
-
const
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
const fetchedTokens = await this.#fetch('tokens', body, 'tokens')
|
|
407
|
+
const fetchedTokens = await this.#fetchTokensByNames({
|
|
408
|
+
tokenNames: tokenNamesToFetch,
|
|
409
|
+
allowedStatusList,
|
|
410
|
+
})
|
|
405
411
|
const validTokens = fetchedTokens.filter(this.#isValidCustomToken).map(normalizeToken)
|
|
406
412
|
|
|
407
413
|
if (validTokens && validTokens.length !== fetchedTokens.length) {
|
|
@@ -501,6 +507,22 @@ export class AssetsModule {
|
|
|
501
507
|
this.getAsset(assetName).api?.hasFeature?.('customTokens')
|
|
502
508
|
)
|
|
503
509
|
|
|
510
|
+
#fetchTokensByNames = async ({ tokenNames, allowedStatusList }) => {
|
|
511
|
+
const pages = chunk(tokenNames, CTR_TOKENS_LIMIT)
|
|
512
|
+
|
|
513
|
+
const pagePromises = pages.map(async (page) => {
|
|
514
|
+
const body = {
|
|
515
|
+
tokenNames: page,
|
|
516
|
+
...(allowedStatusList && { lifecycleStatus: allowedStatusList }),
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
return this.#fetch('tokens', body, 'tokens')
|
|
520
|
+
})
|
|
521
|
+
|
|
522
|
+
const pagesResults = await Promise.all(pagePromises)
|
|
523
|
+
return pagesResults.flat()
|
|
524
|
+
}
|
|
525
|
+
|
|
504
526
|
#fetchUpdates = async (assetVersions) => {
|
|
505
527
|
const updatedTokens = await this.#fetch('updates', assetVersions, 'tokens')
|
|
506
528
|
const validatedTokens = updatedTokens.filter(this.#isValidCustomToken).map(normalizeToken)
|
|
@@ -666,6 +688,8 @@ export class AssetsModule {
|
|
|
666
688
|
}
|
|
667
689
|
}
|
|
668
690
|
|
|
691
|
+
#validCustomTokenName = ({ name }) => !this.#invalidTokenNames.has(name)
|
|
692
|
+
|
|
669
693
|
// Custom Tokens storage
|
|
670
694
|
|
|
671
695
|
#assertCustomTokensStorageSupported = () => {
|
|
@@ -679,10 +703,7 @@ export class AssetsModule {
|
|
|
679
703
|
|
|
680
704
|
const tokens = await this.#storage.get(this.#storageDataKey)
|
|
681
705
|
const normalizedTokens = mapValues(tokens, normalizeToken)
|
|
682
|
-
return pickBy(
|
|
683
|
-
normalizedTokens,
|
|
684
|
-
({ name }) => !this.#invalidTokenNames.has(name) || name === oldToNewStyleTokenNames[name]
|
|
685
|
-
)
|
|
706
|
+
return pickBy(normalizedTokens, this.#validCustomTokenName)
|
|
686
707
|
}
|
|
687
708
|
|
|
688
709
|
#updateStoredCustomTokens = async (tokens) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/assets-feature",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.7.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "This Exodus SDK feature provides access to instances of all blockchain asset adapters supported by the wallet, and enables you to search for and add custom tokens at runtime.",
|
|
6
6
|
"type": "module",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"@exodus/asset-schema-validation": "^1.0.1",
|
|
41
41
|
"@exodus/assets": "^11.3.0",
|
|
42
42
|
"@exodus/atoms": "^9.0.0",
|
|
43
|
-
"@exodus/basic-utils": "^
|
|
43
|
+
"@exodus/basic-utils": "^3.6.0",
|
|
44
44
|
"@exodus/fetch": "^1.3.0",
|
|
45
45
|
"@exodus/fusion-atoms": "^1.4.0",
|
|
46
46
|
"@exodus/timer": "^1.1.2",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"@exodus/public-key-provider": "^4.2.0",
|
|
74
74
|
"@exodus/redux-dependency-injection": "^4.1.2",
|
|
75
75
|
"@exodus/storage-memory": "^2.3.0",
|
|
76
|
-
"@exodus/wallet-accounts": "^
|
|
76
|
+
"@exodus/wallet-accounts": "^20.0.0",
|
|
77
77
|
"@exodus/wild-emitter": "^1.0.0",
|
|
78
78
|
"events": "^3.3.0",
|
|
79
79
|
"msw": "^2.0.0",
|
|
@@ -82,5 +82,5 @@
|
|
|
82
82
|
"publishConfig": {
|
|
83
83
|
"access": "public"
|
|
84
84
|
},
|
|
85
|
-
"gitHead": "
|
|
85
|
+
"gitHead": "dde97e04554c3f37aab76ac0c307ba9bcd0673a1"
|
|
86
86
|
}
|