@exodus/solana-api 3.26.4 → 3.26.6

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,26 @@
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.26.6](https://github.com/ExodusMovement/assets/compare/@exodus/solana-api@3.26.5...@exodus/solana-api@3.26.6) (2026-01-08)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+
12
+ * fix: Solana send-all leaving dust due to rent exemption check failure (#7217)
13
+
14
+
15
+
16
+ ## [3.26.5](https://github.com/ExodusMovement/assets/compare/@exodus/solana-api@3.26.4...@exodus/solana-api@3.26.5) (2025-12-29)
17
+
18
+
19
+ ### Bug Fixes
20
+
21
+
22
+ * fix: solana fee handling in createTxFactory (#7185)
23
+
24
+
25
+
6
26
  ## [3.26.4](https://github.com/ExodusMovement/assets/compare/@exodus/solana-api@3.26.3...@exodus/solana-api@3.26.4) (2025-12-27)
7
27
 
8
28
  **Note:** Version bump only for package @exodus/solana-api
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/solana-api",
3
- "version": "3.26.4",
3
+ "version": "3.26.6",
4
4
  "description": "Transaction monitors, fee monitors, RPC with the blockchain node, and other networking code for Solana",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -49,7 +49,7 @@
49
49
  "@exodus/assets-testing": "^1.0.0",
50
50
  "@exodus/solana-web3.js": "^1.63.1-exodus.9-rc3"
51
51
  },
52
- "gitHead": "632c6763bc36bb2a76e60ca1707e99a4d1f66a43",
52
+ "gitHead": "cc6f873a99d2a770ee83f0f7563f803e068d04de",
53
53
  "bugs": {
54
54
  "url": "https://github.com/ExodusMovement/assets/issues?q=is%3Aissue+is%3Aopen+label%3Asolana-api"
55
55
  },
@@ -223,7 +223,7 @@ export const createTxFactory = ({ assetClientInterface, api, feePayerClient }) =
223
223
  )
224
224
  }
225
225
 
226
- const fee = feeData.baseFee
226
+ const calculatedFee = feeData.baseFee
227
227
  .add(
228
228
  asset.feeAsset.currency
229
229
  .baseUnit(unsignedTx.txData.priorityFee ?? 0)
@@ -232,32 +232,34 @@ export const createTxFactory = ({ assetClientInterface, api, feePayerClient }) =
232
232
  )
233
233
  .add(tokenCreationFee)
234
234
 
235
- unsignedTx.txMeta.fee = fee.toBaseNumber()
236
-
237
235
  const tx = await maybeAddFeePayerWithAuth({
238
236
  unsignedTx,
239
237
  feePayerClient,
240
238
  enableFeePayer: feeData.enableFeePayer,
241
239
  })
242
240
 
243
- if (tx.txMeta.usedFeePayer) {
244
- tx.txMeta.fee = asset.feeAsset.currency.ZERO
245
- } else {
246
- const rentExemptValue = await api.getRentExemptionMinAmount(toAddress)
247
- const rentExemptAmount = baseAsset.currency.baseUnit(rentExemptValue)
241
+ const fee = tx.txMeta.usedFeePayer ? asset.feeAsset.currency.ZERO : calculatedFee
242
+ tx.txMeta.fee = fee.toBaseNumber()
243
+
244
+ if (!tx.txMeta.usedFeePayer) {
245
+ const senderRentExemptAmount = baseAsset.currency.baseUnit(
246
+ await api.getMinimumBalanceForRentExemption(0)
247
+ )
248
+
249
+ const baseAssetBalance = baseAsset.currency.baseUnit(await api.getBalance(fromAddress))
248
250
 
249
251
  // differentiate between SOL and Solana token
250
252
  let isEnoughForRent = false
251
253
  if (asset.name === baseAsset.name && !nft) {
252
254
  // sending SOL
253
- isEnoughForRent = amount.gte(rentExemptAmount)
255
+ const rentExemptValue = await api.getRentExemptionMinAmount(toAddress)
256
+ const rentExemptAmount = baseAsset.currency.baseUnit(rentExemptValue)
257
+ const remaining = baseAssetBalance.sub(calculatedFee).sub(amount).clampLowerZero()
258
+ isEnoughForRent =
259
+ amount.gte(rentExemptAmount) && (remaining.isZero || remaining.gte(rentExemptAmount))
254
260
  } else {
255
261
  // sending token/nft
256
- const baseAssetBalance = await api.getBalance(fromAddress)
257
- isEnoughForRent = baseAsset.currency
258
- .baseUnit(baseAssetBalance)
259
- .sub(fee || asset.feeAsset.currency.ZERO)
260
- .gte(rentExemptAmount)
262
+ isEnoughForRent = baseAssetBalance.sub(calculatedFee).gte(senderRentExemptAmount)
261
263
  }
262
264
 
263
265
  if (!isEnoughForRent) {
@@ -267,7 +269,7 @@ export const createTxFactory = ({ assetClientInterface, api, feePayerClient }) =
267
269
  }
268
270
  }
269
271
 
270
- return tx
272
+ return { unsignedTx: tx, fee }
271
273
  }
272
274
  }
273
275
 
package/src/get-fees.js CHANGED
@@ -49,14 +49,14 @@ export const getFeeAsyncFactory = ({ createTx }) => {
49
49
  }
50
50
 
51
51
  try {
52
- unsignedTx = await createTx({
52
+ ;({ unsignedTx } = await createTx({
53
53
  asset,
54
54
  walletAccount,
55
55
  feeData,
56
56
  amount: amount ?? asset.currency.baseUnit(1),
57
57
  toAddress: toAddress ?? rest.fromAddress,
58
58
  ...rest,
59
- })
59
+ }))
60
60
  } catch (err) {
61
61
  console.log('error computing right SOL fee:', err)
62
62
  // simulating a tx will fail if the user has not enough balance