@exodus/solana-api 3.15.0 → 3.16.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 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.16.0](https://github.com/ExodusMovement/assets/compare/@exodus/solana-api@3.15.1...@exodus/solana-api@3.16.0) (2025-04-08)
7
+
8
+
9
+ ### Features
10
+
11
+
12
+ * feat: Solana rent except sender validation (#5394)
13
+
14
+
15
+
16
+ ## [3.15.1](https://github.com/ExodusMovement/assets/compare/@exodus/solana-api@3.15.0...@exodus/solana-api@3.15.1) (2025-04-04)
17
+
18
+
19
+ ### Bug Fixes
20
+
21
+
22
+ * fix(solana): fee payer validation (#5387)
23
+
24
+
25
+
6
26
  ## [3.15.0](https://github.com/ExodusMovement/assets/compare/@exodus/solana-api@3.14.7...@exodus/solana-api@3.15.0) (2025-04-03)
7
27
 
8
28
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/solana-api",
3
- "version": "3.15.0",
3
+ "version": "3.16.0",
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",
@@ -30,7 +30,7 @@
30
30
  "@exodus/fetch": "^1.7.3",
31
31
  "@exodus/models": "^12.0.1",
32
32
  "@exodus/simple-retry": "^0.0.6",
33
- "@exodus/solana-lib": "^3.10.0",
33
+ "@exodus/solana-lib": "^3.10.1",
34
34
  "@exodus/solana-meta": "^2.0.2",
35
35
  "@exodus/timer": "^1.1.1",
36
36
  "bn.js": "^4.11.0",
@@ -46,7 +46,7 @@
46
46
  "@exodus/assets-testing": "^1.0.0",
47
47
  "@exodus/solana-web3.js": "^1.63.1-exodus.9-rc3"
48
48
  },
49
- "gitHead": "59c4d4a4a7404eb915e4fa722a2afe01d1556046",
49
+ "gitHead": "06bfa593f6ed1ccb1905a95ed09b151a5eabe93f",
50
50
  "bugs": {
51
51
  "url": "https://github.com/ExodusMovement/assets/issues?q=is%3Aissue+is%3Aopen+label%3Asolana-api"
52
52
  },
@@ -20,6 +20,7 @@ export const createAccountState = ({ assetList }) => {
20
20
  balance: asset.currency.ZERO,
21
21
  tokenBalances: Object.create(null),
22
22
  rentExemptAmount: asset.currency.ZERO,
23
+ accountSize: 0,
23
24
  stakingInfo: {
24
25
  loaded: false,
25
26
  staking: {
@@ -214,7 +214,7 @@ export const createUnsignedTxForSend = async ({
214
214
  return maybeAddFeePayer({
215
215
  unsignedTx,
216
216
  feePayerApiUrl,
217
- assetName: asset.name,
217
+ assetName: asset.baseAsset.name,
218
218
  useFeePayer,
219
219
  })
220
220
  }
@@ -3,10 +3,14 @@ import { TxSet } from '@exodus/models'
3
3
  // staking may be a feature that may not be available for a given wallet.
4
4
  // In this case, The wallet should exclude the staking balance from the general balance
5
5
 
6
+ const DEFAULT_STAKING_RESERVE = 0.01 * 1_000_000_000
7
+
6
8
  export const getBalancesFactory =
7
9
  ({ stakingFeatureAvailable, allowSendingAll }) =>
8
10
  ({ asset, accountState, txLog }) => {
9
11
  const zero = asset.currency.ZERO
12
+ const defaultStakingReserve = asset.currency.baseUnit(DEFAULT_STAKING_RESERVE)
13
+
10
14
  const { balance, locked, withdrawable, pending } = fixBalances({
11
15
  txLog,
12
16
  balance: getBalanceFromAccountState({ asset, accountState }),
@@ -38,8 +42,9 @@ export const getBalancesFactory =
38
42
  const needsReserve =
39
43
  hasStakedFunds({ locked, withdrawable, pending }) || hasTokensBalance({ accountState })
40
44
 
41
- const networkReserve =
42
- allowSendingAll && !needsReserve ? zero : accountState.rentExemptAmount || zero
45
+ const rentExemptAmountConditional =
46
+ (accountState.accountSize > 0 ? accountState.rentExemptAmount : zero) || zero
47
+ const networkReserve = allowSendingAll && !needsReserve ? zero : rentExemptAmountConditional
43
48
 
44
49
  const accountReserve = asset.accountReserve || zero
45
50
 
@@ -47,9 +52,11 @@ export const getBalancesFactory =
47
52
 
48
53
  const spendable = balanceWithoutStaking.sub(walletReserve).sub(networkReserve).clampLowerZero()
49
54
 
50
- // leave enough amount for accountReserve if it's not reserved already
55
+ // leave enough sol for staking when the reserve is set to 0
56
+ // FIXME: should be able to get total stakeable balance dynamically
57
+ // instead of hardcoding a reserve value.
51
58
  const stakeable = walletReserve.isZero
52
- ? spendable.sub(accountReserve).clampLowerZero()
59
+ ? spendable.sub(defaultStakingReserve).clampLowerZero()
53
60
  : spendable
54
61
 
55
62
  const staked = locked
@@ -299,8 +299,11 @@ export class SolanaMonitor extends BaseMonitor {
299
299
 
300
300
  const solBalance = accountInfo?.lamports || 0
301
301
 
302
- const rentExemptValue = await this.api.getRentExemptionMinAmount(address)
303
- const rentExemptAmount = this.asset.currency.baseUnit(rentExemptValue)
302
+ const accountSize = accountInfo?.space || 0
303
+
304
+ const rentExemptAmount = this.asset.currency.baseUnit(
305
+ await this.api.getMinimumBalanceForRentExemption(accountSize)
306
+ )
304
307
 
305
308
  const tokenBalances = _.mapValues(splBalances, (balance, name) =>
306
309
  this.assets[name].currency.baseUnit(balance)
@@ -337,6 +340,7 @@ export class SolanaMonitor extends BaseMonitor {
337
340
  balance,
338
341
  tokenBalances,
339
342
  rentExemptAmount,
343
+ accountSize,
340
344
  },
341
345
  staking,
342
346
  tokenAccounts,
@@ -344,10 +348,11 @@ export class SolanaMonitor extends BaseMonitor {
344
348
  }
345
349
 
346
350
  async updateState({ account, cursorState, walletAccount, staking }) {
347
- const { balance, tokenBalances, rentExemptAmount } = account
351
+ const { balance, tokenBalances, rentExemptAmount, accountSize } = account
348
352
  const newData = {
349
353
  balance,
350
354
  rentExemptAmount,
355
+ accountSize,
351
356
  tokenBalances,
352
357
  stakingInfo: staking,
353
358
  ...cursorState,