@exodus/assets-feature 7.4.1 → 8.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 CHANGED
@@ -3,6 +3,26 @@
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.1.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/assets-feature@8.0.0...@exodus/assets-feature@8.1.0) (2025-05-19)
7
+
8
+ ### Features
9
+
10
+ - feat: add support for filtering invalid token names (#12443)
11
+
12
+ ### Bug Fixes
13
+
14
+ - fix: asset storage race condition (#12577)
15
+
16
+ ## [8.0.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/assets-feature@7.4.1...@exodus/assets-feature@8.0.0) (2025-05-19)
17
+
18
+ ### ⚠ BREAKING CHANGES
19
+
20
+ - createMultiAddressModeSelector not fallback to bitcoin (#12569)
21
+
22
+ ### Bug Fixes
23
+
24
+ - fix!: createMultiAddressModeSelector not fallback to bitcoin (#12569)
25
+
6
26
  ## [7.4.1](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/assets-feature@7.4.0...@exodus/assets-feature@7.4.1) (2025-05-15)
7
27
 
8
28
  ### Bug Fixes
@@ -1,4 +1,3 @@
1
- /* eslint-disable @exodus/mutable/no-param-reassign-prop-only */
2
1
  import {
3
2
  createAssetRegistry,
4
3
  CT_DEFAULT_SERVER,
@@ -18,6 +17,8 @@ import {
18
17
  import { getAssetFromAssetId, getFetchErrorMessage, isDisabledCustomToken } from './utils.js'
19
18
  import createFetchival from '@exodus/fetch/create-fetchival'
20
19
  import { validateCustomToken, isValidCustomToken } from '@exodus/asset-schema-validation'
20
+ import makeConcurrent from 'make-concurrent'
21
+ import oldToNewStyleTokenNames from '@exodus/asset-legacy-token-name-mapping'
21
22
 
22
23
  const { get, isEmpty, once, uniq } = lodash
23
24
 
@@ -89,6 +90,7 @@ export class AssetsModule {
89
90
  #assetsAtom
90
91
  #fetchival
91
92
  #logger
93
+ #invalidTokenNames
92
94
 
93
95
  constructor({
94
96
  storage,
@@ -122,6 +124,7 @@ export class AssetsModule {
122
124
  this.#fetchCacheExpiry = config.fetchCacheExpiry ?? CT_FETCH_CACHE_EXPIRY
123
125
  this.#fetchival = createFetchival({ fetch })
124
126
  this.#logger = logger
127
+ this.#invalidTokenNames = new Set(Object.keys(oldToNewStyleTokenNames))
125
128
  }
126
129
 
127
130
  #setRegistry = (registry) => {
@@ -599,23 +602,27 @@ export class AssetsModule {
599
602
  if (!this.#storage) return []
600
603
 
601
604
  const tokens = await this.#storage.get(this.#storageDataKey)
602
- return mapValues(tokens, normalizeToken)
605
+ const normalizedTokens = mapValues(tokens, normalizeToken)
606
+ return pickBy(normalizedTokens, ({ name }) => !this.#invalidTokenNames.has(name))
603
607
  }
604
608
 
605
- #storeCustomTokens = async (tokens) => {
606
- const _tokens = await this.#readCustomTokens()
607
- await this.#storage.set(this.#storageDataKey, { ..._tokens, ...keyBy(tokens, 'name') })
609
+ #updateStoredCustomTokens = async (tokens) => {
610
+ await this.#storeCustomTokens(tokens, true)
608
611
  }
609
612
 
610
- #updateStoredCustomTokens = async (tokens) => {
613
+ #storeCustomTokens = makeConcurrent(async (tokens, isUpdate) => {
611
614
  const _tokens = await this.#readCustomTokens()
612
- // safer not to overwrite everything
613
- const updates = tokens.map((token) => ({
614
- ..._tokens[token.name],
615
- ...pick(token, this.#updateableProps), // like state updates, safer not to overwrite everything in storage
616
- }))
617
- await this.#storage.set(this.#storageDataKey, { ..._tokens, ...keyBy(updates, 'name') })
618
- }
615
+ if (isUpdate) {
616
+ // safer not to overwrite everything
617
+ const updates = tokens.map((token) => ({
618
+ ..._tokens[token.name],
619
+ ...pick(token, this.#updateableProps), // like state updates, safer not to overwrite everything in storage
620
+ }))
621
+ await this.#storage.set(this.#storageDataKey, { ..._tokens, ...keyBy(updates, 'name') })
622
+ } else {
623
+ await this.#storage.set(this.#storageDataKey, { ..._tokens, ...keyBy(tokens, 'name') })
624
+ }
625
+ })
619
626
 
620
627
  #getVersionedAssetNames = async () => {
621
628
  const tokens = await this.#readCustomTokens()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/assets-feature",
3
- "version": "7.4.1",
3
+ "version": "8.1.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",
@@ -35,6 +35,7 @@
35
35
  "url": "git+https://github.com/ExodusMovement/exodus-hydra.git"
36
36
  },
37
37
  "dependencies": {
38
+ "@exodus/asset-legacy-token-name-mapping": "^1.4.0",
38
39
  "@exodus/asset-lib": "^5.3.0",
39
40
  "@exodus/asset-schema-validation": "^1.0.1",
40
41
  "@exodus/assets": "^11.3.0",
@@ -44,6 +45,7 @@
44
45
  "@exodus/fusion-atoms": "^1.4.0",
45
46
  "@exodus/timer": "^1.1.2",
46
47
  "lodash": "^4.17.21",
48
+ "make-concurrent": "^5.4.0",
47
49
  "minimalistic-assert": "^1.0.1",
48
50
  "ms": "^2.1.3",
49
51
  "reselect": "^3.0.1"
@@ -55,7 +57,7 @@
55
57
  "@exodus/bitcoin-plugin": "^1.29.1",
56
58
  "@exodus/bitcoinregtest-plugin": "^1.11.0",
57
59
  "@exodus/bitcointestnet-plugin": "^1.13.1",
58
- "@exodus/blockchain-metadata": "^15.10.0",
60
+ "@exodus/blockchain-metadata": "^15.10.1",
59
61
  "@exodus/cardano-lib": "^2.2.0",
60
62
  "@exodus/combined-assets-meta": "^3.0.0",
61
63
  "@exodus/cosmos-plugin": "^1.3.3",
@@ -80,5 +82,5 @@
80
82
  "publishConfig": {
81
83
  "access": "public"
82
84
  },
83
- "gitHead": "45dd4907f5d65078978854be2eb397e479730c85"
85
+ "gitHead": "c0269d54d37bcceefb29cd77f806146438b71e68"
84
86
  }
@@ -59,10 +59,8 @@ const createMultiAddressModeSelectorDefinition = {
59
59
  id: 'createMultiAddressMode',
60
60
  selectorFactory: (multiAddressModeDataSelector) =>
61
61
  memoize((assetName) =>
62
- createSelector(
63
- multiAddressModeDataSelector,
64
- (multiAddressModeData) =>
65
- multiAddressModeData[assetName] ?? multiAddressModeData.bitcoin ?? false
62
+ createSelector(multiAddressModeDataSelector, (multiAddressModeData) =>
63
+ Boolean(multiAddressModeData[assetName])
66
64
  )
67
65
  ),
68
66
  dependencies: [{ selector: 'multiAddressMode' }],