@exodus/solana-api 2.5.21 → 2.5.23

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/solana-api",
3
- "version": "2.5.21",
3
+ "version": "2.5.23",
4
4
  "description": "Exodus internal Solana asset API wrapper",
5
5
  "main": "src/index.js",
6
6
  "files": [
@@ -23,7 +23,7 @@
23
23
  "@exodus/models": "^10.1.0",
24
24
  "@exodus/nfts-core": "^0.5.0",
25
25
  "@exodus/simple-retry": "^0.0.6",
26
- "@exodus/solana-lib": "^1.7.0",
26
+ "@exodus/solana-lib": "^1.7.1",
27
27
  "@exodus/solana-meta": "^1.0.3",
28
28
  "bn.js": "^4.11.0",
29
29
  "debug": "^4.1.1",
@@ -34,5 +34,5 @@
34
34
  "devDependencies": {
35
35
  "@exodus/assets-testing": "file:../../../__testing__"
36
36
  },
37
- "gitHead": "d0aa3d128fe488e0d4849923e5b134b80b6fef97"
37
+ "gitHead": "9e502c63fb13a0d98349cb953f10b24467fff617"
38
38
  }
@@ -1,13 +1,16 @@
1
1
  import { FeeMonitor } from '@exodus/asset-lib'
2
- import api from './'
3
2
 
4
3
  export default class SolanaFeeMonitor extends FeeMonitor {
5
- constructor({ updateFee, interval = '1m', assetName = 'solana' }) {
4
+ #api
5
+
6
+ constructor({ updateFee, interval = '1m', assetName = 'solana', api }) {
6
7
  super({ updateFee, interval, assetName })
8
+ this.#api = api
7
9
  }
8
10
 
9
11
  async fetchFee() {
10
- const fee = await api.getFee()
12
+ const fee = await this.#api.getFee()
13
+ if (fee === undefined) throw new Error('Failed to fetch fee')
11
14
 
12
15
  return {
13
16
  fee: `${fee} Lamports`,
@@ -0,0 +1,25 @@
1
+ // staking may be a feature that may not be available for a given wallet.
2
+ // In this case, The wallet should exclude the staking balance from the general balance
3
+
4
+ export const getBalancesFactory = ({ stakingFeatureAvailable }) => ({ asset, accountState }) => {
5
+ if (asset.baseAsset.name !== asset.name) {
6
+ return { balance: accountState?.tokenBalances?.[asset.name], spendableBalance: null }
7
+ }
8
+
9
+ const zero = asset.currency.ZERO
10
+
11
+ const balance = accountState.balance || zero
12
+
13
+ const { locked, withdrawable, pending } = accountState.mem || {}
14
+
15
+ const balanceWithoutStaking = balance
16
+ .sub(locked || zero)
17
+ .sub(withdrawable || zero)
18
+ .sub(pending || zero)
19
+ .clampLowerZero()
20
+
21
+ return {
22
+ balance: stakingFeatureAvailable ? balance : balanceWithoutStaking,
23
+ spendableBalance: balanceWithoutStaking.sub(asset.accountReserve || zero).clampLowerZero(),
24
+ }
25
+ }
package/src/index.js CHANGED
@@ -4,11 +4,13 @@ import assetsList from '@exodus/solana-meta'
4
4
 
5
5
  import { Api } from './api'
6
6
 
7
+ export { Api }
7
8
  export { default as SolanaFeeMonitor } from './fee-monitor'
8
- export * from './api'
9
- export * from './tx-log'
10
- export * from './account-state'
11
- export * from './tx-send'
9
+ export { SolanaMonitor } from './tx-log'
10
+ export { SolanaAccountState } from './account-state'
11
+ export { getSolStakedFee, getStakingInfo, getUnstakingFee } from './staking-utils'
12
+ export { createAndBroadcastTXFactory } from './tx-send'
13
+ export { getBalancesFactory } from './get-balances'
12
14
 
13
15
  // These are not the same asset objects as the wallet creates, so they should never be returned to the wallet.
14
16
  // Initially this may be violated by the Solana code until the first monitor tick updates assets with setTokens()
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Generates pending Fee for stake-able asset
3
+ * @param {Object} stakingInfo solana staking information object
4
+ * @param {Object} fee solana asset fee
5
+ *
6
+ */
7
+ export const getSolStakedFee = ({ asset, stakingInfo, fee }) => {
8
+ const { currency } = asset
9
+ const { accounts } = stakingInfo
10
+
11
+ const allPending = Object.entries(accounts).length
12
+ const pendingFee = allPending > 0 ? fee.mul(allPending) : currency.ZERO
13
+
14
+ return pendingFee
15
+ }
16
+
17
+ export const getStakingInfo = (accountMem) => {
18
+ return {
19
+ loaded: accountMem.loaded,
20
+ staking: accountMem.staking,
21
+ isDelegating: accountMem.isDelegating,
22
+ locked: accountMem.locked,
23
+ withdrawable: accountMem.withdrawable,
24
+ pending: accountMem.pending,
25
+ accounts: accountMem.accounts,
26
+ earned: accountMem.earned,
27
+ }
28
+ }
29
+
30
+ export const getUnstakingFee = ({ asset, fee, accountState }) => {
31
+ const stakingInfo = getStakingInfo(accountState.mem ?? {})
32
+ return getSolStakedFee({ asset, stakingInfo, fee })
33
+ }
@@ -34,7 +34,11 @@ export class SolanaMonitor extends BaseMonitor {
34
34
  }
35
35
 
36
36
  async startListener({ walletAccount }) {
37
- const address = await this.aci.getReceiveAddress({ assetName: this.asset.name, walletAccount })
37
+ const address = await this.aci.getReceiveAddress({
38
+ assetName: this.asset.name,
39
+ walletAccount,
40
+ useCache: true,
41
+ })
38
42
  return this.api.watchAddress({
39
43
  address,
40
44
  /*
@@ -50,7 +54,11 @@ export class SolanaMonitor extends BaseMonitor {
50
54
  }
51
55
 
52
56
  async stopListener({ walletAccount }) {
53
- const address = await this.aci.getReceiveAddress({ assetName: this.asset.name, walletAccount })
57
+ const address = await this.aci.getReceiveAddress({
58
+ assetName: this.asset.name,
59
+ walletAccount,
60
+ useCache: true,
61
+ })
54
62
  return this.api.unwatchAddress({ address })
55
63
  }
56
64
 
@@ -93,7 +101,7 @@ export class SolanaMonitor extends BaseMonitor {
93
101
  this.api.setTokens(this.assets)
94
102
 
95
103
  const accountState = await this.aci.getAccountState({ assetName, walletAccount })
96
- const address = await this.aci.getReceiveAddress({ assetName, walletAccount })
104
+ const address = await this.aci.getReceiveAddress({ assetName, walletAccount, useCache: true })
97
105
  const stakingAddresses = await this.getStakingAddressesFromTxLog({ assetName, walletAccount })
98
106
 
99
107
  const { logItemsByAsset, hasNewTxs, cursorState } = await this.getHistory({