@exodus/balances 13.15.5 → 13.16.1

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,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.16.1](https://github.com/ExodusMovement/exodus/compare/@exodus/balances@13.16.0...@exodus/balances@13.16.1) (2026-10-09)
7
+
8
+ **Note:** Version bump only for package @exodus/balances
9
+
10
+ ## [13.16.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/balances@13.15.5...@exodus/balances@13.16.0) (2026-05-19)
11
+
12
+ ### Features
13
+
14
+ - **balances:** publish balances atom types ([#16631](https://github.com/ExodusMovement/exodus-hydra/issues/16631)) ([826e09d](https://github.com/ExodusMovement/exodus-hydra/commit/826e09d99701b7e2de43f1a7d6c122d656c4b838))
15
+
6
16
  ## [13.15.5](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/balances@13.15.4...@exodus/balances@13.15.5) (2026-05-13)
7
17
 
8
18
  **Note:** Version bump only for package @exodus/balances
package/README.md CHANGED
@@ -5,7 +5,7 @@ This Exodus SDK feature tracks the crypto-denominated balances for all enabled w
5
5
  ## Install
6
6
 
7
7
  ```sh
8
- yarn add @exodus/balances
8
+ pnpm add @exodus/balances
9
9
  ```
10
10
 
11
11
  ## Usage
package/atoms/balances.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createInMemoryAtom } from '@exodus/atoms'
2
2
 
3
- // eslint-disable-next-line @exodus/hydra/in-memory-atom-default-value
3
+ // oxlint-disable-next-line @exodus/oxlint-plugin-hydra/in-memory-atom-default-value
4
4
  const createBalancesAtom = () => createInMemoryAtom()
5
5
 
6
6
  export default createBalancesAtom
@@ -22,7 +22,7 @@ const createHasBalanceAtom = ({ balancesAtom, storage }) => {
22
22
  isSoleWriter: true,
23
23
  })
24
24
  const computedAtom = createComputedAtom({ balancesAtom })
25
- // eslint-disable-next-line @exodus/hydra/no-eternal-subscription
25
+ // oxlint-disable-next-line @exodus/oxlint-plugin-hydra/no-eternal-subscription
26
26
  computedAtom.observe((value) => storageAtom.set(value))
27
27
 
28
28
  return storageAtom
package/index.d.ts ADDED
@@ -0,0 +1,35 @@
1
+ import type { BalanceFieldName, Balances as AssetBalances } from '@exodus/asset-types'
2
+ import type { Atom } from '@exodus/atoms'
3
+ import type NumberUnit from '@exodus/currency'
4
+
5
+ declare const balances: (walletConfig?: Record<string, unknown>) => {
6
+ id: string
7
+ definitions: unknown[]
8
+ }
9
+
10
+ export type Balances = Partial<AssetBalances>
11
+
12
+ type WalletAccountName = string
13
+
14
+ type AssetName = string
15
+
16
+ export type BalancesByAssetSource = Record<WalletAccountName, Record<AssetName, Balances>>
17
+
18
+ export type BalanceChange = {
19
+ from: NumberUnit
20
+ to: NumberUnit
21
+ }
22
+
23
+ export type BalanceChanges = Record<
24
+ WalletAccountName,
25
+ Record<AssetName, Partial<Record<BalanceFieldName, BalanceChange>>>
26
+ >
27
+
28
+ export type BalancesAtomValue = {
29
+ balances: BalancesByAssetSource
30
+ changes?: BalanceChanges
31
+ }
32
+
33
+ export type BalancesAtom = Atom<BalancesAtomValue>
34
+
35
+ export default balances
package/module/index.js CHANGED
@@ -41,7 +41,8 @@ const zipNonNull = (keys, values) => {
41
41
 
42
42
  class Balances {
43
43
  #logger
44
- #assetsModule
44
+ #assetsAtom
45
+ #assets = Object.create(null)
45
46
  #availableAssetNamesAtom
46
47
  #availableAssetNames = []
47
48
  #balanceFieldsConfig
@@ -58,7 +59,7 @@ class Balances {
58
59
  #subscriptions = []
59
60
  #errorTracking
60
61
  constructor({
61
- assetsModule,
62
+ assetsAtom,
62
63
  availableAssetNamesAtom,
63
64
  enabledWalletAccountsAtom,
64
65
  config,
@@ -69,7 +70,7 @@ class Balances {
69
70
  errorTracking,
70
71
  }) {
71
72
  this.#logger = logger
72
- this.#assetsModule = assetsModule
73
+ this.#assetsAtom = assetsAtom
73
74
  this.#availableAssetNamesAtom = availableAssetNamesAtom
74
75
  this.#balanceFieldsConfig = config?.balanceFieldsConfig || defaultConfig.balanceFieldsConfig
75
76
  this.#balanceFields = config?.balanceFields || defaultConfig.balanceFields
@@ -114,9 +115,15 @@ class Balances {
114
115
  if (this.#loaded) return
115
116
  this.#loaded = true
116
117
 
118
+ const { value } = await this.#assetsAtom.get()
119
+ this.#assets = value
120
+
117
121
  this.#subscriptions.push(
122
+ this.#assetsAtom.observe(({ value }) => {
123
+ this.#assets = value
124
+ }),
118
125
  this.#enabledWalletAccountsAtom.observe((payload) => {
119
- this.#setWalletAccounts(Object.keys(payload))
126
+ void this.#setWalletAccounts(Object.keys(payload))
120
127
  }),
121
128
  this.#blockchainMetadataAtom.observe(({ accountStateChanges, txLogChanges }) => {
122
129
  this.#flattenToBlockchainMetadataObjects({ accountStateChanges, txLogChanges }).forEach(
@@ -144,16 +151,16 @@ class Balances {
144
151
  this.#availableAssetNames = current
145
152
  const added = difference(current, previous)
146
153
  const removed = difference(previous, current)
147
- if (added.length > 0 || removed.length > 0) this.#onAssetsChanged({ added, removed })
154
+ if (added.length > 0 || removed.length > 0) void this.#onAssetsChanged({ added, removed })
148
155
  })
149
156
  )
150
157
 
151
158
  this.#availableAssetNames = await this.#availableAssetNamesAtom.get()
152
159
  }
153
160
 
154
- #getAsset = (assetName) => this.#assetsModule.getAsset(assetName)
161
+ #getAsset = (assetName) => this.#assets[assetName]
155
162
 
156
- #getAssets = () => this.#assetsModule.getAssets()
163
+ #getAssets = () => this.#assets
157
164
 
158
165
  #flattenToBlockchainMetadataObjects = ({
159
166
  accountStateChanges = Object.create(null),
@@ -333,10 +340,10 @@ class Balances {
333
340
  #getSupportedAssetNames = () => Object.keys(this.#getAssets()).filter(this.#isSupportedAsset)
334
341
 
335
342
  #getRelatedAssetNames = (assetName) => {
336
- const asset = this.#assetsModule.getAsset(assetName)
343
+ const asset = this.#assets[assetName]
337
344
  if (asset.baseAsset.name === assetName) {
338
- return [assetName, ...this.#assetsModule.getTokenNames(assetName)].filter(
339
- this.#isSupportedAsset
345
+ return Object.keys(this.#assets).filter(
346
+ (name) => this.#assets[name].baseAsset.name === assetName && this.#isSupportedAsset(name)
340
347
  )
341
348
  }
342
349
 
@@ -474,7 +481,7 @@ const balancesDefinition = {
474
481
  type: 'module',
475
482
  factory: createBalances,
476
483
  dependencies: [
477
- 'assetsModule',
484
+ 'assetsAtom',
478
485
  'availableAssetNamesAtom',
479
486
  'enabledWalletAccountsAtom',
480
487
  'config',
package/package.json CHANGED
@@ -1,22 +1,26 @@
1
1
  {
2
2
  "name": "@exodus/balances",
3
- "version": "13.15.5",
3
+ "version": "13.16.1",
4
4
  "description": "Tracks crypto balances across enabled wallet accounts.",
5
5
  "author": "Exodus Movement, Inc.",
6
6
  "license": "MIT",
7
7
  "scripts": {
8
- "test": "run -T exodus-test --jest",
9
- "lint": "run -T eslint -c ../../eslint.config.mjs",
10
- "lint:fix": "yarn lint --fix",
11
- "format": "run -T prettier --write \"**/*.{json,md,yaml}\" --log-level warn",
12
- "format:check": "run -T prettier --check \"**/*.{json,md,yaml}\" --log-level warn"
8
+ "test": "pnpm exec exodus-test --jest",
9
+ "typecheck": "pnpm exec tsc -p tsconfig.json --noEmit",
10
+ "lint": "pnpm exec eslint -c ../../eslint.config.mjs",
11
+ "lint:fix": "pnpm run lint --fix",
12
+ "format": "pnpm exec prettier --write \"**/*.{json,md,yaml}\" --log-level warn",
13
+ "format:check": "pnpm exec prettier --check \"**/*.{json,md,yaml}\" --log-level warn"
13
14
  },
14
15
  "type": "module",
15
16
  "main": "index.js",
17
+ "types": "index.d.ts",
16
18
  "files": [
17
19
  "module",
18
20
  "atoms",
19
21
  "default-config.js",
22
+ "index.d.ts",
23
+ "tsconfig.json",
20
24
  "report",
21
25
  "plugins",
22
26
  "redux",
@@ -26,24 +30,25 @@
26
30
  ],
27
31
  "repository": {
28
32
  "type": "git",
29
- "url": "git+https://github.com/ExodusMovement/exodus-hydra.git"
33
+ "url": "git+https://github.com/ExodusMovement/exodus.git"
30
34
  },
31
- "homepage": "https://github.com/ExodusMovement/exodus-hydra/tree/master/features/balances",
35
+ "homepage": "https://github.com/ExodusMovement/exodus/tree/master/libs/features/balances",
32
36
  "bugs": {
33
- "url": "https://github.com/ExodusMovement/exodus-hydra/issues?q=is%3Aissue+is%3Aopen+label%3Abalances"
37
+ "url": "https://github.com/ExodusMovement/exodus/issues?q=is%3Aissue+is%3Aopen+label%3Abalances"
34
38
  },
35
39
  "dependencies": {
36
- "@exodus/atoms": "^10.0.0",
37
- "@exodus/basic-utils": "^5.0.0",
38
- "@exodus/core-selectors": "^4.0.0",
39
- "@exodus/currency": "^6.0.0",
40
- "@exodus/errors": "^3.0.0",
41
- "@exodus/models": "^13.0.0",
40
+ "@exodus/asset-types": "^0.6.0",
41
+ "@exodus/atoms": "^10.3.5",
42
+ "@exodus/basic-utils": "^5.2.1",
43
+ "@exodus/core-selectors": "^4.0.3",
44
+ "@exodus/currency": "^6.4.1",
45
+ "@exodus/errors": "^3.8.1",
46
+ "@exodus/models": "^13.3.2",
42
47
  "@exodus/multi-account-redux": "^3.0.0",
43
- "@exodus/redux-dependency-injection": "^4.0.3",
44
- "@exodus/safe-string": "^1.1.0",
45
- "@exodus/typeforce": "^1.18.0",
46
- "@exodus/zod": "^3.24.2",
48
+ "@exodus/redux-dependency-injection": "^5.0.0",
49
+ "@exodus/safe-string": "^1.5.0",
50
+ "@exodus/typeforce": "^1.19.4",
51
+ "@exodus/zod": "^3.24.4",
47
52
  "lodash": "^4.17.21",
48
53
  "make-concurrent": "^4.0.0",
49
54
  "reselect": "^3.0.1"
@@ -54,14 +59,14 @@
54
59
  "devDependencies": {
55
60
  "@exodus/assets": "^11.0.0",
56
61
  "@exodus/assets-base": "^12.0.0",
57
- "@exodus/assets-feature": "^9.2.2",
58
- "@exodus/available-assets": "^8.11.0",
62
+ "@exodus/assets-feature": "^9.4.0",
63
+ "@exodus/available-assets": "^8.11.2",
59
64
  "@exodus/bitcoin-meta": "^2.0.0",
60
- "@exodus/blockchain-metadata": "^17.1.1",
65
+ "@exodus/blockchain-metadata": "^17.2.1",
61
66
  "@exodus/ethereum-meta": "^2.0.0",
62
- "@exodus/fee-data-monitors": "^5.0.5",
63
- "@exodus/storage-memory": "^2.4.0",
64
- "@exodus/wallet-accounts": "^20.4.4",
67
+ "@exodus/fee-data-monitors": "^5.0.6",
68
+ "@exodus/storage-memory": "^2.4.1",
69
+ "@exodus/wallet-accounts": "^20.4.12",
65
70
  "events": "^3.3.0",
66
71
  "redux": "^4.2.1"
67
72
  },
@@ -69,5 +74,5 @@
69
74
  "access": "public",
70
75
  "provenance": false
71
76
  },
72
- "gitHead": "26c6093fc4c0d572e6575b307f492acab9c978e1"
77
+ "gitHead": "1f4cac80971bb7800acb1493c4b231098a9d39d8"
73
78
  }
@@ -3,7 +3,7 @@ import lodash from 'lodash'
3
3
  import { MY_STATE } from '@exodus/redux-dependency-injection'
4
4
  import { createSelector } from 'reselect'
5
5
 
6
- const { memoize } = lodash // eslint-disable-line @exodus/basic-utils/prefer-basic-utils
6
+ const { memoize } = lodash // oxlint-disable-line @exodus/oxlint-plugin-restricted-imports/prefer-basic-utils
7
7
 
8
8
  const createBalanceSelectorFactory = ({ field, id }) => {
9
9
  const selectorFactory = (createAssetSelector, selfSelector) =>
@@ -3,7 +3,7 @@ import lodash from 'lodash'
3
3
  import { createSelector } from 'reselect'
4
4
  import { MY_STATE } from '@exodus/redux-dependency-injection'
5
5
 
6
- const { memoize } = lodash // eslint-disable-line @exodus/basic-utils/prefer-basic-utils
6
+ const { memoize } = lodash // oxlint-disable-line @exodus/oxlint-plugin-restricted-imports/prefer-basic-utils
7
7
 
8
8
  const EMPTY_BALANCES = Object.create(null)
9
9
 
@@ -3,7 +3,7 @@ import lodash from 'lodash'
3
3
  import { createSelector } from 'reselect'
4
4
  import { isNumberUnit } from '@exodus/currency'
5
5
 
6
- const { memoize } = lodash // eslint-disable-line @exodus/basic-utils/prefer-basic-utils
6
+ const { memoize } = lodash // oxlint-disable-line @exodus/oxlint-plugin-restricted-imports/prefer-basic-utils
7
7
 
8
8
  const selectorFactory = (getFeeDataSelector, createAssetSelector) =>
9
9
  memoize((assetName) =>
@@ -3,7 +3,7 @@ import lodash from 'lodash'
3
3
  import { createSelector } from 'reselect'
4
4
  import { getUnconfirmedBalance } from './get-unconfirmed-balance.js'
5
5
 
6
- const { memoize } = lodash // eslint-disable-line @exodus/basic-utils/prefer-basic-utils
6
+ const { memoize } = lodash // oxlint-disable-line @exodus/oxlint-plugin-restricted-imports/prefer-basic-utils
7
7
 
8
8
  const selectorFactory = (createAssetSelector, createAssetSourceSelector) =>
9
9
  memoize(
@@ -2,7 +2,7 @@
2
2
  import lodash from 'lodash'
3
3
  import defaultConfig from '../../default-config.js'
4
4
 
5
- const { memoize } = lodash // eslint-disable-line @exodus/basic-utils/prefer-basic-utils
5
+ const { memoize } = lodash // oxlint-disable-line @exodus/oxlint-plugin-restricted-imports/prefer-basic-utils
6
6
 
7
7
  const { balanceFields } = defaultConfig
8
8
 
@@ -1,7 +1,7 @@
1
1
  // eslint-disable-next-line no-restricted-imports -- TODO: Fix this the next time the file is edited.
2
2
  import lodash from 'lodash'
3
3
 
4
- const { memoize } = lodash // eslint-disable-line @exodus/basic-utils/prefer-basic-utils
4
+ const { memoize } = lodash // oxlint-disable-line @exodus/oxlint-plugin-restricted-imports/prefer-basic-utils
5
5
 
6
6
  const createResultFunction = (field) => (getBalanceForField) =>
7
7
  memoize(
@@ -3,7 +3,7 @@ import lodash from 'lodash'
3
3
  import { createSelector } from 'reselect'
4
4
  import { MY_STATE } from '@exodus/redux-dependency-injection'
5
5
 
6
- const { memoize } = lodash // eslint-disable-line @exodus/basic-utils/prefer-basic-utils
6
+ const { memoize } = lodash // oxlint-disable-line @exodus/oxlint-plugin-restricted-imports/prefer-basic-utils
7
7
 
8
8
  const selectorFactory = (selfSelector) =>
9
9
  createSelector(selfSelector, (balances) =>
@@ -2,7 +2,7 @@
2
2
  import lodash from 'lodash'
3
3
  import { createSelector } from 'reselect'
4
4
 
5
- const { memoize } = lodash // eslint-disable-line @exodus/basic-utils/prefer-basic-utils
5
+ const { memoize } = lodash // oxlint-disable-line @exodus/oxlint-plugin-restricted-imports/prefer-basic-utils
6
6
 
7
7
  export const getUnconfirmedBalance = ({ asset, txs }) => {
8
8
  let result = asset.currency.ZERO
package/tsconfig.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "module": "nodenext",
5
+ "moduleResolution": "nodenext"
6
+ },
7
+ "include": ["index.d.ts"]
8
+ }