@exodus/sui-api 1.4.0 → 1.4.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,15 @@
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
+ ## [1.4.1](https://github.com/ExodusMovement/assets/compare/@exodus/sui-api@1.4.0...@exodus/sui-api@1.4.1) (2026-11-02)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **sui-api:** count sui address balances in balances ([#9140](https://github.com/ExodusMovement/assets/issues/9140)) ([9486138](https://github.com/ExodusMovement/assets/commit/9486138e6cedc7edf88f136bdfc998d735756ece))
12
+
13
+
14
+
6
15
  ## [1.4.0](https://github.com/ExodusMovement/assets/compare/@exodus/sui-api@1.3.1...@exodus/sui-api@1.4.0) (2026-10-22)
7
16
 
8
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/sui-api",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "Transaction monitors, RPC with the blockchain node, and other networking code for Sui",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -24,7 +24,6 @@
24
24
  "@exodus/asset-lib": "^5.0.0",
25
25
  "@exodus/basic-utils": "^5.1.0",
26
26
  "@exodus/crypto": "^1.0.0-rc.26",
27
- "@exodus/currency": "^6.0.1",
28
27
  "@exodus/models": "^13.0.0",
29
28
  "@exodus/sui-lib": "^1.3.0",
30
29
  "@exodus/sui-meta": "^1.2.0",
@@ -33,7 +32,8 @@
33
32
  "ms": "^2.1.3"
34
33
  },
35
34
  "devDependencies": {
36
- "@exodus/assets-testing": "^1.0.0"
35
+ "@exodus/assets-testing": "^1.0.0",
36
+ "@exodus/currency": "^6.0.1"
37
37
  },
38
38
  "homepage": "https://github.com/ExodusMovement/assets/tree/master/sui/sui-api",
39
39
  "bugs": {
@@ -43,5 +43,5 @@
43
43
  "type": "git",
44
44
  "url": "git+https://github.com/ExodusMovement/assets.git"
45
45
  },
46
- "gitHead": "f210c7a3aa55561320c43aa8d8d5804b49f390d0"
46
+ "gitHead": "623851699b6a7b3edeedd9d6a3a95aadf1413a31"
47
47
  }
package/src/api.js CHANGED
@@ -181,9 +181,10 @@ export class SuiApi {
181
181
  variables: { owner: address },
182
182
  getConnection: (data) => data.address?.balances,
183
183
  })
184
- return balances.map(({ coinType, totalBalance }) => ({
184
+ return balances.map(({ coinType, totalBalance, addressBalance }) => ({
185
185
  coinType: toJsonRpcTypeTag(coinType.repr),
186
186
  totalBalance,
187
+ addressBalance,
187
188
  }))
188
189
  }
189
190
 
package/src/balances.js CHANGED
@@ -1,29 +1,29 @@
1
1
  import { getStakingBalances } from './staking/staking-balances.js'
2
2
 
3
+ const getAddressBalance = ({ asset, accountState }) =>
4
+ asset.currency.baseUnit(accountState.addressBalances[asset.name] ?? 0)
5
+
3
6
  export const getBalances = ({ asset, accountState }) => {
4
7
  const isBaseAsset = asset.name === asset.baseAssetName
8
+ const addressBalance = getAddressBalance({ asset, accountState })
5
9
 
6
10
  if (isBaseAsset) {
7
11
  const spendable = accountState.utxos.value
8
12
  const stakingBalances = getStakingBalances({ asset, stakingInfo: accountState.stakingInfo })
9
13
  const { staking, staked, unstaked } = stakingBalances
10
14
  return {
11
- total: spendable.add(staking).add(staked).add(unstaked),
15
+ total: spendable.add(addressBalance).add(staking).add(staked).add(unstaked),
12
16
  spendable,
13
17
  stakeable: spendable,
18
+ unspendable: addressBalance,
14
19
  ...stakingBalances,
15
20
  }
16
21
  }
17
22
 
18
- if (accountState.tokenUtxos[asset.name]) {
19
- return {
20
- total: accountState.tokenUtxos[asset.name].value,
21
- spendable: accountState.tokenUtxos[asset.name].value,
22
- }
23
- }
24
-
23
+ const spendable = accountState.tokenUtxos[asset.name]?.value ?? asset.currency.ZERO
25
24
  return {
26
- total: asset.currency.ZERO,
27
- spendable: asset.currency.ZERO,
25
+ total: spendable.add(addressBalance),
26
+ spendable,
27
+ unspendable: addressBalance,
28
28
  }
29
29
  }
@@ -8,6 +8,7 @@ export const createBasicAccountState = () => {
8
8
  static defaults = {
9
9
  utxos: UtxoCollection.createEmpty({ currency: asset.currency }),
10
10
  tokenUtxos: Object.create(null),
11
+ addressBalances: Object.create(null),
11
12
  stakingInfo: EMPTY_STAKING_INFO,
12
13
  }
13
14
  }
@@ -65,7 +65,7 @@ export const ALL_BALANCES = `
65
65
  address(address: $owner) {
66
66
  balances(first: 50, after: $cursor) {
67
67
  pageInfo { hasNextPage endCursor }
68
- nodes { coinType { repr } totalBalance }
68
+ nodes { coinType { repr } totalBalance addressBalance }
69
69
  }
70
70
  }
71
71
  }
@@ -61,7 +61,7 @@ export class SuiNoHistoryMonitor extends BaseMonitor {
61
61
 
62
62
  const ourWalletAddress = await this.aci.getReceiveAddress({ assetName, walletAccount })
63
63
 
64
- const { utxos, tokenUtxos, unknownAssetIds } = await this.#getNewAccountState({
64
+ const { utxos, tokenUtxos, addressBalances, unknownAssetIds } = await this.#getNewAccountState({
65
65
  address: ourWalletAddress,
66
66
  })
67
67
 
@@ -81,6 +81,7 @@ export class SuiNoHistoryMonitor extends BaseMonitor {
81
81
  newData: {
82
82
  utxos,
83
83
  tokenUtxos,
84
+ addressBalances,
84
85
  ...stakingData,
85
86
  },
86
87
  batch,
@@ -238,9 +239,17 @@ export class SuiNoHistoryMonitor extends BaseMonitor {
238
239
  }
239
240
 
240
241
  #getNewAccountState = async ({ address }) => {
241
- const allCoins = await this.#serverApi.getAllCoins({
242
- owner: address,
243
- })
242
+ const [allCoins, allBalances] = await Promise.all([
243
+ this.#serverApi.getAllCoins({ owner: address }),
244
+ this.#serverApi.getAccountAllBalances({ address }),
245
+ ])
246
+
247
+ const addressBalanceByCoinType = Object.create(null)
248
+ for (const { coinType, addressBalance } of allBalances) {
249
+ if (addressBalance && addressBalance !== '0') {
250
+ addressBalanceByCoinType[coinType] = addressBalance
251
+ }
252
+ }
244
253
 
245
254
  const groupedCoins = allCoins.reduce((acc, coin) => {
246
255
  if (!acc[coin.coinType]) {
@@ -252,39 +261,43 @@ export class SuiNoHistoryMonitor extends BaseMonitor {
252
261
  }, Object.create(null))
253
262
 
254
263
  const tokenUtxos = Object.create(null)
264
+ const addressBalances = Object.create(null)
255
265
  let baseUtxos = UtxoCollection.createEmpty({
256
266
  currency: this.asset.currency,
257
267
  })
258
268
 
259
269
  const unknownAssetIds = new Set(
260
- Object.keys(groupedCoins).filter((coinType) => coinType !== coinTypes.Base)
270
+ [...Object.keys(groupedCoins), ...Object.keys(addressBalanceByCoinType)].filter(
271
+ (coinType) => coinType !== coinTypes.Base
272
+ )
261
273
  )
262
274
 
263
275
  for (const [assetName, asset] of Object.entries(this.assets)) {
264
276
  const isBaseAsset = asset.baseAssetName === asset.name
265
- if (isBaseAsset) {
266
- baseUtxos = this.#formatUtxos({
267
- address,
268
- coinType: coinTypes.Base,
269
- coins: groupedCoins[coinTypes.Base] || [],
270
- asset,
271
- })
272
- continue
273
- }
277
+ const coinType = isBaseAsset ? coinTypes.Base : asset.assetId
278
+ if (!isBaseAsset && !unknownAssetIds.delete(coinType)) continue
274
279
 
275
- if (!unknownAssetIds.delete(asset.assetId)) continue
276
-
277
- tokenUtxos[assetName] = this.#formatUtxos({
280
+ const utxos = this.#formatUtxos({
278
281
  address,
279
- coinType: asset.assetId,
280
- coins: groupedCoins[asset.assetId] || [],
282
+ coinType,
283
+ coins: groupedCoins[coinType] || [],
281
284
  asset,
282
285
  })
286
+ if (isBaseAsset) {
287
+ baseUtxos = utxos
288
+ } else {
289
+ tokenUtxos[assetName] = utxos
290
+ }
291
+
292
+ if (addressBalanceByCoinType[coinType]) {
293
+ addressBalances[assetName] = addressBalanceByCoinType[coinType]
294
+ }
283
295
  }
284
296
 
285
297
  return {
286
298
  utxos: baseUtxos,
287
299
  tokenUtxos,
300
+ addressBalances,
288
301
  unknownAssetIds: [...unknownAssetIds],
289
302
  }
290
303
  }