@exodus/solana-api 2.5.31-alpha.0 → 2.5.31-alpha.1
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 +2 -2
- package/src/api.js +3 -1
- package/src/connection.js +5 -2
- package/src/tx-log/solana-monitor.js +18 -63
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/solana-api",
|
|
3
|
-
"version": "2.5.31-alpha.
|
|
3
|
+
"version": "2.5.31-alpha.1",
|
|
4
4
|
"description": "Exodus internal Solana asset API wrapper",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"files": [
|
|
@@ -34,5 +34,5 @@
|
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@exodus/assets-testing": "file:../../../__testing__"
|
|
36
36
|
},
|
|
37
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "9ec7084bcdfe14f1c6f11df393351885773046a6"
|
|
38
38
|
}
|
package/src/api.js
CHANGED
|
@@ -59,16 +59,18 @@ export class Api {
|
|
|
59
59
|
async watchAddress({
|
|
60
60
|
address,
|
|
61
61
|
tokensAddresses = [],
|
|
62
|
+
onMessage,
|
|
62
63
|
handleAccounts,
|
|
63
64
|
handleTransfers,
|
|
64
65
|
handleReconnect,
|
|
65
66
|
reconnectDelay,
|
|
66
67
|
}) {
|
|
67
|
-
if (
|
|
68
|
+
if (this.connections[address]) return // already subscribed
|
|
68
69
|
const conn = new Connection({
|
|
69
70
|
endpoint: this.wsUrl,
|
|
70
71
|
address,
|
|
71
72
|
tokensAddresses,
|
|
73
|
+
onMsg: (json) => onMessage(json),
|
|
72
74
|
callback: (updates) =>
|
|
73
75
|
this.handleUpdates({ updates, address, handleAccounts, handleTransfers }),
|
|
74
76
|
reconnectCallback: handleReconnect,
|
package/src/connection.js
CHANGED
|
@@ -20,6 +20,7 @@ export class Connection {
|
|
|
20
20
|
address,
|
|
21
21
|
tokensAddresses = [],
|
|
22
22
|
callback,
|
|
23
|
+
onMsg,
|
|
23
24
|
reconnectCallback = () => {},
|
|
24
25
|
reconnectDelay = DEFAULT_RECONNECT_DELAY,
|
|
25
26
|
}) {
|
|
@@ -27,6 +28,7 @@ export class Connection {
|
|
|
27
28
|
this.tokensAddresses = tokensAddresses
|
|
28
29
|
this.endpoint = endpoint
|
|
29
30
|
this.callback = callback
|
|
31
|
+
this.onMsg = onMsg
|
|
30
32
|
this.reconnectCallback = reconnectCallback
|
|
31
33
|
this.reconnectDelay = reconnectDelay
|
|
32
34
|
|
|
@@ -136,7 +138,7 @@ export class Connection {
|
|
|
136
138
|
debug('pushing msg to queue', msg)
|
|
137
139
|
this.messageQueue.push(msg) // sub results
|
|
138
140
|
}
|
|
139
|
-
this.processMessages()
|
|
141
|
+
this.processMessages(json)
|
|
140
142
|
} else {
|
|
141
143
|
if (lodash.get(this.rpcQueue, json.id)) {
|
|
142
144
|
this.rpcQueue[json.id].reject(new Error(json.error.message))
|
|
@@ -195,7 +197,8 @@ export class Connection {
|
|
|
195
197
|
}
|
|
196
198
|
}
|
|
197
199
|
|
|
198
|
-
async processMessages() {
|
|
200
|
+
async processMessages(json) {
|
|
201
|
+
if (this.onMsg) await this.onMsg(json)
|
|
199
202
|
if (this.inProcessMessages) return null
|
|
200
203
|
this.inProcessMessages = true
|
|
201
204
|
try {
|
|
@@ -10,25 +10,14 @@ const DEFAULT_REMOTE_CONFIG = {
|
|
|
10
10
|
staking: { enabled: true, pool: DEFAULT_POOL_ADDRESS },
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
const TICKS_BETWEEN_HISTORY_FETCHES = 10
|
|
14
|
-
const TICKS_BETWEEN_STAKE_FETCHES = 5
|
|
15
|
-
|
|
16
13
|
export class SolanaMonitor extends BaseMonitor {
|
|
17
|
-
constructor({
|
|
18
|
-
api,
|
|
19
|
-
includeUnparsed = false,
|
|
20
|
-
ticksBetweenHistoryFetches = TICKS_BETWEEN_HISTORY_FETCHES,
|
|
21
|
-
ticksBetweenStakeFetches = TICKS_BETWEEN_STAKE_FETCHES,
|
|
22
|
-
...args
|
|
23
|
-
}) {
|
|
14
|
+
constructor({ api, includeUnparsed = false, ...args }) {
|
|
24
15
|
super(args)
|
|
25
16
|
assert(api, 'api is required')
|
|
26
17
|
this.api = api
|
|
27
18
|
this.cursors = {}
|
|
28
19
|
this.assets = {}
|
|
29
20
|
this.staking = DEFAULT_REMOTE_CONFIG.staking
|
|
30
|
-
this.ticksBetweenStakeFetches = ticksBetweenStakeFetches
|
|
31
|
-
this.ticksBetweenHistoryFetches = ticksBetweenHistoryFetches
|
|
32
21
|
this.includeUnparsed = includeUnparsed
|
|
33
22
|
this.addHook('before-stop', (...args) => this.beforeStop(...args))
|
|
34
23
|
}
|
|
@@ -52,15 +41,10 @@ export class SolanaMonitor extends BaseMonitor {
|
|
|
52
41
|
})
|
|
53
42
|
return this.api.watchAddress({
|
|
54
43
|
address,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
handleAccounts: (updates) => this.accountsCallback({ updates, walletAccount }),
|
|
59
|
-
handleTransfers: (txs) => {
|
|
60
|
-
// new SOL tx, ticking monitor
|
|
61
|
-
this.tick({ walletAccount }) // it will cause refresh for both sender/receiver. Without necessarily fetching the tx if it's not finalized in the node.
|
|
44
|
+
onMessage: (json) => {
|
|
45
|
+
// new SOL tx event, tick monitor with 15 sec delay (to avoid hitting delayed nodes)
|
|
46
|
+
setTimeout(() => this.tick({ walletAccount }), 15_000)
|
|
62
47
|
},
|
|
63
|
-
*/
|
|
64
48
|
})
|
|
65
49
|
}
|
|
66
50
|
|
|
@@ -103,20 +87,6 @@ export class SolanaMonitor extends BaseMonitor {
|
|
|
103
87
|
return _.uniq(_.flatten(stakingAddresses))
|
|
104
88
|
}
|
|
105
89
|
|
|
106
|
-
balanceChanged({ account, newAccount }) {
|
|
107
|
-
const solBalanceChanged = !account.balance || !account.balance.equals(newAccount.balance)
|
|
108
|
-
if (solBalanceChanged) return true
|
|
109
|
-
|
|
110
|
-
const tokenBalanceChanged =
|
|
111
|
-
!account.tokenBalances ||
|
|
112
|
-
Object.entries(newAccount.tokenBalances).some(
|
|
113
|
-
([token, balance]) =>
|
|
114
|
-
!account.tokenBalances[token] || !account.tokenBalances[token].equals(balance)
|
|
115
|
-
)
|
|
116
|
-
|
|
117
|
-
return tokenBalanceChanged
|
|
118
|
-
}
|
|
119
|
-
|
|
120
90
|
async tick({ walletAccount, refresh }) {
|
|
121
91
|
// Check for new wallet account
|
|
122
92
|
await this.initWalletAccount({ walletAccount })
|
|
@@ -129,43 +99,28 @@ export class SolanaMonitor extends BaseMonitor {
|
|
|
129
99
|
const address = await this.aci.getReceiveAddress({ assetName, walletAccount, useCache: true })
|
|
130
100
|
const stakingAddresses = await this.getStakingAddressesFromTxLog({ assetName, walletAccount })
|
|
131
101
|
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const account = await this.getAccount({ address, staking, tokenAccounts })
|
|
102
|
+
const { logItemsByAsset, hasNewTxs, cursorState } = await this.getHistory({
|
|
103
|
+
address,
|
|
104
|
+
accountState,
|
|
105
|
+
walletAccount,
|
|
106
|
+
refresh,
|
|
107
|
+
})
|
|
139
108
|
|
|
140
|
-
const
|
|
109
|
+
const cursorChanged = this.hasNewCursor({ walletAccount, cursorState })
|
|
141
110
|
|
|
142
|
-
|
|
143
|
-
|
|
111
|
+
if (refresh || hasNewTxs || cursorChanged) {
|
|
112
|
+
const staking =
|
|
113
|
+
refresh || cursorChanged
|
|
114
|
+
? await this.getStakingInfo({ address, stakingAddresses })
|
|
115
|
+
: accountState.mem
|
|
144
116
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const shouldUpdateBalanceBeforeHistory = true
|
|
117
|
+
const tokenAccounts = await this.api.getTokenAccountsByOwner(address)
|
|
118
|
+
const account = await this.getAccount({ address, staking, tokenAccounts })
|
|
148
119
|
|
|
149
|
-
// getHistory is more likely to fail/be rate limited, so we want to update users balance only on a lot of ticks
|
|
150
|
-
if (shouldUpdateBalanceBeforeHistory || shouldUpdateOnlyBalance) {
|
|
151
120
|
// update all state at once
|
|
152
|
-
await this.updateState({ account, walletAccount, staking })
|
|
153
121
|
await this.emitUnknownTokensEvent({ tokenAccounts })
|
|
154
|
-
}
|
|
155
|
-
if (shouldUpdateHistory) {
|
|
156
|
-
const { logItemsByAsset, cursorState } = await this.getHistory({
|
|
157
|
-
address,
|
|
158
|
-
accountState,
|
|
159
|
-
walletAccount,
|
|
160
|
-
refresh,
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
const cursorChanged = this.hasNewCursor({ walletAccount, cursorState })
|
|
164
|
-
|
|
165
|
-
// update all state at once
|
|
166
122
|
await this.updateTxLogByAsset({ walletAccount, logItemsByAsset, refresh })
|
|
167
123
|
await this.updateState({ account, cursorState, walletAccount, staking })
|
|
168
|
-
await this.emitUnknownTokensEvent({ tokenAccounts })
|
|
169
124
|
if (refresh || cursorChanged) {
|
|
170
125
|
this.cursors[walletAccount] = cursorState.cursor
|
|
171
126
|
}
|