@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 +16 -0
- package/atoms/assets.js +10 -0
- package/index.js +6 -1
- package/module/assets-module.js +64 -44
- package/module/index.js +5 -3
- package/package.json +8 -7
- package/plugin/index.js +29 -19
- package/redux/index.js +4 -7
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
|
package/atoms/assets.js
ADDED
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
|
{
|
package/module/assets-module.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
103
|
-
|
|
104
|
+
this.#assetsAtom = assetsAtom
|
|
104
105
|
this.#storage = storage
|
|
105
106
|
this.#isExternalRegistry = !!assetRegistry
|
|
106
|
-
this.#
|
|
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.#
|
|
120
|
+
this.#fetchival = createFetchival({ fetch })
|
|
121
|
+
this.#logger = logger
|
|
120
122
|
}
|
|
121
123
|
|
|
122
|
-
|
|
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.#
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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.#
|
|
192
|
+
this.#flushChanges({ added, updated })
|
|
179
193
|
} catch (e) {
|
|
180
|
-
this.
|
|
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.
|
|
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.
|
|
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.#
|
|
240
|
+
this.#flushChanges({ added: [asset] })
|
|
227
241
|
} else {
|
|
228
|
-
this.#
|
|
242
|
+
this.#flushChanges({ updated: [asset] })
|
|
229
243
|
}
|
|
230
244
|
|
|
231
245
|
return asset
|
|
232
246
|
} catch (err) {
|
|
233
|
-
this.
|
|
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.
|
|
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.#
|
|
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.
|
|
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.#
|
|
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
|
-
|
|
328
|
-
|
|
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.
|
|
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.
|
|
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
|
-
#
|
|
397
|
-
if (added.length
|
|
398
|
-
|
|
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)(
|
|
405
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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(
|
|
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
|
+
"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.
|
|
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.
|
|
45
|
-
"@exodus/available-assets": "^
|
|
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
|
|
52
|
+
"@exodus/ethereum-meta": "^1.1.0",
|
|
53
53
|
"@exodus/models": "^9.1.1",
|
|
54
|
-
"@exodus/module": "^1.2.
|
|
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": "
|
|
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
|
|
12
|
-
const assets =
|
|
13
|
-
|
|
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
|
-
|
|
28
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|