@render-foundation/utils 0.0.197 → 0.0.198

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 (75) hide show
  1. package/lib/cjs/assertSecrets.js +42 -0
  2. package/lib/cjs/assertSecrets.js.map +1 -0
  3. package/lib/cjs/backfiller.js +16 -16
  4. package/lib/cjs/backfiller.js.map +1 -1
  5. package/lib/cjs/burn/burnAnalysis.js +3 -3
  6. package/lib/cjs/burn/burnAnalysis.js.map +1 -1
  7. package/lib/cjs/burn/burnCalculations.js.map +1 -1
  8. package/lib/cjs/client/onchain.js +3 -3
  9. package/lib/cjs/client/onchain.js.map +1 -1
  10. package/lib/cjs/client/pg/base.js +7 -7
  11. package/lib/cjs/client/pg/base.js.map +1 -1
  12. package/lib/cjs/client/pg/v1.js +31 -31
  13. package/lib/cjs/client/pg/v1.js.map +1 -1
  14. package/lib/cjs/client/pg/v2Client.js +156 -107
  15. package/lib/cjs/client/pg/v2Client.js.map +1 -1
  16. package/lib/cjs/client/pg/viewClient.js +6 -6
  17. package/lib/cjs/client/pg/viewClient.js.map +1 -1
  18. package/lib/cjs/client/price.js +3 -3
  19. package/lib/cjs/client/price.js.map +1 -1
  20. package/lib/cjs/client/render.js +10 -10
  21. package/lib/cjs/client/render.js.map +1 -1
  22. package/lib/cjs/client/squads.js +20 -10
  23. package/lib/cjs/client/squads.js.map +1 -1
  24. package/lib/cjs/client/trade.js +15 -12
  25. package/lib/cjs/client/trade.js.map +1 -1
  26. package/lib/cjs/client/wormhole.js +19 -9
  27. package/lib/cjs/client/wormhole.js.map +1 -1
  28. package/lib/cjs/errorReporter.js +1 -1
  29. package/lib/cjs/errorReporter.js.map +1 -1
  30. package/lib/cjs/index.js +18 -7
  31. package/lib/cjs/index.js.map +1 -1
  32. package/lib/esm/src/assertSecrets.js +39 -0
  33. package/lib/esm/src/assertSecrets.js.map +1 -0
  34. package/lib/esm/src/backfiller.js.map +1 -1
  35. package/lib/esm/src/burn/burnAnalysis.js +1 -1
  36. package/lib/esm/src/burn/burnAnalysis.js.map +1 -1
  37. package/lib/esm/src/burn/burnCalculations.js.map +1 -1
  38. package/lib/esm/src/client/onchain.js.map +1 -1
  39. package/lib/esm/src/client/pg/base.js.map +1 -1
  40. package/lib/esm/src/client/pg/v1.js.map +1 -1
  41. package/lib/esm/src/client/pg/v2Client.js +49 -10
  42. package/lib/esm/src/client/pg/v2Client.js.map +1 -1
  43. package/lib/esm/src/client/pg/viewClient.js.map +1 -1
  44. package/lib/esm/src/client/price.js.map +1 -1
  45. package/lib/esm/src/client/render.js.map +1 -1
  46. package/lib/esm/src/client/squads.js.map +1 -1
  47. package/lib/esm/src/client/trade.js +2 -2
  48. package/lib/esm/src/client/trade.js.map +1 -1
  49. package/lib/esm/src/client/wormhole.js.map +1 -1
  50. package/lib/esm/src/errorReporter.js.map +1 -1
  51. package/lib/esm/src/index.js +1 -0
  52. package/lib/esm/src/index.js.map +1 -1
  53. package/lib/esm/tsconfig.esm.tsbuildinfo +1 -1
  54. package/lib/types/src/assertSecrets.d.ts +27 -0
  55. package/lib/types/src/assertSecrets.d.ts.map +1 -0
  56. package/lib/types/src/backfiller.d.ts.map +1 -1
  57. package/lib/types/src/burn/burnAnalysis.d.ts.map +1 -1
  58. package/lib/types/src/burn/burnCalculations.d.ts.map +1 -1
  59. package/lib/types/src/client/onchain.d.ts +2 -1
  60. package/lib/types/src/client/onchain.d.ts.map +1 -1
  61. package/lib/types/src/client/pg/base.d.ts.map +1 -1
  62. package/lib/types/src/client/pg/v1.d.ts.map +1 -1
  63. package/lib/types/src/client/pg/v2Client.d.ts.map +1 -1
  64. package/lib/types/src/client/pg/viewClient.d.ts.map +1 -1
  65. package/lib/types/src/client/render.d.ts.map +1 -1
  66. package/lib/types/src/client/squads.d.ts.map +1 -1
  67. package/lib/types/src/client/trade.d.ts.map +1 -1
  68. package/lib/types/src/client/wormhole.d.ts +1 -1
  69. package/lib/types/src/client/wormhole.d.ts.map +1 -1
  70. package/lib/types/src/dbTypesV2.d.ts +1 -1
  71. package/lib/types/src/dbTypesV2.d.ts.map +1 -1
  72. package/lib/types/src/errorReporter.d.ts.map +1 -1
  73. package/lib/types/src/index.d.ts +1 -0
  74. package/lib/types/src/index.d.ts.map +1 -1
  75. package/package.json +1 -1
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
25
35
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
36
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
37
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -92,7 +102,7 @@ const pgClient = (config) => {
92
102
  const db = new kysely_1.Kysely({
93
103
  dialect,
94
104
  });
95
- const getOrInsertEntity = (db, p, log = logger_1.consoleLogger) => __awaiter(void 0, void 0, void 0, function* () {
105
+ const getOrInsertEntity = (db_1, p_1, ...args_1) => __awaiter(void 0, [db_1, p_1, ...args_1], void 0, function* (db, p, log = logger_1.consoleLogger) {
96
106
  const res = (yield db
97
107
  .selectFrom(exports.ENTITY_TABLE)
98
108
  .select('id')
@@ -113,7 +123,7 @@ const pgClient = (config) => {
113
123
  log.debug(`inserted entity ${id}`);
114
124
  return id;
115
125
  });
116
- const getOrInsertTx = (db, p, log = logger_1.consoleLogger) => __awaiter(void 0, void 0, void 0, function* () {
126
+ const getOrInsertTx = (db_1, p_1, ...args_1) => __awaiter(void 0, [db_1, p_1, ...args_1], void 0, function* (db, p, log = logger_1.consoleLogger) {
117
127
  const res = yield db
118
128
  .selectFrom(exports.SOL_TX_TABLE)
119
129
  .select('id')
@@ -135,7 +145,7 @@ const pgClient = (config) => {
135
145
  log.debug(`inserted tx ${id}`);
136
146
  return id;
137
147
  });
138
- const getOrInsertEpoch = (db, p, log = logger_1.consoleLogger) => __awaiter(void 0, void 0, void 0, function* () {
148
+ const getOrInsertEpoch = (db_1, p_1, ...args_1) => __awaiter(void 0, [db_1, p_1, ...args_1], void 0, function* (db, p, log = logger_1.consoleLogger) {
139
149
  const res = yield db
140
150
  .selectFrom(exports.EPOCH_TABLE)
141
151
  .select('id')
@@ -163,7 +173,7 @@ const pgClient = (config) => {
163
173
  log.debug(`inserted epoch ${id}`);
164
174
  return id;
165
175
  });
166
- const getCurrentUserGrantSpend = (db, p, log = logger_1.consoleLogger) => __awaiter(void 0, void 0, void 0, function* () {
176
+ const getCurrentUserGrantSpend = (db_1, p_1, ...args_1) => __awaiter(void 0, [db_1, p_1, ...args_1], void 0, function* (db, p, log = logger_1.consoleLogger) {
167
177
  var _a;
168
178
  const res = yield db
169
179
  .selectFrom(exports.CURRENT_USER_GRANT_SPEND_TABLE)
@@ -193,7 +203,7 @@ const pgClient = (config) => {
193
203
  .executeTakeFirst());
194
204
  log.info(`set ${res.numUpdatedRows} rows. channel: ${p.channel}, ui: ${p.uiEpochId} -> totalRndr ${totalRndr} `);
195
205
  });
196
- const fetchJobs1 = (db, f, log = logger_1.consoleLogger) => __awaiter(void 0, void 0, void 0, function* () {
206
+ const fetchJobs1 = (db_1, f_1, ...args_1) => __awaiter(void 0, [db_1, f_1, ...args_1], void 0, function* (db, f, log = logger_1.consoleLogger) {
197
207
  let q = db.selectFrom('job').selectAll();
198
208
  //.where('job.burn_id', 'is not', null)
199
209
  if (f.completedAtAfter) {
@@ -223,7 +233,7 @@ const pgClient = (config) => {
223
233
  insertedAt: r.inserted_at,
224
234
  }));
225
235
  });
226
- const fetchJobs2 = (db, f, log = logger_1.consoleLogger) => __awaiter(void 0, void 0, void 0, function* () {
236
+ const fetchJobs2 = (db_1, f_1, ...args_1) => __awaiter(void 0, [db_1, f_1, ...args_1], void 0, function* (db, f, log = logger_1.consoleLogger) {
227
237
  let q = db.selectFrom('job').selectAll();
228
238
  //.where('job.burn_id', 'is not', null)
229
239
  if (f.completedAtAfter) {
@@ -257,7 +267,7 @@ const pgClient = (config) => {
257
267
  });
258
268
  });
259
269
  });
260
- const createBridgeTransfers = (db, bts, log = logger_1.consoleLogger) => __awaiter(void 0, void 0, void 0, function* () {
270
+ const createBridgeTransfers = (db_1, bts_1, ...args_1) => __awaiter(void 0, [db_1, bts_1, ...args_1], void 0, function* (db, bts, log = logger_1.consoleLogger) {
261
271
  const sequenceNumbers = [];
262
272
  const dbEpochIds = [];
263
273
  for (const bt of bts) {
@@ -301,7 +311,7 @@ const pgClient = (config) => {
301
311
  }
302
312
  return { sequenceNumbers: sequenceNumbers };
303
313
  });
304
- const createPayments = (db, ps, log = logger_1.consoleLogger) => __awaiter(void 0, void 0, void 0, function* () {
314
+ const createPayments = (db_1, ps_1, ...args_1) => __awaiter(void 0, [db_1, ps_1, ...args_1], void 0, function* (db, ps, log = logger_1.consoleLogger) {
305
315
  const ids = [];
306
316
  const epochDbIds = [];
307
317
  for (const p of ps) {
@@ -355,7 +365,11 @@ const pgClient = (config) => {
355
365
  sig: solTx,
356
366
  executedAt,
357
367
  }, log);
358
- const { id } = yield db
368
+ // sol_transfer1 already has UNIQUE(sol_tx_id, from_entity_id,
369
+ // to_entity_id, symbol). Without ON CONFLICT a retry of the record step
370
+ // throws a unique violation and wedges the BullMQ job; make it an
371
+ // idempotent no-op and re-fetch the existing id instead.
372
+ let transferRow = yield db
359
373
  .insertInto(exports.SOL_TRANSFER_TABLE)
360
374
  .values({
361
375
  id: dbId,
@@ -366,9 +380,23 @@ const pgClient = (config) => {
366
380
  symbol,
367
381
  amount_payed: amountPayed,
368
382
  })
383
+ .onConflict((oc) => oc
384
+ .columns(['sol_tx_id', 'from_entity_id', 'to_entity_id', 'symbol'])
385
+ .doNothing())
369
386
  .returning((eb) => ['id as id'])
370
- .executeTakeFirstOrThrow();
371
- transferId = BigInt(id);
387
+ .executeTakeFirst();
388
+ if (!transferRow) {
389
+ log.warn(`sol_transfer for sol_tx_id ${solTxId} ${fromEntityId}->${toEntityId} ${symbol} already exists; reusing existing id (idempotent retry)`);
390
+ transferRow = yield db
391
+ .selectFrom(exports.SOL_TRANSFER_TABLE)
392
+ .select((eb) => ['id as id'])
393
+ .where('sol_tx_id', '=', solTxId)
394
+ .where('from_entity_id', '=', fromEntityId)
395
+ .where('to_entity_id', '=', toEntityId)
396
+ .where('symbol', '=', symbol)
397
+ .executeTakeFirstOrThrow();
398
+ }
399
+ transferId = BigInt(transferRow.id);
372
400
  }
373
401
  ids.push({ transferId, liabilityId });
374
402
  }
@@ -380,18 +408,18 @@ const pgClient = (config) => {
380
408
  rollback: () => { },
381
409
  trx: db,
382
410
  },
383
- startTransaction(log = logger_1.consoleLogger) {
384
- return __awaiter(this, void 0, void 0, function* () {
411
+ startTransaction() {
412
+ return __awaiter(this, arguments, void 0, function* (log = logger_1.consoleLogger) {
385
413
  return (0, base_2.begin)(db, log);
386
414
  });
387
415
  },
388
- createPayments(db, ps, log = logger_1.consoleLogger) {
389
- return __awaiter(this, void 0, void 0, function* () {
416
+ createPayments(db_1, ps_1) {
417
+ return __awaiter(this, arguments, void 0, function* (db, ps, log = logger_1.consoleLogger) {
390
418
  return createPayments(db.trx, ps, log);
391
419
  });
392
420
  },
393
- fetchTransfers(db, f, log = logger_1.consoleLogger) {
394
- return __awaiter(this, void 0, void 0, function* () {
421
+ fetchTransfers(db_1, f_1) {
422
+ return __awaiter(this, arguments, void 0, function* (db, f, log = logger_1.consoleLogger) {
395
423
  let lastId = undefined;
396
424
  if (f.cursor) {
397
425
  lastId = atob(f.cursor);
@@ -447,8 +475,8 @@ const pgClient = (config) => {
447
475
  };
448
476
  });
449
477
  },
450
- fetchEpochs(db, f, log = logger_1.consoleLogger) {
451
- return __awaiter(this, void 0, void 0, function* () {
478
+ fetchEpochs(db_1, f_1) {
479
+ return __awaiter(this, arguments, void 0, function* (db, f, log = logger_1.consoleLogger) {
452
480
  let q = db.trx.selectFrom(exports.EPOCH_TABLE).selectAll();
453
481
  if (f.channels) {
454
482
  q = q.where('channel', 'in', f.channels);
@@ -471,9 +499,9 @@ const pgClient = (config) => {
471
499
  }));
472
500
  });
473
501
  },
474
- fetchLiabilities(db, f, log = logger_1.consoleLogger) {
475
- var _a;
476
- return __awaiter(this, void 0, void 0, function* () {
502
+ fetchLiabilities(db_1, f_1) {
503
+ return __awaiter(this, arguments, void 0, function* (db, f, log = logger_1.consoleLogger) {
504
+ var _a;
477
505
  let offset = 0;
478
506
  let orderBy = (_a = f.orderBy) !== null && _a !== void 0 ? _a : 'epoch.ui,liability.id';
479
507
  if (f.cursor) {
@@ -540,8 +568,8 @@ const pgClient = (config) => {
540
568
  };
541
569
  });
542
570
  },
543
- getLiabilitiesAndTransfers(f, log = logger_1.consoleLogger) {
544
- return __awaiter(this, void 0, void 0, function* () {
571
+ getLiabilitiesAndTransfers(f_1) {
572
+ return __awaiter(this, arguments, void 0, function* (f, log = logger_1.consoleLogger) {
545
573
  let lq = db
546
574
  .selectFrom(exports.LIABILITY_TABLE)
547
575
  .selectAll()
@@ -602,9 +630,9 @@ const pgClient = (config) => {
602
630
  return { transfers, liabilities, epochs: Object.values(epochs) };
603
631
  });
604
632
  },
605
- getOutstanding(f, log = logger_1.consoleLogger) {
606
- var _a, _b, _c, _d, _e;
607
- return __awaiter(this, void 0, void 0, function* () {
633
+ getOutstanding(f_1) {
634
+ return __awaiter(this, arguments, void 0, function* (f, log = logger_1.consoleLogger) {
635
+ var _a, _b, _c, _d, _e;
608
636
  log.info(`getting outstanding balances for ${(_a = f.channels) !== null && _a !== void 0 ? _a : '(no channels specified)'} epoch: ${(_b = f.startEpochId.id) !== null && _b !== void 0 ? _b : '(no epoch specified)'}`);
609
637
  let epochUi;
610
638
  let epochEndTime;
@@ -713,9 +741,9 @@ const pgClient = (config) => {
713
741
  return out;
714
742
  });
715
743
  },
716
- fetchNodeOperatorEpoch(epochId, log = logger_1.consoleLogger) {
717
- var _a;
718
- return __awaiter(this, void 0, void 0, function* () {
744
+ fetchNodeOperatorEpoch(epochId_1) {
745
+ return __awaiter(this, arguments, void 0, function* (epochId, log = logger_1.consoleLogger) {
746
+ var _a;
719
747
  const q = db
720
748
  .selectFrom(exports.JOB_ID_TABLE)
721
749
  .innerJoin(exports.EPOCH_TABLE, 'epoch.id', 'job_id.epoch_id')
@@ -765,14 +793,14 @@ const pgClient = (config) => {
765
793
  };
766
794
  });
767
795
  },
768
- insertEpoch(db, epoch, log = logger_1.consoleLogger) {
769
- return __awaiter(this, void 0, void 0, function* () {
796
+ insertEpoch(db_1, epoch_1) {
797
+ return __awaiter(this, arguments, void 0, function* (db, epoch, log = logger_1.consoleLogger) {
770
798
  yield getOrInsertEpoch(db.trx, Object.assign(Object.assign({}, epoch), { uiEpochId: epoch.ui }), log);
771
799
  });
772
800
  },
773
- getEpoch(f, log = logger_1.consoleLogger) {
774
- var _a;
775
- return __awaiter(this, void 0, void 0, function* () {
801
+ getEpoch(f_1) {
802
+ return __awaiter(this, arguments, void 0, function* (f, log = logger_1.consoleLogger) {
803
+ var _a;
776
804
  const now = new Date(Date.now());
777
805
  try {
778
806
  let q = db
@@ -810,9 +838,9 @@ const pgClient = (config) => {
810
838
  }
811
839
  });
812
840
  },
813
- getLatestNodeOperatorEpoch(f, log = logger_1.consoleLogger) {
814
- var _a;
815
- return __awaiter(this, void 0, void 0, function* () {
841
+ getLatestNodeOperatorEpoch(f_1) {
842
+ return __awaiter(this, arguments, void 0, function* (f, log = logger_1.consoleLogger) {
843
+ var _a;
816
844
  const now = new Date(Date.now());
817
845
  try {
818
846
  let q = db
@@ -852,8 +880,8 @@ const pgClient = (config) => {
852
880
  }
853
881
  });
854
882
  },
855
- saveNodeOperatorEpoch(epochId, liabilities, jobIds, totalRndr, log = logger_1.consoleLogger) {
856
- return __awaiter(this, void 0, void 0, function* () {
883
+ saveNodeOperatorEpoch(epochId_1, liabilities_1, jobIds_1, totalRndr_1) {
884
+ return __awaiter(this, arguments, void 0, function* (epochId, liabilities, jobIds, totalRndr, log = logger_1.consoleLogger) {
857
885
  yield db
858
886
  .transaction()
859
887
  .setIsolationLevel('repeatable read')
@@ -889,8 +917,8 @@ const pgClient = (config) => {
889
917
  return;
890
918
  });
891
919
  },
892
- produceBurnedJobs(jobs, log = logger_1.consoleLogger) {
893
- return __awaiter(this, void 0, void 0, function* () {
920
+ produceBurnedJobs(jobs_1) {
921
+ return __awaiter(this, arguments, void 0, function* (jobs, log = logger_1.consoleLogger) {
894
922
  yield db.transaction().execute((trx) => __awaiter(this, void 0, void 0, function* () {
895
923
  var _a;
896
924
  let num = BigInt(0);
@@ -913,9 +941,9 @@ const pgClient = (config) => {
913
941
  }));
914
942
  });
915
943
  },
916
- markJobsBurntWithGrant(db, p, log = logger_1.consoleLogger) {
917
- var _a;
918
- return __awaiter(this, void 0, void 0, function* () {
944
+ markJobsBurntWithGrant(db_1, p_1) {
945
+ return __awaiter(this, arguments, void 0, function* (db, p, log = logger_1.consoleLogger) {
946
+ var _a;
919
947
  const solTxId = yield getOrInsertTx(db.trx, { sig: p.tx.sig, executedAt: p.tx.executedAt }, log);
920
948
  const { id } = yield db.trx
921
949
  .insertInto(exports.GRANT_BURN_TABLE)
@@ -946,9 +974,9 @@ const pgClient = (config) => {
946
974
  return;
947
975
  });
948
976
  },
949
- insertGrantSpend(db, p, log = logger_1.consoleLogger) {
950
- var _a, _b, _c;
951
- return __awaiter(this, void 0, void 0, function* () {
977
+ insertGrantSpend(db_1, p_1) {
978
+ return __awaiter(this, arguments, void 0, function* (db, p, log = logger_1.consoleLogger) {
979
+ var _a, _b, _c;
952
980
  const existing = yield getCurrentUserGrantSpend(db.trx, { userId: p.userId }, log);
953
981
  const diff = {
954
982
  render_spent: ((_a = existing === null || existing === void 0 ? void 0 : existing.renderSpent) !== null && _a !== void 0 ? _a : BigInt(0)) + p.renderSpentDelta,
@@ -1013,9 +1041,9 @@ const pgClient = (config) => {
1013
1041
  }
1014
1042
  });
1015
1043
  },
1016
- markJobsBurnt(trx, p, log = logger_1.consoleLogger) {
1017
- var _a, _b;
1018
- return __awaiter(this, void 0, void 0, function* () {
1044
+ markJobsBurnt(trx_1, p_1) {
1045
+ return __awaiter(this, arguments, void 0, function* (trx, p, log = logger_1.consoleLogger) {
1046
+ var _a, _b;
1019
1047
  if (!p.buyBurn && !p.grantBurn) {
1020
1048
  throw new Error('no buyBurn or grantBurn');
1021
1049
  }
@@ -1046,13 +1074,24 @@ const pgClient = (config) => {
1046
1074
  to_burn: toBurn,
1047
1075
  };
1048
1076
  log.debug(`inserting burn ${JSON.stringify(v)}`);
1049
- const { id } = yield trx.trx
1077
+ // Idempotent on sol_tx_id (uniq_burn_sol_tx_id, migration 27): a retry of
1078
+ // the record step for the same on-chain burn is a safe no-op. On conflict
1079
+ // executeTakeFirst() returns undefined, so re-fetch the existing id.
1080
+ let burnRow = yield trx.trx
1050
1081
  .insertInto(exports.BURN_TABLE)
1051
1082
  .values(v)
1052
- //.onConflict((oc) => oc.column('sol_tx').doNothing())
1083
+ .onConflict((oc) => oc.column('sol_tx_id').doNothing())
1053
1084
  .returning((eb) => ['id as id'])
1054
- .executeTakeFirstOrThrow();
1055
- buyBurnId = Number(id);
1085
+ .executeTakeFirst();
1086
+ if (!burnRow) {
1087
+ log.warn(`burn for sol_tx_id ${solTxId} already exists; reusing existing id (idempotent retry)`);
1088
+ burnRow = yield trx.trx
1089
+ .selectFrom(exports.BURN_TABLE)
1090
+ .select((eb) => ['id as id'])
1091
+ .where('sol_tx_id', '=', solTxId)
1092
+ .executeTakeFirstOrThrow();
1093
+ }
1094
+ buyBurnId = Number(burnRow.id);
1056
1095
  }
1057
1096
  if (p.grantBurn) {
1058
1097
  const { burned, tags } = p.grantBurn;
@@ -1062,12 +1101,22 @@ const pgClient = (config) => {
1062
1101
  tags: tags === null || tags === void 0 ? void 0 : tags.join(','),
1063
1102
  };
1064
1103
  log.debug(`inserting grant burn ${JSON.stringify(v)}`);
1065
- const { id } = yield trx.trx
1104
+ // Idempotent on sol_tx_id (uniq_grant_burn_sol_tx_id, migration 27).
1105
+ let grantBurnRow = yield trx.trx
1066
1106
  .insertInto(exports.GRANT_BURN_TABLE)
1067
1107
  .values(v)
1108
+ .onConflict((oc) => oc.column('sol_tx_id').doNothing())
1068
1109
  .returning((eb) => ['id as id'])
1069
- .executeTakeFirstOrThrow();
1070
- grantBurnId = Number(id);
1110
+ .executeTakeFirst();
1111
+ if (!grantBurnRow) {
1112
+ log.warn(`grant_burn for sol_tx_id ${solTxId} already exists; reusing existing id (idempotent retry)`);
1113
+ grantBurnRow = yield trx.trx
1114
+ .selectFrom(exports.GRANT_BURN_TABLE)
1115
+ .select((eb) => ['id as id'])
1116
+ .where('sol_tx_id', '=', solTxId)
1117
+ .executeTakeFirstOrThrow();
1118
+ }
1119
+ grantBurnId = Number(grantBurnRow.id);
1071
1120
  }
1072
1121
  const burnId = buyBurnId;
1073
1122
  const grantId = grantBurnId !== null && grantBurnId !== void 0 ? grantBurnId : buyBurnId;
@@ -1093,8 +1142,8 @@ const pgClient = (config) => {
1093
1142
  return { grantBurnId, buyBurnId };
1094
1143
  });
1095
1144
  },
1096
- markJobsBurned(trx, p, log = logger_1.consoleLogger) {
1097
- return __awaiter(this, void 0, void 0, function* () {
1145
+ markJobsBurned(trx_1, p_1) {
1146
+ return __awaiter(this, arguments, void 0, function* (trx, p, log = logger_1.consoleLogger) {
1098
1147
  let { markedAt, solTx } = p;
1099
1148
  let res = yield trx.trx
1100
1149
  .updateTable(exports.BURN_TABLE)
@@ -1118,8 +1167,8 @@ const pgClient = (config) => {
1118
1167
  }
1119
1168
  });
1120
1169
  },
1121
- consumeAndLockBurnJobs(limit, lowerRndrThreshold, upperRndrThreshold, log = logger_1.consoleLogger) {
1122
- return __awaiter(this, void 0, void 0, function* () {
1170
+ consumeAndLockBurnJobs(limit_1, lowerRndrThreshold_1, upperRndrThreshold_1) {
1171
+ return __awaiter(this, arguments, void 0, function* (limit, lowerRndrThreshold, upperRndrThreshold, log = logger_1.consoleLogger) {
1123
1172
  const trx = yield (0, base_2.begin)(db, log);
1124
1173
  const q = trx.trx
1125
1174
  .selectFrom(trx.trx
@@ -1226,9 +1275,9 @@ const pgClient = (config) => {
1226
1275
  };
1227
1276
  });
1228
1277
  },
1229
- incrBuyBurnMetrics(log = logger_1.consoleLogger) {
1230
- var _a;
1231
- return __awaiter(this, void 0, void 0, function* () {
1278
+ incrBuyBurnMetrics() {
1279
+ return __awaiter(this, arguments, void 0, function* (log = logger_1.consoleLogger) {
1280
+ var _a;
1232
1281
  const res = yield db
1233
1282
  .selectFrom(exports.JOB_TABLE)
1234
1283
  .select('inserted_at')
@@ -1245,9 +1294,9 @@ const pgClient = (config) => {
1245
1294
  };
1246
1295
  });
1247
1296
  },
1248
- fetchBurns(db, f, log = logger_1.consoleLogger) {
1249
- var _a, _b;
1250
- return __awaiter(this, void 0, void 0, function* () {
1297
+ fetchBurns(db_1, f_1) {
1298
+ return __awaiter(this, arguments, void 0, function* (db, f, log = logger_1.consoleLogger) {
1299
+ var _a, _b;
1251
1300
  let q = db.trx
1252
1301
  .selectFrom('burn')
1253
1302
  .selectAll('burn')
@@ -1316,9 +1365,9 @@ const pgClient = (config) => {
1316
1365
  return burns;
1317
1366
  });
1318
1367
  },
1319
- fetchBurnsAndGrants(db, f, log = logger_1.consoleLogger) {
1320
- var _a, _b;
1321
- return __awaiter(this, void 0, void 0, function* () {
1368
+ fetchBurnsAndGrants(db_1, f_1) {
1369
+ return __awaiter(this, arguments, void 0, function* (db, f, log = logger_1.consoleLogger) {
1370
+ var _a, _b;
1322
1371
  // Build a unified query to get all transactions with both buy burns and grant burns
1323
1372
  let baseQuery = db.trx
1324
1373
  .selectFrom('sol_tx')
@@ -1456,13 +1505,13 @@ const pgClient = (config) => {
1456
1505
  return groupedBurns;
1457
1506
  });
1458
1507
  },
1459
- createBridgeTransfers(db, bts, log = logger_1.consoleLogger) {
1460
- return __awaiter(this, void 0, void 0, function* () {
1508
+ createBridgeTransfers(db_1, bts_1) {
1509
+ return __awaiter(this, arguments, void 0, function* (db, bts, log = logger_1.consoleLogger) {
1461
1510
  return createBridgeTransfers(db.trx, bts, log);
1462
1511
  });
1463
1512
  },
1464
- getBridgeTransfers({ solKey, page, }, log = logger_1.consoleLogger) {
1465
- return __awaiter(this, void 0, void 0, function* () {
1513
+ getBridgeTransfers(_a) {
1514
+ return __awaiter(this, arguments, void 0, function* ({ solKey, page, }, log = logger_1.consoleLogger) {
1466
1515
  let q = db
1467
1516
  .selectFrom(exports.BRIDGE_TRANSFER_TABLE)
1468
1517
  .innerJoin(exports.EPOCH_TABLE, 'epoch.id', 'bridge_transfer.epoch_id')
@@ -1539,8 +1588,8 @@ const pgClient = (config) => {
1539
1588
  });
1540
1589
  },
1541
1590
  getTotalBurned(db) {
1542
- var _a, _b;
1543
1591
  return __awaiter(this, void 0, void 0, function* () {
1592
+ var _a, _b;
1544
1593
  const total = yield db.trx
1545
1594
  .selectFrom('burn')
1546
1595
  .select(({ fn }) => fn.sum('burned').as('total_burned'))
@@ -1548,8 +1597,8 @@ const pgClient = (config) => {
1548
1597
  return BigInt((_b = (_a = total[0]) === null || _a === void 0 ? void 0 : _a.total_burned) !== null && _b !== void 0 ? _b : 0);
1549
1598
  });
1550
1599
  },
1551
- insertBurn(p, log = logger_1.consoleLogger) {
1552
- return __awaiter(this, void 0, void 0, function* () {
1600
+ insertBurn(p_1) {
1601
+ return __awaiter(this, arguments, void 0, function* (p, log = logger_1.consoleLogger) {
1553
1602
  yield db.transaction().execute((trx) => __awaiter(this, void 0, void 0, function* () {
1554
1603
  var _a;
1555
1604
  const solTxId = yield getOrInsertTx(trx, { sig: p.solTx, executedAt: p.executedAt }, log);
@@ -1586,18 +1635,18 @@ const pgClient = (config) => {
1586
1635
  }));
1587
1636
  });
1588
1637
  },
1589
- fetchJobs(db, f, log = logger_1.consoleLogger) {
1590
- return __awaiter(this, void 0, void 0, function* () {
1638
+ fetchJobs(db_1, f_1) {
1639
+ return __awaiter(this, arguments, void 0, function* (db, f, log = logger_1.consoleLogger) {
1591
1640
  return yield fetchJobs1(db.trx, f, log);
1592
1641
  });
1593
1642
  },
1594
- fetchJobsWithGrantValues(db, f, log = logger_1.consoleLogger) {
1595
- return __awaiter(this, void 0, void 0, function* () {
1643
+ fetchJobsWithGrantValues(db_1, f_1) {
1644
+ return __awaiter(this, arguments, void 0, function* (db, f, log = logger_1.consoleLogger) {
1596
1645
  return yield fetchJobs2(db.trx, f, log);
1597
1646
  });
1598
1647
  },
1599
- fetchLiabilityEpochs(db, log = logger_1.consoleLogger) {
1600
- return __awaiter(this, void 0, void 0, function* () {
1648
+ fetchLiabilityEpochs(db_1) {
1649
+ return __awaiter(this, arguments, void 0, function* (db, log = logger_1.consoleLogger) {
1601
1650
  const q = db.trx
1602
1651
  .selectFrom(exports.LIABILITY_TABLE)
1603
1652
  .select(({ fn }) => [
@@ -1655,8 +1704,8 @@ const pgClient = (config) => {
1655
1704
  }));
1656
1705
  });
1657
1706
  },
1658
- getBurnAdjustments(trx, ps, log = logger_1.consoleLogger) {
1659
- return __awaiter(this, void 0, void 0, function* () {
1707
+ getBurnAdjustments(trx_1, ps_1) {
1708
+ return __awaiter(this, arguments, void 0, function* (trx, ps, log = logger_1.consoleLogger) {
1660
1709
  if (ps.toFill) {
1661
1710
  const q = trx.trx
1662
1711
  .selectFrom(exports.BURN_ADJUSTMENT_TABLE)
@@ -1697,8 +1746,8 @@ const pgClient = (config) => {
1697
1746
  return [];
1698
1747
  });
1699
1748
  },
1700
- insertPolygonUpgrade(db, p, log = logger_1.consoleLogger) {
1701
- return __awaiter(this, void 0, void 0, function* () {
1749
+ insertPolygonUpgrade(db_1, p_1) {
1750
+ return __awaiter(this, arguments, void 0, function* (db, p, log = logger_1.consoleLogger) {
1702
1751
  const solTxId = yield getOrInsertTx(db.trx, {
1703
1752
  sig: p.solTx.sig,
1704
1753
  executedAt: p.solTx.executedAt,
@@ -1716,8 +1765,8 @@ const pgClient = (config) => {
1716
1765
  return;
1717
1766
  });
1718
1767
  },
1719
- fetchPolygonUpgrades(db, f, log = logger_1.consoleLogger) {
1720
- return __awaiter(this, void 0, void 0, function* () {
1768
+ fetchPolygonUpgrades(db_1, f_1) {
1769
+ return __awaiter(this, arguments, void 0, function* (db, f, log = logger_1.consoleLogger) {
1721
1770
  let query = db.trx
1722
1771
  .selectFrom('polygon_upgrade')
1723
1772
  .selectAll('polygon_upgrade')
@@ -1743,13 +1792,13 @@ const pgClient = (config) => {
1743
1792
  }));
1744
1793
  });
1745
1794
  },
1746
- getCurrentUserGrantSpend(db, f, log = logger_1.consoleLogger) {
1747
- return __awaiter(this, void 0, void 0, function* () {
1795
+ getCurrentUserGrantSpend(db_1, f_1) {
1796
+ return __awaiter(this, arguments, void 0, function* (db, f, log = logger_1.consoleLogger) {
1748
1797
  return yield getCurrentUserGrantSpend(db.trx, f, log);
1749
1798
  });
1750
1799
  },
1751
- deleteAll(log = logger_1.consoleLogger) {
1752
- return __awaiter(this, void 0, void 0, function* () {
1800
+ deleteAll() {
1801
+ return __awaiter(this, arguments, void 0, function* (log = logger_1.consoleLogger) {
1753
1802
  if (config.database.includes('render')) {
1754
1803
  throw new Error('cannot nuke from deployed database. call from tests only');
1755
1804
  }
@@ -1795,8 +1844,8 @@ const pgClient = (config) => {
1795
1844
  }
1796
1845
  });
1797
1846
  },
1798
- checkPaymentsForDate(targetDate, channel = 'both', log = logger_1.consoleLogger) {
1799
- return __awaiter(this, void 0, void 0, function* () {
1847
+ checkPaymentsForDate(targetDate_1) {
1848
+ return __awaiter(this, arguments, void 0, function* (targetDate, channel = 'both', log = logger_1.consoleLogger) {
1800
1849
  const startOfDay = new Date(targetDate);
1801
1850
  startOfDay.setHours(0, 0, 0, 0);
1802
1851
  const endOfDay = new Date(targetDate);
@@ -1847,8 +1896,8 @@ const pgClient = (config) => {
1847
1896
  }
1848
1897
  });
1849
1898
  },
1850
- checkEpochProcessed(epochId, channel, log = logger_1.consoleLogger) {
1851
- return __awaiter(this, void 0, void 0, function* () {
1899
+ checkEpochProcessed(epochId_1, channel_1) {
1900
+ return __awaiter(this, arguments, void 0, function* (epochId, channel, log = logger_1.consoleLogger) {
1852
1901
  try {
1853
1902
  const result = yield db
1854
1903
  .selectFrom('epoch')
@@ -1868,8 +1917,8 @@ const pgClient = (config) => {
1868
1917
  }
1869
1918
  });
1870
1919
  },
1871
- checkRecentPaymentActivity(lookbackHours = 2, channel = 'both', log = logger_1.consoleLogger) {
1872
- return __awaiter(this, void 0, void 0, function* () {
1920
+ checkRecentPaymentActivity() {
1921
+ return __awaiter(this, arguments, void 0, function* (lookbackHours = 2, channel = 'both', log = logger_1.consoleLogger) {
1873
1922
  const lookbackTime = new Date(Date.now() - lookbackHours * 60 * 60 * 1000);
1874
1923
  const now = new Date();
1875
1924
  try {