@render-foundation/utils 0.0.170 → 0.0.171
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/lib/cjs/backfiller.js +895 -0
- package/lib/cjs/backfiller.js.map +1 -0
- package/lib/cjs/client/onchain.js +132 -0
- package/lib/cjs/client/onchain.js.map +1 -0
- package/lib/cjs/client/pg/base.js +198 -0
- package/lib/cjs/client/pg/base.js.map +1 -0
- package/lib/cjs/client/pg/v1.js +623 -0
- package/lib/cjs/client/pg/v1.js.map +1 -0
- package/lib/cjs/client/pg/v2.js +840 -0
- package/lib/cjs/client/pg/v2.js.map +1 -0
- package/lib/cjs/client/pg/v2Client.js +1436 -0
- package/lib/cjs/client/pg/v2Client.js.map +1 -0
- package/lib/cjs/client/pg/viewClient.js +107 -0
- package/lib/cjs/client/pg/viewClient.js.map +1 -0
- package/lib/cjs/client/price.js +63 -0
- package/lib/cjs/client/price.js.map +1 -0
- package/lib/cjs/client/render.js +172 -0
- package/lib/cjs/client/render.js.map +1 -0
- package/lib/cjs/client/squads.js +204 -0
- package/lib/cjs/client/squads.js.map +1 -0
- package/lib/cjs/client/trade.js +231 -0
- package/lib/cjs/client/trade.js.map +1 -0
- package/lib/cjs/client/wormhole.js +69 -0
- package/lib/cjs/client/wormhole.js.map +1 -0
- package/lib/cjs/constants.js +46 -0
- package/lib/cjs/constants.js.map +1 -0
- package/lib/cjs/dbTypes.js +3 -0
- package/lib/cjs/dbTypes.js.map +1 -0
- package/lib/cjs/dbTypesV2.js +3 -0
- package/lib/cjs/dbTypesV2.js.map +1 -0
- package/lib/cjs/dbViewTypes.js +3 -0
- package/lib/cjs/dbViewTypes.js.map +1 -0
- package/lib/cjs/errorReporter.js +126 -0
- package/lib/cjs/errorReporter.js.map +1 -0
- package/lib/cjs/index.js +45 -0
- package/lib/cjs/index.js.map +1 -0
- package/lib/cjs/logger.js +21 -0
- package/lib/cjs/logger.js.map +1 -0
- package/lib/esm/src/backfiller.js +850 -0
- package/lib/esm/src/backfiller.js.map +1 -0
- package/lib/esm/src/client/onchain.js +122 -0
- package/lib/esm/src/client/onchain.js.map +1 -0
- package/lib/esm/src/client/pg/base.js +162 -0
- package/lib/esm/src/client/pg/base.js.map +1 -0
- package/lib/esm/src/client/pg/v1.js +559 -0
- package/lib/esm/src/client/pg/v1.js.map +1 -0
- package/lib/esm/src/client/pg/v2.js +774 -0
- package/lib/esm/src/client/pg/v2.js.map +1 -0
- package/lib/esm/src/client/pg/v2Client.js +1327 -0
- package/lib/esm/src/client/pg/v2Client.js.map +1 -0
- package/lib/esm/src/client/pg/viewClient.js +91 -0
- package/lib/esm/src/client/pg/viewClient.js.map +1 -0
- package/lib/esm/src/client/price.js +41 -0
- package/lib/esm/src/client/price.js.map +1 -0
- package/lib/esm/src/client/render.js +146 -0
- package/lib/esm/src/client/render.js.map +1 -0
- package/lib/esm/src/client/squads.js +163 -0
- package/lib/esm/src/client/squads.js.map +1 -0
- package/lib/esm/src/client/trade.js +215 -0
- package/lib/esm/src/client/trade.js.map +1 -0
- package/lib/esm/src/client/wormhole.js +33 -0
- package/lib/esm/src/client/wormhole.js.map +1 -0
- package/lib/esm/src/constants.js +43 -0
- package/lib/esm/src/constants.js.map +1 -0
- package/lib/esm/src/dbTypes.js +2 -0
- package/lib/esm/src/dbTypes.js.map +1 -0
- package/lib/esm/src/dbTypesV2.js +2 -0
- package/lib/esm/src/dbTypesV2.js.map +1 -0
- package/lib/esm/src/dbViewTypes.js +2 -0
- package/lib/esm/src/dbViewTypes.js.map +1 -0
- package/lib/esm/src/errorReporter.js +117 -0
- package/lib/esm/src/errorReporter.js.map +1 -0
- package/lib/esm/src/index.js +16 -0
- package/lib/esm/src/index.js.map +1 -0
- package/lib/esm/src/logger.js +18 -0
- package/lib/esm/src/logger.js.map +1 -0
- package/lib/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/lib/types/src/backfiller.d.ts +62 -0
- package/lib/types/src/backfiller.d.ts.map +1 -0
- package/lib/types/src/client/onchain.d.ts +24 -0
- package/lib/types/src/client/onchain.d.ts.map +1 -0
- package/lib/types/src/client/pg/base.d.ts +65 -0
- package/lib/types/src/client/pg/base.d.ts.map +1 -0
- package/lib/types/src/client/pg/v1.d.ts +137 -0
- package/lib/types/src/client/pg/v1.d.ts.map +1 -0
- package/lib/types/src/client/pg/v2.d.ts +36 -0
- package/lib/types/src/client/pg/v2.d.ts.map +1 -0
- package/lib/types/src/client/pg/v2Client.d.ts +273 -0
- package/lib/types/src/client/pg/v2Client.d.ts.map +1 -0
- package/lib/types/src/client/pg/viewClient.d.ts +55 -0
- package/lib/types/src/client/pg/viewClient.d.ts.map +1 -0
- package/lib/types/src/client/price.d.ts +12 -0
- package/lib/types/src/client/price.d.ts.map +1 -0
- package/lib/types/src/client/render.d.ts +23 -0
- package/lib/types/src/client/render.d.ts.map +1 -0
- package/lib/types/src/client/squads.d.ts +17 -0
- package/lib/types/src/client/squads.d.ts.map +1 -0
- package/lib/types/src/client/trade.d.ts +24 -0
- package/lib/types/src/client/trade.d.ts.map +1 -0
- package/lib/types/src/client/wormhole.d.ts +9 -0
- package/lib/types/src/client/wormhole.d.ts.map +1 -0
- package/lib/types/src/constants.d.ts +41 -0
- package/lib/types/src/constants.d.ts.map +1 -0
- package/lib/types/src/dbTypes.d.ts +123 -0
- package/lib/types/src/dbTypes.d.ts.map +1 -0
- package/lib/types/src/dbTypesV2.d.ts +163 -0
- package/lib/types/src/dbTypesV2.d.ts.map +1 -0
- package/lib/types/src/dbViewTypes.d.ts +35 -0
- package/lib/types/src/dbViewTypes.d.ts.map +1 -0
- package/lib/types/src/errorReporter.d.ts +13 -0
- package/lib/types/src/errorReporter.d.ts.map +1 -0
- package/lib/types/src/index.d.ts +16 -0
- package/lib/types/src/index.d.ts.map +1 -0
- package/lib/types/src/logger.d.ts +16 -0
- package/lib/types/src/logger.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,850 @@
|
|
|
1
|
+
import { PublicKey } from '@solana/web3.js';
|
|
2
|
+
import { renderMint, buyAndBurnEscrow, passthruEscrow, v3SquadsVault, upgradeRewardsEscrow, upgradeRewardsCircuitBreaker, usdcMint, devsSquadsVault, masterSquadsVault, bridgeEscrow, polyBridgeEscrow, } from './constants';
|
|
3
|
+
import { pgClient } from './client/pg/v2Client';
|
|
4
|
+
import { emissionDistributorKey, emissionDistributorV1Key, } from '@render-foundation/emission-distributor-sdk';
|
|
5
|
+
import { Helius } from 'helius-sdk';
|
|
6
|
+
export const solscanProClient = (apiKey) => {
|
|
7
|
+
const headers = {
|
|
8
|
+
token: apiKey,
|
|
9
|
+
};
|
|
10
|
+
const baseUrl = 'https://pro-api.solscan.io/v2.0';
|
|
11
|
+
return {
|
|
12
|
+
async getSignaturesForAddress(addr, options) {
|
|
13
|
+
const allSignatures = [];
|
|
14
|
+
let before = options?.before;
|
|
15
|
+
const limit = Math.min(options?.limit || 40, 40);
|
|
16
|
+
while (true) {
|
|
17
|
+
const params = new URLSearchParams({
|
|
18
|
+
address: addr.toString(),
|
|
19
|
+
limit: limit.toString(),
|
|
20
|
+
});
|
|
21
|
+
if (before) {
|
|
22
|
+
params.append('before', before);
|
|
23
|
+
}
|
|
24
|
+
const endpoint = `${baseUrl}/account/transactions?${params}`;
|
|
25
|
+
const response = await fetch(endpoint, { headers });
|
|
26
|
+
if (!response.ok) {
|
|
27
|
+
throw new Error(`Failed to fetch signatures: ${response.statusText}`);
|
|
28
|
+
}
|
|
29
|
+
const data = await response.json();
|
|
30
|
+
const signatures = data.data || [];
|
|
31
|
+
const transformedSigs = signatures.map((tx) => ({
|
|
32
|
+
signature: tx.txHash || tx.signature,
|
|
33
|
+
blockTime: tx.blockTime || tx.block_time || 0,
|
|
34
|
+
err: tx.status !== 'Success' ? { err: tx.status } : null,
|
|
35
|
+
}));
|
|
36
|
+
allSignatures.push(...transformedSigs);
|
|
37
|
+
if (signatures.length < limit ||
|
|
38
|
+
(options?.limit && allSignatures.length >= options.limit)) {
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
// Set before to the last signature for next page
|
|
42
|
+
if (signatures.length > 0) {
|
|
43
|
+
before =
|
|
44
|
+
signatures[signatures.length - 1].txHash ||
|
|
45
|
+
signatures[signatures.length - 1].signature;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return allSignatures.slice(0, options?.limit);
|
|
49
|
+
},
|
|
50
|
+
async getParsedTransaction(signature) {
|
|
51
|
+
const endpoint = `${baseUrl}/transaction/details?tx=${signature}`;
|
|
52
|
+
const response = await fetch(endpoint, { headers });
|
|
53
|
+
if (!response.ok) {
|
|
54
|
+
throw new Error(`Failed to fetch transaction: ${response.statusText}`);
|
|
55
|
+
}
|
|
56
|
+
const data = await response.json();
|
|
57
|
+
return {
|
|
58
|
+
meta: {
|
|
59
|
+
err: data.status !== 'Success' ? { err: data.status } : null,
|
|
60
|
+
logMessages: data.logMessages || [],
|
|
61
|
+
preTokenBalances: data.inputAccount || [],
|
|
62
|
+
postTokenBalances: data.outputAccount || [],
|
|
63
|
+
},
|
|
64
|
+
blockTime: data.blockTime || data.block_time || 0,
|
|
65
|
+
status: data.status,
|
|
66
|
+
err: data.status !== 'Success' ? { err: data.status } : null,
|
|
67
|
+
tokenBalances: data.tokenBalances || [],
|
|
68
|
+
preTokenBalances: data.inputAccount || [],
|
|
69
|
+
postTokenBalances: data.outputAccount || [],
|
|
70
|
+
};
|
|
71
|
+
},
|
|
72
|
+
async getBalanceChange(f) {
|
|
73
|
+
try {
|
|
74
|
+
const allTransfers = [];
|
|
75
|
+
let page = 1;
|
|
76
|
+
const pageSize = Math.min(f.options?.limit || 100, 100);
|
|
77
|
+
while (true) {
|
|
78
|
+
const params = new URLSearchParams({
|
|
79
|
+
address: f.addr.toString(),
|
|
80
|
+
page: page.toString(),
|
|
81
|
+
page_size: pageSize.toString(),
|
|
82
|
+
});
|
|
83
|
+
if (f.mint) {
|
|
84
|
+
params.append('token', f.mint.toString());
|
|
85
|
+
}
|
|
86
|
+
if (f.flow) {
|
|
87
|
+
params.append('flow', f.flow);
|
|
88
|
+
}
|
|
89
|
+
if (f.tokenAccount) {
|
|
90
|
+
params.append('token_account', f.tokenAccount.toString());
|
|
91
|
+
}
|
|
92
|
+
const endpoint = `${baseUrl}/account/balance_change?${params}`;
|
|
93
|
+
const response = await fetch(endpoint, { headers });
|
|
94
|
+
if (f.tokenAccount.toString() === polyBridgeEscrow) {
|
|
95
|
+
console.log('Poly solscan response: ', JSON.stringify(response));
|
|
96
|
+
}
|
|
97
|
+
if (!response.ok) {
|
|
98
|
+
console.error(`Failed to fetch balance changes: ${response.statusText}`);
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
const body = await response.json();
|
|
102
|
+
const transfers = [];
|
|
103
|
+
if (f.tokenAccount.toString() === polyBridgeEscrow) {
|
|
104
|
+
console.log('poly solscan data: ', JSON.stringify(body));
|
|
105
|
+
}
|
|
106
|
+
for (const item of body.data || []) {
|
|
107
|
+
if (item.change_type === (f.flow === 'in' ? 'inc' : 'dec')) {
|
|
108
|
+
transfers.push({
|
|
109
|
+
amount: Math.abs(item.amount || 0),
|
|
110
|
+
tokenDecimals: item.token_decimals || 0,
|
|
111
|
+
sig: item.trans_id,
|
|
112
|
+
blockTime: item.block_time || 0,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
allTransfers.push(...transfers);
|
|
117
|
+
if (transfers.length === 0 || transfers.length < pageSize) {
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
page++;
|
|
121
|
+
}
|
|
122
|
+
return allTransfers.filter((t) => t.amount !== 0);
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
console.error('Error in getBalanceChange:', error);
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
async getTransfers(f) {
|
|
130
|
+
try {
|
|
131
|
+
const allTransfers = [];
|
|
132
|
+
let page = 1;
|
|
133
|
+
const pageSize = Math.min(f.pageSize || 100, 100);
|
|
134
|
+
while (true) {
|
|
135
|
+
const params = new URLSearchParams({
|
|
136
|
+
address: f.addr.toString(),
|
|
137
|
+
token: f.mint.toString(),
|
|
138
|
+
flow: f.flow,
|
|
139
|
+
page: page.toString(),
|
|
140
|
+
page_size: pageSize.toString(),
|
|
141
|
+
});
|
|
142
|
+
const endpoint = `${baseUrl}/account/transfer?${params}`;
|
|
143
|
+
const response = await fetch(endpoint, { headers });
|
|
144
|
+
if (!response.ok) {
|
|
145
|
+
throw new Error(`Failed to fetch transfers: ${response.statusText}`);
|
|
146
|
+
}
|
|
147
|
+
const body = await response.json();
|
|
148
|
+
const transfers = [];
|
|
149
|
+
for (const item of body.data || []) {
|
|
150
|
+
transfers.push({
|
|
151
|
+
amount: item.amount || 0,
|
|
152
|
+
tokenDecimals: item.token_decimals || 0,
|
|
153
|
+
fromAddress: item.from_address
|
|
154
|
+
? new PublicKey(item.from_address)
|
|
155
|
+
: undefined,
|
|
156
|
+
toAddress: item.to_address
|
|
157
|
+
? new PublicKey(item.to_address)
|
|
158
|
+
: undefined,
|
|
159
|
+
sig: item.trans_id,
|
|
160
|
+
blockTime: item.block_time || 0,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
allTransfers.push(...transfers);
|
|
164
|
+
if (transfers.length === 0 || transfers.length < pageSize) {
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
page++;
|
|
168
|
+
}
|
|
169
|
+
return allTransfers.filter((t) => t.amount !== 0);
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
console.error('Error in getTransfers:', error);
|
|
173
|
+
throw new Error(`Failed to get transfers: ${error}`);
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
export const heliusClient = (apiKey) => {
|
|
179
|
+
const helius = new Helius(apiKey, 'mainnet-beta');
|
|
180
|
+
return {
|
|
181
|
+
async getSignaturesForAddress(addr, options) {
|
|
182
|
+
return helius.connection.getSignaturesForAddress(addr, {
|
|
183
|
+
before: options?.before,
|
|
184
|
+
limit: options?.limit || 1000,
|
|
185
|
+
});
|
|
186
|
+
},
|
|
187
|
+
async getParsedTransaction(signature) {
|
|
188
|
+
return helius.connection.getTransaction(signature, {
|
|
189
|
+
maxSupportedTransactionVersion: 0,
|
|
190
|
+
});
|
|
191
|
+
},
|
|
192
|
+
async getBalanceChange(f) {
|
|
193
|
+
try {
|
|
194
|
+
// Get transactions for the address
|
|
195
|
+
const response = await helius.connection.getSignaturesForAddress(f.addr, {
|
|
196
|
+
limit: 100,
|
|
197
|
+
});
|
|
198
|
+
const transfers = [];
|
|
199
|
+
// Process each signature to get transaction details
|
|
200
|
+
for (const sig of response) {
|
|
201
|
+
try {
|
|
202
|
+
const tx = await helius.connection.getTransaction(sig.signature, {
|
|
203
|
+
maxSupportedTransactionVersion: 0,
|
|
204
|
+
});
|
|
205
|
+
if (!tx || tx.meta?.err)
|
|
206
|
+
continue;
|
|
207
|
+
// Look for token balance changes
|
|
208
|
+
const preBalances = tx.meta.preTokenBalances || [];
|
|
209
|
+
const postBalances = tx.meta.postTokenBalances || [];
|
|
210
|
+
for (const postBalance of postBalances) {
|
|
211
|
+
if (postBalance.mint !== f.mint.toString())
|
|
212
|
+
continue;
|
|
213
|
+
if (postBalance.owner !== f.addr.toString())
|
|
214
|
+
continue;
|
|
215
|
+
const preBalance = preBalances.find((pre) => pre.accountIndex === postBalance.accountIndex);
|
|
216
|
+
const preAmount = Number(preBalance?.uiTokenAmount?.amount || 0);
|
|
217
|
+
const postAmount = Number(postBalance.uiTokenAmount?.amount || 0);
|
|
218
|
+
const change = postAmount - preAmount;
|
|
219
|
+
if (change !== 0) {
|
|
220
|
+
const isInflow = change > 0;
|
|
221
|
+
if ((f.flow === 'in' && isInflow) ||
|
|
222
|
+
(f.flow === 'out' && !isInflow)) {
|
|
223
|
+
transfers.push({
|
|
224
|
+
amount: Math.abs(change),
|
|
225
|
+
tokenDecimals: postBalance.uiTokenAmount?.decimals || 0,
|
|
226
|
+
sig: sig.signature,
|
|
227
|
+
blockTime: tx.blockTime || 0,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
catch (e) {
|
|
234
|
+
console.error(`Error processing signature ${sig.signature}:`, e);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return transfers.filter((t) => t.amount !== 0);
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
console.error('Error in getBalanceChange:', error);
|
|
241
|
+
return [];
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
async getTransfers(f) {
|
|
245
|
+
try {
|
|
246
|
+
// Use enhanced transactions API for better token transfer data
|
|
247
|
+
const response = await helius.connection.getSignaturesForAddress(f.addr, {
|
|
248
|
+
limit: f.pageSize || 100,
|
|
249
|
+
});
|
|
250
|
+
const transfers = [];
|
|
251
|
+
for (const sig of response) {
|
|
252
|
+
try {
|
|
253
|
+
const tx = await helius.connection.getTransaction(sig.signature, {
|
|
254
|
+
maxSupportedTransactionVersion: 0,
|
|
255
|
+
});
|
|
256
|
+
if (!tx || tx.meta?.err)
|
|
257
|
+
continue;
|
|
258
|
+
// Parse token transfers from transaction
|
|
259
|
+
const preTokenBalances = tx.meta.preTokenBalances || [];
|
|
260
|
+
const postTokenBalances = tx.meta.postTokenBalances || [];
|
|
261
|
+
// Group by account index to track transfers
|
|
262
|
+
const balanceChanges = new Map();
|
|
263
|
+
for (const postBalance of postTokenBalances) {
|
|
264
|
+
if (postBalance.mint !== f.mint.toString())
|
|
265
|
+
continue;
|
|
266
|
+
const preBalance = preTokenBalances.find((pre) => pre.accountIndex === postBalance.accountIndex);
|
|
267
|
+
const preAmount = Number(preBalance?.uiTokenAmount?.amount || 0);
|
|
268
|
+
const postAmount = Number(postBalance.uiTokenAmount?.amount || 0);
|
|
269
|
+
const change = postAmount - preAmount;
|
|
270
|
+
if (change !== 0) {
|
|
271
|
+
balanceChanges.set(postBalance.accountIndex, {
|
|
272
|
+
mint: postBalance.mint,
|
|
273
|
+
owner: postBalance.owner,
|
|
274
|
+
change,
|
|
275
|
+
decimals: postBalance.uiTokenAmount?.decimals || 0,
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
// Find transfers involving the target address
|
|
280
|
+
for (const [accountIndex, balanceChange] of balanceChanges) {
|
|
281
|
+
const isFromTarget = balanceChange.owner === f.addr.toString() &&
|
|
282
|
+
balanceChange.change < 0;
|
|
283
|
+
const isToTarget = balanceChange.owner === f.addr.toString() &&
|
|
284
|
+
balanceChange.change > 0;
|
|
285
|
+
if ((f.flow === 'out' && isFromTarget) ||
|
|
286
|
+
(f.flow === 'in' && isToTarget)) {
|
|
287
|
+
// Find the counterpart transfer
|
|
288
|
+
let fromAddress;
|
|
289
|
+
let toAddress;
|
|
290
|
+
if (isFromTarget) {
|
|
291
|
+
fromAddress = f.addr;
|
|
292
|
+
// Find who received the tokens
|
|
293
|
+
for (const [_, otherChange] of balanceChanges) {
|
|
294
|
+
if (otherChange.owner !== f.addr.toString() &&
|
|
295
|
+
otherChange.change > 0) {
|
|
296
|
+
toAddress = new PublicKey(otherChange.owner);
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
toAddress = f.addr;
|
|
303
|
+
// Find who sent the tokens
|
|
304
|
+
for (const [_, otherChange] of balanceChanges) {
|
|
305
|
+
if (otherChange.owner !== f.addr.toString() &&
|
|
306
|
+
otherChange.change < 0) {
|
|
307
|
+
fromAddress = new PublicKey(otherChange.owner);
|
|
308
|
+
break;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
transfers.push({
|
|
313
|
+
amount: Math.abs(balanceChange.change),
|
|
314
|
+
tokenDecimals: balanceChange.decimals,
|
|
315
|
+
fromAddress,
|
|
316
|
+
toAddress,
|
|
317
|
+
sig: sig.signature,
|
|
318
|
+
blockTime: tx.blockTime || 0,
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
catch (e) {
|
|
324
|
+
console.error(`Error processing signature ${sig.signature}:`, e);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return transfers.filter((t) => t.amount !== 0);
|
|
328
|
+
}
|
|
329
|
+
catch (error) {
|
|
330
|
+
console.error('Error in getTransfers:', error);
|
|
331
|
+
throw new Error(`Failed to get transfers: ${error}`);
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
};
|
|
335
|
+
};
|
|
336
|
+
export class Backfiller {
|
|
337
|
+
_types = {};
|
|
338
|
+
_txs = [];
|
|
339
|
+
solscanClient;
|
|
340
|
+
heliusClient;
|
|
341
|
+
pg;
|
|
342
|
+
isDryRun = false;
|
|
343
|
+
solscan = { pageSize: 100 };
|
|
344
|
+
constructor(solscanApiKey, heliusApiKey, pg, isDryRun = false) {
|
|
345
|
+
this.solscan.apiKey = solscanApiKey;
|
|
346
|
+
this.solscanClient = solscanProClient(solscanApiKey);
|
|
347
|
+
this.heliusClient = heliusClient(heliusApiKey);
|
|
348
|
+
this.pg = pg;
|
|
349
|
+
this.isDryRun = isDryRun;
|
|
350
|
+
}
|
|
351
|
+
emit() {
|
|
352
|
+
this._types['emit'] = {};
|
|
353
|
+
return this;
|
|
354
|
+
}
|
|
355
|
+
loans() {
|
|
356
|
+
this._types['loan'] = {};
|
|
357
|
+
return this;
|
|
358
|
+
}
|
|
359
|
+
buyBurnUSDCInflow() {
|
|
360
|
+
this._types['buyBurnUSDCInflow'] = {};
|
|
361
|
+
return this;
|
|
362
|
+
}
|
|
363
|
+
manualMint() {
|
|
364
|
+
this._types['manualMint'] = {};
|
|
365
|
+
return this;
|
|
366
|
+
}
|
|
367
|
+
vaultOutflows(p) {
|
|
368
|
+
this._types['vaultOutflows'] = {};
|
|
369
|
+
this.solscan.pageSize = p.pageSize || 100;
|
|
370
|
+
return this;
|
|
371
|
+
}
|
|
372
|
+
txs(...sigs) {
|
|
373
|
+
this._txs.push(...sigs);
|
|
374
|
+
}
|
|
375
|
+
formatAmount(amount, decimals = 8) {
|
|
376
|
+
const amt = typeof amount === 'bigint' ? Number(amount) : amount;
|
|
377
|
+
return (amt / Math.pow(10, decimals)).toLocaleString(undefined, {
|
|
378
|
+
maximumFractionDigits: 8,
|
|
379
|
+
minimumFractionDigits: 0,
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
formatTimestamp(blockTime) {
|
|
383
|
+
return new Date(blockTime * 1000).toISOString();
|
|
384
|
+
}
|
|
385
|
+
async indexLoans() {
|
|
386
|
+
const trs = [
|
|
387
|
+
{
|
|
388
|
+
transfer: {
|
|
389
|
+
toSolKey: '2P2gisXpbsYEUsTDQKdcDKSg1UZvx7qxfLTkvJGZdeJC',
|
|
390
|
+
fromSolKey: v3SquadsVault,
|
|
391
|
+
solTx: '3oC8BybX5YrkfPyvV8rAE1tnJr6egtZFHLghqHuLi3eaT4aWm87qZPJFrjFRn6nwVemd2ponsew85tBs6VVQzTJv',
|
|
392
|
+
executedAt: new Date('December 22, 2023 04:13:58 UTC'),
|
|
393
|
+
symbol: 'RENDER',
|
|
394
|
+
channel: 'loan',
|
|
395
|
+
amountPayed: BigInt(44999 * Math.pow(10, 8)),
|
|
396
|
+
},
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
transfer: {
|
|
400
|
+
toSolKey: '2P2gisXpbsYEUsTDQKdcDKSg1UZvx7qxfLTkvJGZdeJC',
|
|
401
|
+
fromSolKey: v3SquadsVault,
|
|
402
|
+
channel: 'loan',
|
|
403
|
+
solTx: '2f5sEBHcP8wpF79voUEUiP8pryDt7FvqrTXQrEpXzAxbzyFYPkavZGtJc5N8CXhfbJav8hQTr9YcENKseiouaWzc',
|
|
404
|
+
executedAt: new Date('December 22, 2023 02:39:53 UTC'),
|
|
405
|
+
symbol: 'RENDER',
|
|
406
|
+
amountPayed: BigInt(1 * Math.pow(10, 8)),
|
|
407
|
+
},
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
transfer: {
|
|
411
|
+
toSolKey: '5DGbogKUo8haEYC9Tt4FTHE5ue55bjLC4DpSgE1g6yT1',
|
|
412
|
+
fromSolKey: v3SquadsVault,
|
|
413
|
+
channel: 'loan',
|
|
414
|
+
solTx: '42n55BZcKVBCSZQoaneBQLn57v7zZGZorGe3uBLheGu4BQtpaTChdT1z3vHwgU4MHghJw3wJ72rFLkib761ewJCj',
|
|
415
|
+
executedAt: new Date('January 12, 2024 00:17:02 UTC'),
|
|
416
|
+
symbol: 'RENDER',
|
|
417
|
+
amountPayed: BigInt(1 * Math.pow(10, 8)),
|
|
418
|
+
},
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
transfer: {
|
|
422
|
+
toSolKey: '5DGbogKUo8haEYC9Tt4FTHE5ue55bjLC4DpSgE1g6yT1',
|
|
423
|
+
fromSolKey: v3SquadsVault,
|
|
424
|
+
channel: 'loan',
|
|
425
|
+
solTx: 'THJLvA1UTqH22hNP7Ecnfn4iY736VJAZ8scgSUjrDDaGpSQJmGYKJYXGtDu6TB96fKo6mJBtUBZvLb4ors17JUR',
|
|
426
|
+
executedAt: new Date('January 17, 2024 22:09:58 UTC'),
|
|
427
|
+
symbol: 'RENDER',
|
|
428
|
+
amountPayed: BigInt(49999 * Math.pow(10, 8)),
|
|
429
|
+
},
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
transfer: {
|
|
433
|
+
toSolKey: '5DGbogKUo8haEYC9Tt4FTHE5ue55bjLC4DpSgE1g6yT1',
|
|
434
|
+
fromSolKey: devsSquadsVault,
|
|
435
|
+
channel: 'loan',
|
|
436
|
+
solTx: '5BcxrMExq34jtMB5c3bH3A8TN4pCp9sxjC5HMcS7Mh8pig3r2eQhvRnJeE1RBTyQ4JDXyANWmDU9SKdYFyT2wDoq',
|
|
437
|
+
executedAt: new Date('February 28, 2024 22:43:21 UTC'),
|
|
438
|
+
symbol: 'RENDER',
|
|
439
|
+
amountPayed: BigInt(1 * Math.pow(10, 8)),
|
|
440
|
+
},
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
transfer: {
|
|
444
|
+
toSolKey: '5DGbogKUo8haEYC9Tt4FTHE5ue55bjLC4DpSgE1g6yT1',
|
|
445
|
+
fromSolKey: devsSquadsVault,
|
|
446
|
+
channel: 'loan',
|
|
447
|
+
solTx: '5E4E35CT4e3fhbMAwcKdfAvJL4uUHR8hHE8REmKnDCEsFZ6mxaE1YyeYK8Sbg5AJqBJxsZkcYSohY8T14YLC5pXs',
|
|
448
|
+
executedAt: new Date('February 29, 2024 01:17:51 UTC'),
|
|
449
|
+
symbol: 'RENDER',
|
|
450
|
+
amountPayed: BigInt(199999 * Math.pow(10, 8)),
|
|
451
|
+
},
|
|
452
|
+
},
|
|
453
|
+
];
|
|
454
|
+
if (this.isDryRun) {
|
|
455
|
+
for (const t of trs) {
|
|
456
|
+
const amount = this.formatAmount(t.transfer.amountPayed);
|
|
457
|
+
const timestamp = this.formatTimestamp(t.transfer.executedAt.getTime() / 1000);
|
|
458
|
+
console.log(`${t.transfer.solTx} | ${timestamp} | ${t.transfer.channel} | ${t.transfer.fromSolKey} -> ${t.transfer.toSolKey} | ${amount} ${t.transfer.symbol}`);
|
|
459
|
+
}
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
for (const t of trs) {
|
|
463
|
+
try {
|
|
464
|
+
await this.pg.createPayments(this.pg.db, [t]);
|
|
465
|
+
}
|
|
466
|
+
catch (e) {
|
|
467
|
+
console.log(`except ${e}`);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
async findEmitTxs() {
|
|
472
|
+
const fetchSigs = async (ads) => {
|
|
473
|
+
const uniqSigs = {};
|
|
474
|
+
const sigsAgg = [];
|
|
475
|
+
for (const ad of ads) {
|
|
476
|
+
const sigs = [];
|
|
477
|
+
while (true) {
|
|
478
|
+
const sigsBatch = await this.heliusClient.getSignaturesForAddress(ad, {
|
|
479
|
+
before: sigs.length > 0 ? sigs[sigs.length - 1].signature : undefined,
|
|
480
|
+
limit: 1000,
|
|
481
|
+
});
|
|
482
|
+
sigs.push(...sigsBatch.filter((s) => !uniqSigs[s.signature]));
|
|
483
|
+
for (const s of sigsBatch) {
|
|
484
|
+
uniqSigs[s.signature] = true;
|
|
485
|
+
}
|
|
486
|
+
if (sigsBatch.length < 1000) {
|
|
487
|
+
break;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
if (!this.isDryRun) {
|
|
491
|
+
console.log(`fetched ${sigs.length} sigs for ${ad}`);
|
|
492
|
+
}
|
|
493
|
+
sigsAgg.push(...sigs);
|
|
494
|
+
}
|
|
495
|
+
sigsAgg.sort((a, b) => b.blockTime - a.blockTime);
|
|
496
|
+
return sigsAgg;
|
|
497
|
+
};
|
|
498
|
+
const sigs = await fetchSigs([
|
|
499
|
+
emissionDistributorKey(new PublicKey(renderMint))[0],
|
|
500
|
+
emissionDistributorV1Key(new PublicKey(renderMint))[0],
|
|
501
|
+
]);
|
|
502
|
+
if (!this.isDryRun) {
|
|
503
|
+
console.log(`sigs ${sigs.length}`);
|
|
504
|
+
}
|
|
505
|
+
let proced = 0;
|
|
506
|
+
const out = [];
|
|
507
|
+
for (const s of sigs) {
|
|
508
|
+
const p = await this.heliusClient.getParsedTransaction(s.signature);
|
|
509
|
+
if (p?.meta?.err || p?.err) {
|
|
510
|
+
continue;
|
|
511
|
+
}
|
|
512
|
+
const logMessages = p?.meta?.logMessages || [];
|
|
513
|
+
for (const l of logMessages) {
|
|
514
|
+
if (l.includes('DistributeEmissionsV0') ||
|
|
515
|
+
l.includes('DistributeEmissionsV1')) {
|
|
516
|
+
out.push(s.signature);
|
|
517
|
+
if (this.isDryRun) {
|
|
518
|
+
console.log(`${s.signature} | ${this.formatTimestamp(s.blockTime)} | emission | Emission Distributor -> Various Recipients | N/A RENDER`);
|
|
519
|
+
}
|
|
520
|
+
break;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
proced += 1;
|
|
524
|
+
if (proced % 10 == 0 && !this.isDryRun) {
|
|
525
|
+
console.log(`proced ${proced}`);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
console.log(`emit txs: ${out.length}`);
|
|
529
|
+
return out;
|
|
530
|
+
}
|
|
531
|
+
async indexTxs(txs, channel, reindexTx = false, deleteFailed = false, mints = [renderMint, usdcMint], senders = [
|
|
532
|
+
passthruEscrow,
|
|
533
|
+
v3SquadsVault,
|
|
534
|
+
upgradeRewardsEscrow,
|
|
535
|
+
upgradeRewardsCircuitBreaker,
|
|
536
|
+
renderMint,
|
|
537
|
+
], assertSender = '') {
|
|
538
|
+
let proced = 0;
|
|
539
|
+
console.log(`processing ${txs.length} txs`);
|
|
540
|
+
const insertedIds = [];
|
|
541
|
+
for (const solTx of txs) {
|
|
542
|
+
if (solTx == '') {
|
|
543
|
+
continue;
|
|
544
|
+
}
|
|
545
|
+
console.log(`solTx ${solTx}`);
|
|
546
|
+
const tx = await this.heliusClient.getParsedTransaction(solTx);
|
|
547
|
+
if (!tx || (tx.status !== 'Success' && tx.err)) {
|
|
548
|
+
if (this.isDryRun) {
|
|
549
|
+
console.log(`Would delete failed transaction ${solTx} from database`);
|
|
550
|
+
continue;
|
|
551
|
+
}
|
|
552
|
+
console.log(`shouldnt exist ${solTx} in db. deleting`);
|
|
553
|
+
try {
|
|
554
|
+
const res = await this.pg.db.trx.deleteFrom('sol_tx')
|
|
555
|
+
.where('sig', '=', solTx)
|
|
556
|
+
.execute();
|
|
557
|
+
console.log(`deleted ${res.length > 0 ? res[0].numDeletedRows || 0 : 0} tx`);
|
|
558
|
+
}
|
|
559
|
+
catch (e) {
|
|
560
|
+
console.log(`failed to delete tx ${solTx}: ${e}`);
|
|
561
|
+
}
|
|
562
|
+
continue;
|
|
563
|
+
}
|
|
564
|
+
const onchain = {};
|
|
565
|
+
const tokenBalances = tx.meta?.tokenBalances || [];
|
|
566
|
+
const preTokenBalances = tx.meta?.preTokenBalances || [];
|
|
567
|
+
const postTokenBalances = tx.meta?.postTokenBalances || [];
|
|
568
|
+
for (const balance of postTokenBalances) {
|
|
569
|
+
const mint = mints.find((m) => balance.mint === m);
|
|
570
|
+
if (mint) {
|
|
571
|
+
const amt = Number(balance.uiTokenAmount?.amount || balance.amount || 0);
|
|
572
|
+
onchain[balance.owner] = { mint, amt };
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
let sender = '';
|
|
576
|
+
for (const balance of preTokenBalances) {
|
|
577
|
+
const mint = mints.find((m) => balance.mint === m);
|
|
578
|
+
if (mint) {
|
|
579
|
+
const amt = Number(balance.uiTokenAmount?.amount || balance.amount || 0);
|
|
580
|
+
if (onchain[balance.owner]) {
|
|
581
|
+
onchain[balance.owner] = {
|
|
582
|
+
mint,
|
|
583
|
+
amt: onchain[balance.owner].amt - amt,
|
|
584
|
+
};
|
|
585
|
+
if (onchain[balance.owner].amt < 0) {
|
|
586
|
+
const foundSender = senders.find((s) => s === balance.owner.toString());
|
|
587
|
+
if (!foundSender) {
|
|
588
|
+
throw new Error(`sender ${balance.owner} not in expected senders ${senders}`);
|
|
589
|
+
}
|
|
590
|
+
if (assertSender !== '' && foundSender !== assertSender) {
|
|
591
|
+
throw new Error(`assert sender ${balance.owner} != ${assertSender}`);
|
|
592
|
+
}
|
|
593
|
+
sender = foundSender;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
if (channel === 'emit') {
|
|
599
|
+
sender = renderMint;
|
|
600
|
+
}
|
|
601
|
+
if (!sender) {
|
|
602
|
+
console.log(`no matching sender found`);
|
|
603
|
+
}
|
|
604
|
+
if (Object.keys(onchain).length === 0) {
|
|
605
|
+
console.log(`skipping ${solTx}. nothing to index`);
|
|
606
|
+
continue;
|
|
607
|
+
}
|
|
608
|
+
const result = await this.indexTransfers(onchain, { blockTime: tx.blockTime || tx.blocktime || 0, sig: solTx }, sender, channel, reindexTx);
|
|
609
|
+
if (!this.isDryRun && result.insertedIds) {
|
|
610
|
+
insertedIds.push(...result.insertedIds);
|
|
611
|
+
}
|
|
612
|
+
if (result.stop) {
|
|
613
|
+
console.log(`stopping processing due to catch-up at tx ${solTx}`);
|
|
614
|
+
break;
|
|
615
|
+
}
|
|
616
|
+
proced += 1;
|
|
617
|
+
if (proced % 10 === 0 && !this.isDryRun) {
|
|
618
|
+
console.log(`proced ${proced}`);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
console.log(`done. inserted ${insertedIds.length} transfers: ${insertedIds.join(',')}`);
|
|
622
|
+
}
|
|
623
|
+
async indexTransfers(onchain, tx, sender, channel, reindexTx = false) {
|
|
624
|
+
const ents = Object.entries(onchain).filter(([k, { mint, amt }]) => amt != 0);
|
|
625
|
+
if (this.isDryRun) {
|
|
626
|
+
for (const [k, { amt, mint }] of ents) {
|
|
627
|
+
if (k == sender) {
|
|
628
|
+
continue;
|
|
629
|
+
}
|
|
630
|
+
const symbol = (() => {
|
|
631
|
+
if (mint == renderMint) {
|
|
632
|
+
return 'RENDER';
|
|
633
|
+
}
|
|
634
|
+
if (mint == usdcMint) {
|
|
635
|
+
return 'USDC';
|
|
636
|
+
}
|
|
637
|
+
return 'UNKNOWN';
|
|
638
|
+
})();
|
|
639
|
+
const amount = this.formatAmount(amt);
|
|
640
|
+
const timestamp = this.formatTimestamp(tx.blockTime);
|
|
641
|
+
console.log(`would insert ${tx.sig.slice(0, 8)}... | ${timestamp} | ${channel} | ${sender} -> ${k} | ${amount} ${symbol}`);
|
|
642
|
+
}
|
|
643
|
+
return { stop: false, insertedIds: [] };
|
|
644
|
+
}
|
|
645
|
+
if (reindexTx) {
|
|
646
|
+
try {
|
|
647
|
+
const res = await this.pg.db.trx.deleteFrom('sol_tx')
|
|
648
|
+
.where('sig', '=', tx.sig)
|
|
649
|
+
.execute();
|
|
650
|
+
console.log(`deleted ${res.length > 0 ? res[0].numDeletedRows || 0 : 0} tx`);
|
|
651
|
+
}
|
|
652
|
+
catch (e) {
|
|
653
|
+
console.log(`failed to delete tx ${tx.sig}: ${e}`);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
console.log(`diffs: ${ents.map(([k, v]) => `k ${k} v -> ${JSON.stringify(v)}`)}`);
|
|
657
|
+
const insertedIds = [];
|
|
658
|
+
for (const [k, { amt, mint }] of ents) {
|
|
659
|
+
if (k == sender) {
|
|
660
|
+
continue;
|
|
661
|
+
}
|
|
662
|
+
const trx = await this.pg.startTransaction();
|
|
663
|
+
try {
|
|
664
|
+
const { inserted } = await this.pg.createPayments(trx, [
|
|
665
|
+
{
|
|
666
|
+
transfer: {
|
|
667
|
+
fromSolKey: sender,
|
|
668
|
+
toSolKey: k,
|
|
669
|
+
symbol: (() => {
|
|
670
|
+
if (mint == renderMint) {
|
|
671
|
+
return 'RENDER';
|
|
672
|
+
}
|
|
673
|
+
if (mint == usdcMint) {
|
|
674
|
+
return 'USDC';
|
|
675
|
+
}
|
|
676
|
+
throw new Error(`unknown mint ${mint}`);
|
|
677
|
+
})(),
|
|
678
|
+
channel: channel,
|
|
679
|
+
solTx: tx.sig,
|
|
680
|
+
executedAt: new Date(tx.blockTime * 1000),
|
|
681
|
+
amountPayed: BigInt(amt),
|
|
682
|
+
},
|
|
683
|
+
},
|
|
684
|
+
]);
|
|
685
|
+
console.log(`inserted ${JSON.stringify(inserted)}`);
|
|
686
|
+
insertedIds.push(...inserted.map((t) => t.transferId).filter((i) => !!i));
|
|
687
|
+
trx.commit();
|
|
688
|
+
}
|
|
689
|
+
catch (e) {
|
|
690
|
+
trx.rollback();
|
|
691
|
+
if (`${e}`.includes('duplicate key value violates unique constraint')) {
|
|
692
|
+
console.log(`caught up indexing ${e}`);
|
|
693
|
+
return { stop: true, insertedIds };
|
|
694
|
+
}
|
|
695
|
+
throw e;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
console.log(`tx ${tx.sig} -> insertedIds ${insertedIds.length}`);
|
|
699
|
+
return { stop: false, insertedIds };
|
|
700
|
+
}
|
|
701
|
+
async run() {
|
|
702
|
+
for (const t of Object.keys(this._types)) {
|
|
703
|
+
if (t == 'emit') {
|
|
704
|
+
const txs = await this.findEmitTxs();
|
|
705
|
+
await this.indexTxs(txs, 'emit');
|
|
706
|
+
}
|
|
707
|
+
else if (t == 'buyBurnUSDCInflow') {
|
|
708
|
+
const trs = await this.solscanClient.getTransfers({
|
|
709
|
+
mint: new PublicKey(usdcMint),
|
|
710
|
+
flow: 'in',
|
|
711
|
+
addr: new PublicKey(buyAndBurnEscrow),
|
|
712
|
+
});
|
|
713
|
+
for (const t of trs) {
|
|
714
|
+
if (!this.isDryRun) {
|
|
715
|
+
console.log(`buyBurnUSDCInflows: ${JSON.stringify(t)}`);
|
|
716
|
+
}
|
|
717
|
+
const { stop } = await this.indexTransfers({ [buyAndBurnEscrow]: { mint: usdcMint, amt: t.amount } }, { blockTime: t.blockTime, sig: t.sig }, t.fromAddress.toString(), 'internal');
|
|
718
|
+
if (stop) {
|
|
719
|
+
break;
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
else if (t == 'manualMint') {
|
|
724
|
+
console.log(`About to fetch manual mints - renderMint: ${renderMint}, bridgeEscrow: ${bridgeEscrow}, isDryRun: ${this.isDryRun}`);
|
|
725
|
+
const trs = await this.solscanClient.getBalanceChange({
|
|
726
|
+
mint: new PublicKey(renderMint),
|
|
727
|
+
addr: new PublicKey('AYm4Knn6Sw1f52Eq42ujQ2ez5Xb7iBJeviprFCA7ADCy'),
|
|
728
|
+
flow: 'in',
|
|
729
|
+
tokenAccount: new PublicKey(bridgeEscrow),
|
|
730
|
+
});
|
|
731
|
+
console.log(`polyTrs result: ${trs.length} transactions`);
|
|
732
|
+
for (const t of trs) {
|
|
733
|
+
if (!this.isDryRun) {
|
|
734
|
+
console.log(`manualMints: ${JSON.stringify(t)}`);
|
|
735
|
+
}
|
|
736
|
+
const { stop } = await this.indexTransfers({ [bridgeEscrow]: { mint: renderMint, amt: t.amount } }, { blockTime: t.blockTime, sig: t.sig }, renderMint, 'manual_mint');
|
|
737
|
+
if (stop) {
|
|
738
|
+
break;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
console.log(`About to fetch poly manual mints - renderMint: ${renderMint}, polyBridgeEscrow: ${polyBridgeEscrow}, isDryRun: ${this.isDryRun}`);
|
|
742
|
+
// polygon bridge escrow
|
|
743
|
+
const polyTrs = await this.solscanClient.getBalanceChange({
|
|
744
|
+
mint: new PublicKey(renderMint),
|
|
745
|
+
addr: new PublicKey('E5uyafHUFpNTsiPvGmUpr8BmM1L8t1gx3g6H4Y4vraU5'),
|
|
746
|
+
flow: 'in',
|
|
747
|
+
tokenAccount: new PublicKey(polyBridgeEscrow),
|
|
748
|
+
});
|
|
749
|
+
console.log(`polyTrs result: ${polyTrs.length} transactions`);
|
|
750
|
+
for (const t of polyTrs) {
|
|
751
|
+
if (!this.isDryRun) {
|
|
752
|
+
console.log(`polyManualMints: ${JSON.stringify(t)}`);
|
|
753
|
+
}
|
|
754
|
+
const { stop } = await this.indexTransfers({ [polyBridgeEscrow]: { mint: renderMint, amt: t.amount } }, { blockTime: t.blockTime, sig: t.sig }, renderMint, 'manual_mint');
|
|
755
|
+
if (stop) {
|
|
756
|
+
break;
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
else if (t == 'vaultOutflows') {
|
|
761
|
+
for (const addr of [devsSquadsVault, masterSquadsVault]) {
|
|
762
|
+
const trs = await this.solscanClient.getTransfers({
|
|
763
|
+
mint: new PublicKey(renderMint),
|
|
764
|
+
flow: 'out',
|
|
765
|
+
addr: new PublicKey(addr),
|
|
766
|
+
pageSize: this.solscan.pageSize,
|
|
767
|
+
});
|
|
768
|
+
for (const t of trs) {
|
|
769
|
+
if (!this.isDryRun) {
|
|
770
|
+
console.log(`vaultOutflow: ${JSON.stringify(t)}`);
|
|
771
|
+
}
|
|
772
|
+
const { stop } = await this.indexTransfers({
|
|
773
|
+
[t.toAddress.toString()]: { mint: renderMint, amt: t.amount },
|
|
774
|
+
}, { blockTime: t.blockTime, sig: t.sig }, addr, 'internal');
|
|
775
|
+
if (stop) {
|
|
776
|
+
break;
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
else if (t == 'loan') {
|
|
782
|
+
await this.indexLoans();
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
async function main() {
|
|
788
|
+
const args = process.argv.slice(2);
|
|
789
|
+
const getArgValue = (argName) => {
|
|
790
|
+
const argIndex = args.indexOf(`--${argName}`);
|
|
791
|
+
return argIndex !== -1 && argIndex + 1 < args.length
|
|
792
|
+
? args[argIndex + 1]
|
|
793
|
+
: undefined;
|
|
794
|
+
};
|
|
795
|
+
const hasFlag = (flagName) => {
|
|
796
|
+
return args.includes(`--${flagName}`);
|
|
797
|
+
};
|
|
798
|
+
const solscanApiKey = getArgValue('solscanApiKey');
|
|
799
|
+
if (!solscanApiKey) {
|
|
800
|
+
console.error('Error: --solscanApiKey is required');
|
|
801
|
+
process.exit(1);
|
|
802
|
+
}
|
|
803
|
+
const heliusApiKey = getArgValue('heliusApiKey');
|
|
804
|
+
if (!heliusApiKey) {
|
|
805
|
+
console.error('Error: --heliusApiKey is required');
|
|
806
|
+
process.exit(1);
|
|
807
|
+
}
|
|
808
|
+
const isDryRun = hasFlag('dryRun');
|
|
809
|
+
let pg;
|
|
810
|
+
if (!isDryRun) {
|
|
811
|
+
const pgUrl = getArgValue('pgUrl');
|
|
812
|
+
if (!pgUrl) {
|
|
813
|
+
console.error('Error: --pgUrl is required (unless using --dryRun)');
|
|
814
|
+
process.exit(1);
|
|
815
|
+
}
|
|
816
|
+
pg = pgClient({
|
|
817
|
+
connectionString: pgUrl,
|
|
818
|
+
});
|
|
819
|
+
}
|
|
820
|
+
const backfiller = new Backfiller(solscanApiKey, heliusApiKey, pg, isDryRun);
|
|
821
|
+
if (hasFlag('loans')) {
|
|
822
|
+
backfiller.loans();
|
|
823
|
+
}
|
|
824
|
+
if (hasFlag('vaultOutflows')) {
|
|
825
|
+
backfiller.vaultOutflows({});
|
|
826
|
+
}
|
|
827
|
+
if (hasFlag('emissions')) {
|
|
828
|
+
backfiller.emit();
|
|
829
|
+
}
|
|
830
|
+
if (hasFlag('buyBurnUSDCInflow')) {
|
|
831
|
+
backfiller.buyBurnUSDCInflow();
|
|
832
|
+
}
|
|
833
|
+
if (hasFlag('manualMints')) {
|
|
834
|
+
backfiller.manualMint();
|
|
835
|
+
}
|
|
836
|
+
if (hasFlag('loans') ||
|
|
837
|
+
hasFlag('vaultOutflows') ||
|
|
838
|
+
hasFlag('emissions') ||
|
|
839
|
+
hasFlag('buyBurnUSDCInflow') ||
|
|
840
|
+
hasFlag('manualMints')) {
|
|
841
|
+
await backfiller.run();
|
|
842
|
+
}
|
|
843
|
+
else {
|
|
844
|
+
console.log('No operations specified. Available flags: --loans, --vaultOutflows, --emissions, --buyBurnUSDCInflow, --manualMints, --dryRun');
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
if (require.main === module) {
|
|
848
|
+
main().catch(console.error);
|
|
849
|
+
}
|
|
850
|
+
//# sourceMappingURL=backfiller.js.map
|