@render-foundation/utils 0.0.169 → 0.0.170

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