@exodus/assets-feature 9.4.0 → 9.6.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,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
+ ## [9.6.0](https://github.com/ExodusMovement/exodus/compare/@exodus/assets-feature@9.5.0...@exodus/assets-feature@9.6.0) (2026-10-28)
7
+
8
+ ### Features
9
+
10
+ - **assets-feature:** allow bitcoin testnet and regtest address modes ([#47982](https://github.com/ExodusMovement/exodus/issues/47982)) ([e242c66](https://github.com/ExodusMovement/exodus/commit/e242c6627965e7f1f78a44e1a4538752af16c51b))
11
+
12
+ ## [9.5.0](https://github.com/ExodusMovement/exodus/compare/@exodus/assets-feature@9.4.0...@exodus/assets-feature@9.5.0) (2026-10-12)
13
+
14
+ ### Features
15
+
16
+ - **assets:** configure dynamic combined asset overrides ([#46749](https://github.com/ExodusMovement/exodus/issues/46749)) ([582f204](https://github.com/ExodusMovement/exodus/commit/582f20416509431e63b2d5a47160e4ff6a5296d1))
17
+
6
18
  ## [9.4.0](https://github.com/ExodusMovement/exodus/compare/@exodus/assets-feature@9.3.3...@exodus/assets-feature@9.4.0) (2026-10-07)
7
19
 
8
20
  ### Features
package/README.md CHANGED
@@ -40,6 +40,8 @@ See [api/index.d.ts](./api/index.d.ts) for more details on the API and token val
40
40
 
41
41
  ### API Side
42
42
 
43
+ `assetsModule.dynamicCombinedAssetOverrides` maps a token's asset name to the asset whose name and ticker should identify its dynamic combined group. For example, `{ cbbtc_basemainnet_58df8ab4: 'bitcoin' }` combines Base cbBTC with Bitcoin while preserving cbBTC's metadata and transaction identity. The target is the primary member; both assets must be loaded and eligible for dynamic grouping. Until the target is available and eligible, the token remains available individually and does not fall back to name/ticker grouping. Static grouping is unchanged.
44
+
43
45
  See [using the sdk](../../docs/development/using-the-sdk.md#setup-the-api-side) for more details on how features plug into the SDK and the API interface in the [type declaration](./api/index.d.ts).
44
46
 
45
47
  ### UI Side
@@ -1,19 +1,28 @@
1
- import { compute } from '@exodus/atoms'
1
+ import { combine, compute, createStorageAtomFactory } from '@exodus/atoms'
2
2
  import { createFusionAtom } from '@exodus/fusion-atoms'
3
3
 
4
- const createLegacyAddressModeAtom = ({ fusion }) => {
4
+ const createLegacyAddressModeAtom = ({ storage, fusion, logger }) => {
5
+ const storageAtom = createStorageAtomFactory({ storage, logger })({
6
+ key: 'legacyAddressMode',
7
+ defaultValue: {},
8
+ isSoleWriter: true,
9
+ })
10
+
5
11
  const bitcoinFusionAtom = createFusionAtom({
6
12
  fusion,
7
13
  path: `bitcoinLegacyAddressEnabled`,
8
14
  })
9
15
 
10
16
  const computedAtom = compute({
11
- atom: bitcoinFusionAtom,
12
- selector: (bitcoin) => (bitcoin === undefined ? {} : { bitcoin }),
17
+ atom: combine({ storage: storageAtom, bitcoin: bitcoinFusionAtom }),
18
+ selector: ({ storage, bitcoin }) => (bitcoin === undefined ? storage : { ...storage, bitcoin }),
13
19
  })
14
20
 
15
21
  const set = async (value) => {
16
- const { bitcoin } = typeof value === 'function' ? value(await computedAtom.get()) : value
22
+ const { bitcoin, ...rest } =
23
+ typeof value === 'function' ? value(await computedAtom.get()) : value
24
+
25
+ await storageAtom.set(rest)
17
26
 
18
27
  const bitcoinPreviousValue = await bitcoinFusionAtom.get()
19
28
  if (bitcoinPreviousValue !== bitcoin) {
@@ -28,7 +37,7 @@ const legacyAddressModeAtomDefinition = {
28
37
  id: 'legacyAddressModeAtom',
29
38
  type: 'atom',
30
39
  factory: createLegacyAddressModeAtom,
31
- dependencies: ['fusion'],
40
+ dependencies: ['storage', 'fusion', 'logger'],
32
41
  public: true,
33
42
  }
34
43
 
@@ -1,19 +1,28 @@
1
- import { compute } from '@exodus/atoms'
1
+ import { combine, compute, createStorageAtomFactory } from '@exodus/atoms'
2
2
  import { createFusionAtom } from '@exodus/fusion-atoms'
3
3
 
4
- const createTaprootAddressModeAtom = ({ fusion }) => {
4
+ const createTaprootAddressModeAtom = ({ storage, fusion, logger }) => {
5
+ const storageAtom = createStorageAtomFactory({ storage, logger })({
6
+ key: 'taprootAddressMode',
7
+ defaultValue: {},
8
+ isSoleWriter: true,
9
+ })
10
+
5
11
  const bitcoinFusionAtom = createFusionAtom({
6
12
  fusion,
7
13
  path: `bitcoinTaprootAddressEnabled`,
8
14
  })
9
15
 
10
16
  const computedAtom = compute({
11
- atom: bitcoinFusionAtom,
12
- selector: (bitcoin) => (bitcoin === undefined ? {} : { bitcoin }),
17
+ atom: combine({ storage: storageAtom, bitcoin: bitcoinFusionAtom }),
18
+ selector: ({ storage, bitcoin }) => (bitcoin === undefined ? storage : { ...storage, bitcoin }),
13
19
  })
14
20
 
15
21
  const set = async (value) => {
16
- const { bitcoin } = typeof value === 'function' ? value(await computedAtom.get()) : value
22
+ const { bitcoin, ...rest } =
23
+ typeof value === 'function' ? value(await computedAtom.get()) : value
24
+
25
+ await storageAtom.set(rest)
17
26
 
18
27
  const bitcoinPreviousValue = await bitcoinFusionAtom.get()
19
28
  if (bitcoinPreviousValue !== bitcoin) {
@@ -28,7 +37,7 @@ const taprootAddressModeAtomDefinition = {
28
37
  id: 'taprootAddressModeAtom',
29
38
  type: 'atom',
30
39
  factory: createTaprootAddressModeAtom,
31
- dependencies: ['fusion'],
40
+ dependencies: ['storage', 'fusion', 'logger'],
32
41
  public: true,
33
42
  }
34
43
 
package/constants.js CHANGED
@@ -8,6 +8,7 @@ export const disabledPurposesDefaultConfig = {
8
8
 
9
9
  export const assetsModuleDefaultConfig = {
10
10
  useDynamicCombinedAssets: false,
11
+ dynamicCombinedAssetOverrides: Object.create(null),
11
12
  }
12
13
 
13
14
  export const defaultConfig = {
package/index.js CHANGED
@@ -40,8 +40,14 @@ const assets = (config = Object.create(null)) => {
40
40
  storage: { namespace: 'assetPreferences' },
41
41
  config: multiAddressMode,
42
42
  },
43
- { definition: legacyAddressModeAtomDefinition },
44
- { definition: taprootAddressModeAtomDefinition },
43
+ {
44
+ definition: legacyAddressModeAtomDefinition,
45
+ storage: { namespace: 'assetPreferences' },
46
+ },
47
+ {
48
+ definition: taprootAddressModeAtomDefinition,
49
+ storage: { namespace: 'assetPreferences' },
50
+ },
45
51
  { definition: assetsAtomDefinition },
46
52
  {
47
53
  definition: disabledPurposesAtomDefinition,
@@ -1,24 +1,40 @@
1
1
  import { omit } from '@exodus/basic-utils'
2
2
  import assert from 'minimalistic-assert'
3
3
 
4
+ const supportsLegacyAddressMode = (asset) => asset?.useBip84 === true
5
+ const supportsTaprootAddressMode = (asset) => asset?.useBip86 === true
6
+
4
7
  class AssetPreferences {
8
+ #assetsModule
5
9
  #disabledPurposesAtom
6
10
  #multiAddressModeAtom
7
11
  #legacyAddressModeAtom
8
12
  #taprootAddressModeAtom
9
13
 
10
14
  constructor({
15
+ assetsModule,
11
16
  disabledPurposesAtom,
12
17
  multiAddressModeAtom,
13
18
  legacyAddressModeAtom,
14
19
  taprootAddressModeAtom,
15
20
  }) {
21
+ this.#assetsModule = assetsModule
16
22
  this.#disabledPurposesAtom = disabledPurposesAtom
17
23
  this.#multiAddressModeAtom = multiAddressModeAtom
18
24
  this.#legacyAddressModeAtom = legacyAddressModeAtom
19
25
  this.#taprootAddressModeAtom = taprootAddressModeAtom
20
26
  }
21
27
 
28
+ #assertAssetsSupport = ({ assetNames, method, isSupported }) => {
29
+ assert(assetNames.length > 0, `${method} requires at least one asset`)
30
+ for (const assetName of assetNames) {
31
+ assert(
32
+ isSupported(this.#assetsModule.getAsset(assetName)),
33
+ `${method} does not support ${assetName}`
34
+ )
35
+ }
36
+ }
37
+
22
38
  enableMultiAddressMode = ({ assetNames }) =>
23
39
  this.#multiAddressModeAtom.set((value) => ({
24
40
  ...value,
@@ -38,10 +54,11 @@ class AssetPreferences {
38
54
  }))
39
55
 
40
56
  enableLegacyAddressMode = async ({ assetNames }) => {
41
- assert(
42
- assetNames.length === 1 && assetNames[0] === 'bitcoin',
43
- 'enableLegacyAddressMode only supports bitcoin'
44
- )
57
+ this.#assertAssetsSupport({
58
+ assetNames,
59
+ method: 'enableLegacyAddressMode',
60
+ isSupported: supportsLegacyAddressMode,
61
+ })
45
62
 
46
63
  await this.#legacyAddressModeAtom.set((value) => ({
47
64
  ...value,
@@ -53,19 +70,21 @@ class AssetPreferences {
53
70
  }
54
71
 
55
72
  disableLegacyAddressMode = async ({ assetNames }) => {
56
- assert(
57
- assetNames.length === 1 && assetNames[0] === 'bitcoin',
58
- 'disableLegacyAddressMode only supports bitcoin'
59
- )
73
+ this.#assertAssetsSupport({
74
+ assetNames,
75
+ method: 'disableLegacyAddressMode',
76
+ isSupported: supportsLegacyAddressMode,
77
+ })
60
78
 
61
79
  await this.#legacyAddressModeAtom.set((value) => omit(value, assetNames))
62
80
  }
63
81
 
64
82
  enableTaprootAddressMode = async ({ assetNames }) => {
65
- assert(
66
- assetNames.length === 1 && assetNames[0] === 'bitcoin',
67
- 'enableTaprootAddressMode only supports bitcoin'
68
- )
83
+ this.#assertAssetsSupport({
84
+ assetNames,
85
+ method: 'enableTaprootAddressMode',
86
+ isSupported: supportsTaprootAddressMode,
87
+ })
69
88
 
70
89
  await this.#taprootAddressModeAtom.set((value) => ({
71
90
  ...value,
@@ -77,10 +96,11 @@ class AssetPreferences {
77
96
  }
78
97
 
79
98
  disableTaprootAddressMode = async ({ assetNames }) => {
80
- assert(
81
- assetNames.length === 1 && assetNames[0] === 'bitcoin',
82
- 'disableTaprootAddressMode only supports bitcoin'
83
- )
99
+ this.#assertAssetsSupport({
100
+ assetNames,
101
+ method: 'disableTaprootAddressMode',
102
+ isSupported: supportsTaprootAddressMode,
103
+ })
84
104
 
85
105
  await this.#taprootAddressModeAtom.set((value) => omit(value, assetNames))
86
106
  }
@@ -115,6 +135,7 @@ const assetPreferencesDefinition = {
115
135
  type: 'module',
116
136
  factory: (opts) => new AssetPreferences(opts),
117
137
  dependencies: [
138
+ 'assetsModule',
118
139
  'disabledPurposesAtom',
119
140
  'multiAddressModeAtom',
120
141
  'legacyAddressModeAtom',
@@ -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, pickBy, difference } from '@exodus/basic-utils'
7
+ import { keyBy, mapValues, partition, pickBy, difference, pick } from '@exodus/basic-utils'
8
8
  // eslint-disable-next-line no-restricted-imports -- TODO: Fix this the next time the file is edited.
9
9
  import lodash from 'lodash'
10
10
  import assert from 'minimalistic-assert'
@@ -30,10 +30,10 @@ import {
30
30
  createDynamicCombinedAssetDefinitions,
31
31
  shouldTokenJoinCombinedAsset,
32
32
  findDynamicCombinedAssetForToken,
33
+ getDynamicCombinedAssetKey,
33
34
  } from './dynamic-combined-assets.js'
34
35
 
35
- // oxlint-disable-next-line @exodus/oxlint-plugin-restricted-imports/prefer-basic-utils
36
- const { get, isEmpty, once, uniq, chunk, pick } = lodash
36
+ const { get, isEmpty, once, uniq, chunk } = lodash
37
37
 
38
38
  const getFetchCacheKey = (baseAssetName, assetId) => `${assetId}-${baseAssetName}`
39
39
 
@@ -85,6 +85,7 @@ export class AssetsModule {
85
85
  #logger
86
86
  #invalidTokenNames
87
87
  #useDynamicCombinedAssets
88
+ #dynamicCombinedAssetOverrides
88
89
 
89
90
  constructor({
90
91
  storage,
@@ -125,6 +126,8 @@ export class AssetsModule {
125
126
  ...(config.invalidTokenNames || []),
126
127
  ])
127
128
  this.#useDynamicCombinedAssets = config.useDynamicCombinedAssets ?? false
129
+ this.#dynamicCombinedAssetOverrides =
130
+ config.dynamicCombinedAssetOverrides ?? Object.create(null)
128
131
  }
129
132
 
130
133
  #setRegistry = (registry) => {
@@ -242,7 +245,9 @@ export class AssetsModule {
242
245
 
243
246
  #createDynamicCombinedAssets = () => {
244
247
  const allAssets = this.getAssets()
245
- const definitions = createDynamicCombinedAssetDefinitions(allAssets)
248
+ const definitions = createDynamicCombinedAssetDefinitions(allAssets, {
249
+ overrides: this.#dynamicCombinedAssetOverrides,
250
+ })
246
251
 
247
252
  const newlyCreatedNames = []
248
253
  for (const definition of definitions) {
@@ -671,7 +676,8 @@ export class AssetsModule {
671
676
 
672
677
  const allAssets = this.getAssets()
673
678
  const combinedAssets = Object.values(allAssets).filter((a) => a.isCombined)
674
- const matchingCombined = findDynamicCombinedAssetForToken(token, combinedAssets)
679
+ const options = { assets: allAssets, overrides: this.#dynamicCombinedAssetOverrides }
680
+ const matchingCombined = findDynamicCombinedAssetForToken(token, combinedAssets, options)
675
681
 
676
682
  if (matchingCombined) {
677
683
  if (!matchingCombined.combinedAssetNames.includes(token.name)) {
@@ -679,16 +685,17 @@ export class AssetsModule {
679
685
  return { updated: [matchingCombined.name], created: [], members: [] }
680
686
  }
681
687
  } else {
688
+ const tokenKey = getDynamicCombinedAssetKey(token, options)
689
+ if (!tokenKey) return { updated: [], created: [], members: [] }
682
690
  const matchingAssets = Object.values(allAssets).filter(
683
691
  (a) =>
684
692
  !a.isCombined &&
685
- a.displayTicker?.toLowerCase() === token.displayTicker?.toLowerCase() &&
686
- a.displayName?.toLowerCase() === token.displayName?.toLowerCase() &&
693
+ getDynamicCombinedAssetKey(a, options) === tokenKey &&
687
694
  shouldTokenJoinCombinedAsset(a)
688
695
  )
689
696
 
690
697
  if (matchingAssets.length >= 2) {
691
- const definitions = createDynamicCombinedAssetDefinitions(matchingAssets)
698
+ const definitions = createDynamicCombinedAssetDefinitions(matchingAssets, options)
692
699
  if (definitions.length > 0) {
693
700
  const newCombined = this.#registry.addCombinedAsset(definitions[0])
694
701
  const memberNames = matchingAssets.map((a) => a.name).filter((n) => n !== token.name)
@@ -8,13 +8,29 @@ const normalizeForName = (str) => str.toLowerCase().replace(/[^a-z0-9]/g, '')
8
8
  const createGroupKey = (displayTicker, displayName) =>
9
9
  `${normalizeForKey(displayTicker)}::${normalizeForKey(displayName)}`
10
10
 
11
- const groupAssetsByTickerAndName = (assets) => {
11
+ const getGroupingAsset = (asset, { assets = {}, overrides = Object.create(null) } = {}) => {
12
+ if (!Object.hasOwn(overrides, asset.name)) return asset
13
+
14
+ const target = assets[overrides[asset.name]]
15
+ return target && !target.isCombined && shouldTokenJoinCombinedAsset(target) ? target : null
16
+ }
17
+
18
+ export const getDynamicCombinedAssetKey = (asset, options) => {
19
+ const groupingAsset = getGroupingAsset(asset, options)
20
+ if (!groupingAsset) return null
21
+
22
+ const { displayTicker, displayName } = groupingAsset
23
+ return displayTicker && displayName ? createGroupKey(displayTicker, displayName) : null
24
+ }
25
+
26
+ const groupAssetsByTickerAndName = (assets, options) => {
12
27
  const groups = Object.create(null)
13
28
 
14
29
  for (const asset of assets) {
15
- if (asset.isCombined || !asset.displayTicker || !asset.displayName) continue
30
+ if (asset.isCombined) continue
16
31
 
17
- const key = createGroupKey(asset.displayTicker, asset.displayName)
32
+ const key = getDynamicCombinedAssetKey(asset, options)
33
+ if (!key) continue
18
34
  if (!groups[key]) groups[key] = []
19
35
  groups[key].push(asset)
20
36
  }
@@ -31,9 +47,12 @@ const resolveDecimals = (assets) => {
31
47
  return Math.max(...decimals)
32
48
  }
33
49
 
34
- const createDynamicCombinedAssetDefinition = (assetGroup) => {
50
+ const createDynamicCombinedAssetDefinition = (assetGroup, { overrides }) => {
35
51
  const sortedAssets = [...assetGroup].sort(byName)
36
- const [primary] = sortedAssets
52
+ const targetNames = new Set(Object.values(overrides))
53
+ const overrideTarget = sortedAssets.find((asset) => targetNames.has(asset.name))
54
+ const primary = overrideTarget ?? sortedAssets[0]
55
+ const members = [primary, ...sortedAssets.filter((asset) => asset !== primary)]
37
56
 
38
57
  const normalizedTicker = normalizeForName(primary.displayTicker)
39
58
  const normalizedDisplayName = normalizeForName(primary.displayName)
@@ -53,7 +72,7 @@ const createDynamicCombinedAssetDefinition = (assetGroup) => {
53
72
  [`${name}_base`]: 0,
54
73
  [ticker]: decimals,
55
74
  },
56
- combinedAssetNames: sortedAssets.map((a) => a.name),
75
+ combinedAssetNames: members.map((a) => a.name),
57
76
  info: primary.info || { description: '' },
58
77
  primaryColor: primary.primaryColor || '#888888',
59
78
  gradientColors: primary.gradientColors || ['#888888', '#666666'],
@@ -71,27 +90,33 @@ export const isTrustedAsset = (asset) => {
71
90
  return false
72
91
  }
73
92
 
74
- export const createDynamicCombinedAssetDefinitions = (assets) => {
93
+ export const createDynamicCombinedAssetDefinitions = (
94
+ assets,
95
+ { overrides = Object.create(null) } = {}
96
+ ) => {
75
97
  const assetList = Array.isArray(assets) ? assets : Object.values(assets)
98
+ const options = {
99
+ assets: Object.fromEntries(assetList.map((asset) => [asset.name, asset])),
100
+ overrides,
101
+ }
76
102
  const trustedAssets = assetList.filter(
77
103
  (asset) => isTrustedAsset(asset) && !isTestnetVariant(asset)
78
104
  )
79
- const groups = groupAssetsByTickerAndName(trustedAssets)
105
+ const groups = groupAssetsByTickerAndName(trustedAssets, options)
80
106
 
81
107
  const definitions = []
82
108
  for (const assetGroup of Object.values(groups)) {
83
109
  if (assetGroup.length >= MIN_ASSETS_TO_COMBINE) {
84
- definitions.push(createDynamicCombinedAssetDefinition(assetGroup))
110
+ definitions.push(createDynamicCombinedAssetDefinition(assetGroup, options))
85
111
  }
86
112
  }
87
113
 
88
114
  return definitions
89
115
  }
90
116
 
91
- export const findDynamicCombinedAssetForToken = (token, existingCombinedAssets) => {
92
- if (!token.displayTicker || !token.displayName) return null
93
-
94
- const tokenKey = createGroupKey(token.displayTicker, token.displayName)
117
+ export const findDynamicCombinedAssetForToken = (token, existingCombinedAssets, options) => {
118
+ const tokenKey = getDynamicCombinedAssetKey(token, options)
119
+ if (!tokenKey) return null
95
120
 
96
121
  for (const combined of existingCombinedAssets) {
97
122
  if (!combined.isCombined) continue
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/assets-feature",
3
- "version": "9.4.0",
3
+ "version": "9.6.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,11 +40,11 @@
40
40
  "@exodus/asset-schema-validation": "^1.2.0",
41
41
  "@exodus/asset-types": "^0.5.0",
42
42
  "@exodus/assets": "^11.3.0",
43
- "@exodus/atoms": "^10.3.4",
44
- "@exodus/basic-utils": "^5.2.0",
43
+ "@exodus/atoms": "^10.3.5",
44
+ "@exodus/basic-utils": "^5.2.1",
45
45
  "@exodus/fetch": "^1.3.0",
46
- "@exodus/fusion-atoms": "^1.4.0",
47
- "@exodus/timer": "^1.2.2",
46
+ "@exodus/fusion-atoms": "^1.4.1",
47
+ "@exodus/timer": "^1.2.3",
48
48
  "lodash": "^4.17.21",
49
49
  "make-concurrent": "^5.4.0",
50
50
  "minimalistic-assert": "^1.0.1",
@@ -53,8 +53,8 @@
53
53
  },
54
54
  "devDependencies": {
55
55
  "@exodus/bip32": "^4.3.1",
56
- "@exodus/bip39": "^1.1.0",
57
- "@exodus/bip44-constants": "^195.0.2",
56
+ "@exodus/bip39": "^1.1.1",
57
+ "@exodus/bip44-constants": "^195.0.3",
58
58
  "@exodus/bitcoin-meta": "^2.0.0",
59
59
  "@exodus/bitcoin-plugin": "^2.0.0",
60
60
  "@exodus/bitcoinregtest-plugin": "^2.0.0",
@@ -64,16 +64,16 @@
64
64
  "@exodus/ethereum-lib": "^5.26.0",
65
65
  "@exodus/ethereum-meta": "^2.0.0",
66
66
  "@exodus/ethereum-plugin": "^3.1.1",
67
- "@exodus/fusion-local": "^2.1.0",
67
+ "@exodus/fusion-local": "^2.1.1",
68
68
  "@exodus/keychain": "^12.1.0",
69
- "@exodus/logger": "^1.2.3",
70
- "@exodus/models": "^13.3.2",
69
+ "@exodus/logger": "^1.2.4",
70
+ "@exodus/models": "^13.3.3",
71
71
  "@exodus/osmosis-plugin": "^1.3.3",
72
- "@exodus/public-key-provider": "^4.3.1",
72
+ "@exodus/public-key-provider": "^4.3.2",
73
73
  "@exodus/redux-dependency-injection": "^5.0.0",
74
- "@exodus/storage-memory": "^2.4.0",
74
+ "@exodus/storage-memory": "^2.4.1",
75
75
  "@exodus/wallet-accounts": "^20.4.12",
76
- "@exodus/wild-emitter": "^1.1.2",
76
+ "@exodus/wild-emitter": "^1.1.3",
77
77
  "events": "^3.3.0",
78
78
  "msw": "^2.0.0",
79
79
  "redux": "^4.0.0"
@@ -82,5 +82,5 @@
82
82
  "access": "public",
83
83
  "provenance": false
84
84
  },
85
- "gitHead": "a65e66ff61d27471e199419be8b31806f58c6b1b"
85
+ "gitHead": "dc6d4bfa087c6aaf5bf26a6fbe7f8ebebeb23670"
86
86
  }