@render-foundation/utils 0.0.232-beta.0 → 0.0.233-beta.0

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.
@@ -58,7 +58,7 @@ const dispersedClient = (cfg, fetchImpl = node_fetch_1.default) => {
58
58
  }),
59
59
  });
60
60
  if (res.status !== 200) {
61
- throw new Error(`dispersed token mint failed. code: ${res.status} body: ${JSON.stringify(yield res.text())}`);
61
+ throw new Error(`dispersed token mint failed. code: ${res.status} body: ${yield res.text()}`);
62
62
  }
63
63
  const json = (yield res.json());
64
64
  cached = {
@@ -1 +1 @@
1
- {"version":3,"file":"dispersed.js","sourceRoot":"","sources":["../../../src/client/dispersed.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dispersed.js","sourceRoot":"","sources":["../../../src/client/dispersed.ts"],"names":[],"mappings":"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"}
@@ -35,7 +35,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
35
35
  return (mod && mod.__esModule) ? mod : { "default": mod };
36
36
  };
37
37
  Object.defineProperty(exports, "__esModule", { value: true });
38
- exports.pgClient = exports.batchFinishedAtMedian = exports.DISPERSED_SETTLEMENT_TABLE = exports.GRANT_BURN_TABLE = exports.GRANT_BURN_ID_TABLE = exports.USER_GRANT_SPEND_TABLE = exports.CURRENT_USER_GRANT_SPEND_TABLE = exports.POLYGON_UPGRADE_TABLE = exports.ENTITY_EPOCH_INFO_TABLE = exports.BURN_ADJUSTMENT_TABLE = exports.NETWORK_REVENUE_TABLE = exports.BRIDGE_TRANSFER_TABLE = exports.BURN_TABLE = exports.JOB_TABLE = exports.JOB_ID_TABLE = exports.LIABILITY_TABLE = exports.SOL_TRANSFER_TABLE = exports.ENTITY_TABLE = exports.MANUAL_BURN_TABLE = exports.EPOCH_TABLE = exports.SOL_TX_TABLE = void 0;
38
+ exports.pgClient = exports.batchFinishedAtMedian = exports.DISPERSED_SETTLEMENT_TABLE = exports.GRANT_BURN_TABLE = exports.GRANT_BURN_ID_TABLE = exports.USER_GRANT_SPEND_TABLE = exports.CURRENT_USER_GRANT_SPEND_TABLE = exports.POLYGON_UPGRADE_TABLE = exports.ENTITY_EPOCH_INFO_TABLE = exports.TX_BURN_ADJUSTMENT_TABLE = exports.JOB_BURN_ADJUSTMENT_TABLE = exports.NETWORK_REVENUE_TABLE = exports.BRIDGE_TRANSFER_TABLE = exports.BURN_TABLE = exports.JOB_TABLE = exports.JOB_ID_TABLE = exports.LIABILITY_ADJUSTMENT_BATCH_TABLE = exports.LIABILITY_ADJUSTMENT_TABLE = exports.LIABILITY_TABLE = exports.SOL_TRANSFER_TABLE = exports.ENTITY_TABLE = exports.MANUAL_BURN_TABLE = exports.EPOCH_TABLE = exports.SOL_TX_TABLE = void 0;
39
39
  const kysely_1 = require("kysely");
40
40
  const logger_1 = require("../../logger");
41
41
  const pg_1 = require("pg");
@@ -47,12 +47,15 @@ exports.MANUAL_BURN_TABLE = 'manual_burn';
47
47
  exports.ENTITY_TABLE = 'entity';
48
48
  exports.SOL_TRANSFER_TABLE = 'sol_transfer1';
49
49
  exports.LIABILITY_TABLE = 'liability';
50
+ exports.LIABILITY_ADJUSTMENT_TABLE = 'liability_adjustment';
51
+ exports.LIABILITY_ADJUSTMENT_BATCH_TABLE = 'liability_adjustment_batch';
50
52
  exports.JOB_ID_TABLE = 'job_id';
51
53
  exports.JOB_TABLE = 'job';
52
54
  exports.BURN_TABLE = 'burn';
53
55
  exports.BRIDGE_TRANSFER_TABLE = 'bridge_transfer';
54
56
  exports.NETWORK_REVENUE_TABLE = 'network_revenue';
55
- exports.BURN_ADJUSTMENT_TABLE = 'burn_adjustment';
57
+ exports.JOB_BURN_ADJUSTMENT_TABLE = 'job_burn_adjustment';
58
+ exports.TX_BURN_ADJUSTMENT_TABLE = 'tx_burn_adjustment';
56
59
  exports.ENTITY_EPOCH_INFO_TABLE = 'entity_epoch_info';
57
60
  exports.POLYGON_UPGRADE_TABLE = 'polygon_upgrade';
58
61
  exports.CURRENT_USER_GRANT_SPEND_TABLE = 'current_user_grant_spend';
@@ -356,7 +359,11 @@ const pgClient = (config) => {
356
359
  sig: solTx,
357
360
  executedAt,
358
361
  }, log);
359
- const { id } = yield db
362
+ // sol_transfer1 already has UNIQUE(sol_tx_id, from_entity_id,
363
+ // to_entity_id, symbol). Without ON CONFLICT a retry of the record step
364
+ // throws a unique violation and wedges the BullMQ job; make it an
365
+ // idempotent no-op and re-fetch the existing id instead.
366
+ let transferRow = yield db
360
367
  .insertInto(exports.SOL_TRANSFER_TABLE)
361
368
  .values({
362
369
  id: dbId,
@@ -367,9 +374,23 @@ const pgClient = (config) => {
367
374
  symbol,
368
375
  amount_payed: amountPayed,
369
376
  })
377
+ .onConflict((oc) => oc
378
+ .columns(['sol_tx_id', 'from_entity_id', 'to_entity_id', 'symbol'])
379
+ .doNothing())
370
380
  .returning((eb) => ['id as id'])
371
- .executeTakeFirstOrThrow();
372
- transferId = BigInt(id);
381
+ .executeTakeFirst();
382
+ if (!transferRow) {
383
+ log.warn(`sol_transfer for sol_tx_id ${solTxId} ${fromEntityId}->${toEntityId} ${symbol} already exists; reusing existing id (idempotent retry)`);
384
+ transferRow = yield db
385
+ .selectFrom(exports.SOL_TRANSFER_TABLE)
386
+ .select((eb) => ['id as id'])
387
+ .where('sol_tx_id', '=', solTxId)
388
+ .where('from_entity_id', '=', fromEntityId)
389
+ .where('to_entity_id', '=', toEntityId)
390
+ .where('symbol', '=', symbol)
391
+ .executeTakeFirstOrThrow();
392
+ }
393
+ transferId = BigInt(transferRow.id);
373
394
  }
374
395
  ids.push({ transferId, liabilityId });
375
396
  }
@@ -691,9 +712,36 @@ const pgClient = (config) => {
691
712
  }
692
713
  return b.as('x');
693
714
  }, (join) => join.onRef('y.sol_key', '=', 'x.sol_key'))
715
+ // Standing per-wallet/channel corrections (migration 36). NO epoch filter — an adjustment is
716
+ // a permanent delta on outstanding, not tied to a payout window; payments net it via `payed`.
717
+ .fullJoin((eb) => {
718
+ let b = eb
719
+ .selectFrom(exports.LIABILITY_ADJUSTMENT_TABLE)
720
+ .select(({ fn }) => fn.sum(`amount_adjustment`).as('adj'))
721
+ .innerJoin(exports.ENTITY_TABLE, `${exports.LIABILITY_ADJUSTMENT_TABLE}.entity_id`, 'entity.id')
722
+ .select(['entity.sol_key'])
723
+ .groupBy('entity.sol_key');
724
+ if (f.banned) {
725
+ b = b.where('entity.banned', '=', true);
726
+ }
727
+ else {
728
+ b = b.where('entity.banned', '=', false);
729
+ }
730
+ if (f.channels && f.channels.length > 0) {
731
+ b = b.where((eb) => eb.or(f.channels.map((c) => eb('liability_adjustment.channel', '=', c))));
732
+ }
733
+ else {
734
+ b = b.where((eb) => eb.or([
735
+ eb('liability_adjustment.channel', '=', 'node_operator'),
736
+ eb('liability_adjustment.channel', '=', 'availability'),
737
+ ]));
738
+ }
739
+ return b.as('a');
740
+ }, (join) => join.on((0, kysely_1.sql) `"a"."sol_key" = coalesce("y"."sol_key", "x"."sol_key")`))
694
741
  .select(({ fn }) => [
695
- fn.coalesce('y.sol_key', 'x.sol_key').as('sol_key'),
696
- (0, kysely_1.sql) `${fn.coalesce(`x.due`, (0, kysely_1.sql) `0`)} -
742
+ fn.coalesce('y.sol_key', 'x.sol_key', 'a.sol_key').as('sol_key'),
743
+ (0, kysely_1.sql) `${fn.coalesce(`x.due`, (0, kysely_1.sql) `0`)} +
744
+ ${fn.coalesce(`a.adj`, (0, kysely_1.sql) `0`)} -
697
745
  ${fn.coalesce(`y.payed`, (0, kysely_1.sql) `0`)}`.as('out'),
698
746
  ])
699
747
  .as('z'))
@@ -714,6 +762,59 @@ const pgClient = (config) => {
714
762
  return out;
715
763
  });
716
764
  },
765
+ addLiabilityAdjustments(batch, rows, log = logger_1.consoleLogger) {
766
+ return __awaiter(this, void 0, void 0, function* () {
767
+ return yield db.transaction().execute((trx) => __awaiter(this, void 0, void 0, function* () {
768
+ var _a;
769
+ // Upsert the batch by its label (idempotent re-runs; label is the run identity).
770
+ const b = yield trx
771
+ .insertInto(exports.LIABILITY_ADJUSTMENT_BATCH_TABLE)
772
+ .values({
773
+ label: batch.label,
774
+ description: batch.description,
775
+ created_by: batch.createdBy,
776
+ })
777
+ .onConflict((oc) => oc.column('label').doUpdateSet({
778
+ description: batch.description,
779
+ created_by: batch.createdBy,
780
+ }))
781
+ .returning('id')
782
+ .executeTakeFirstOrThrow();
783
+ const batchId = BigInt(b.id);
784
+ let inserted = 0;
785
+ let skipped = 0;
786
+ let net = BigInt(0);
787
+ let positive = BigInt(0);
788
+ let negative = BigInt(0);
789
+ for (const r of rows) {
790
+ const entityId = yield getOrInsertEntity(trx, { solKey: r.solKey }, log);
791
+ const res = yield trx
792
+ .insertInto(exports.LIABILITY_ADJUSTMENT_TABLE)
793
+ .values({
794
+ entity_id: entityId,
795
+ channel: r.channel,
796
+ amount_adjustment: r.amountAdjustment,
797
+ batch_id: batchId,
798
+ })
799
+ // unique (entity_id, channel, batch_id) → a re-run of the same batch is a no-op
800
+ .onConflict((oc) => oc.columns(['entity_id', 'channel', 'batch_id']).doNothing())
801
+ .executeTakeFirst();
802
+ if (((_a = res.numInsertedOrUpdatedRows) !== null && _a !== void 0 ? _a : BigInt(0)) > BigInt(0))
803
+ inserted++;
804
+ else
805
+ skipped++;
806
+ net += r.amountAdjustment;
807
+ if (r.amountAdjustment > BigInt(0))
808
+ positive += r.amountAdjustment;
809
+ else
810
+ negative += r.amountAdjustment;
811
+ }
812
+ log.info(`liability_adjustment batch '${batch.label}' (id ${batchId}): ` +
813
+ `inserted ${inserted}, skipped ${skipped}, net ${net} (+${positive} / ${negative})`);
814
+ return { batchId, inserted, skipped, net, positive, negative };
815
+ }));
816
+ });
817
+ },
717
818
  fetchNodeOperatorEpoch(epochId, log = logger_1.consoleLogger) {
718
819
  var _a;
719
820
  return __awaiter(this, void 0, void 0, function* () {
@@ -1024,7 +1125,7 @@ const pgClient = (config) => {
1024
1125
  let buyBurnId;
1025
1126
  let grantBurnId;
1026
1127
  if (p.buyBurn) {
1027
- const { burned, usdcSpent, eurToUsdc, renderToUsdc, quoteAmt, tags, burnAdjustmentId, toBurn, } = p.buyBurn;
1128
+ const { burned, usdcSpent, eurToUsdc, renderToUsdc, quoteAmt, tags, jobBurnAdjustmentId, txBurnAdjustmentId, toBurn, fromEscrowUsdc, } = p.buyBurn;
1028
1129
  let pricedAt = p.buyBurn.pricedAt;
1029
1130
  if (!pricedAt) {
1030
1131
  const jobs = yield fetchJobs1(trx.trx, { ids: p.jobs.map((j) => String(j.id)) }, log);
@@ -1043,17 +1144,30 @@ const pgClient = (config) => {
1043
1144
  quote_amt: quoteAmt,
1044
1145
  burned: burned,
1045
1146
  tags: tags.join(','),
1046
- burn_adjustment_id: burnAdjustmentId,
1147
+ job_burn_adjustment_id: jobBurnAdjustmentId,
1148
+ tx_burn_adjustment_id: txBurnAdjustmentId,
1047
1149
  to_burn: toBurn,
1150
+ from_escrow_usdc: fromEscrowUsdc !== null && fromEscrowUsdc !== void 0 ? fromEscrowUsdc : 0,
1048
1151
  };
1049
1152
  log.debug(`inserting burn ${JSON.stringify(v)}`);
1050
- const { id } = yield trx.trx
1153
+ // Idempotent on sol_tx_id (uniq_burn_sol_tx_id, migration 27): a retry of
1154
+ // the record step for the same on-chain burn is a safe no-op. On conflict
1155
+ // executeTakeFirst() returns undefined, so re-fetch the existing id.
1156
+ let burnRow = yield trx.trx
1051
1157
  .insertInto(exports.BURN_TABLE)
1052
1158
  .values(v)
1053
- //.onConflict((oc) => oc.column('sol_tx').doNothing())
1159
+ .onConflict((oc) => oc.column('sol_tx_id').doNothing())
1054
1160
  .returning((eb) => ['id as id'])
1055
- .executeTakeFirstOrThrow();
1056
- buyBurnId = Number(id);
1161
+ .executeTakeFirst();
1162
+ if (!burnRow) {
1163
+ log.warn(`burn for sol_tx_id ${solTxId} already exists; reusing existing id (idempotent retry)`);
1164
+ burnRow = yield trx.trx
1165
+ .selectFrom(exports.BURN_TABLE)
1166
+ .select((eb) => ['id as id'])
1167
+ .where('sol_tx_id', '=', solTxId)
1168
+ .executeTakeFirstOrThrow();
1169
+ }
1170
+ buyBurnId = Number(burnRow.id);
1057
1171
  }
1058
1172
  if (p.grantBurn) {
1059
1173
  const { burned, tags } = p.grantBurn;
@@ -1063,12 +1177,22 @@ const pgClient = (config) => {
1063
1177
  tags: tags === null || tags === void 0 ? void 0 : tags.join(','),
1064
1178
  };
1065
1179
  log.debug(`inserting grant burn ${JSON.stringify(v)}`);
1066
- const { id } = yield trx.trx
1180
+ // Idempotent on sol_tx_id (uniq_grant_burn_sol_tx_id, migration 27).
1181
+ let grantBurnRow = yield trx.trx
1067
1182
  .insertInto(exports.GRANT_BURN_TABLE)
1068
1183
  .values(v)
1184
+ .onConflict((oc) => oc.column('sol_tx_id').doNothing())
1069
1185
  .returning((eb) => ['id as id'])
1070
- .executeTakeFirstOrThrow();
1071
- grantBurnId = Number(id);
1186
+ .executeTakeFirst();
1187
+ if (!grantBurnRow) {
1188
+ log.warn(`grant_burn for sol_tx_id ${solTxId} already exists; reusing existing id (idempotent retry)`);
1189
+ grantBurnRow = yield trx.trx
1190
+ .selectFrom(exports.GRANT_BURN_TABLE)
1191
+ .select((eb) => ['id as id'])
1192
+ .where('sol_tx_id', '=', solTxId)
1193
+ .executeTakeFirstOrThrow();
1194
+ }
1195
+ grantBurnId = Number(grantBurnRow.id);
1072
1196
  }
1073
1197
  const burnId = buyBurnId;
1074
1198
  const grantId = grantBurnId !== null && grantBurnId !== void 0 ? grantBurnId : buyBurnId;
@@ -1723,46 +1847,90 @@ const pgClient = (config) => {
1723
1847
  }));
1724
1848
  });
1725
1849
  },
1726
- getBurnAdjustments(trx, ps, log = logger_1.consoleLogger) {
1850
+ createTxBurnAdjustment(trx, p, log = logger_1.consoleLogger) {
1727
1851
  return __awaiter(this, void 0, void 0, function* () {
1728
- if (ps.toFill) {
1729
- const q = trx.trx
1730
- .selectFrom(exports.BURN_ADJUSTMENT_TABLE)
1731
- .selectAll(exports.BURN_ADJUSTMENT_TABLE)
1732
- .innerJoin(exports.JOB_TABLE, `${exports.JOB_TABLE}.id`, `${exports.BURN_ADJUSTMENT_TABLE}.job_id`)
1733
- .select([`${exports.JOB_TABLE}.completed_at`, `${exports.JOB_TABLE}.render_amt`])
1734
- .leftJoin(exports.BURN_TABLE, `${exports.BURN_TABLE}.burn_adjustment_id`, `${exports.BURN_ADJUSTMENT_TABLE}.id`)
1735
- .select(({ fn, lit }) => [
1736
- fn
1737
- .sum(fn.coalesce(`${exports.BURN_TABLE}.to_burn`, lit(0)))
1738
- .as('tot_to_burn'),
1739
- fn
1740
- .sum(fn.coalesce(`${exports.BURN_TABLE}.burned`, lit(0)))
1741
- .as('tot_burned'),
1742
- ])
1743
- .groupBy([
1744
- `${exports.BURN_ADJUSTMENT_TABLE}.id`,
1745
- `${exports.JOB_TABLE}.completed_at`,
1746
- `${exports.JOB_TABLE}.render_amt`,
1747
- ])
1748
- .havingRef((0, kysely_1.sql) `SUM(COALESCE("burn"."to_burn", 0)) - SUM(COALESCE("burn"."burned", 0))`, '<', `${exports.BURN_ADJUSTMENT_TABLE}.down_adj_to_burn`);
1749
- log.info(`getBurnAdjustments ${q.compile().sql}`);
1750
- const res = yield q.execute();
1751
- return res.map((r) => ({
1752
- id: Number(r.id),
1753
- createdAt: r.created_at,
1754
- jobId: Number(r.job_id),
1755
- downAdjRndrUsed: Number(r.down_adj_rndr_used),
1756
- downAdjToBurn: Number(r.down_adj_to_burn),
1757
- adjusted: Number(r.tot_to_burn) - Number(r.tot_burned),
1758
- job: {
1759
- id: Number(r.job_id),
1760
- completedAt: r.completed_at,
1761
- rndrUsed: BigInt(r.render_amt),
1762
- },
1763
- }));
1852
+ // Idempotent per sol_tx_id (unique) — a re-run for the same bad tx is a no-op.
1853
+ const row = yield trx.trx
1854
+ .insertInto(exports.TX_BURN_ADJUSTMENT_TABLE)
1855
+ .values({
1856
+ sol_tx_id: p.solTxId,
1857
+ surplus_usdc: p.surplusUsdc,
1858
+ description: p.description,
1859
+ })
1860
+ .onConflict((oc) => oc.column('sol_tx_id').doNothing())
1861
+ .returning('id')
1862
+ .executeTakeFirst();
1863
+ if (!row) {
1864
+ log.info(`tx_burn_adjustment for sol_tx ${p.solTxId} already exists — skipped`);
1865
+ return undefined;
1764
1866
  }
1765
- return [];
1867
+ log.info(`created tx_burn_adjustment ${row.id}: ${p.surplusUsdc} USDC over-spent (sol_tx ${p.solTxId})`);
1868
+ return Number(row.id);
1869
+ });
1870
+ },
1871
+ getJobBurnAdjustments(trx, ps, log = logger_1.consoleLogger) {
1872
+ return __awaiter(this, void 0, void 0, function* () {
1873
+ if (!ps.toFill)
1874
+ return [];
1875
+ const q = trx.trx
1876
+ .selectFrom(exports.JOB_BURN_ADJUSTMENT_TABLE)
1877
+ .selectAll(exports.JOB_BURN_ADJUSTMENT_TABLE)
1878
+ .innerJoin(exports.JOB_TABLE, `${exports.JOB_TABLE}.id`, `${exports.JOB_BURN_ADJUSTMENT_TABLE}.job_id`)
1879
+ .select([`${exports.JOB_TABLE}.completed_at`, `${exports.JOB_TABLE}.render_amt`])
1880
+ .leftJoin(exports.BURN_TABLE, `${exports.BURN_TABLE}.job_burn_adjustment_id`, `${exports.JOB_BURN_ADJUSTMENT_TABLE}.id`)
1881
+ .select(({ fn, lit }) => [
1882
+ fn.sum(fn.coalesce(`${exports.BURN_TABLE}.to_burn`, lit(0))).as('tot_to_burn'),
1883
+ fn.sum(fn.coalesce(`${exports.BURN_TABLE}.burned`, lit(0))).as('tot_burned'),
1884
+ ])
1885
+ .groupBy([
1886
+ `${exports.JOB_BURN_ADJUSTMENT_TABLE}.id`,
1887
+ `${exports.JOB_TABLE}.completed_at`,
1888
+ `${exports.JOB_TABLE}.render_amt`,
1889
+ ]);
1890
+ log.info(`getJobBurnAdjustments ${q.compile().sql}`);
1891
+ const res = yield q.execute();
1892
+ return res
1893
+ .map((r) => ({
1894
+ id: Number(r.id),
1895
+ createdAt: r.created_at,
1896
+ jobId: Number(r.job_id),
1897
+ downAdjRndrUsed: Number(r.down_adj_rndr_used),
1898
+ downAdjToBurn: Number(r.down_adj_to_burn),
1899
+ adjusted: Number(r.tot_to_burn) - Number(r.tot_burned),
1900
+ job: {
1901
+ id: Number(r.job_id),
1902
+ completedAt: r.completed_at,
1903
+ rndrUsed: BigInt(r.render_amt),
1904
+ },
1905
+ }))
1906
+ .filter((a) => a.adjusted < a.downAdjToBurn);
1907
+ });
1908
+ },
1909
+ getTxBurnAdjustments(trx, ps, log = logger_1.consoleLogger) {
1910
+ return __awaiter(this, void 0, void 0, function* () {
1911
+ if (!ps.toFill)
1912
+ return [];
1913
+ const q = trx.trx
1914
+ .selectFrom(exports.TX_BURN_ADJUSTMENT_TABLE)
1915
+ .selectAll(exports.TX_BURN_ADJUSTMENT_TABLE)
1916
+ .leftJoin(exports.BURN_TABLE, `${exports.BURN_TABLE}.tx_burn_adjustment_id`, `${exports.TX_BURN_ADJUSTMENT_TABLE}.id`)
1917
+ .select(({ fn, lit }) => [
1918
+ fn
1919
+ .sum(fn.coalesce(`${exports.BURN_TABLE}.from_escrow_usdc`, lit(0)))
1920
+ .as('tot_from_escrow'),
1921
+ ])
1922
+ .groupBy(`${exports.TX_BURN_ADJUSTMENT_TABLE}.id`);
1923
+ log.info(`getTxBurnAdjustments ${q.compile().sql}`);
1924
+ const res = yield q.execute();
1925
+ return res
1926
+ .map((r) => ({
1927
+ id: Number(r.id),
1928
+ createdAt: r.created_at,
1929
+ solTxId: Number(r.sol_tx_id),
1930
+ surplusUsdc: Number(r.surplus_usdc),
1931
+ consumed: Number(r.tot_from_escrow),
1932
+ }))
1933
+ .filter((a) => a.consumed < a.surplusUsdc);
1766
1934
  });
1767
1935
  },
1768
1936
  insertPolygonUpgrade(db, p, log = logger_1.consoleLogger) {