@exodus/assets-feature 2.0.2 → 3.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 +26 -0
- package/client/asset-client-interface.js +1 -0
- package/index.js +2 -0
- package/module/assets-module.js +48 -25
- package/module/constants.js +1 -0
- package/monitor/index.js +22 -0
- package/package.json +4 -2
- package/plugin/index.js +12 -1
- package/redux/index.js +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,32 @@
|
|
|
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
|
+
## [3.1.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/assets-feature@3.0.0...@exodus/assets-feature@3.1.0) (2023-09-20)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- add custom tokens monitor ([#4150](https://github.com/ExodusMovement/exodus-hydra/issues/4150)) ([f9d8bee](https://github.com/ExodusMovement/exodus-hydra/commit/f9d8bee4b0aecdf8c04bb03b960316ce64e24b91))
|
|
11
|
+
- support external asset registry ([#4138](https://github.com/ExodusMovement/exodus-hydra/issues/4138)) ([3100890](https://github.com/ExodusMovement/exodus-hydra/commit/3100890ed264cf670cad1c76290067f58bf8cd62))
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
- ensure tokens have display properties ([#4149](https://github.com/ExodusMovement/exodus-hydra/issues/4149)) ([4f39d42](https://github.com/ExodusMovement/exodus-hydra/commit/4f39d42b7446b89638791d1c01af1fe035898b2d))
|
|
16
|
+
- minor custom token bugs ([#13202](https://github.com/ExodusMovement/exodus-hydra/issues/13202)) ([876214a](https://github.com/ExodusMovement/exodus-hydra/commit/876214a8e04e4fb84b729cabd804b4345f03a51d))
|
|
17
|
+
|
|
18
|
+
## [3.0.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/assets-feature@2.0.2...@exodus/assets-feature@3.0.0) (2023-09-19)
|
|
19
|
+
|
|
20
|
+
### ⚠ BREAKING CHANGES
|
|
21
|
+
|
|
22
|
+
- emit defaultAccountStates from assets-load (#4072)
|
|
23
|
+
|
|
24
|
+
### Features
|
|
25
|
+
|
|
26
|
+
- emit defaultAccountStates from assets-load ([#4072](https://github.com/ExodusMovement/exodus-hydra/issues/4072)) ([1b3887a](https://github.com/ExodusMovement/exodus-hydra/commit/1b3887ab0d10c14ee90622121bf2fa6847f53b17))
|
|
27
|
+
|
|
28
|
+
### Bug Fixes
|
|
29
|
+
|
|
30
|
+
- update assets module ([#4123](https://github.com/ExodusMovement/exodus-hydra/issues/4123)) ([8f1cd56](https://github.com/ExodusMovement/exodus-hydra/commit/8f1cd56d774336e389cf932944755c4670356dcc))
|
|
31
|
+
|
|
6
32
|
## [2.0.2](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/assets-feature@2.0.1...@exodus/assets-feature@2.0.2) (2023-09-14)
|
|
7
33
|
|
|
8
34
|
### Bug Fixes
|
|
@@ -192,6 +192,7 @@ class AssetClientInterface {
|
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
signTransaction = async ({ assetName, unsignedTx, walletAccount }) => {
|
|
195
|
+
// eslint-disable-next-line unicorn/no-await-expression-member
|
|
195
196
|
const accountIndex = (await this.#getWalletAccount(walletAccount)).index
|
|
196
197
|
const baseAssetName = this.assetsModule.getAsset(assetName).baseAsset.name
|
|
197
198
|
return this.wallet.signTransaction({ baseAssetName, unsignedTx, accountIndex })
|
package/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import multiAddressModeAtomDefinition from './atoms/multi-address-mode'
|
|
|
4
4
|
import disabledPurposesAtomDefinition from './atoms/disabled-purposes'
|
|
5
5
|
import assetsApiDefinition from './api'
|
|
6
6
|
import assetModuleDefinition from './module'
|
|
7
|
+
import customTokensMonitorDefinition from './monitor'
|
|
7
8
|
import assetPreferencesDefinition from './module/asset-preferences'
|
|
8
9
|
|
|
9
10
|
const assets = ({ config = {} } = {}) => {
|
|
@@ -34,6 +35,7 @@ const assets = ({ config = {} } = {}) => {
|
|
|
34
35
|
definition: assetPreferencesDefinition,
|
|
35
36
|
writesAtoms: ['multiAddressModeAtom', 'disabledPurposesAtom'],
|
|
36
37
|
},
|
|
38
|
+
{ definition: customTokensMonitorDefinition },
|
|
37
39
|
],
|
|
38
40
|
}
|
|
39
41
|
}
|
package/module/assets-module.js
CHANGED
|
@@ -12,16 +12,44 @@ import ExodusModule from '@exodus/module'
|
|
|
12
12
|
// eslint-disable-next-line @exodus/restricted-imports/prefer-basic-utils
|
|
13
13
|
import { get, isEmpty, keyBy, once } from 'lodash'
|
|
14
14
|
import assert from 'minimalistic-assert'
|
|
15
|
-
import ms from 'ms'
|
|
16
15
|
|
|
17
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
CT_DATA_KEY,
|
|
18
|
+
CT_FETCH_CACHE_EXPIRY,
|
|
19
|
+
CT_TIMESTAMP_KEY,
|
|
20
|
+
CT_UPDATE_INTERVAL,
|
|
21
|
+
} from './constants'
|
|
18
22
|
import { getAssetFromAssetId, getFetchErrorMessage, isDisabledCustomToken } from './utils'
|
|
19
23
|
|
|
20
24
|
const getFetchCacheKey = (baseAssetName, assetId) => `${assetId}-${baseAssetName}`
|
|
21
25
|
|
|
22
26
|
const _isDisabledCustomToken = (token) => token.lifecycleStatus === STATUS.DISABLED
|
|
23
27
|
|
|
24
|
-
const normalizeToken = (token) => (
|
|
28
|
+
const normalizeToken = (token) => ({
|
|
29
|
+
...token,
|
|
30
|
+
name: token.name || token.assetName,
|
|
31
|
+
displayName: token.displayName || token.properName,
|
|
32
|
+
displayTicker: token.displayTicker || token.properTicker,
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
const initialAssetRegistry = {
|
|
36
|
+
getAsset: (assetName) => {
|
|
37
|
+
try {
|
|
38
|
+
throw new Error(`accessing asset ${assetName} too early`)
|
|
39
|
+
} catch (e) {
|
|
40
|
+
console.warn(e.message, e.stack)
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
getAssets: () => {
|
|
44
|
+
try {
|
|
45
|
+
throw new Error(`accessing assets too early`)
|
|
46
|
+
} catch (e) {
|
|
47
|
+
console.warn(e.message, e.stack)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return {}
|
|
51
|
+
},
|
|
52
|
+
}
|
|
25
53
|
|
|
26
54
|
export class AssetsModule extends ExodusModule {
|
|
27
55
|
#registry
|
|
@@ -37,11 +65,14 @@ export class AssetsModule extends ExodusModule {
|
|
|
37
65
|
#storageDataKey
|
|
38
66
|
#storageTimestampKey
|
|
39
67
|
#customTokenUpdateInterval
|
|
68
|
+
#fetchCacheExpiry
|
|
40
69
|
#globalAssetRegistry // temporary
|
|
70
|
+
#isExternalRegistry
|
|
41
71
|
|
|
42
72
|
constructor({
|
|
43
73
|
storage,
|
|
44
74
|
iconsStorage,
|
|
75
|
+
assetRegistry, // temporary
|
|
45
76
|
assetPlugins,
|
|
46
77
|
combinedAssetsList,
|
|
47
78
|
globalAssetRegistry, // temporary
|
|
@@ -50,24 +81,8 @@ export class AssetsModule extends ExodusModule {
|
|
|
50
81
|
}) {
|
|
51
82
|
super({ name: 'AssetsModule' })
|
|
52
83
|
this.#storage = storage
|
|
53
|
-
this.#
|
|
54
|
-
|
|
55
|
-
try {
|
|
56
|
-
throw new Error(`accessing asset ${assetName} too early`)
|
|
57
|
-
} catch (e) {
|
|
58
|
-
console.warn(e.message, e.stack)
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
getAssets: () => {
|
|
62
|
-
try {
|
|
63
|
-
throw new Error(`accessing assets too early`)
|
|
64
|
-
} catch (e) {
|
|
65
|
-
console.warn(e.message, e.stack)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return {}
|
|
69
|
-
},
|
|
70
|
-
}
|
|
84
|
+
this.#isExternalRegistry = !!assetRegistry
|
|
85
|
+
this.#registry = this.#isExternalRegistry ? assetRegistry : initialAssetRegistry
|
|
71
86
|
this.#assetPlugins = assetPlugins
|
|
72
87
|
this.#combinedAssetsList = combinedAssetsList
|
|
73
88
|
this.#fetchCache = {}
|
|
@@ -79,12 +94,17 @@ export class AssetsModule extends ExodusModule {
|
|
|
79
94
|
this.#storageDataKey = config.storageDataKey || CT_DATA_KEY
|
|
80
95
|
this.#storageTimestampKey = config.storageTimestampKey || CT_TIMESTAMP_KEY
|
|
81
96
|
this.#customTokenUpdateInterval = config.customTokenUpdateInterval || CT_UPDATE_INTERVAL
|
|
97
|
+
this.#fetchCacheExpiry = config.fetchCacheExpiry ?? CT_FETCH_CACHE_EXPIRY
|
|
82
98
|
this.#globalAssetRegistry = globalAssetRegistry // temporary
|
|
83
99
|
}
|
|
84
100
|
|
|
85
101
|
// Assets Registry API
|
|
86
102
|
|
|
87
103
|
initialize = ({ assetClientInterface }) => {
|
|
104
|
+
assert(
|
|
105
|
+
!this.#isExternalRegistry,
|
|
106
|
+
'initialize(): cannot initialize when using external registry'
|
|
107
|
+
)
|
|
88
108
|
// TODO: pass asset specific config to assets module in `config.assetsConfig`
|
|
89
109
|
const { assetsConfig = {} } = this.#config
|
|
90
110
|
const assetsList = Object.entries(this.#assetPlugins)
|
|
@@ -159,6 +179,7 @@ export class AssetsModule extends ExodusModule {
|
|
|
159
179
|
'icon', // there is no icon field in built in assets, but there may be for custom tokens (TODO?)
|
|
160
180
|
'isBuiltIn',
|
|
161
181
|
'isCustomToken',
|
|
182
|
+
'lifecycleStatus',
|
|
162
183
|
'name',
|
|
163
184
|
'primaryColor',
|
|
164
185
|
'properName',
|
|
@@ -254,9 +275,11 @@ export class AssetsModule extends ExodusModule {
|
|
|
254
275
|
addRemoteTokens = async ({ tokenNames }) => {
|
|
255
276
|
const assets = this.getAssets()
|
|
256
277
|
const tokenNamesToFetch = tokenNames.filter((tokenName) => !assets[tokenName])
|
|
257
|
-
if (tokenNamesToFetch.length === 0) return
|
|
258
278
|
|
|
259
|
-
const tokensToAdd =
|
|
279
|
+
const tokensToAdd =
|
|
280
|
+
tokenNamesToFetch.length > 0
|
|
281
|
+
? await this.#fetch('tokens', { tokenNames: tokenNamesToFetch }, 'tokens')
|
|
282
|
+
: []
|
|
260
283
|
const tokensToUpdate = tokenNames
|
|
261
284
|
.map((tokenName) => assets[tokenName])
|
|
262
285
|
.filter((token) => !!token)
|
|
@@ -337,8 +360,8 @@ export class AssetsModule extends ExodusModule {
|
|
|
337
360
|
#getAssetNamesBy = (filter) =>
|
|
338
361
|
Object.keys(this.getAssets()).filter((assetName) => filter(this.getAsset(assetName)))
|
|
339
362
|
|
|
340
|
-
#setCache = (key, value
|
|
341
|
-
this.#fetchCache[key] = { value, expiry: Date.now() +
|
|
363
|
+
#setCache = (key, value) => {
|
|
364
|
+
this.#fetchCache[key] = { value, expiry: Date.now() + this.#fetchCacheExpiry }
|
|
342
365
|
}
|
|
343
366
|
|
|
344
367
|
#getCache = (key) => {
|
package/module/constants.js
CHANGED
package/monitor/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Timer } from '@exodus/timer'
|
|
2
|
+
import ms from 'ms'
|
|
3
|
+
|
|
4
|
+
const createCustomTokensMonitor = ({ assetsModule, appProcess }) => {
|
|
5
|
+
const timer = new Timer(ms('1m'))
|
|
6
|
+
|
|
7
|
+
timer.callback = async () => {
|
|
8
|
+
await appProcess?.awaitState('active')
|
|
9
|
+
assetsModule.updateTokens()
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return timer
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const customTokensMonitorDefinition = {
|
|
16
|
+
id: 'customTokensMonitor',
|
|
17
|
+
type: 'monitor',
|
|
18
|
+
factory: createCustomTokensMonitor,
|
|
19
|
+
dependencies: ['assetsModule', 'appProcess?'],
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default customTokensMonitorDefinition
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/assets-feature",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"description": "Assets module, clients and apis",
|
|
6
6
|
"main": "index.js",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"files": [
|
|
14
14
|
"client",
|
|
15
15
|
"module",
|
|
16
|
+
"monitor",
|
|
16
17
|
"plugin",
|
|
17
18
|
"redux",
|
|
18
19
|
"api",
|
|
@@ -32,6 +33,7 @@
|
|
|
32
33
|
"dependencies": {
|
|
33
34
|
"@exodus/basic-utils": "^2.1.0",
|
|
34
35
|
"@exodus/fetch": "^1.2.1",
|
|
36
|
+
"@exodus/timer": "^1.0.0",
|
|
35
37
|
"lodash": "^4.17.21",
|
|
36
38
|
"minimalistic-assert": "^1.0.1",
|
|
37
39
|
"ms": "^2.1.3",
|
|
@@ -60,5 +62,5 @@
|
|
|
60
62
|
"jest": "^29.1.2",
|
|
61
63
|
"redux": "^4.0.0"
|
|
62
64
|
},
|
|
63
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "c2300eac2bdc89cb16b5976a0de5d14005ad720a"
|
|
64
66
|
}
|
package/plugin/index.js
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
|
+
import { mapValues, pickBy } from '@exodus/basic-utils'
|
|
1
2
|
import { createAtomObserver } from '@exodus/atoms'
|
|
2
3
|
|
|
3
4
|
const createAssetsPlugin = ({ port, assetsModule, disabledPurposesAtom, multiAddressModeAtom }) => {
|
|
4
|
-
const emitAssetsLoad = () =>
|
|
5
|
+
const emitAssetsLoad = () => {
|
|
6
|
+
const assets = assetsModule.getAssets()
|
|
7
|
+
port.emit('assets-load', {
|
|
8
|
+
assets,
|
|
9
|
+
defaultAccountStates: mapValues(
|
|
10
|
+
pickBy(assets, (asset) => asset.api.hasFeature('accountState')),
|
|
11
|
+
(asset) => asset?.api?.createAccountState?.()?.create?.()
|
|
12
|
+
),
|
|
13
|
+
})
|
|
14
|
+
}
|
|
15
|
+
|
|
5
16
|
const listeners = [
|
|
6
17
|
['assets-add', (data) => port.emit('assets-add', data)],
|
|
7
18
|
['assets-update', (data) => port.emit('assets-update', data)],
|
package/redux/index.js
CHANGED
|
@@ -16,11 +16,11 @@ const assetsReduxDefinition = {
|
|
|
16
16
|
type: 'redux-module',
|
|
17
17
|
initialState,
|
|
18
18
|
eventReducers: {
|
|
19
|
-
'assets-load': (state,
|
|
19
|
+
'assets-load': (state, { assets }) => ({
|
|
20
20
|
...state,
|
|
21
21
|
error: null,
|
|
22
22
|
loaded: true,
|
|
23
|
-
data:
|
|
23
|
+
data: assets,
|
|
24
24
|
}),
|
|
25
25
|
'assets-add': mergeAssets,
|
|
26
26
|
'assets-update': mergeAssets,
|