@exodus/solana-lib 1.2.9 → 1.2.11

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-lib",
3
- "version": "1.2.9",
3
+ "version": "1.2.11",
4
4
  "description": "Exodus internal Solana low-level library",
5
5
  "main": "src/index.js",
6
6
  "files": [
@@ -20,6 +20,7 @@
20
20
  "bn.js": "~4.11.0",
21
21
  "bs58": "~4.0.1",
22
22
  "create-hash": "~1.1.3",
23
+ "lodash": "^4.17.11",
23
24
  "tweetnacl": "^1.0.3"
24
25
  }
25
26
  }
package/src/index.js CHANGED
@@ -4,5 +4,6 @@ export * from './constants'
4
4
  export * from './encode'
5
5
  export * from './keypair'
6
6
  export * from './tx'
7
+ export { StakeInstruction } from './vendor'
7
8
  export { default as tokens } from './tokens'
8
9
  export { default as Transaction } from './transaction'
@@ -1,5 +1,7 @@
1
1
  // @flow
2
2
  import assert from 'assert'
3
+ import bs58 from 'bs58'
4
+ import { get } from 'lodash'
3
5
 
4
6
  import { getKeyPairFromPrivateKey } from './keypair'
5
7
  import { findAssociatedTokenAddress, createStakeAddress } from './encode'
@@ -13,12 +15,12 @@ import {
13
15
  Transaction,
14
16
  SystemProgram,
15
17
  StakeProgram,
18
+ StakeInstruction,
16
19
  Authorized,
17
20
  Lockup,
18
21
  } from './vendor'
19
- import { SEED } from './constants'
22
+ import { SEED, STAKE_PROGRAM_ID } from './constants'
20
23
  import TOKENS from './tokens'
21
- import bs58 from 'bs58'
22
24
 
23
25
  class Tx {
24
26
  constructor({
@@ -220,6 +222,56 @@ class Tx {
220
222
  return transaction.serialize().toString('base64')
221
223
  }
222
224
 
225
+ static decodeStakingTx(serialized: string) {
226
+ // as base64
227
+ const wireTransaction = Buffer.from(serialized, 'base64')
228
+ const tx = Transaction.from(wireTransaction) // Transaction instance
229
+
230
+ const txId = bs58.encode(tx.signature)
231
+
232
+ const stakingInstructions = tx.instructions.filter(
233
+ (ix) => ix.programId.toString() === STAKE_PROGRAM_ID.toString()
234
+ )
235
+ const isStakingTx = !!stakingInstructions.length
236
+
237
+ if (!isStakingTx) return null // normal transfer tx
238
+
239
+ const info = {
240
+ txId,
241
+ owner: tx.feePayer.toString(), // SOL sender
242
+ }
243
+ const txDetails = stakingInstructions.reduce((info, ix) => {
244
+ const type = StakeInstruction.decodeInstructionType(ix)
245
+ switch (type) {
246
+ case 'Delegate':
247
+ info.type = 'Delegate'
248
+ info.stakeAddress = get(ix, 'keys[0].pubkey', '').toString()
249
+ info.validator = get(ix, 'keys[1].pubkey', '').toString() // pool
250
+ return info
251
+
252
+ case 'Deactivate': // undelegate
253
+ info.type = 'Deactivate'
254
+ info.stakeAddress = get(ix, 'keys[0].pubkey', '').toString()
255
+ // TODO: could have multiple addresses undelegating
256
+ return info
257
+
258
+ case 'Withdraw':
259
+ info.type = 'Withdraw'
260
+ info.stakeAddress = get(ix, 'keys[0].pubkey', '').toString()
261
+ const { lamports, toPubkey } = StakeInstruction.decodeWithdraw(ix)
262
+ info.to = toPubkey.toString()
263
+ info.lamports = lamports.toString()
264
+ return info
265
+
266
+ default:
267
+ // skip unknown instruction type
268
+ return info
269
+ }
270
+ }, info)
271
+
272
+ return txDetails
273
+ }
274
+
223
275
  getTxId() {
224
276
  if (!this.transaction.signature) {
225
277
  throw new Error('Cannot get txId, tx is not signed')