@exodus/solana-api 3.20.0 → 3.20.2

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,24 @@
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.20.2](https://github.com/ExodusMovement/assets/compare/@exodus/solana-api@3.20.1...@exodus/solana-api@3.20.2) (2025-06-17)
7
+
8
+ **Note:** Version bump only for package @exodus/solana-api
9
+
10
+
11
+
12
+
13
+
14
+ ## [3.20.1](https://github.com/ExodusMovement/assets/compare/@exodus/solana-api@3.20.0...@exodus/solana-api@3.20.1) (2025-06-11)
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+
20
+ * fix: SOL owner changed check (#5805)
21
+
22
+
23
+
6
24
  ## [3.20.0](https://github.com/ExodusMovement/assets/compare/@exodus/solana-api@3.19.0...@exodus/solana-api@3.20.0) (2025-06-11)
7
25
 
8
26
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/solana-api",
3
- "version": "3.20.0",
3
+ "version": "3.20.2",
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",
@@ -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": "a11096f37c71032ca704876059c11b2e55cc592a",
49
+ "gitHead": "e2dffb7c0eaca3832d0cccae123955903071bb36",
50
50
  "bugs": {
51
51
  "url": "https://github.com/ExodusMovement/assets/issues?q=is%3Aissue+is%3Aopen+label%3Asolana-api"
52
52
  },
@@ -21,6 +21,7 @@ export const createAccountState = ({ assetList }) => {
21
21
  tokenBalances: Object.create(null),
22
22
  rentExemptAmount: asset.currency.ZERO,
23
23
  accountSize: 0,
24
+ ownerChanged: false,
24
25
  stakingInfo: {
25
26
  loaded: false,
26
27
  staking: {
package/src/api.js CHANGED
@@ -953,6 +953,19 @@ export class Api {
953
953
  return owner && owner !== address
954
954
  }
955
955
 
956
+ async ownerChanged(address, accountInfo) {
957
+ // method to check if the owner of the account has changed, compared to standard programs.
958
+ // as there could be malicious dapps that reassign the ownership of the account (see https://github.com/coinspect/solana-assign-test)
959
+ const value = accountInfo || (await this.getAccountInfo(address))
960
+ const owner = value?.owner // program owner
961
+ if (!owner) return false // not initialized account (or purged)
962
+ return ![
963
+ SYSTEM_PROGRAM_ID.toBase58(),
964
+ TOKEN_PROGRAM_ID.toBase58(),
965
+ TOKEN_2022_PROGRAM_ID.toBase58(),
966
+ ].includes(owner)
967
+ }
968
+
956
969
  ataOwnershipChangedCached = memoizeLruCache(
957
970
  (...args) => this.ataOwnershipChanged(...args),
958
971
  (address, tokenAddress) => `${address}:${tokenAddress}`,
@@ -1092,20 +1105,16 @@ export class Api {
1092
1105
  return { accounts, totalStake, locked, withdrawable, pending, activating }
1093
1106
  }
1094
1107
 
1095
- async getRewards(stakingAddresses = []) {
1096
- if (stakingAddresses.length === 0) return 0
1108
+ async getRewards(address) {
1109
+ if (Array.isArray(address)) throw new Error('getRewards does not support multiple addresses')
1097
1110
 
1098
1111
  // custom endpoint!
1099
- const rewards = await this.request('rewards')
1100
- .post({ addresses: stakingAddresses })
1101
- .error(500, () => ({})) // addresses not found
1102
- .error(400, () => ({}))
1112
+ const { rewards } = await this.request('everstake-rewards') // proxied
1113
+ .post({ address })
1103
1114
  .json()
1104
1115
 
1105
- // sum rewards for all addresses
1106
- return Object.values(rewards).reduce((total, x) => {
1107
- return total + x
1108
- }, 0)
1116
+ // sum rewards for all epochs
1117
+ return rewards || 0
1109
1118
  }
1110
1119
 
1111
1120
  async getProgramAccounts(programId, config) {
@@ -305,6 +305,8 @@ export class SolanaMonitor extends BaseMonitor {
305
305
  await this.api.getMinimumBalanceForRentExemption(accountSize)
306
306
  )
307
307
 
308
+ const ownerChanged = await this.api.ownerChanged(address, accountInfo)
309
+
308
310
  const tokenBalances = _.mapValues(splBalances, (balance, name) =>
309
311
  this.assets[name].currency.baseUnit(balance)
310
312
  )
@@ -343,6 +345,7 @@ export class SolanaMonitor extends BaseMonitor {
343
345
  tokenBalances,
344
346
  rentExemptAmount,
345
347
  accountSize,
348
+ ownerChanged,
346
349
  },
347
350
  staking,
348
351
  tokenAccounts,
@@ -350,11 +353,12 @@ export class SolanaMonitor extends BaseMonitor {
350
353
  }
351
354
 
352
355
  async updateState({ account, cursorState, walletAccount, staking }) {
353
- const { balance, tokenBalances, rentExemptAmount, accountSize } = account
356
+ const { balance, tokenBalances, rentExemptAmount, accountSize, ownerChanged } = account
354
357
  const newData = {
355
358
  balance,
356
359
  rentExemptAmount,
357
360
  accountSize,
361
+ ownerChanged,
358
362
  tokenBalances,
359
363
  stakingInfo: staking,
360
364
  ...cursorState,
@@ -364,13 +368,7 @@ export class SolanaMonitor extends BaseMonitor {
364
368
 
365
369
  async getStakingInfo({ address, walletAccount }) {
366
370
  const stakingInfo = await this.api.getStakeAccountsInfo(address)
367
- const stakingAddresses = await this.getStakingAddressesFromTxLog({
368
- assetName: this.asset.name,
369
- walletAccount,
370
- })
371
- // merge current and old staking addresses
372
- const allStakingAddresses = _.uniq([...Object.keys(stakingInfo.accounts), ...stakingAddresses])
373
- const rewards = await this.api.getRewards(allStakingAddresses)
371
+ const rewards = await this.api.getRewards(address)
374
372
 
375
373
  return {
376
374
  loaded: true,