@exodus/balances 13.13.0 → 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 +14 -0
- package/atoms/has-balance.js +1 -0
- package/index.js +2 -1
- package/module/index.js +49 -36
- package/package.json +12 -11
- 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,20 @@
|
|
|
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
|
+
|
|
16
|
+
## [13.13.1](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/balances@13.13.0...@exodus/balances@13.13.1) (2025-08-22)
|
|
17
|
+
|
|
18
|
+
**Note:** Version bump only for package @exodus/balances
|
|
19
|
+
|
|
6
20
|
## [13.13.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/balances@13.12.0...@exodus/balances@13.13.0) (2025-07-16)
|
|
7
21
|
|
|
8
22
|
### Features
|
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,23 +109,25 @@ 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
|
|
127
|
-
if (asset.api?.features?.balancesRequireFeeData)
|
|
126
|
+
if (asset.api?.features?.balancesRequireFeeData) {
|
|
128
127
|
this.#walletAccounts.forEach((walletAccount) => {
|
|
129
128
|
return this.#handleFeeDataUpdate({ walletAccount, assetName, feeData })
|
|
130
129
|
})
|
|
130
|
+
}
|
|
131
131
|
})
|
|
132
132
|
}),
|
|
133
133
|
|
|
@@ -145,18 +145,34 @@ class Balances {
|
|
|
145
145
|
|
|
146
146
|
#getAssets = () => this.#assetsModule.getAssets()
|
|
147
147
|
|
|
148
|
-
#
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
+
)
|
|
153
155
|
|
|
154
|
-
|
|
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
|
+
)
|
|
155
171
|
}
|
|
156
172
|
|
|
157
|
-
#
|
|
173
|
+
#handleBlockchainMetadataUpdate = (opts) => {
|
|
158
174
|
if (!this.#ready) {
|
|
159
|
-
this.#logger.log('ignore update from
|
|
175
|
+
this.#logger.log('ignore update from blockchain-metadata event.', { isReady: this.#ready })
|
|
160
176
|
return
|
|
161
177
|
}
|
|
162
178
|
|
|
@@ -297,15 +313,15 @@ class Balances {
|
|
|
297
313
|
accountState: providedAccountState = null,
|
|
298
314
|
txLogsByAssetName: providedTxLogsByAssetName = {},
|
|
299
315
|
}) => {
|
|
300
|
-
const {
|
|
316
|
+
const {
|
|
317
|
+
value: { txs: txLogsByAssetSource, accountStates },
|
|
318
|
+
} = await this.#blockchainMetadataAtom.get()
|
|
301
319
|
let accountState = providedAccountState
|
|
302
320
|
|
|
303
321
|
const baseAsset = this.#getAsset(assetName).baseAsset
|
|
304
322
|
|
|
305
323
|
if (!accountState) {
|
|
306
|
-
const
|
|
307
|
-
const { value } = await this.#accountStatesAtom.get()
|
|
308
|
-
const cached = value[walletAccount]?.[assetNameToUse]
|
|
324
|
+
const cached = accountStates[walletAccount]?.[baseAsset.name]
|
|
309
325
|
if (cached) {
|
|
310
326
|
accountState = cached
|
|
311
327
|
} else {
|
|
@@ -342,7 +358,7 @@ class Balances {
|
|
|
342
358
|
assetName,
|
|
343
359
|
walletAccount,
|
|
344
360
|
accountState: providedAccountState,
|
|
345
|
-
|
|
361
|
+
txLogsByAssetName: providedTxLogsByAssetName,
|
|
346
362
|
feeData: providedFeeData,
|
|
347
363
|
}) => {
|
|
348
364
|
if (!this.#isSupportedAsset(assetName)) return
|
|
@@ -358,9 +374,7 @@ class Balances {
|
|
|
358
374
|
walletAccount,
|
|
359
375
|
feeData: providedFeeData,
|
|
360
376
|
accountState: providedAccountState,
|
|
361
|
-
txLogsByAssetName:
|
|
362
|
-
[assetName]: providedTxLog,
|
|
363
|
-
},
|
|
377
|
+
txLogsByAssetName: providedTxLogsByAssetName,
|
|
364
378
|
})
|
|
365
379
|
|
|
366
380
|
const accountBalances = this.#balances[walletAccount]
|
|
@@ -429,8 +443,7 @@ const balancesDefinition = {
|
|
|
429
443
|
'config',
|
|
430
444
|
'logger',
|
|
431
445
|
'balancesAtom',
|
|
432
|
-
'
|
|
433
|
-
'accountStatesAtom',
|
|
446
|
+
'blockchainMetadataAtom',
|
|
434
447
|
'feeDataAtom',
|
|
435
448
|
'errorTracking',
|
|
436
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,9 +33,9 @@
|
|
|
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
|
-
"@exodus/core-selectors": "^
|
|
38
|
+
"@exodus/core-selectors": "^4.0.0",
|
|
39
39
|
"@exodus/currency": "^5.0.2",
|
|
40
40
|
"@exodus/errors": "^3.0.0",
|
|
41
41
|
"@exodus/models": "^12.0.1",
|
|
@@ -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.1
|
|
58
|
-
"@exodus/available-assets": "^8.
|
|
57
|
+
"@exodus/assets-feature": "^8.7.1",
|
|
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
|
-
"@exodus/storage-memory": "^2.
|
|
64
|
-
"@exodus/wallet-accounts": "^
|
|
63
|
+
"@exodus/storage-memory": "^2.3.0",
|
|
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'
|