@exodus/solana-api 1.2.4 → 1.2.6
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 +3 -3
- package/src/index.js +58 -20
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/solana-api",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.6",
|
|
4
4
|
"description": "Exodus internal Solana asset API wrapper",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"files": [
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@exodus/asset-json-rpc": "^1.0.0",
|
|
17
|
-
"@exodus/solana-lib": "^1.2.
|
|
17
|
+
"@exodus/solana-lib": "^1.2.5",
|
|
18
18
|
"lodash": "^4.17.11",
|
|
19
19
|
"wretch": "^1.5.2"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"node-fetch": "~1.6.3"
|
|
23
23
|
},
|
|
24
|
-
"gitHead": "
|
|
24
|
+
"gitHead": "eb8a5bdbe538630232a503c7bdbd130a0de19706"
|
|
25
25
|
}
|
package/src/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import lodash from 'lodash'
|
|
|
6
6
|
|
|
7
7
|
// Doc: https://docs.solana.com/apps/jsonrpc-api
|
|
8
8
|
|
|
9
|
-
const RPC_URL = 'https://api.mainnet-beta.solana.com' // https://solana-api.projectserum.com
|
|
9
|
+
const RPC_URL = 'https://vip-api.mainnet-beta.solana.com/' // https://api.mainnet-beta.solana.com, https://solana-api.projectserum.com
|
|
10
10
|
|
|
11
11
|
// Tokens + SOL api support
|
|
12
12
|
class Api {
|
|
@@ -75,25 +75,32 @@ class Api {
|
|
|
75
75
|
/**
|
|
76
76
|
* Get transactions from an address
|
|
77
77
|
*/
|
|
78
|
-
async getTransactions(address: string, { cursor, before, limit
|
|
78
|
+
async getTransactions(address: string, { cursor, before, limit } = {}): any {
|
|
79
79
|
let transactions = []
|
|
80
80
|
// cursor is a txHash
|
|
81
81
|
|
|
82
82
|
try {
|
|
83
83
|
let until = cursor
|
|
84
84
|
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
85
|
+
const tokenAccountsByOwner = await this.getTokenAccountsByOwner(address) // Array
|
|
86
|
+
const tokenAccountAddresses = tokenAccountsByOwner
|
|
87
|
+
.filter(({ tokenName }) => tokenName !== 'unknown')
|
|
88
|
+
.map(({ tokenAccountAddress }) => tokenAccountAddress)
|
|
89
|
+
const accountsToCheck = [address, ...tokenAccountAddresses]
|
|
90
|
+
|
|
91
|
+
console.log('accountsToCheck::', accountsToCheck)
|
|
92
|
+
|
|
93
|
+
const txsResultsByAccount = await Promise.all(
|
|
94
|
+
accountsToCheck.map((addr) =>
|
|
95
|
+
this.getConfirmedSignaturesForAddress(addr, {
|
|
96
|
+
until,
|
|
97
|
+
before,
|
|
98
|
+
limit,
|
|
99
|
+
})
|
|
100
|
+
)
|
|
101
|
+
)
|
|
102
|
+
let txsId = txsResultsByAccount.reduce((arr, row) => arr.concat(row), []) // merge arrays
|
|
103
|
+
txsId = lodash.uniqBy(txsId, 'signature')
|
|
97
104
|
|
|
98
105
|
for (let tx of txsId) {
|
|
99
106
|
// get tx details
|
|
@@ -115,6 +122,8 @@ class Api {
|
|
|
115
122
|
throw err
|
|
116
123
|
}
|
|
117
124
|
|
|
125
|
+
transactions = lodash.orderBy(transactions, ['timestamp'], ['desc'])
|
|
126
|
+
|
|
118
127
|
const newCursor = transactions[0] ? transactions[0].id : cursor
|
|
119
128
|
|
|
120
129
|
return { transactions, newCursor }
|
|
@@ -148,6 +157,7 @@ class Api {
|
|
|
148
157
|
// Solana tx
|
|
149
158
|
const isSending = ownerAddress === solanaTx.source
|
|
150
159
|
tx = {
|
|
160
|
+
owner: solanaTx.source,
|
|
151
161
|
from: solanaTx.source,
|
|
152
162
|
to: solanaTx.destination,
|
|
153
163
|
amount: solanaTx.lamports, // number
|
|
@@ -170,10 +180,12 @@ class Api {
|
|
|
170
180
|
tokenAccountAddress: ix.destination,
|
|
171
181
|
}) // receiving
|
|
172
182
|
if (!tokenAccount) return null // no transfers with our addresses involved
|
|
183
|
+
const owner = isSending ? ownerAddress : null
|
|
184
|
+
|
|
173
185
|
delete tokenAccount.balance
|
|
174
186
|
delete tokenAccount.owner
|
|
175
|
-
|
|
176
187
|
return {
|
|
188
|
+
owner,
|
|
177
189
|
token: tokenAccount,
|
|
178
190
|
from: ix.source,
|
|
179
191
|
to: ix.destination,
|
|
@@ -181,6 +193,7 @@ class Api {
|
|
|
181
193
|
fee: isSending ? fee : 0, // in lamports
|
|
182
194
|
}
|
|
183
195
|
})
|
|
196
|
+
|
|
184
197
|
// .reduce to sum/sub (based on isSending) all the same tokens amount (From instructions -> 1 single tx)
|
|
185
198
|
tx = tokenTxs.reduce((finalTx, ix) => {
|
|
186
199
|
if (!ix) return finalTx // skip null instructions
|
|
@@ -234,6 +247,33 @@ class Api {
|
|
|
234
247
|
: tokenAccounts
|
|
235
248
|
}
|
|
236
249
|
|
|
250
|
+
async getTokensBalance(address: string) {
|
|
251
|
+
let accounts = await this.getTokenAccountsByOwner(address) // Tokens
|
|
252
|
+
|
|
253
|
+
const tokensBalance = accounts.reduce((acc, { tokenName, balance }) => {
|
|
254
|
+
if (tokenName === 'unknown') return acc // filter by supported tokens only
|
|
255
|
+
if (!acc[tokenName]) acc[tokenName] = Number(balance)
|
|
256
|
+
// e.g { 'serum': 123 }
|
|
257
|
+
else acc[tokenName] += Number(balance) // merge same token account balance
|
|
258
|
+
return acc
|
|
259
|
+
}, {})
|
|
260
|
+
|
|
261
|
+
return tokensBalance
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
async isAssociatedTokenAccountActive(tokenAddress: string) {
|
|
265
|
+
// Returns the token balance of an SPL Token account.
|
|
266
|
+
try {
|
|
267
|
+
await this.api.post({
|
|
268
|
+
method: 'getTokenAccountBalance',
|
|
269
|
+
params: [tokenAddress],
|
|
270
|
+
})
|
|
271
|
+
return true
|
|
272
|
+
} catch (e) {
|
|
273
|
+
return false
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
237
277
|
async getAddressType(address: string) {
|
|
238
278
|
// solana, token or null (unknown), meaning address has never been initialized
|
|
239
279
|
const { value } = await this.api.post({
|
|
@@ -272,14 +312,12 @@ class Api {
|
|
|
272
312
|
broadcastTransaction = async (signedTx: string): string => {
|
|
273
313
|
console.log('Solana broadcasting TX:', signedTx) // base64
|
|
274
314
|
|
|
275
|
-
const
|
|
315
|
+
const result = await this.api.post({
|
|
276
316
|
method: 'sendTransaction',
|
|
277
|
-
params: [signedTx, { encoding: 'base64' }],
|
|
317
|
+
params: [signedTx, { encoding: 'base64', commitment: 'singleGossip' }],
|
|
278
318
|
})
|
|
279
319
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
console.log(`tx ${result} sent!`)
|
|
320
|
+
console.log(`tx ${JSON.stringify(result)} sent!`)
|
|
283
321
|
return result || null
|
|
284
322
|
}
|
|
285
323
|
}
|