@exodus/balances 13.13.1 → 13.14.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 +10 -0
- package/atoms/has-balance.js +1 -0
- package/index.js +2 -1
- package/module/index.js +47 -35
- package/package.json +9 -8
- package/redux/index.js +1 -0
- package/redux/selectors/create-balance-selectors.js +1 -0
- package/redux/selectors/create-balances.js +1 -0
- package/redux/selectors/create-fuel-threshold.js +1 -0
- package/redux/selectors/create-unconfirmed-balance.js +1 -0
- package/redux/selectors/get-balance-for-field.js +1 -0
- package/redux/selectors/get-balance-selectors.js +1 -0
- package/redux/selectors/get-balances.js +1 -0
- package/redux/selectors/get-unconfirmed-balance.js +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
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
|
+
## [13.14.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/balances@13.13.1...@exodus/balances@13.14.0) (2025-11-27)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- feat: bump atoms for importers of observer factory (#14057)
|
|
11
|
+
|
|
12
|
+
- feat: introduce blockChainMetadataAtom (#14470)
|
|
13
|
+
|
|
14
|
+
- feat: update all consumers to use safe strings for error namespaces (#14429)
|
|
15
|
+
|
|
6
16
|
## [13.13.1](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/balances@13.13.0...@exodus/balances@13.13.1) (2025-08-22)
|
|
7
17
|
|
|
8
18
|
**Note:** Version bump only for package @exodus/balances
|
package/atoms/has-balance.js
CHANGED
package/index.js
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
import typeforce from '@exodus/typeforce'
|
|
16
16
|
import defaultConfig from './default-config.js'
|
|
17
17
|
import mockableBalancesDefinition from './module/mockable-balances.js'
|
|
18
|
+
import { safeString } from '@exodus/safe-string'
|
|
18
19
|
|
|
19
20
|
const balances = (walletConfig) => {
|
|
20
21
|
const config = {
|
|
@@ -34,7 +35,7 @@ const balances = (walletConfig) => {
|
|
|
34
35
|
)
|
|
35
36
|
|
|
36
37
|
return {
|
|
37
|
-
id:
|
|
38
|
+
id: safeString`balances`,
|
|
38
39
|
definitions: [
|
|
39
40
|
{
|
|
40
41
|
definition: walletConfig?.importReport ? mockableBalancesDefinition : balancesDefinition,
|
package/module/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { safeString } from '@exodus/safe-string'
|
|
2
2
|
import { isNumberUnit } from '@exodus/currency'
|
|
3
3
|
import { TxSet } from '@exodus/models'
|
|
4
|
+
// eslint-disable-next-line no-restricted-imports -- TODO: Fix this the next time the file is edited.
|
|
4
5
|
import lodash from 'lodash'
|
|
5
6
|
import { difference as getChanges } from '@exodus/atoms'
|
|
6
|
-
import { difference,
|
|
7
|
+
import { difference, pick, set, mapValues } from '@exodus/basic-utils'
|
|
7
8
|
import makeConcurrent from 'make-concurrent'
|
|
8
9
|
import { processAssetBalances, validateBalances } from './balances-utils.js'
|
|
9
10
|
import defaultConfig from '../default-config.js'
|
|
@@ -41,8 +42,7 @@ class Balances {
|
|
|
41
42
|
|
|
42
43
|
#balances = Object.create(null)
|
|
43
44
|
#balancesAtom
|
|
44
|
-
#
|
|
45
|
-
#txLogsAtom
|
|
45
|
+
#blockchainMetadataAtom
|
|
46
46
|
#feeDataAtom
|
|
47
47
|
#enabledWalletAccountsAtom
|
|
48
48
|
#loaded = false
|
|
@@ -55,8 +55,7 @@ class Balances {
|
|
|
55
55
|
config,
|
|
56
56
|
logger,
|
|
57
57
|
balancesAtom,
|
|
58
|
-
|
|
59
|
-
accountStatesAtom,
|
|
58
|
+
blockchainMetadataAtom,
|
|
60
59
|
feeDataAtom,
|
|
61
60
|
errorTracking,
|
|
62
61
|
}) {
|
|
@@ -66,8 +65,7 @@ class Balances {
|
|
|
66
65
|
this.#balanceFieldsConfig = config?.balanceFieldsConfig || defaultConfig.balanceFieldsConfig
|
|
67
66
|
this.#balanceFields = config?.balanceFields || defaultConfig.balanceFields
|
|
68
67
|
this.#balancesAtom = balancesAtom
|
|
69
|
-
this.#
|
|
70
|
-
this.#txLogsAtom = txLogsAtom
|
|
68
|
+
this.#blockchainMetadataAtom = blockchainMetadataAtom
|
|
71
69
|
this.#feeDataAtom = feeDataAtom
|
|
72
70
|
this.#enabledWalletAccountsAtom = enabledWalletAccountsAtom
|
|
73
71
|
this.#errorTracking = errorTracking
|
|
@@ -92,7 +90,7 @@ class Balances {
|
|
|
92
90
|
|
|
93
91
|
// these share a queue
|
|
94
92
|
this.#updateAssetSource = shareQueue(this.#updateAssetSource)
|
|
95
|
-
this.#
|
|
93
|
+
this.#handleBlockchainMetadataUpdate = shareQueue(this.#handleBlockchainMetadataUpdate)
|
|
96
94
|
this.#handleFeeDataUpdate = shareQueue(this.#handleFeeDataUpdate)
|
|
97
95
|
this.#recompute = shareQueue(this.#recompute)
|
|
98
96
|
this.#onAssetsChanged = shareQueue(this.#onAssetsChanged)
|
|
@@ -111,16 +109,17 @@ class Balances {
|
|
|
111
109
|
this.#enabledWalletAccountsAtom.observe((payload) => {
|
|
112
110
|
this.#setWalletAccounts(Object.keys(payload))
|
|
113
111
|
}),
|
|
114
|
-
this.#
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
112
|
+
this.#blockchainMetadataAtom.observe(({ accountStateChanges, txLogChanges }) => {
|
|
113
|
+
this.#flattenToBlockchainMetadataObjects({ accountStateChanges, txLogChanges }).forEach(
|
|
114
|
+
({ walletAccount, assetName, accountState, txLogsByAssetName }) =>
|
|
115
|
+
this.#handleBlockchainMetadataUpdate({
|
|
116
|
+
walletAccount,
|
|
117
|
+
assetName,
|
|
118
|
+
accountState,
|
|
119
|
+
txLogsByAssetName,
|
|
120
|
+
})
|
|
122
121
|
)
|
|
123
|
-
),
|
|
122
|
+
}),
|
|
124
123
|
this.#feeDataAtom.observe((changes) => {
|
|
125
124
|
Object.entries(changes).forEach(([assetName, feeData]) => {
|
|
126
125
|
const asset = this.#getAsset(assetName).baseAsset
|
|
@@ -146,18 +145,34 @@ class Balances {
|
|
|
146
145
|
|
|
147
146
|
#getAssets = () => this.#assetsModule.getAssets()
|
|
148
147
|
|
|
149
|
-
#
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
148
|
+
#flattenToBlockchainMetadataObjects = ({
|
|
149
|
+
accountStateChanges = Object.create(null),
|
|
150
|
+
txLogChanges = Object.create(null),
|
|
151
|
+
}) => {
|
|
152
|
+
const byBaseAssetName = mapValues(accountStateChanges, (accountStates) =>
|
|
153
|
+
mapValues(accountStates, (accountState) => ({ accountState }))
|
|
154
|
+
)
|
|
154
155
|
|
|
155
|
-
|
|
156
|
+
Object.entries(txLogChanges).forEach(([walletAccount, txLogs]) => {
|
|
157
|
+
Object.entries(txLogs).map(([assetName, txLog]) => {
|
|
158
|
+
const { baseAsset } = this.#getAsset(assetName)
|
|
159
|
+
set(byBaseAssetName, [walletAccount, baseAsset.name, 'txLogsByAssetName', assetName], txLog)
|
|
160
|
+
})
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
return Object.entries(byBaseAssetName).flatMap(([walletAccount, baseAssets]) =>
|
|
164
|
+
Object.entries(baseAssets).map(([baseAssetName, { accountState, txLogsByAssetName }]) => ({
|
|
165
|
+
walletAccount,
|
|
166
|
+
assetName: baseAssetName,
|
|
167
|
+
...(accountState && { accountState }),
|
|
168
|
+
...(txLogsByAssetName && { txLogsByAssetName }),
|
|
169
|
+
}))
|
|
170
|
+
)
|
|
156
171
|
}
|
|
157
172
|
|
|
158
|
-
#
|
|
173
|
+
#handleBlockchainMetadataUpdate = (opts) => {
|
|
159
174
|
if (!this.#ready) {
|
|
160
|
-
this.#logger.log('ignore update from
|
|
175
|
+
this.#logger.log('ignore update from blockchain-metadata event.', { isReady: this.#ready })
|
|
161
176
|
return
|
|
162
177
|
}
|
|
163
178
|
|
|
@@ -298,15 +313,15 @@ class Balances {
|
|
|
298
313
|
accountState: providedAccountState = null,
|
|
299
314
|
txLogsByAssetName: providedTxLogsByAssetName = {},
|
|
300
315
|
}) => {
|
|
301
|
-
const {
|
|
316
|
+
const {
|
|
317
|
+
value: { txs: txLogsByAssetSource, accountStates },
|
|
318
|
+
} = await this.#blockchainMetadataAtom.get()
|
|
302
319
|
let accountState = providedAccountState
|
|
303
320
|
|
|
304
321
|
const baseAsset = this.#getAsset(assetName).baseAsset
|
|
305
322
|
|
|
306
323
|
if (!accountState) {
|
|
307
|
-
const
|
|
308
|
-
const { value } = await this.#accountStatesAtom.get()
|
|
309
|
-
const cached = value[walletAccount]?.[assetNameToUse]
|
|
324
|
+
const cached = accountStates[walletAccount]?.[baseAsset.name]
|
|
310
325
|
if (cached) {
|
|
311
326
|
accountState = cached
|
|
312
327
|
} else {
|
|
@@ -343,7 +358,7 @@ class Balances {
|
|
|
343
358
|
assetName,
|
|
344
359
|
walletAccount,
|
|
345
360
|
accountState: providedAccountState,
|
|
346
|
-
|
|
361
|
+
txLogsByAssetName: providedTxLogsByAssetName,
|
|
347
362
|
feeData: providedFeeData,
|
|
348
363
|
}) => {
|
|
349
364
|
if (!this.#isSupportedAsset(assetName)) return
|
|
@@ -359,9 +374,7 @@ class Balances {
|
|
|
359
374
|
walletAccount,
|
|
360
375
|
feeData: providedFeeData,
|
|
361
376
|
accountState: providedAccountState,
|
|
362
|
-
txLogsByAssetName:
|
|
363
|
-
[assetName]: providedTxLog,
|
|
364
|
-
},
|
|
377
|
+
txLogsByAssetName: providedTxLogsByAssetName,
|
|
365
378
|
})
|
|
366
379
|
|
|
367
380
|
const accountBalances = this.#balances[walletAccount]
|
|
@@ -430,8 +443,7 @@ const balancesDefinition = {
|
|
|
430
443
|
'config',
|
|
431
444
|
'logger',
|
|
432
445
|
'balancesAtom',
|
|
433
|
-
'
|
|
434
|
-
'accountStatesAtom',
|
|
446
|
+
'blockchainMetadataAtom',
|
|
435
447
|
'feeDataAtom',
|
|
436
448
|
'errorTracking',
|
|
437
449
|
],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/balances",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.14.0",
|
|
4
4
|
"description": "Tracks crypto balances across enabled wallet accounts.",
|
|
5
5
|
"author": "Exodus Movement, Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"url": "https://github.com/ExodusMovement/exodus-hydra/issues?q=is%3Aissue+is%3Aopen+label%3Abalances"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@exodus/atoms": "^
|
|
36
|
+
"@exodus/atoms": "^10.0.0",
|
|
37
37
|
"@exodus/basic-utils": "^3.0.1",
|
|
38
38
|
"@exodus/core-selectors": "^4.0.0",
|
|
39
39
|
"@exodus/currency": "^5.0.2",
|
|
@@ -49,24 +49,25 @@
|
|
|
49
49
|
"reselect": "^3.0.1"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
|
-
"@exodus/blockchain-metadata": "^
|
|
52
|
+
"@exodus/blockchain-metadata": "^17.0.0"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@exodus/assets": "^11.0.0",
|
|
56
56
|
"@exodus/assets-base": "^10.0.0",
|
|
57
|
-
"@exodus/assets-feature": "^8.
|
|
57
|
+
"@exodus/assets-feature": "^8.7.1",
|
|
58
58
|
"@exodus/available-assets": "^8.8.0",
|
|
59
59
|
"@exodus/bitcoin-meta": "^2.0.0",
|
|
60
|
-
"@exodus/blockchain-metadata": "^
|
|
60
|
+
"@exodus/blockchain-metadata": "^17.1.0",
|
|
61
61
|
"@exodus/ethereum-meta": "^2.0.0",
|
|
62
62
|
"@exodus/fee-data-monitors": "^5.0.4",
|
|
63
63
|
"@exodus/storage-memory": "^2.3.0",
|
|
64
|
-
"@exodus/wallet-accounts": "^
|
|
64
|
+
"@exodus/wallet-accounts": "^20.2.1",
|
|
65
65
|
"events": "^3.3.0",
|
|
66
66
|
"redux": "^4.2.1"
|
|
67
67
|
},
|
|
68
68
|
"publishConfig": {
|
|
69
|
-
"access": "public"
|
|
69
|
+
"access": "public",
|
|
70
|
+
"provenance": false
|
|
70
71
|
},
|
|
71
|
-
"gitHead": "
|
|
72
|
+
"gitHead": "1535d3792c06b4c96e94e0787f75d40fbb5cca1f"
|
|
72
73
|
}
|
package/redux/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import id from './id.js'
|
|
|
2
2
|
import initialState from './initial-state.js'
|
|
3
3
|
import selectorDefinitions from './selectors/index.js'
|
|
4
4
|
import { mapValues } from '@exodus/basic-utils'
|
|
5
|
+
// eslint-disable-next-line no-restricted-imports -- TODO: Fix this the next time the file is edited.
|
|
5
6
|
import lodash from 'lodash'
|
|
6
7
|
import helper from './multi-account-helper.js'
|
|
7
8
|
import { setAccounts } from '@exodus/multi-account-redux/src/common.js'
|