@exodus/assets-feature 8.6.0 → 8.7.1
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/atoms/multi-address-mode.js +1 -0
- package/client/asset-client-interface.js +1 -0
- package/module/assets-module.js +19 -11
- package/module/utils.js +1 -0
- package/package.json +5 -5
- package/redux/selectors/index.js +1 -0
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.1](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/assets-feature@8.7.0...@exodus/assets-feature@8.7.1) (2025-10-03)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- fix: loading custom tokens when base asset doesn't exist (#13998)
|
|
11
|
+
|
|
12
|
+
## [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)
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
- feat: filter out invalid custom token names in addRemoteTokens (#13839)
|
|
17
|
+
|
|
6
18
|
## [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)
|
|
7
19
|
|
|
8
20
|
### Features
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { combine, compute, createStorageAtomFactory } from '@exodus/atoms'
|
|
2
2
|
import { omitBy } from '@exodus/basic-utils'
|
|
3
3
|
import { createFusionAtom } from '@exodus/fusion-atoms'
|
|
4
|
+
// eslint-disable-next-line no-restricted-imports -- TODO: Fix this the next time the file is edited.
|
|
4
5
|
import lodash from 'lodash'
|
|
5
6
|
|
|
6
7
|
const { isUndefined } = lodash
|
package/module/assets-module.js
CHANGED
|
@@ -4,7 +4,8 @@ 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
|
+
// eslint-disable-next-line no-restricted-imports -- TODO: Fix this the next time the file is edited.
|
|
8
9
|
import lodash from 'lodash'
|
|
9
10
|
import assert from 'minimalistic-assert'
|
|
10
11
|
import { memoizeLruCache } from '@exodus/asset-lib'
|
|
@@ -26,7 +27,8 @@ import { validateCustomToken, isValidCustomToken } from '@exodus/asset-schema-va
|
|
|
26
27
|
import makeConcurrent from 'make-concurrent'
|
|
27
28
|
import oldToNewStyleTokenNames from '@exodus/asset-legacy-token-name-mapping'
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
// eslint-disable-next-line @exodus/basic-utils/prefer-basic-utils
|
|
31
|
+
const { get, isEmpty, once, uniq, chunk, pick } = lodash
|
|
30
32
|
|
|
31
33
|
const getFetchCacheKey = (baseAssetName, assetId) => `${assetId}-${baseAssetName}`
|
|
32
34
|
|
|
@@ -110,7 +112,12 @@ export class AssetsModule {
|
|
|
110
112
|
this.#fetchCacheExpiry = config.fetchCacheExpiry ?? CT_FETCH_CACHE_EXPIRY
|
|
111
113
|
this.#fetchival = createFetchival({ fetch })
|
|
112
114
|
this.#logger = logger
|
|
113
|
-
this.#invalidTokenNames = new Set(
|
|
115
|
+
this.#invalidTokenNames = new Set([
|
|
116
|
+
...Object.keys(oldToNewStyleTokenNames).filter(
|
|
117
|
+
(name) => name !== oldToNewStyleTokenNames[name]
|
|
118
|
+
),
|
|
119
|
+
...(config.invalidTokenNames || []),
|
|
120
|
+
])
|
|
114
121
|
}
|
|
115
122
|
|
|
116
123
|
#setRegistry = (registry) => {
|
|
@@ -168,7 +175,7 @@ export class AssetsModule {
|
|
|
168
175
|
const storedTokens = await this.#readCustomTokens()
|
|
169
176
|
const tokens = pickBy(storedTokens, ({ baseAssetName }) => {
|
|
170
177
|
const baseAsset = this.getAsset(baseAssetName)
|
|
171
|
-
return baseAsset
|
|
178
|
+
return baseAsset?.api?.hasFeature?.('customTokens')
|
|
172
179
|
})
|
|
173
180
|
|
|
174
181
|
// tokens may be:
|
|
@@ -179,7 +186,7 @@ export class AssetsModule {
|
|
|
179
186
|
const { added, updated } = this.#handleFetchedTokens(Object.values(tokens))
|
|
180
187
|
this.#flushChanges({ added, updated })
|
|
181
188
|
} catch (e) {
|
|
182
|
-
this.#logger.
|
|
189
|
+
this.#logger.error('error reading custom tokens from storage: ' + e.message, e)
|
|
183
190
|
}
|
|
184
191
|
})
|
|
185
192
|
|
|
@@ -382,14 +389,16 @@ export class AssetsModule {
|
|
|
382
389
|
|
|
383
390
|
addRemoteTokens = async ({ tokenNames, allowedStatusList }) => {
|
|
384
391
|
this.#assertCustomTokensStorageSupported()
|
|
392
|
+
assert(Array.isArray(tokenNames), 'addRemoteTokens: expected array')
|
|
385
393
|
assert(
|
|
386
394
|
!allowedStatusList || Array.isArray(allowedStatusList),
|
|
387
395
|
'addRemoteTokens: expected `allowedStatusList` to be an array'
|
|
388
396
|
)
|
|
389
397
|
|
|
390
398
|
const assets = this.getAssets()
|
|
399
|
+
const validNames = tokenNames.filter((name) => this.#validCustomTokenName({ name }))
|
|
391
400
|
const [tokenNamesToUpdate, tokenNamesToFetch] = partition(
|
|
392
|
-
|
|
401
|
+
validNames,
|
|
393
402
|
(tokenName) => !!assets[tokenName]
|
|
394
403
|
)
|
|
395
404
|
|
|
@@ -629,7 +638,7 @@ export class AssetsModule {
|
|
|
629
638
|
parentNames.push(...updates)
|
|
630
639
|
}
|
|
631
640
|
} catch (err) {
|
|
632
|
-
this.#logger.
|
|
641
|
+
this.#logger.error('Handle fetched custom tokens error: ' + err.message, err)
|
|
633
642
|
}
|
|
634
643
|
}
|
|
635
644
|
|
|
@@ -680,6 +689,8 @@ export class AssetsModule {
|
|
|
680
689
|
}
|
|
681
690
|
}
|
|
682
691
|
|
|
692
|
+
#validCustomTokenName = ({ name }) => !this.#invalidTokenNames.has(name)
|
|
693
|
+
|
|
683
694
|
// Custom Tokens storage
|
|
684
695
|
|
|
685
696
|
#assertCustomTokensStorageSupported = () => {
|
|
@@ -693,10 +704,7 @@ export class AssetsModule {
|
|
|
693
704
|
|
|
694
705
|
const tokens = await this.#storage.get(this.#storageDataKey)
|
|
695
706
|
const normalizedTokens = mapValues(tokens, normalizeToken)
|
|
696
|
-
return pickBy(
|
|
697
|
-
normalizedTokens,
|
|
698
|
-
({ name }) => !this.#invalidTokenNames.has(name) || name === oldToNewStyleTokenNames[name]
|
|
699
|
-
)
|
|
707
|
+
return pickBy(normalizedTokens, this.#validCustomTokenName)
|
|
700
708
|
}
|
|
701
709
|
|
|
702
710
|
#updateStoredCustomTokens = async (tokens) => {
|
package/module/utils.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CT_STATUS as STATUS } from '@exodus/assets'
|
|
2
2
|
import { pick } from '@exodus/basic-utils'
|
|
3
|
+
// eslint-disable-next-line no-restricted-imports -- TODO: Fix this the next time the file is edited.
|
|
3
4
|
import lodash from 'lodash'
|
|
4
5
|
import assert from 'minimalistic-assert'
|
|
5
6
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/assets-feature",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.7.1",
|
|
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",
|
|
@@ -68,12 +68,12 @@
|
|
|
68
68
|
"@exodus/fusion-local": "^2.1.0",
|
|
69
69
|
"@exodus/keychain": "^7.3.0",
|
|
70
70
|
"@exodus/logger": "^1.2.3",
|
|
71
|
-
"@exodus/models": "^12.
|
|
71
|
+
"@exodus/models": "^12.17.1",
|
|
72
72
|
"@exodus/osmosis-plugin": "^1.3.3",
|
|
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.2",
|
|
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": "c8b9b92a330150086c1ecae88bd9a063250238e3"
|
|
86
86
|
}
|
package/redux/selectors/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { keyBy } from '@exodus/basic-utils'
|
|
2
2
|
import { createSelector } from 'reselect'
|
|
3
3
|
|
|
4
|
+
// eslint-disable-next-line no-restricted-imports -- TODO: Fix this the next time the file is edited.
|
|
4
5
|
import lodash from 'lodash'
|
|
5
6
|
|
|
6
7
|
const { memoize } = lodash // eslint-disable-line @exodus/basic-utils/prefer-basic-utils
|