@render-foundation/utils 0.0.165 → 0.0.166

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