@render-foundation/utils 0.0.179 → 0.0.180

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.
Files changed (110) hide show
  1. package/lib/esm/tsconfig.esm.tsbuildinfo +1 -1
  2. package/package.json +1 -1
  3. package/lib/cjs/backfiller.js +0 -895
  4. package/lib/cjs/backfiller.js.map +0 -1
  5. package/lib/cjs/client/onchain.js +0 -132
  6. package/lib/cjs/client/onchain.js.map +0 -1
  7. package/lib/cjs/client/pg/base.js +0 -198
  8. package/lib/cjs/client/pg/base.js.map +0 -1
  9. package/lib/cjs/client/pg/v1.js +0 -623
  10. package/lib/cjs/client/pg/v1.js.map +0 -1
  11. package/lib/cjs/client/pg/v2Client.js +0 -1584
  12. package/lib/cjs/client/pg/v2Client.js.map +0 -1
  13. package/lib/cjs/client/pg/viewClient.js +0 -107
  14. package/lib/cjs/client/pg/viewClient.js.map +0 -1
  15. package/lib/cjs/client/price.js +0 -63
  16. package/lib/cjs/client/price.js.map +0 -1
  17. package/lib/cjs/client/render.js +0 -173
  18. package/lib/cjs/client/render.js.map +0 -1
  19. package/lib/cjs/client/squads.js +0 -204
  20. package/lib/cjs/client/squads.js.map +0 -1
  21. package/lib/cjs/client/trade.js +0 -235
  22. package/lib/cjs/client/trade.js.map +0 -1
  23. package/lib/cjs/client/wormhole.js +0 -69
  24. package/lib/cjs/client/wormhole.js.map +0 -1
  25. package/lib/cjs/constants.js +0 -46
  26. package/lib/cjs/constants.js.map +0 -1
  27. package/lib/cjs/dbTypes.js +0 -3
  28. package/lib/cjs/dbTypes.js.map +0 -1
  29. package/lib/cjs/dbTypesV2.js +0 -3
  30. package/lib/cjs/dbTypesV2.js.map +0 -1
  31. package/lib/cjs/dbViewTypes.js +0 -3
  32. package/lib/cjs/dbViewTypes.js.map +0 -1
  33. package/lib/cjs/errorReporter.js +0 -126
  34. package/lib/cjs/errorReporter.js.map +0 -1
  35. package/lib/cjs/index.js +0 -44
  36. package/lib/cjs/index.js.map +0 -1
  37. package/lib/cjs/logger.js +0 -21
  38. package/lib/cjs/logger.js.map +0 -1
  39. package/lib/esm/src/backfiller.js +0 -850
  40. package/lib/esm/src/backfiller.js.map +0 -1
  41. package/lib/esm/src/client/onchain.js +0 -122
  42. package/lib/esm/src/client/onchain.js.map +0 -1
  43. package/lib/esm/src/client/pg/base.js +0 -162
  44. package/lib/esm/src/client/pg/base.js.map +0 -1
  45. package/lib/esm/src/client/pg/v1.js +0 -559
  46. package/lib/esm/src/client/pg/v1.js.map +0 -1
  47. package/lib/esm/src/client/pg/v2Client.js +0 -1465
  48. package/lib/esm/src/client/pg/v2Client.js.map +0 -1
  49. package/lib/esm/src/client/pg/viewClient.js +0 -91
  50. package/lib/esm/src/client/pg/viewClient.js.map +0 -1
  51. package/lib/esm/src/client/price.js +0 -41
  52. package/lib/esm/src/client/price.js.map +0 -1
  53. package/lib/esm/src/client/render.js +0 -147
  54. package/lib/esm/src/client/render.js.map +0 -1
  55. package/lib/esm/src/client/squads.js +0 -163
  56. package/lib/esm/src/client/squads.js.map +0 -1
  57. package/lib/esm/src/client/trade.js +0 -219
  58. package/lib/esm/src/client/trade.js.map +0 -1
  59. package/lib/esm/src/client/wormhole.js +0 -33
  60. package/lib/esm/src/client/wormhole.js.map +0 -1
  61. package/lib/esm/src/constants.js +0 -43
  62. package/lib/esm/src/constants.js.map +0 -1
  63. package/lib/esm/src/dbTypes.js +0 -2
  64. package/lib/esm/src/dbTypes.js.map +0 -1
  65. package/lib/esm/src/dbTypesV2.js +0 -2
  66. package/lib/esm/src/dbTypesV2.js.map +0 -1
  67. package/lib/esm/src/dbViewTypes.js +0 -2
  68. package/lib/esm/src/dbViewTypes.js.map +0 -1
  69. package/lib/esm/src/errorReporter.js +0 -117
  70. package/lib/esm/src/errorReporter.js.map +0 -1
  71. package/lib/esm/src/index.js +0 -15
  72. package/lib/esm/src/index.js.map +0 -1
  73. package/lib/esm/src/logger.js +0 -18
  74. package/lib/esm/src/logger.js.map +0 -1
  75. package/lib/types/src/backfiller.d.ts +0 -62
  76. package/lib/types/src/backfiller.d.ts.map +0 -1
  77. package/lib/types/src/client/onchain.d.ts +0 -24
  78. package/lib/types/src/client/onchain.d.ts.map +0 -1
  79. package/lib/types/src/client/pg/base.d.ts +0 -82
  80. package/lib/types/src/client/pg/base.d.ts.map +0 -1
  81. package/lib/types/src/client/pg/v1.d.ts +0 -137
  82. package/lib/types/src/client/pg/v1.d.ts.map +0 -1
  83. package/lib/types/src/client/pg/v2Client.d.ts +0 -309
  84. package/lib/types/src/client/pg/v2Client.d.ts.map +0 -1
  85. package/lib/types/src/client/pg/viewClient.d.ts +0 -55
  86. package/lib/types/src/client/pg/viewClient.d.ts.map +0 -1
  87. package/lib/types/src/client/price.d.ts +0 -12
  88. package/lib/types/src/client/price.d.ts.map +0 -1
  89. package/lib/types/src/client/render.d.ts +0 -24
  90. package/lib/types/src/client/render.d.ts.map +0 -1
  91. package/lib/types/src/client/squads.d.ts +0 -17
  92. package/lib/types/src/client/squads.d.ts.map +0 -1
  93. package/lib/types/src/client/trade.d.ts +0 -24
  94. package/lib/types/src/client/trade.d.ts.map +0 -1
  95. package/lib/types/src/client/wormhole.d.ts +0 -9
  96. package/lib/types/src/client/wormhole.d.ts.map +0 -1
  97. package/lib/types/src/constants.d.ts +0 -41
  98. package/lib/types/src/constants.d.ts.map +0 -1
  99. package/lib/types/src/dbTypes.d.ts +0 -123
  100. package/lib/types/src/dbTypes.d.ts.map +0 -1
  101. package/lib/types/src/dbTypesV2.d.ts +0 -193
  102. package/lib/types/src/dbTypesV2.d.ts.map +0 -1
  103. package/lib/types/src/dbViewTypes.d.ts +0 -35
  104. package/lib/types/src/dbViewTypes.d.ts.map +0 -1
  105. package/lib/types/src/errorReporter.d.ts +0 -13
  106. package/lib/types/src/errorReporter.d.ts.map +0 -1
  107. package/lib/types/src/index.d.ts +0 -15
  108. package/lib/types/src/index.d.ts.map +0 -1
  109. package/lib/types/src/logger.d.ts +0 -16
  110. package/lib/types/src/logger.d.ts.map +0 -1
@@ -1,850 +0,0 @@
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