@exodus/assets-feature 3.7.0 → 4.0.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,22 @@
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
+ ## [4.0.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/assets-feature@3.8.0...@exodus/assets-feature@4.0.0) (2023-11-23)
7
+
8
+ ### ⚠ BREAKING CHANGES
9
+
10
+ - remove legacy asset events (#4826)
11
+
12
+ ### Features
13
+
14
+ - remove legacy asset events ([#4826](https://github.com/ExodusMovement/exodus-hydra/issues/4826)) ([6f27e5f](https://github.com/ExodusMovement/exodus-hydra/commit/6f27e5fa2294cb82db2651069eba4964b37f8e5e))
15
+
16
+ ## [3.8.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/assets-feature@3.7.0...@exodus/assets-feature@3.8.0) (2023-11-21)
17
+
18
+ ### Features
19
+
20
+ - assets atom ([#4109](https://github.com/ExodusMovement/exodus-hydra/issues/4109)) ([d08880d](https://github.com/ExodusMovement/exodus-hydra/commit/d08880d8fe6f2f596cb01b955787de07f2a0747e))
21
+
6
22
  ## [3.7.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/assets-feature@3.6.0...@exodus/assets-feature@3.7.0) (2023-10-25)
7
23
 
8
24
  ### Features
@@ -0,0 +1,10 @@
1
+ import { createInMemoryAtom } from '@exodus/atoms'
2
+
3
+ const assetsAtomDefinition = {
4
+ id: 'assetsAtom',
5
+ type: 'atom',
6
+ factory: createInMemoryAtom,
7
+ dependencies: [],
8
+ }
9
+
10
+ export default assetsAtomDefinition
package/index.js CHANGED
@@ -6,6 +6,7 @@ import assetsApiDefinition from './api'
6
6
  import assetModuleDefinition from './module'
7
7
  import customTokensMonitorDefinition from './monitor'
8
8
  import assetPreferencesDefinition from './module/asset-preferences'
9
+ import assetsAtomDefinition from './atoms/assets'
9
10
 
10
11
  const assets = ({ config = {} } = {}) => {
11
12
  return {
@@ -18,6 +19,9 @@ const assets = ({ config = {} } = {}) => {
18
19
  storage: { namespace: 'assetPreferences' },
19
20
  config: config.multiAddressMode || {},
20
21
  },
22
+ {
23
+ definition: assetsAtomDefinition,
24
+ },
21
25
  {
22
26
  definition: disabledPurposesAtomDefinition,
23
27
  storage: { namespace: 'assetPreferences' },
@@ -25,10 +29,11 @@ const assets = ({ config = {} } = {}) => {
25
29
  },
26
30
  { definition: assetsApiDefinition },
27
31
  // TODO: add storage namespace once we remove customTokensStorage
28
- // eslint-disable-next-line hydra/missing-storage-namespace
32
+ // eslint-disable-next-line @exodus/hydra/missing-storage-namespace
29
33
  {
30
34
  definition: assetModuleDefinition,
31
35
  // storage: { namespace: 'customTokens' },
36
+ writesAtoms: ['assetsAtom'],
32
37
  aliases: [{ implementationId: 'customTokensStorage', interfaceId: 'storage' }],
33
38
  },
34
39
  {
@@ -6,9 +6,6 @@ import {
6
6
  CT_UPDATEABLE_PROPERTIES,
7
7
  } from '@exodus/assets'
8
8
  import { mapValues, pick, pickBy } from '@exodus/basic-utils'
9
- // eslint-disable-next-line no-restricted-imports
10
- import { fetchival } from '@exodus/fetch'
11
- import ExodusModule from '@exodus/module'
12
9
  // eslint-disable-next-line @exodus/restricted-imports/prefer-basic-utils
13
10
  import { get, isEmpty, keyBy, once } from 'lodash'
14
11
  import assert from 'minimalistic-assert'
@@ -20,6 +17,7 @@ import {
20
17
  CT_UPDATE_INTERVAL,
21
18
  } from './constants'
22
19
  import { getAssetFromAssetId, getFetchErrorMessage, isDisabledCustomToken } from './utils'
20
+ import createFetchival from '@exodus/fetch/create-fetchival'
23
21
 
24
22
  const FILTERED_FIELDS = [
25
23
  'assetId',
@@ -71,7 +69,7 @@ const initialAssetRegistry = {
71
69
  },
72
70
  }
73
71
 
74
- export class AssetsModule extends ExodusModule {
72
+ export class AssetsModule {
75
73
  #registry
76
74
  #storage
77
75
  #fetchCache
@@ -86,24 +84,27 @@ export class AssetsModule extends ExodusModule {
86
84
  #storageTimestampKey
87
85
  #customTokenUpdateInterval
88
86
  #fetchCacheExpiry
89
- #globalAssetRegistry // temporary
90
87
  #isExternalRegistry
88
+ #assetsAtom
89
+ #fetchival
90
+ #logger
91
91
 
92
92
  constructor({
93
93
  storage,
94
94
  iconsStorage,
95
95
  assetRegistry, // temporary
96
96
  assetPlugins,
97
+ assetsAtom,
97
98
  combinedAssetsList = [],
98
- globalAssetRegistry, // temporary
99
99
  validateCustomToken = () => true,
100
100
  config = {},
101
+ fetch,
102
+ logger,
101
103
  }) {
102
- super({ name: 'AssetsModule' })
103
-
104
+ this.#assetsAtom = assetsAtom
104
105
  this.#storage = storage
105
106
  this.#isExternalRegistry = !!assetRegistry
106
- this.#registry = this.#isExternalRegistry ? assetRegistry : initialAssetRegistry
107
+ this.#setRegistry(assetRegistry ?? initialAssetRegistry)
107
108
  this.#assetPlugins = assetPlugins
108
109
  this.#combinedAssetsList = combinedAssetsList
109
110
  this.#fetchCache = {}
@@ -116,10 +117,25 @@ export class AssetsModule extends ExodusModule {
116
117
  this.#storageTimestampKey = config.storageTimestampKey || CT_TIMESTAMP_KEY
117
118
  this.#customTokenUpdateInterval = config.customTokenUpdateInterval || CT_UPDATE_INTERVAL
118
119
  this.#fetchCacheExpiry = config.fetchCacheExpiry ?? CT_FETCH_CACHE_EXPIRY
119
- this.#globalAssetRegistry = globalAssetRegistry // temporary
120
+ this.#fetchival = createFetchival({ fetch })
121
+ this.#logger = logger
120
122
  }
121
123
 
122
- // Assets Registry API
124
+ #setRegistry = (registry) => {
125
+ this.#registry = registry
126
+
127
+ if (registry === initialAssetRegistry) {
128
+ return
129
+ }
130
+
131
+ // we want this to happen asap before load and even before start
132
+ this.#assetsAtom.set({
133
+ value: { ...this.#registry.getAssets() },
134
+ added: [],
135
+ updated: [],
136
+ disabled: [],
137
+ })
138
+ }
123
139
 
124
140
  initialize = ({ assetClientInterface }) => {
125
141
  assert(
@@ -135,11 +151,11 @@ export class AssetsModule extends ExodusModule {
135
151
  console.warn(`Incorrectly referenced supported asset ${name}. Expected ${asset.name}.`)
136
152
  })
137
153
  .filter(Boolean)
138
- this.#registry = createAssetRegistry({
139
- supportedAssetsList: [...assetsList, ...this.#combinedAssetsList],
140
- globalAssetRegistry: this.#globalAssetRegistry, // temporarily supply the deprecated globalAssetRegistry until @exodus/models v10. Afterwards it can simply be removed.
141
- })
142
- // this.emit('assets-initialized')
154
+ this.#setRegistry(
155
+ createAssetRegistry({
156
+ supportedAssetsList: [...assetsList, ...this.#combinedAssetsList],
157
+ })
158
+ )
143
159
  }
144
160
 
145
161
  getAssets = () => this.#registry.getAssets()
@@ -160,8 +176,6 @@ export class AssetsModule extends ExodusModule {
160
176
  getBaseAssetNames = () => this.#getAssetNamesBy((asset) => asset.baseAsset.name === asset.name)
161
177
 
162
178
  load = once(async () => {
163
- this.emit('assets-load', { importedTokens: {} })
164
-
165
179
  try {
166
180
  const storedTokens = await this.#readCustomTokens()
167
181
  const tokens = pickBy(storedTokens, ({ baseAssetName }) => {
@@ -175,9 +189,9 @@ export class AssetsModule extends ExodusModule {
175
189
  // 3. both of the above from a network that has feature flag customTokens === false
176
190
  // It is OK to add all of these to the assets registry
177
191
  const { added, updated } = this.#handleFetchedTokens(Object.values(tokens))
178
- this.#announceChanges({ added, updated })
192
+ this.#flushChanges({ added, updated })
179
193
  } catch (e) {
180
- this._logger.log('error reading custom tokens from storage:', e)
194
+ this.#logger.log('error reading custom tokens from storage:', e)
181
195
  }
182
196
  })
183
197
 
@@ -198,7 +212,7 @@ export class AssetsModule extends ExodusModule {
198
212
 
199
213
  const _token = await this.#fetch(`networks/${baseAssetName}`, { assetId }, 'token')
200
214
  if (!this.#validateCustomToken(_token)) {
201
- this._logger.warn('Invalid Custom Token schema')
215
+ this.#logger.warn('Invalid Custom Token schema')
202
216
  throw new Error('Token did not pass validation')
203
217
  }
204
218
 
@@ -207,7 +221,7 @@ export class AssetsModule extends ExodusModule {
207
221
  try {
208
222
  await this.#iconsStorage.storeIcons([token])
209
223
  } catch (err) {
210
- this._logger.warn(`An error occurred while decoding icon for ${assetId}`, err.message)
224
+ this.#logger.warn(`An error occurred while decoding icon for ${assetId}`, err.message)
211
225
  }
212
226
 
213
227
  this.#setCache(key, token)
@@ -223,14 +237,14 @@ export class AssetsModule extends ExodusModule {
223
237
 
224
238
  if (isAdded) {
225
239
  await this.#storeCustomTokens([token])
226
- this.#announceChanges({ added: [asset] })
240
+ this.#flushChanges({ added: [asset] })
227
241
  } else {
228
- this.#announceChanges({ updated: [asset] })
242
+ this.#flushChanges({ updated: [asset] })
229
243
  }
230
244
 
231
245
  return asset
232
246
  } catch (err) {
233
- this._logger.warn(`Add custom token ${assetId} error on ${baseAssetName}`, err.message)
247
+ this.#logger.warn(`Add custom token ${assetId} error on ${baseAssetName}`, err.message)
234
248
  throw err
235
249
  }
236
250
  }
@@ -247,7 +261,7 @@ export class AssetsModule extends ExodusModule {
247
261
  try {
248
262
  return await this.fetchToken(assetId, baseAssetName)
249
263
  } catch (err) {
250
- this._logger.warn('fetch custom tokens error:', err.message)
264
+ this.#logger.warn('fetch custom tokens error:', err.message)
251
265
  }
252
266
  })
253
267
  )
@@ -269,7 +283,7 @@ export class AssetsModule extends ExodusModule {
269
283
  await this.#storeCustomTokens(fetchedAndHandledTokens)
270
284
  }
271
285
 
272
- this.#announceChanges({ added, updated })
286
+ this.#flushChanges({ added, updated })
273
287
 
274
288
  return added.concat(updated)
275
289
  }
@@ -290,7 +304,7 @@ export class AssetsModule extends ExodusModule {
290
304
  if (isEmpty(tokens)) return
291
305
 
292
306
  const validTokens = tokensToAdd.filter(this.#validateCustomToken).map(normalizeToken)
293
- if (validTokens.length !== tokensToAdd.length) this._logger.warn('Invalid Custom Token schema')
307
+ if (validTokens.length !== tokensToAdd.length) this.#logger.warn('Invalid Custom Token schema')
294
308
 
295
309
  const { fetchedAndHandledTokens, added, updated } = this.#handleFetchedTokens(validTokens)
296
310
 
@@ -299,7 +313,7 @@ export class AssetsModule extends ExodusModule {
299
313
  await this.#iconsStorage.storeIcons(fetchedAndHandledTokens)
300
314
  }
301
315
 
302
- this.#announceChanges({ added, updated })
316
+ this.#flushChanges({ added, updated })
303
317
  }
304
318
 
305
319
  updateTokens = async () => {
@@ -324,10 +338,8 @@ export class AssetsModule extends ExodusModule {
324
338
  (token) => _isDisabledCustomToken(token) && !isDisabledCustomToken(this.getAsset(token.name))
325
339
  )
326
340
  const updatedAssets = tokens.map(this.#registry.updateCustomToken)
327
- this.emit('assets-update', updatedAssets)
328
- if (disabled.length > 0) {
329
- this.emit('assets-disable', disabled)
330
- }
341
+
342
+ this.#flushChanges({ updated: updatedAssets, disabled })
331
343
  }
332
344
 
333
345
  searchTokens = async ({ baseAssetName, lifecycleStatus, query, excludeTags = ['offensive'] }) => {
@@ -354,7 +366,7 @@ export class AssetsModule extends ExodusModule {
354
366
  )
355
367
  const validTokens = tokens.filter(this.#validateCustomToken)
356
368
 
357
- if (validTokens.length !== tokens.length) this._logger.warn('Invalid Custom Token schema')
369
+ if (validTokens.length !== tokens.length) this.#logger.warn('Invalid Custom Token schema')
358
370
 
359
371
  return validTokens.map((token) => {
360
372
  const asset = this.#getAssetFromAssetId(token.assetId, token.baseAssetName)
@@ -371,7 +383,7 @@ export class AssetsModule extends ExodusModule {
371
383
  const updatedTokens = await this.#fetch('updates', assetVersions, 'tokens')
372
384
  const validatedTokens = updatedTokens.filter(this.#validateCustomToken).map(normalizeToken)
373
385
  if (validatedTokens.length !== updatedTokens.length) {
374
- this._logger.warn('Invalid Custom Token schema')
386
+ this.#logger.warn('Invalid Custom Token schema')
375
387
  }
376
388
 
377
389
  await this.#iconsStorage.storeIcons(validatedTokens)
@@ -393,17 +405,25 @@ export class AssetsModule extends ExodusModule {
393
405
  return item?.value && Date.now() < item.expiry ? item.value : null
394
406
  }
395
407
 
396
- #announceChanges = ({ added = [], updated = [] }) => {
397
- if (added.length > 0) this.emit('assets-add', added)
398
- if (updated.length > 0) this.emit('assets-update', updated)
408
+ #flushChanges = ({ added = [], updated = [], disabled = [] } = {}) => {
409
+ if (added.length + updated.length + disabled.length === 0) {
410
+ return
411
+ }
412
+
413
+ this.#assetsAtom.set({
414
+ value: { ...this.#registry.getAssets() },
415
+ added,
416
+ updated,
417
+ disabled,
418
+ })
399
419
  }
400
420
 
401
421
  #fetch = async (endpoint, body, resultPath) => {
402
422
  try {
403
423
  const testDataParam = this.#config.fetchTestValues ? '?test=true' : ''
404
- const res = await fetchival(this.#customTokensServerUrl)(`${endpoint}${testDataParam}`).post(
405
- body
406
- )
424
+ const res = await this.#fetchival(this.#customTokensServerUrl)(
425
+ `${endpoint}${testDataParam}`
426
+ ).post(body)
407
427
 
408
428
  if (res.status !== 'OK')
409
429
  throw new Error(`Custom tokens registry ${endpoint} ${res.status} ${res.message}`)
@@ -419,7 +439,7 @@ export class AssetsModule extends ExodusModule {
419
439
  if (asset) return { asset, isAdded: false }
420
440
 
421
441
  const { name } = this.#registry.addCustomToken(token) // add to `#/assets`
422
- this._logger.log('Custom token added:', name)
442
+ this.#logger.log('Custom token added:', name)
423
443
  return { asset: this.getAsset(name), isAdded: true }
424
444
  }
425
445
 
@@ -437,7 +457,7 @@ export class AssetsModule extends ExodusModule {
437
457
  updated.push(asset)
438
458
  }
439
459
  } catch (err) {
440
- this._logger.warn('Handle fetched custom tokens error:', err.message)
460
+ this.#logger.warn('Handle fetched custom tokens error:', err.message)
441
461
  }
442
462
  }
443
463
 
@@ -448,7 +468,7 @@ export class AssetsModule extends ExodusModule {
448
468
  const baseAsset = this.getAsset(baseAssetName)
449
469
  if (!baseAsset.api.hasFeature('customTokens')) {
450
470
  const reason = `BUG: network ${baseAsset.name} does not support custom tokens.`
451
- this._logger.warn(reason)
471
+ this.#logger.warn(reason)
452
472
  throw new Error(reason)
453
473
  }
454
474
  }
package/module/index.js CHANGED
@@ -1,20 +1,22 @@
1
- // eslint-disable-next-line @exodus/restricted-imports/no-exodus-assets
2
- import globalAssetRegistry from '@exodus/assets' // this is deprecated, do not use for any other purpose. Remove when we have @exodus/models v10.
3
1
  import AssetsModule from './assets-module'
4
2
 
5
- const createAssetsModule = (props) => new AssetsModule({ ...props, globalAssetRegistry })
3
+ const createAssetsModule = (props) => new AssetsModule(props)
6
4
 
7
5
  const assetsModuleDefinition = {
8
6
  id: 'assetsModule',
9
7
  type: 'module',
10
8
  factory: createAssetsModule,
11
9
  dependencies: [
10
+ 'assetsAtom',
12
11
  'storage',
13
12
  'iconsStorage',
14
13
  'assetPlugins',
15
14
  'combinedAssetsList?',
16
15
  'validateCustomToken?',
17
16
  'config',
17
+ 'fetch',
18
+ 'logger',
19
+ 'assetRegistry?', // temporary
18
20
  ],
19
21
  }
20
22
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/assets-feature",
3
- "version": "3.7.0",
3
+ "version": "4.0.0",
4
4
  "license": "UNLICENSED",
5
5
  "description": "Assets module, clients and apis",
6
6
  "main": "index.js",
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "@exodus/basic-utils": "^2.1.0",
35
- "@exodus/fetch": "^1.2.1",
35
+ "@exodus/fetch": "^1.3.0",
36
36
  "@exodus/timer": "^1.0.0",
37
37
  "lodash": "^4.17.21",
38
38
  "minimalistic-assert": "^1.0.1",
@@ -41,17 +41,17 @@
41
41
  },
42
42
  "devDependencies": {
43
43
  "@exodus/assets": "^8.0.95",
44
- "@exodus/atoms": "^6.0.0",
45
- "@exodus/available-assets": "^7.0.0",
44
+ "@exodus/atoms": "^6.0.1",
45
+ "@exodus/available-assets": "^8.0.0",
46
46
  "@exodus/bitcoin-meta": "^1.0.1",
47
47
  "@exodus/bitcoin-plugin": "^1.0.3",
48
48
  "@exodus/bitcoinregtest-plugin": "^1.0.3",
49
49
  "@exodus/bitcointestnet-plugin": "^1.0.3",
50
50
  "@exodus/combined-assets-meta": "^1.2.5",
51
51
  "@exodus/cosmos-plugin": "^1.0.0",
52
- "@exodus/ethereum-meta": "^1.0.30",
52
+ "@exodus/ethereum-meta": "^1.1.0",
53
53
  "@exodus/models": "^9.1.1",
54
- "@exodus/module": "^1.2.0",
54
+ "@exodus/module": "^1.2.2",
55
55
  "@exodus/osmosis-plugin": "^1.0.0",
56
56
  "@exodus/redux-dependency-injection": "^3.0.0",
57
57
  "@exodus/storage-memory": "^2.1.1",
@@ -60,7 +60,8 @@
60
60
  "eslint": "^8.44.0",
61
61
  "events": "^3.3.0",
62
62
  "jest": "^29.1.2",
63
+ "msw": "^2.0.0",
63
64
  "redux": "^4.0.0"
64
65
  },
65
- "gitHead": "c083b9655607e20206217c44bd55bd1b68e3c9b4"
66
+ "gitHead": "6fe52cd3aa2ffc3fa76d2334228a0dcd02dc9e2e"
66
67
  }
package/plugin/index.js CHANGED
@@ -4,47 +4,59 @@ import { createAtomObserver } from '@exodus/atoms'
4
4
  const createAssetsPlugin = ({
5
5
  port,
6
6
  assetsModule,
7
+ assetsAtom,
7
8
  customTokensMonitor,
8
9
  disabledPurposesAtom,
9
10
  multiAddressModeAtom,
10
11
  }) => {
11
- const emitAssetsLoad = () => {
12
- const assets = assetsModule.getAssets()
13
- port.emit('assets-load', {
12
+ const emitAssets = async () => {
13
+ const { value: assets } = await assetsAtom.get()
14
+ const payload = {
14
15
  assets,
15
16
  defaultAccountStates: mapValues(
16
17
  pickBy(assets, (asset) => asset.api?.hasFeature?.('accountState')),
17
18
  (asset) => asset.api.createAccountState().create()
18
19
  ),
19
- })
20
- }
21
-
22
- const listeners = [
23
- ['assets-add', (data) => port.emit('assets-add', data)],
24
- ['assets-update', (data) => port.emit('assets-update', data)],
25
- ]
20
+ }
26
21
 
27
- listeners.forEach(([event, callback]) => {
28
- assetsModule.on(event, callback)
29
- })
22
+ port.emit('assets', payload)
23
+ }
30
24
 
31
25
  const observers = [
32
26
  createAtomObserver({ atom: disabledPurposesAtom, port, event: 'disabledPurposes' }),
33
27
  createAtomObserver({ atom: multiAddressModeAtom, port, event: 'multiAddressMode' }),
34
28
  ]
35
29
 
30
+ const subscribers = []
31
+
36
32
  const onStart = async () => {
33
+ subscribers.push(
34
+ assetsAtom.observe(({ added, updated, disabled }) => {
35
+ if (added.length > 0) {
36
+ port.emit('assets-add', added)
37
+ }
38
+
39
+ if (updated.length > 0) {
40
+ port.emit('assets-update', updated)
41
+ }
42
+
43
+ if (disabled.length > 0) {
44
+ port.emit('assets-disable', disabled)
45
+ }
46
+ })
47
+ )
48
+
37
49
  observers.forEach((observer) => observer.register())
38
50
 
39
51
  await assetsModule.load()
40
- emitAssetsLoad()
52
+ await emitAssets()
41
53
  }
42
54
 
43
55
  const onLoad = async () => {
44
56
  observers.forEach((observer) => observer.start())
45
57
 
46
58
  await assetsModule.load()
47
- emitAssetsLoad()
59
+ await emitAssets()
48
60
  }
49
61
 
50
62
  const onUnlock = () => {
@@ -56,11 +68,8 @@ const createAssetsPlugin = ({
56
68
  }
57
69
 
58
70
  const onStop = () => {
59
- listeners.forEach(([event, callback]) => {
60
- assetsModule.removeListener(event, callback)
61
- })
62
-
63
71
  observers.forEach((observer) => observer.unregister())
72
+ subscribers.forEach((unsubscribe) => unsubscribe())
64
73
  }
65
74
 
66
75
  const onClear = async () => {
@@ -77,6 +86,7 @@ const assetsPluginDefinition = {
77
86
  dependencies: [
78
87
  'port',
79
88
  'assetsModule',
89
+ 'assetsAtom',
80
90
  'customTokensMonitor',
81
91
  'disabledPurposesAtom',
82
92
  'multiAddressModeAtom',
package/redux/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { keyBy } from '@exodus/basic-utils'
2
1
  import id from './id'
3
2
  import initialState from './initial-state'
4
3
  import selectorDefinitions from './selectors'
4
+ import { keyBy } from '@exodus/basic-utils'
5
5
 
6
6
  const mergeAssets = (state, payload) => ({
7
7
  ...state,
@@ -16,14 +16,11 @@ const assetsReduxDefinition = {
16
16
  type: 'redux-module',
17
17
  initialState,
18
18
  eventReducers: {
19
- 'assets-load': (state, { assets }) => ({
20
- ...state,
21
- error: null,
22
- loaded: true,
23
- data: assets,
24
- }),
25
19
  'assets-add': mergeAssets,
26
20
  'assets-update': mergeAssets,
21
+ assets: (state, { assets }) => {
22
+ return { ...state, error: null, loaded: true, data: assets }
23
+ },
27
24
  multiAddressMode: (state, payload) => ({
28
25
  ...state,
29
26
  multiAddressMode: payload,