@exodus/solana-api 2.5.6 → 2.5.8
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 +4 -4
- package/src/api.js +3 -3
- package/src/tx-log/solana-monitor.js +1 -1
- package/src/__tests__/api.test.js +0 -273
- package/src/__tests__/assets.js +0 -7
- package/src/__tests__/fixtures.js +0 -3166
- package/src/__tests__/index.test.js +0 -7
- package/src/__tests__/staking.test.js +0 -85
- package/src/__tests__/token.test.js +0 -374
- package/src/__tests__/ws.test.js +0 -72
- package/src/tx-log/__tests__/solana-monitor-api-mock.js +0 -382
- package/src/tx-log/__tests__/solana-monitor.integration.test.js +0 -128
- package/src/tx-log/__tests__/solana-monitor.test.js +0 -135
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { fetch } from '@exodus/fetch'
|
|
2
|
-
import wretch from 'wretch'
|
|
3
|
-
import { Api } from '../index'
|
|
4
|
-
import { SAMPLE_DELEGATE_TX, SAMPLE_UNDELEGATE_TX, SAMPLE_WITHDRAW_TX } from './fixtures'
|
|
5
|
-
import assets from './assets'
|
|
6
|
-
|
|
7
|
-
const api = new Api({ assets })
|
|
8
|
-
|
|
9
|
-
wretch().polyfills({
|
|
10
|
-
fetch,
|
|
11
|
-
})
|
|
12
|
-
|
|
13
|
-
const ADDRESS = 'Bb44g79UH5b7EqPRTStSqNWuBRy1mCPS9GHSteh3ai5j' // main SOL address (owner)
|
|
14
|
-
const STAKE_ADDRESS = '3XGtroRneSQbbAWfeanaZeSmZRTyrHmCnHsYugnYzBzW' // derived from main SOL address at stake:1
|
|
15
|
-
const EXPECTED_VOTE_ACCOUNT = 'FkK9cat6c8zhLXeYFn4UTvy6fnSLB4p6SCbRQQfdFkkP' // baker/validator vote acc
|
|
16
|
-
|
|
17
|
-
const ACCOUNT_OWNER = 'EPpRmq7oNByckkC1nWjmQ48URQR8FEw8igNjMzfWZg6k'
|
|
18
|
-
const DELEGATE_TX_ID =
|
|
19
|
-
'Q7BXFNrfkjwWZ3j8FyqDtezPyv6t8NJGyGpaCNnQTPhVbHAurUShCDcneJHpunubU39BSwKUqiBubz6C7BikqMu'
|
|
20
|
-
const UNDELEGATE_TX_ID =
|
|
21
|
-
'6bsiwBZWY5nMb6Sbg4LgSJ5y9v4Z8UWj398f2ifunwimMLzUNQSozGy3yJEET86ZrqmNJzbQmBxvyTMJdFsFMxj'
|
|
22
|
-
const WITHDRAW_TX_ID =
|
|
23
|
-
'7mo5H9yMSi4dSQBCHRgwmttqHEfqgbUSah6SGyB6kP7f2CqS1KrzLBdj2GjXgsk6how3JyU5VHDUMuNQ6UYsCTx'
|
|
24
|
-
|
|
25
|
-
test('Solana: getEpochInfo', async () => {
|
|
26
|
-
const epoch = await api.getEpochInfo()
|
|
27
|
-
console.log(epoch)
|
|
28
|
-
expect(epoch > 0).toBeTruthy()
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
test('Solana: getRewards', async () => {
|
|
32
|
-
const addresses = [
|
|
33
|
-
'AKcDnoJm3EEAKxYLecNkK9HWuneP65tvwqb3t3vU3CXX',
|
|
34
|
-
'8wH1UPiv1oq5YpY6GggQA4ht45i8vyungZJMRhYuT56u',
|
|
35
|
-
]
|
|
36
|
-
const rewards = await api.getRewards(addresses)
|
|
37
|
-
console.log('rewards:', rewards)
|
|
38
|
-
expect(rewards >= 31084037).toBeTruthy() // rewards at 24-09-21
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
test('Solana: getStakeActivation', async () => {
|
|
42
|
-
const state = await api.getStakeActivation(STAKE_ADDRESS)
|
|
43
|
-
console.log(state)
|
|
44
|
-
expect(state).toEqual('inactive')
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
test('Solana: getStakeAccountsInfo from a base SOL address', async () => {
|
|
48
|
-
const { accounts, totalStake, locked, withdrawable } = await api.getStakeAccountsInfo(ADDRESS)
|
|
49
|
-
// console.log(accounts)
|
|
50
|
-
console.log('totalStake', totalStake)
|
|
51
|
-
console.log('locked', locked)
|
|
52
|
-
console.log('withdrawable', withdrawable)
|
|
53
|
-
expect(Object.keys(accounts).length).toEqual(2)
|
|
54
|
-
expect(totalStake).toBeTruthy()
|
|
55
|
-
expect(locked).toEqual(0)
|
|
56
|
-
expect(typeof withdrawable).toEqual('number')
|
|
57
|
-
const account = accounts[STAKE_ADDRESS]
|
|
58
|
-
expect(account).toBeTruthy()
|
|
59
|
-
expect(typeof account.stake).toEqual('number')
|
|
60
|
-
expect(account.stake > 2700100).toBeTruthy() // active staked amount
|
|
61
|
-
expect(account.lamports > 0).toBeTruthy() // sol amount
|
|
62
|
-
expect(account.voter).toEqual(EXPECTED_VOTE_ACCOUNT)
|
|
63
|
-
expect(account.deactivationEpoch).toBeTruthy()
|
|
64
|
-
expect(typeof account.isDeactivating).toEqual('boolean')
|
|
65
|
-
expect(typeof account.canWithdraw).toEqual('boolean')
|
|
66
|
-
expect(typeof account.state).toEqual('string')
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
test('Solana: got expected results from delegate transaction', async () => {
|
|
70
|
-
const tx = await api.getTransactionById(DELEGATE_TX_ID)
|
|
71
|
-
const parsedTx = api.parseTransaction(ACCOUNT_OWNER, tx)
|
|
72
|
-
expect(parsedTx).toEqual(SAMPLE_DELEGATE_TX)
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
test('Solana: got expected results from undelegate transaction', async () => {
|
|
76
|
-
const tx = await api.getTransactionById(UNDELEGATE_TX_ID)
|
|
77
|
-
const parsedTx = api.parseTransaction(ACCOUNT_OWNER, tx)
|
|
78
|
-
expect(parsedTx).toEqual(SAMPLE_UNDELEGATE_TX)
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
test('Solana: got expected results from withdraw transaction', async () => {
|
|
82
|
-
const tx = await api.getTransactionById(WITHDRAW_TX_ID)
|
|
83
|
-
const parsedTx = api.parseTransaction(ACCOUNT_OWNER, tx)
|
|
84
|
-
expect(parsedTx).toEqual(SAMPLE_WITHDRAW_TX)
|
|
85
|
-
})
|
|
@@ -1,374 +0,0 @@
|
|
|
1
|
-
import { fetch } from '@exodus/fetch'
|
|
2
|
-
import wretch from 'wretch'
|
|
3
|
-
import { Api } from '../index'
|
|
4
|
-
import {
|
|
5
|
-
TOKEN_TRANSFER_TX,
|
|
6
|
-
TOKEN_ACCOUNTS,
|
|
7
|
-
SIMPLE_SERUM_TRANSFER,
|
|
8
|
-
SAMPLE_RAYDIUM_SWAP,
|
|
9
|
-
SAMPLE_JUPITER_SWAP,
|
|
10
|
-
SAMPLE_JUPITER_SWAP_TWO_SPL,
|
|
11
|
-
SAMPLE_RAYDIUM_NEW_SWAP,
|
|
12
|
-
SAMPLE_MAGIC_EDEN_BUY,
|
|
13
|
-
} from './fixtures'
|
|
14
|
-
import assets from './assets'
|
|
15
|
-
|
|
16
|
-
wretch().polyfills({
|
|
17
|
-
fetch,
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
const api = new Api({ assets })
|
|
21
|
-
|
|
22
|
-
const ADDRESS = 'DmUHBhkq3deAEjV6u2kY5TZP9CVQhqXs7sniGCCULiK4' // main SOL address (owner)
|
|
23
|
-
const ASSOCIATED_TOKEN_ADDRESS = 'BzB6ViSQtuvaXA1rUWjTB3TpzDmWQJbSL2KchUyYeWqv' // Serum (SRM) associatedTokenAddress
|
|
24
|
-
const TOKEN_TX_ID =
|
|
25
|
-
'3ACX53v5ZznEFocbHgEjzVbrN6GCbHxGV2qC7Zhq6x7WKcjCF9ChtFzLq53yTxdo5RunYvgPpSp7X9TRnjqm4H7s'
|
|
26
|
-
|
|
27
|
-
const SRM_MINT_ADDRESS = 'SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt'
|
|
28
|
-
const RAY_MINT_ADDRESS = '4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R'
|
|
29
|
-
|
|
30
|
-
beforeAll(() => {
|
|
31
|
-
return api.watchAddress({ address: ADDRESS }) // Open WS connection
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
test('Solana: getTransactionById on a token tx', async () => {
|
|
35
|
-
const tx = await api.getTransactionById(TOKEN_TX_ID)
|
|
36
|
-
expect(tx.meta).toBeTruthy()
|
|
37
|
-
expect(tx.slot).toEqual(51207058)
|
|
38
|
-
expect(tx.transaction.message.recentBlockhash).toEqual(
|
|
39
|
-
'HfARGEPbBqXUHeEEX1nGtdL76uWzgT9YSufe5bBb61gP'
|
|
40
|
-
)
|
|
41
|
-
expect(tx.transaction.signatures[0]).toEqual(TOKEN_TX_ID)
|
|
42
|
-
expect(tx.transaction.message.accountKeys[0].pubkey).toEqual(
|
|
43
|
-
'2WpsMPKqxztJ8zkwZwSj1axinmV5aewhqkLeMCaYhCMA'
|
|
44
|
-
)
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
test('Solana: getTokenAccountsByOwner', async () => {
|
|
48
|
-
const srmAccounts = await api.getTokenAccountsByOwner(ADDRESS, 'SRM')
|
|
49
|
-
// console.log(srmAccounts)
|
|
50
|
-
expect(srmAccounts.length).toBeTruthy()
|
|
51
|
-
expect(srmAccounts[0].tokenName).toEqual('serum')
|
|
52
|
-
expect(srmAccounts[0].ticker).toEqual('SRM')
|
|
53
|
-
expect(srmAccounts[0].owner).toEqual(ADDRESS)
|
|
54
|
-
expect(srmAccounts[0].tokenAccountAddress).toEqual(ASSOCIATED_TOKEN_ADDRESS)
|
|
55
|
-
expect(srmAccounts[0].balance).toEqual('100') // in lamports
|
|
56
|
-
|
|
57
|
-
// expect no usdc tokens
|
|
58
|
-
const usdcAccounts = await api.getTokenAccountsByOwner(ADDRESS, 'USDCSOL')
|
|
59
|
-
expect(usdcAccounts.length).toEqual(0)
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
test('Solana: getTokensBalance', async () => {
|
|
63
|
-
const tokensBalance = await api.getTokensBalance({ address: ADDRESS })
|
|
64
|
-
expect(tokensBalance).toEqual({ serum: 100 })
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
test('Solana: getTokenAddressOwner', async () => {
|
|
68
|
-
const owner = await api.getTokenAddressOwner('5jvtTmrGFQFX1YHa4ibGhMc9Nu2n3SKncHGTVjGsHc2c')
|
|
69
|
-
expect(owner).toEqual('HfPrmxTGBnVoEjpcCN5ekSCtg8b6ZPJLvnCRnH8owtUf')
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
test('Solana: isAssociatedTokenAccountActive', async () => {
|
|
73
|
-
expect(await api.isAssociatedTokenAccountActive(ADDRESS)).toEqual(false) // false because needs a SPL addr
|
|
74
|
-
expect(await api.isAssociatedTokenAccountActive(ASSOCIATED_TOKEN_ADDRESS)).toEqual(true)
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
test('Solana: isTokenAddress', async () => {
|
|
78
|
-
expect(await api.isTokenAddress(ASSOCIATED_TOKEN_ADDRESS)).toBeTruthy()
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
test('Solana: isSOLaddress', async () => {
|
|
82
|
-
// ADDRESS has never been initialized
|
|
83
|
-
expect(await api.isSOLaddress(ADDRESS)).toBeFalsy()
|
|
84
|
-
expect(await api.getAddressType(ADDRESS)).toEqual(null)
|
|
85
|
-
expect(await api.isSOLaddress('EPpRmq7oNByckkC1nWjmQ48URQR8FEw8igNjMzfWZg6k')).toBeTruthy()
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
test('Solana: check getAddressMint returns the expected mint address', async () => {
|
|
89
|
-
const mintAddr = await api.getAddressMint(ASSOCIATED_TOKEN_ADDRESS)
|
|
90
|
-
expect(mintAddr).toEqual(SRM_MINT_ADDRESS)
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
test('Solana: parseTransaction on a token tx', async () => {
|
|
94
|
-
const owner = '2WpsMPKqxztJ8zkwZwSj1axinmV5aewhqkLeMCaYhCMA'
|
|
95
|
-
const tokenAccounts = TOKEN_ACCOUNTS // await api.getTokenAccountsByOwner(owner)
|
|
96
|
-
const tx = await api.parseTransaction(owner, TOKEN_TRANSFER_TX, tokenAccounts)
|
|
97
|
-
// console.log(tx)
|
|
98
|
-
expect(tx.id).toEqual(TOKEN_TX_ID)
|
|
99
|
-
expect(tx.slot).toEqual(51207058)
|
|
100
|
-
expect(tx.error).toEqual(false)
|
|
101
|
-
expect(tx.from).toEqual('BB7cjxz123SVzAV5Fvb9WdvEnfYirrq1pYt2EqmUP9KG')
|
|
102
|
-
expect(tx.to).toEqual('71GbXnJkHz15kzjagB2f7N9H7HPA99v6BFuqfdYL5qtf')
|
|
103
|
-
expect(tx.amount).toEqual(36280)
|
|
104
|
-
expect(tx.fee).toEqual(1e4)
|
|
105
|
-
expect(tx.token).toEqual({
|
|
106
|
-
tokenAccountAddress: 'BB7cjxz123SVzAV5Fvb9WdvEnfYirrq1pYt2EqmUP9KG',
|
|
107
|
-
tokenName: 'Serum',
|
|
108
|
-
ticker: 'SRM',
|
|
109
|
-
})
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
test('Solana: parseTransaction on a simple Serum transfer', async () => {
|
|
113
|
-
const owner = 'EPpRmq7oNByckkC1nWjmQ48URQR8FEw8igNjMzfWZg6k' // owner is the receiver (SOL addr) in this test case
|
|
114
|
-
const tokenAccounts = [
|
|
115
|
-
{
|
|
116
|
-
tokenAccountAddress: '71GbXnJkHz15kzjagB2f7N9H7HPA99v6BFuqfdYL5qtf',
|
|
117
|
-
owner: 'EPpRmq7oNByckkC1nWjmQ48URQR8FEw8igNjMzfWZg6k',
|
|
118
|
-
tokenName: 'Serum',
|
|
119
|
-
ticker: 'SRM',
|
|
120
|
-
balance: '138000',
|
|
121
|
-
},
|
|
122
|
-
]
|
|
123
|
-
const tx = await api.parseTransaction(owner, SIMPLE_SERUM_TRANSFER, tokenAccounts)
|
|
124
|
-
// console.log('serum tx:', tx)
|
|
125
|
-
expect(tx.id).toEqual(
|
|
126
|
-
'5xcuZSj57qw5uodMDrEctXZjW9yubtJKjeW6KjYRwqsG8Wj7Pa79pZ9TEcPLQgNYr3QE1oiow1rqQZ3JPkVD8TZB'
|
|
127
|
-
)
|
|
128
|
-
expect(tx.from).toEqual('8Z5YeQHwHf4Cf8rJpt2TL2zx4r2ta88EmSrPpZA5KKid')
|
|
129
|
-
expect(tx.to).toEqual('71GbXnJkHz15kzjagB2f7N9H7HPA99v6BFuqfdYL5qtf')
|
|
130
|
-
expect(tx.slot).toEqual(56939843)
|
|
131
|
-
expect(tx.amount).toEqual(1807280)
|
|
132
|
-
expect(tx.fee).toEqual(0) // receiving tx
|
|
133
|
-
expect(tx.token).toBeTruthy()
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
test('Solana: parseTransaction on a simple Raydium swap', async () => {
|
|
137
|
-
const owner = 'G5xnKeJ6pK4YGVfTPgwaHbkoya3jbf3PCVzWRXaDeKfj' // SOL base addr
|
|
138
|
-
const tokenAccounts = [
|
|
139
|
-
{
|
|
140
|
-
tokenAccountAddress: '5cJVdyyduNUaVhvjhMvyScjMsrgfztbLLDKG1Qenn83L',
|
|
141
|
-
owner: 'G5xnKeJ6pK4YGVfTPgwaHbkoya3jbf3PCVzWRXaDeKfj',
|
|
142
|
-
tokenName: 'usdcoin_solana',
|
|
143
|
-
ticker: 'USDCSOL',
|
|
144
|
-
balance: '2949699',
|
|
145
|
-
mintAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
146
|
-
},
|
|
147
|
-
]
|
|
148
|
-
const tx = await api.parseTransaction(owner, SAMPLE_RAYDIUM_SWAP, tokenAccounts)
|
|
149
|
-
// console.log('raydium tx:', JSON.stringify(tx, null, 2))
|
|
150
|
-
expect(tx.id).toEqual(
|
|
151
|
-
'4gLnaweGbK3boh3jdooCPKpwJRroYscoVgFLG25oxnhGrLUhPSVtgqvYUitpNVXgDFG8rQ7zRjLwkcpsvoE1c9da'
|
|
152
|
-
)
|
|
153
|
-
|
|
154
|
-
expect(tx.from).toEqual('HLmqeL62xR1QoZ1HKKbXRrdN1p3phKpxRMb2VVopvBBz')
|
|
155
|
-
expect(tx.to).toEqual('5cJVdyyduNUaVhvjhMvyScjMsrgfztbLLDKG1Qenn83L') // token address
|
|
156
|
-
expect(tx.slot).toEqual(108487844)
|
|
157
|
-
expect(tx.amount).toEqual(2117789)
|
|
158
|
-
expect(tx.fee).toEqual(0) // receiving tx
|
|
159
|
-
expect(tx.token.tokenName).toEqual('usdcoin_solana')
|
|
160
|
-
})
|
|
161
|
-
|
|
162
|
-
test('Solana: parseTransaction on a Jupiter DEX swap', async () => {
|
|
163
|
-
const owner = 'AG4WTn4ftX6JHCsUswqANRuRy1sKC1X9gmKXH94xDUfq' // SOL base addr
|
|
164
|
-
const tokenAccounts = [
|
|
165
|
-
{
|
|
166
|
-
tokenAccountAddress: 'DwFjmVmtWQKdJCvGCXX9CfJykNKr82FcRwFVfxPjyZrx',
|
|
167
|
-
owner: 'AG4WTn4ftX6JHCsUswqANRuRy1sKC1X9gmKXH94xDUfq',
|
|
168
|
-
tokenName: 'serum',
|
|
169
|
-
ticker: 'SRM',
|
|
170
|
-
balance: '0',
|
|
171
|
-
mintAddress: SRM_MINT_ADDRESS,
|
|
172
|
-
},
|
|
173
|
-
]
|
|
174
|
-
const tx = await api.parseTransaction(owner, SAMPLE_JUPITER_SWAP, tokenAccounts)
|
|
175
|
-
// console.log('jupiter tx:', JSON.stringify(tx, null, 2))
|
|
176
|
-
expect(tx.id).toEqual(
|
|
177
|
-
'2LDaZzo4M9rF8bamfZyvhfS5XVMR47nhdBmHD6cERWcBtgtMHwuf1swNbFfY2r73h5nQHQAWpWNcjPdqyHELh8C1'
|
|
178
|
-
)
|
|
179
|
-
|
|
180
|
-
expect(tx.from).toEqual('AG4WTn4ftX6JHCsUswqANRuRy1sKC1X9gmKXH94xDUfq')
|
|
181
|
-
expect(tx.to).toEqual('2KUDvQNLSbLNqFc6BmfGEhKmMsd64h6yzareCDyH3YDv')
|
|
182
|
-
expect(tx.slot).toEqual(126288995)
|
|
183
|
-
expect(tx.amount).toEqual(144375911)
|
|
184
|
-
expect(tx.fee).toEqual(5000) // sending SOL tx
|
|
185
|
-
expect(tx.token).toBeFalsy()
|
|
186
|
-
|
|
187
|
-
// additional instruction (stored as separate txLog in wallet)
|
|
188
|
-
expect(tx.dexTxs[0].owner).toEqual(null)
|
|
189
|
-
expect(tx.dexTxs[0].from).toEqual('BCNYwsnz3yXvi4mY5e9w2RmZvwUW3pefzYQ4tsoNdDhp')
|
|
190
|
-
expect(tx.dexTxs[0].to).toEqual('DwFjmVmtWQKdJCvGCXX9CfJykNKr82FcRwFVfxPjyZrx')
|
|
191
|
-
expect(tx.dexTxs[0].amount).toEqual(4646016)
|
|
192
|
-
expect(tx.dexTxs[0].fee).toEqual(0)
|
|
193
|
-
expect(tx.dexTxs[0].token.tokenName).toEqual('serum')
|
|
194
|
-
})
|
|
195
|
-
|
|
196
|
-
test('Solana: parseTransaction on a Jupiter DEX swap with 2 SPL tokens', async () => {
|
|
197
|
-
const owner = '8pfWkMuCQM1WDAUunbVaWyJ791gQoMqqsLFmjB6RujAq' // SOL base addr
|
|
198
|
-
const tokenAccounts = [
|
|
199
|
-
{
|
|
200
|
-
tokenAccountAddress: '8LSHSGNfUWb8Qp4ae2wHPWGR6zGjhzYzpDzWSh3cuBch',
|
|
201
|
-
owner: '8pfWkMuCQM1WDAUunbVaWyJ791gQoMqqsLFmjB6RujAq',
|
|
202
|
-
tokenName: 'serum',
|
|
203
|
-
ticker: 'SRM',
|
|
204
|
-
balance: '45000000',
|
|
205
|
-
mintAddress: SRM_MINT_ADDRESS,
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
tokenAccountAddress: '4Wio6KwPVAr19WF5iaVUUMLtJNMLrMPbkuZgdMv76jhb',
|
|
209
|
-
owner: '8pfWkMuCQM1WDAUunbVaWyJ791gQoMqqsLFmjB6RujAq',
|
|
210
|
-
tokenName: 'raydium',
|
|
211
|
-
ticker: 'RAY',
|
|
212
|
-
balance: '406756',
|
|
213
|
-
mintAddress: RAY_MINT_ADDRESS,
|
|
214
|
-
},
|
|
215
|
-
]
|
|
216
|
-
const tx = await api.parseTransaction(owner, SAMPLE_JUPITER_SWAP_TWO_SPL, tokenAccounts)
|
|
217
|
-
// console.log('jupiter tx:', JSON.stringify(tx, null, 2))
|
|
218
|
-
expect(tx.id).toEqual(
|
|
219
|
-
'Vi3boAZ7WFR6hox4PNdiSYwq5ZrPcv5W7DSbnnfqoBkeRkNKfJyWv4TuYESgPWFUZNRjqbjnG6nMgmsmnLbNUfJ'
|
|
220
|
-
)
|
|
221
|
-
|
|
222
|
-
expect(tx.from).toEqual('8LSHSGNfUWb8Qp4ae2wHPWGR6zGjhzYzpDzWSh3cuBch')
|
|
223
|
-
expect(tx.to).toEqual('zuLDJ5SEe76L3bpFp2Sm9qTTe5vpJL3gdQFT5At5xXG')
|
|
224
|
-
expect(tx.slot).toEqual(127240689)
|
|
225
|
-
expect(tx.amount).toEqual(403000)
|
|
226
|
-
expect(tx.fee).toEqual(5000) // sending tx
|
|
227
|
-
expect(tx.token.tokenName).toEqual('serum')
|
|
228
|
-
|
|
229
|
-
// additional instruction (store as separate txLog in wallet)
|
|
230
|
-
expect(tx.dexTxs[0].owner).toEqual(null)
|
|
231
|
-
expect(tx.dexTxs[0].from).toEqual('9ASj9zDg7cT6wtvn4euSUiZte8yN2U3Tn6cTVZvMHbU7')
|
|
232
|
-
expect(tx.dexTxs[0].to).toEqual('4Wio6KwPVAr19WF5iaVUUMLtJNMLrMPbkuZgdMv76jhb')
|
|
233
|
-
expect(tx.dexTxs[0].amount).toEqual(406756)
|
|
234
|
-
expect(tx.dexTxs[0].fee).toEqual(0)
|
|
235
|
-
})
|
|
236
|
-
|
|
237
|
-
test('Solana: parseTransaction on a Jupiter DEX swap with includeUnparsed', async () => {
|
|
238
|
-
const owner = 'AG4WTn4ftX6JHCsUswqANRuRy1sKC1X9gmKXH94xDUfq' // SOL base addr
|
|
239
|
-
const tokenAccounts = [
|
|
240
|
-
{
|
|
241
|
-
tokenAccountAddress: 'DwFjmVmtWQKdJCvGCXX9CfJykNKr82FcRwFVfxPjyZrx',
|
|
242
|
-
owner: 'AG4WTn4ftX6JHCsUswqANRuRy1sKC1X9gmKXH94xDUfq',
|
|
243
|
-
tokenName: 'serum',
|
|
244
|
-
ticker: 'SRM',
|
|
245
|
-
balance: '0',
|
|
246
|
-
mintAddress: SRM_MINT_ADDRESS,
|
|
247
|
-
},
|
|
248
|
-
]
|
|
249
|
-
const tx = await api.parseTransaction(owner, SAMPLE_JUPITER_SWAP, tokenAccounts, {
|
|
250
|
-
includeUnparsed: true,
|
|
251
|
-
})
|
|
252
|
-
// console.log('jupiter tx:', JSON.stringify(tx, null, 2))
|
|
253
|
-
expect(tx.id).toEqual(
|
|
254
|
-
'2LDaZzo4M9rF8bamfZyvhfS5XVMR47nhdBmHD6cERWcBtgtMHwuf1swNbFfY2r73h5nQHQAWpWNcjPdqyHELh8C1'
|
|
255
|
-
)
|
|
256
|
-
expect(tx.unparsed).toEqual(true)
|
|
257
|
-
expect(tx.data.meta).toBeTruthy()
|
|
258
|
-
|
|
259
|
-
expect(tx.amount).toEqual(-146415191)
|
|
260
|
-
expect(tx.fee).toEqual(5000) // sending SOL tx
|
|
261
|
-
expect(tx.token).toBeFalsy()
|
|
262
|
-
|
|
263
|
-
// additional instruction (stored as separate txLog in wallet)
|
|
264
|
-
expect(tx.dexTxs[0].owner).toEqual(null)
|
|
265
|
-
expect(tx.dexTxs[0].from).toEqual('BCNYwsnz3yXvi4mY5e9w2RmZvwUW3pefzYQ4tsoNdDhp')
|
|
266
|
-
expect(tx.dexTxs[0].to).toEqual('DwFjmVmtWQKdJCvGCXX9CfJykNKr82FcRwFVfxPjyZrx')
|
|
267
|
-
expect(tx.dexTxs[0].amount).toEqual('4646016')
|
|
268
|
-
expect(tx.dexTxs[0].fee).toEqual(0)
|
|
269
|
-
expect(tx.dexTxs[0].token.tokenName).toEqual('serum')
|
|
270
|
-
})
|
|
271
|
-
|
|
272
|
-
test('Solana: parseTransaction on a Jupiter DEX swap with 2 SPL tokens with includeUnparsed', async () => {
|
|
273
|
-
const owner = '8pfWkMuCQM1WDAUunbVaWyJ791gQoMqqsLFmjB6RujAq' // SOL base addr
|
|
274
|
-
const tokenAccounts = [
|
|
275
|
-
{
|
|
276
|
-
tokenAccountAddress: '8LSHSGNfUWb8Qp4ae2wHPWGR6zGjhzYzpDzWSh3cuBch',
|
|
277
|
-
owner: '8pfWkMuCQM1WDAUunbVaWyJ791gQoMqqsLFmjB6RujAq',
|
|
278
|
-
tokenName: 'serum',
|
|
279
|
-
ticker: 'SRM',
|
|
280
|
-
balance: '45000000',
|
|
281
|
-
mintAddress: SRM_MINT_ADDRESS,
|
|
282
|
-
},
|
|
283
|
-
{
|
|
284
|
-
tokenAccountAddress: '4Wio6KwPVAr19WF5iaVUUMLtJNMLrMPbkuZgdMv76jhb',
|
|
285
|
-
owner: '8pfWkMuCQM1WDAUunbVaWyJ791gQoMqqsLFmjB6RujAq',
|
|
286
|
-
tokenName: 'raydium',
|
|
287
|
-
ticker: 'RAY',
|
|
288
|
-
balance: '406756',
|
|
289
|
-
mintAddress: RAY_MINT_ADDRESS,
|
|
290
|
-
},
|
|
291
|
-
]
|
|
292
|
-
const tx = await api.parseTransaction(owner, SAMPLE_JUPITER_SWAP_TWO_SPL, tokenAccounts, {
|
|
293
|
-
includeUnparsed: true,
|
|
294
|
-
})
|
|
295
|
-
// console.log('jupiter tx:', JSON.stringify(tx, null, 2))
|
|
296
|
-
expect(tx.id).toEqual(
|
|
297
|
-
'Vi3boAZ7WFR6hox4PNdiSYwq5ZrPcv5W7DSbnnfqoBkeRkNKfJyWv4TuYESgPWFUZNRjqbjnG6nMgmsmnLbNUfJ'
|
|
298
|
-
)
|
|
299
|
-
expect(tx.unparsed).toEqual(true)
|
|
300
|
-
expect(tx.data.meta).toBeTruthy()
|
|
301
|
-
|
|
302
|
-
expect(tx.amount).toEqual(0)
|
|
303
|
-
expect(tx.fee).toEqual(5000)
|
|
304
|
-
|
|
305
|
-
// additional instruction (store as separate txLog in wallet)
|
|
306
|
-
expect(tx.dexTxs[0].from).toEqual('8LSHSGNfUWb8Qp4ae2wHPWGR6zGjhzYzpDzWSh3cuBch')
|
|
307
|
-
expect(tx.dexTxs[0].to).toEqual('zuLDJ5SEe76L3bpFp2Sm9qTTe5vpJL3gdQFT5At5xXG')
|
|
308
|
-
expect(tx.dexTxs[0].amount).toEqual('403000')
|
|
309
|
-
expect(tx.dexTxs[0].fee).toEqual(0)
|
|
310
|
-
|
|
311
|
-
expect(tx.dexTxs[1].owner).toEqual(null)
|
|
312
|
-
expect(tx.dexTxs[1].from).toEqual('9ASj9zDg7cT6wtvn4euSUiZte8yN2U3Tn6cTVZvMHbU7')
|
|
313
|
-
expect(tx.dexTxs[1].to).toEqual('4Wio6KwPVAr19WF5iaVUUMLtJNMLrMPbkuZgdMv76jhb')
|
|
314
|
-
expect(tx.dexTxs[1].amount).toEqual('406756')
|
|
315
|
-
expect(tx.dexTxs[1].fee).toEqual(0)
|
|
316
|
-
})
|
|
317
|
-
|
|
318
|
-
test('Solana: parseTransaction on a Raydium call with includeUnparsed', async () => {
|
|
319
|
-
const owner = '4houxrezgCzSg75Wuu6fL3cyJYtWc5SBwsMKz3TP4iB5' // SOL base addr
|
|
320
|
-
const tokenAccounts = [
|
|
321
|
-
{
|
|
322
|
-
tokenAccountAddress: 'HyCEsyJUwFjic1VkWerNAes5fu384nuxBdDUHYskuvQe',
|
|
323
|
-
owner: '4houxrezgCzSg75Wuu6fL3cyJYtWc5SBwsMKz3TP4iB5',
|
|
324
|
-
tokenName: 'raydium',
|
|
325
|
-
ticker: 'RAY',
|
|
326
|
-
balance: '0',
|
|
327
|
-
mintAddress: '4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R',
|
|
328
|
-
},
|
|
329
|
-
{
|
|
330
|
-
tokenAccountAddress: '4q4GGt8k4rXmqDQbuR8jnyjU2P3xjkN4nB9C9sxZ9NNA',
|
|
331
|
-
owner: '4houxrezgCzSg75Wuu6fL3cyJYtWc5SBwsMKz3TP4iB5',
|
|
332
|
-
tokenName: 'serum',
|
|
333
|
-
ticker: 'SRM',
|
|
334
|
-
balance: '0',
|
|
335
|
-
mintAddress: 'SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt',
|
|
336
|
-
},
|
|
337
|
-
]
|
|
338
|
-
const tx = await api.parseTransaction(owner, SAMPLE_RAYDIUM_NEW_SWAP, tokenAccounts, {
|
|
339
|
-
includeUnparsed: true,
|
|
340
|
-
})
|
|
341
|
-
|
|
342
|
-
expect(tx.id).toBe(
|
|
343
|
-
'4jRzAT7sVqWTTmeRfLyFECjproCCApbWRWuqJXvLYPM8BxD3K5tyh5RVQYJmm6XiW4oA5z5LZMGBxehpk3QvDN3F'
|
|
344
|
-
)
|
|
345
|
-
expect(tx.data.meta).toBeTruthy()
|
|
346
|
-
expect(tx.amount).toBe(0)
|
|
347
|
-
expect(tx.fee).toBe(5000)
|
|
348
|
-
|
|
349
|
-
expect(tx.dexTxs.length).toBe(1)
|
|
350
|
-
expect(tx.dexTxs[0].token.tokenName).toBe('serum')
|
|
351
|
-
expect(tx.dexTxs[0].from).toBe('384kWWf2Km56EReGvmtCKVo1BBmmt2SwiEizjhwpCmrN')
|
|
352
|
-
expect(tx.dexTxs[0].to).toBe('4q4GGt8k4rXmqDQbuR8jnyjU2P3xjkN4nB9C9sxZ9NNA')
|
|
353
|
-
expect(tx.dexTxs[0].amount).toBe('38837150')
|
|
354
|
-
expect(tx.dexTxs[0].fee).toBe(0)
|
|
355
|
-
})
|
|
356
|
-
|
|
357
|
-
test('Solana: parseTransaction on a random contract call with includeUnparsed', async () => {
|
|
358
|
-
const owner = 'nsn7DmCMsKWGUWcL92XfPKXFbUz7KtFDRa4nnkc3RiF' // SOL base addr
|
|
359
|
-
const tokenAccounts = []
|
|
360
|
-
const tx = await api.parseTransaction(owner, SAMPLE_MAGIC_EDEN_BUY, tokenAccounts, {
|
|
361
|
-
includeUnparsed: true,
|
|
362
|
-
})
|
|
363
|
-
expect(tx.id).toEqual(
|
|
364
|
-
'5QecXzTAzDbq3W7PiryRDWYjJcsJSa5dQVwG8wf7CzTkf9y3Ry8ibW2iSqGbEeSbJNs4MQ9e3LEB1G2c3MPK5hke'
|
|
365
|
-
)
|
|
366
|
-
expect(tx.unparsed).toEqual(true)
|
|
367
|
-
expect(tx.data.meta).toBeTruthy()
|
|
368
|
-
expect(tx.amount).toEqual(-8039280)
|
|
369
|
-
expect(tx.fee).toEqual(5000)
|
|
370
|
-
})
|
|
371
|
-
|
|
372
|
-
afterAll(async () => {
|
|
373
|
-
return api.unwatchAddress({ address: ADDRESS })
|
|
374
|
-
})
|
package/src/__tests__/ws.test.js
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import ms from 'ms'
|
|
2
|
-
import delay from 'delay'
|
|
3
|
-
import debugLogger from 'debug'
|
|
4
|
-
// import api from '../index'
|
|
5
|
-
import { Connection } from '../connection'
|
|
6
|
-
const debug = debugLogger('exodus:solana-api')
|
|
7
|
-
|
|
8
|
-
const ADDRESS = 'EPpRmq7oNByckkC1nWjmQ48URQR8FEw8igNjMzfWZg6k'
|
|
9
|
-
|
|
10
|
-
let connection
|
|
11
|
-
function initializeConnection() {
|
|
12
|
-
if (connection) return connection
|
|
13
|
-
const conn = new Connection({
|
|
14
|
-
address: ADDRESS,
|
|
15
|
-
callback: (items) => {
|
|
16
|
-
debug('items:', items)
|
|
17
|
-
},
|
|
18
|
-
})
|
|
19
|
-
conn.start()
|
|
20
|
-
return conn
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
test(
|
|
24
|
-
'test ws Connection',
|
|
25
|
-
async () => {
|
|
26
|
-
const connection = initializeConnection()
|
|
27
|
-
await delay(ms('2s'))
|
|
28
|
-
|
|
29
|
-
const tx = await connection.sendMessage('getConfirmedTransaction', [
|
|
30
|
-
'toEFZFB4vRdomCnCFy7R99UUVpHzCw1XujjhBXNgm2Y7giELpd7rxhEJGcxjgoTA6VqSsfHp4wynwAyakRKVFdg',
|
|
31
|
-
{ encoding: 'jsonParsed' },
|
|
32
|
-
])
|
|
33
|
-
debug('fetched tx', tx)
|
|
34
|
-
await connection.stop()
|
|
35
|
-
},
|
|
36
|
-
ms('1m')
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
// This runs for a very long time
|
|
40
|
-
// Used for testing. Set 'address' to your address and send some SOL from/to that address.
|
|
41
|
-
test.skip(
|
|
42
|
-
'test running websocket to listen for transactions',
|
|
43
|
-
async () => {
|
|
44
|
-
const connection = new Connection({
|
|
45
|
-
address: ADDRESS,
|
|
46
|
-
callback: async (items) => {
|
|
47
|
-
// accountNotification or logsNotification
|
|
48
|
-
debug('items:', items)
|
|
49
|
-
expect(items.length).toEqual(1)
|
|
50
|
-
// get incoming tx info
|
|
51
|
-
if (items[0].method === 'logsNotification') {
|
|
52
|
-
const txId = items[0].value.signature
|
|
53
|
-
const tx = await connection.sendMessage('getConfirmedTransaction', [
|
|
54
|
-
txId,
|
|
55
|
-
{ encoding: 'jsonParsed' },
|
|
56
|
-
])
|
|
57
|
-
debug('got tx:', tx)
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
})
|
|
61
|
-
connection.start()
|
|
62
|
-
|
|
63
|
-
await delay(ms('5m')) // runs for a long time
|
|
64
|
-
// manually send some SOL
|
|
65
|
-
await connection.stop()
|
|
66
|
-
},
|
|
67
|
-
ms('5m')
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
afterAll(async () => {
|
|
71
|
-
if (connection) return connection.stop()
|
|
72
|
-
})
|