@exodus/solana-api 1.2.25 → 1.2.27

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.
Files changed (2) hide show
  1. package/package.json +3 -3
  2. package/src/index.js +70 -19
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/solana-api",
3
- "version": "1.2.25",
3
+ "version": "1.2.27",
4
4
  "description": "Exodus internal Solana asset API wrapper",
5
5
  "main": "src/index.js",
6
6
  "files": [
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "dependencies": {
16
16
  "@exodus/asset-json-rpc": "^1.0.0",
17
- "@exodus/solana-lib": "^1.2.25",
17
+ "@exodus/solana-lib": "^1.2.27",
18
18
  "lodash": "^4.17.11",
19
19
  "url-join": "4.0.0",
20
20
  "wretch": "^1.5.2"
@@ -22,5 +22,5 @@
22
22
  "devDependencies": {
23
23
  "node-fetch": "~1.6.3"
24
24
  },
25
- "gitHead": "2703cd0c4f81f6b99570579e3b3ae3bfb1585f0a"
25
+ "gitHead": "9db27ad00ebacbd66b1344bbf258fb30e7170e39"
26
26
  }
package/src/index.js CHANGED
@@ -160,8 +160,8 @@ class Api {
160
160
  txDetails: Object,
161
161
  tokenAccountsByOwner: ?Array
162
162
  ): Object {
163
- const { fee } = txDetails.meta
164
- let { instructions } = txDetails.transaction.message
163
+ const { fee, preTokenBalances, postTokenBalances } = txDetails.meta
164
+ let { instructions, accountKeys } = txDetails.transaction.message
165
165
  instructions = instructions
166
166
  .filter((ix) => ix.parsed) // only known instructions
167
167
  .map((ix) => ({
@@ -179,7 +179,7 @@ class Api {
179
179
  const stakeWithdraw = lodash.find(instructions, { program: 'stake', type: 'withdraw' })
180
180
  const stakeUndelegate = lodash.find(instructions, { program: 'stake', type: 'deactivate' })
181
181
 
182
- let tx
182
+ let tx = {}
183
183
  if (solanaTx) {
184
184
  // Solana tx
185
185
  const isSending = ownerAddress === solanaTx.source
@@ -271,13 +271,62 @@ class Api {
271
271
  }
272
272
  })
273
273
 
274
- // .reduce to sum/sub (based on isSending) all the same tokens amount (From instructions -> 1 single tx)
275
- tx = tokenTxs.reduce((finalTx, ix) => {
276
- if (!ix) return finalTx // skip null instructions
277
- if (!finalTx.token) return ix // init finalTx (support just 1 token type per tx)
278
- if (finalTx.token.ticker === ix.token.ticker) finalTx.amount += ix.amount
279
- return finalTx
280
- }, {})
274
+ if (tokenTxs.length) {
275
+ // found spl-token simple transfer/transferChecked instruction
276
+ // .reduce to sum/sub (based on isSending) all the same tokens amount (From instructions -> 1 single tx)
277
+ tx = tokenTxs.reduce((finalTx, ix) => {
278
+ if (!ix) return finalTx // skip null instructions
279
+ if (!finalTx.token) return ix // init finalTx (support just 1 token type per tx)
280
+ if (finalTx.token.ticker === ix.token.ticker) finalTx.amount += ix.amount
281
+ return finalTx
282
+ }, {})
283
+ } else if (preTokenBalances && postTokenBalances) {
284
+ // probably a DEX program is involved (multiple instructions), compute balance changes
285
+
286
+ const accountIndexes = lodash.mapKeys(accountKeys, (x, i) => i)
287
+ Object.values(accountIndexes).forEach((acc) => {
288
+ // filter by ownerAddress
289
+ const hasKnownOwner = !!lodash.find(tokenAccountsByOwner, {
290
+ tokenAccountAddress: acc.pubkey,
291
+ })
292
+ acc.owner = hasKnownOwner ? ownerAddress : null
293
+ })
294
+
295
+ // group by owner and supported token
296
+ const preBalances = preTokenBalances.filter((t) => {
297
+ return accountIndexes[t.accountIndex].owner === ownerAddress && isTokenSupported(t.mint)
298
+ })
299
+ const postBalances = postTokenBalances.filter((t) => {
300
+ return accountIndexes[t.accountIndex].owner === ownerAddress && isTokenSupported(t.mint)
301
+ })
302
+
303
+ if (preBalances.length && preBalances.length === postBalances.length) {
304
+ // parse and compute pre-balances/post-balances difference (1 token per tx spported at the moment)
305
+ const amount =
306
+ Number(lodash.get(postBalances, '[0].uiTokenAmount.amount', 0)) -
307
+ Number(lodash.get(preBalances, '[0].uiTokenAmount.amount', 0))
308
+ const isSending = Math.sign(amount) <= 0
309
+
310
+ const mint = lodash.get(postBalances, '[0].mint', '')
311
+ const { tokenName, ticker } = tokens.find(({ mintAddress }) => mintAddress === mint) || {
312
+ tokenName: 'unknown',
313
+ ticker: 'UNKNOWN',
314
+ }
315
+
316
+ tx = {
317
+ owner: isSending ? ownerAddress : TOKEN_PROGRAM_ID.toBase58(),
318
+ token: {
319
+ tokenAccountAddress: '', // token account is closed after the swap
320
+ tokenName,
321
+ ticker,
322
+ },
323
+ from: isSending ? ownerAddress : TOKEN_PROGRAM_ID.toBase58(),
324
+ to: ownerAddress, // DEX always interact with the owner address
325
+ amount,
326
+ fee: isSending ? fee : 0, // in lamports
327
+ }
328
+ }
329
+ }
281
330
  }
282
331
 
283
332
  // How tokens tx are parsed:
@@ -379,6 +428,12 @@ class Api {
379
428
  : null
380
429
  }
381
430
 
431
+ async getTokenAddressOwner(address: string) {
432
+ const value = await this.getAccountInfo(address)
433
+ const owner = lodash.get(value, 'data.parsed.info.owner', null)
434
+ return owner
435
+ }
436
+
382
437
  async getAddressMint(address) {
383
438
  const value = await this.getAccountInfo(address)
384
439
  const mintAddress = lodash.get(value, 'data.parsed.info.mint', null) // token mint
@@ -443,18 +498,10 @@ class Api {
443
498
  return { accounts, totalStake, locked, withdrawable, pending }
444
499
  }
445
500
 
446
- async getInflationReward(stakingAddresses: Array, epoch: number) {
447
- const rewards = await this.api.post({
448
- method: 'getInflationReward',
449
- params: [stakingAddresses, { epoch }],
450
- })
451
-
452
- return rewards
453
- }
454
-
455
501
  async getRewards(stakingAddresses = []) {
456
502
  if (!stakingAddresses.length) return 0
457
503
 
504
+ // custom endpoint!
458
505
  const rewards = await this.request(`rewards?addresses=${stakingAddresses.join(',')}`)
459
506
  .get()
460
507
  .error(500, () => ({})) // addresses not found
@@ -494,4 +541,8 @@ class Api {
494
541
  }
495
542
  }
496
543
 
544
+ function isTokenSupported(mint: string) {
545
+ return !!tokens.find(({ mintAddress }) => mintAddress === mint)
546
+ }
547
+
497
548
  export default new Api()