@render-foundation/utils 0.0.78 → 0.0.79

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 (86) hide show
  1. package/lib/cjs/client/onchain.js +109 -0
  2. package/lib/cjs/client/onchain.js.map +1 -0
  3. package/lib/cjs/client/pg/v1.js +623 -0
  4. package/lib/cjs/client/pg/v1.js.map +1 -0
  5. package/lib/cjs/client/pg/v2.js +840 -0
  6. package/lib/cjs/client/pg/v2.js.map +1 -0
  7. package/lib/cjs/client/pg/v2Client.js +770 -0
  8. package/lib/cjs/client/pg/v2Client.js.map +1 -0
  9. package/lib/cjs/client/price.js +46 -0
  10. package/lib/cjs/client/price.js.map +1 -0
  11. package/lib/cjs/client/render.js +164 -0
  12. package/lib/cjs/client/render.js.map +1 -0
  13. package/lib/cjs/client/squads.js +204 -0
  14. package/lib/cjs/client/squads.js.map +1 -0
  15. package/lib/cjs/client/trade.js +127 -0
  16. package/lib/cjs/client/trade.js.map +1 -0
  17. package/lib/cjs/client/wormhole.js +69 -0
  18. package/lib/cjs/client/wormhole.js.map +1 -0
  19. package/lib/cjs/dbTypes.js +3 -0
  20. package/lib/cjs/dbTypes.js.map +1 -0
  21. package/lib/cjs/dbTypesV2.js +3 -0
  22. package/lib/cjs/dbTypesV2.js.map +1 -0
  23. package/lib/cjs/errorReporter.js +77 -0
  24. package/lib/cjs/errorReporter.js.map +1 -0
  25. package/lib/cjs/index.js +41 -0
  26. package/lib/cjs/index.js.map +1 -0
  27. package/lib/cjs/logger.js +21 -0
  28. package/lib/cjs/logger.js.map +1 -0
  29. package/lib/esm/src/client/onchain.js +100 -0
  30. package/lib/esm/src/client/onchain.js.map +1 -0
  31. package/lib/esm/src/client/pg/v1.js +559 -0
  32. package/lib/esm/src/client/pg/v1.js.map +1 -0
  33. package/lib/esm/src/client/pg/v2.js +774 -0
  34. package/lib/esm/src/client/pg/v2.js.map +1 -0
  35. package/lib/esm/src/client/pg/v2Client.js +710 -0
  36. package/lib/esm/src/client/pg/v2Client.js.map +1 -0
  37. package/lib/esm/src/client/price.js +32 -0
  38. package/lib/esm/src/client/price.js.map +1 -0
  39. package/lib/esm/src/client/render.js +138 -0
  40. package/lib/esm/src/client/render.js.map +1 -0
  41. package/lib/esm/src/client/squads.js +163 -0
  42. package/lib/esm/src/client/squads.js.map +1 -0
  43. package/lib/esm/src/client/trade.js +114 -0
  44. package/lib/esm/src/client/trade.js.map +1 -0
  45. package/lib/esm/src/client/wormhole.js +33 -0
  46. package/lib/esm/src/client/wormhole.js.map +1 -0
  47. package/lib/esm/src/dbTypes.js +2 -0
  48. package/lib/esm/src/dbTypes.js.map +1 -0
  49. package/lib/esm/src/dbTypesV2.js +2 -0
  50. package/lib/esm/src/dbTypesV2.js.map +1 -0
  51. package/lib/esm/src/errorReporter.js +68 -0
  52. package/lib/esm/src/errorReporter.js.map +1 -0
  53. package/lib/esm/src/index.js +12 -0
  54. package/lib/esm/src/index.js.map +1 -0
  55. package/lib/esm/src/logger.js +18 -0
  56. package/lib/esm/src/logger.js.map +1 -0
  57. package/lib/esm/tsconfig.esm.tsbuildinfo +1 -0
  58. package/lib/types/src/client/onchain.d.ts +19 -0
  59. package/lib/types/src/client/onchain.d.ts.map +1 -0
  60. package/lib/types/src/client/pg/v1.d.ts +163 -0
  61. package/lib/types/src/client/pg/v1.d.ts.map +1 -0
  62. package/lib/types/src/client/pg/v2.d.ts +35 -0
  63. package/lib/types/src/client/pg/v2.d.ts.map +1 -0
  64. package/lib/types/src/client/pg/v2Client.d.ts +142 -0
  65. package/lib/types/src/client/pg/v2Client.d.ts.map +1 -0
  66. package/lib/types/src/client/price.d.ts +11 -0
  67. package/lib/types/src/client/price.d.ts.map +1 -0
  68. package/lib/types/src/client/render.d.ts +19 -0
  69. package/lib/types/src/client/render.d.ts.map +1 -0
  70. package/lib/types/src/client/squads.d.ts +17 -0
  71. package/lib/types/src/client/squads.d.ts.map +1 -0
  72. package/lib/types/src/client/trade.d.ts +15 -0
  73. package/lib/types/src/client/trade.d.ts.map +1 -0
  74. package/lib/types/src/client/wormhole.d.ts +9 -0
  75. package/lib/types/src/client/wormhole.d.ts.map +1 -0
  76. package/lib/types/src/dbTypes.d.ts +123 -0
  77. package/lib/types/src/dbTypes.d.ts.map +1 -0
  78. package/lib/types/src/dbTypesV2.d.ts +109 -0
  79. package/lib/types/src/dbTypesV2.d.ts.map +1 -0
  80. package/lib/types/src/errorReporter.d.ts +12 -0
  81. package/lib/types/src/errorReporter.d.ts.map +1 -0
  82. package/lib/types/src/index.d.ts +12 -0
  83. package/lib/types/src/index.d.ts.map +1 -0
  84. package/lib/types/src/logger.d.ts +16 -0
  85. package/lib/types/src/logger.d.ts.map +1 -0
  86. package/package.json +1 -1
@@ -0,0 +1,770 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
12
+ if (kind === "m") throw new TypeError("Private method is not writable");
13
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
14
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
15
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
16
+ };
17
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
18
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
19
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
20
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
21
+ };
22
+ var _Deferred_promise, _Deferred_resolve, _Deferred_reject;
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.Deferred = exports.pgClient = 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;
25
+ const kysely_1 = require("kysely");
26
+ const logger_1 = require("../../logger");
27
+ const pg_1 = require("pg");
28
+ exports.SOL_TX_TABLE = 'sol_tx';
29
+ exports.EPOCH_TABLE = 'epoch';
30
+ exports.MANUAL_BURN_TABLE = 'manual_burn';
31
+ exports.ENTITY_TABLE = 'entity';
32
+ exports.SOL_TRANSFER_TABLE = 'sol_transfer1';
33
+ exports.LIABILITY_TABLE = 'liability';
34
+ exports.JOB_ID_TABLE = 'job_id';
35
+ exports.JOB_TABLE = 'job';
36
+ exports.BURN_TABLE = 'burn';
37
+ BigInt.prototype.toJSON = function () {
38
+ return this.toString();
39
+ };
40
+ const pgClient = (config) => {
41
+ var _a, _b;
42
+ const dialect = new kysely_1.PostgresDialect({
43
+ pool: new pg_1.Pool(Object.assign(Object.assign({}, config), { port: (_a = config.port) !== null && _a !== void 0 ? _a : 5432, max: (_b = config.max) !== null && _b !== void 0 ? _b : 10 })),
44
+ });
45
+ // Database interface is passed to Kysely's constructor, and from now on, Kysely
46
+ // knows your database structure.
47
+ // Dialect is passed to Kysely's constructor, and from now on, Kysely knows how
48
+ // to communicate with your database.
49
+ const db = new kysely_1.Kysely({
50
+ dialect,
51
+ });
52
+ const getOrInsertEntity = (db, p, log = logger_1.consoleLogger) => __awaiter(void 0, void 0, void 0, function* () {
53
+ const res = (yield db
54
+ .selectFrom(exports.ENTITY_TABLE)
55
+ .select('id')
56
+ .where('sol_key', '=', p.solKey)
57
+ .executeTakeFirst());
58
+ if (res) {
59
+ log.debug(`already found entity ${res.id}`);
60
+ return res.id;
61
+ }
62
+ const { id } = (yield db
63
+ .insertInto(exports.ENTITY_TABLE)
64
+ .values({
65
+ sol_key: p.solKey,
66
+ })
67
+ .onConflict((oc) => oc.column('sol_key').doNothing())
68
+ .returning((eb) => ['id as id'])
69
+ .executeTakeFirst());
70
+ log.debug(`inserted entity ${id}`);
71
+ return id;
72
+ });
73
+ const getOrInsertTx = (db, p, log = logger_1.consoleLogger) => __awaiter(void 0, void 0, void 0, function* () {
74
+ const res = yield db
75
+ .selectFrom(exports.SOL_TX_TABLE)
76
+ .select('id')
77
+ .where('sig', '=', p.sig)
78
+ .executeTakeFirst();
79
+ if (res) {
80
+ log.debug(`already found tx ${res.id}`);
81
+ return res.id;
82
+ }
83
+ const { id } = (yield db
84
+ .insertInto(exports.SOL_TX_TABLE)
85
+ .values({
86
+ sig: p.sig,
87
+ executed_at: p.executedAt,
88
+ })
89
+ .onConflict((oc) => oc.column('sig').doNothing())
90
+ .returning((eb) => ['id as id'])
91
+ .executeTakeFirst());
92
+ log.debug(`inserted tx ${id}`);
93
+ return id;
94
+ });
95
+ const getOrInsertEpoch = (db, p, log = logger_1.consoleLogger) => __awaiter(void 0, void 0, void 0, function* () {
96
+ const res = yield db
97
+ .selectFrom(exports.EPOCH_TABLE)
98
+ .select('id')
99
+ .where('ui', '=', String(p.uiEpochId))
100
+ .where('channel', '=', p.channel)
101
+ .executeTakeFirst();
102
+ if (res) {
103
+ log.debug(`already found epoch ${res.id}`);
104
+ return res.id;
105
+ }
106
+ const { id } = (yield db
107
+ .insertInto(exports.EPOCH_TABLE)
108
+ .values({
109
+ ui: p.uiEpochId,
110
+ channel: p.channel,
111
+ start_time: p.startTime,
112
+ end_time: p.endTime,
113
+ saved_at: p.channel == 'node_operator' ? new Date() : undefined,
114
+ })
115
+ .onConflict((oc) => oc.columns(['ui', 'channel']).doNothing())
116
+ .returning((eb) => ['id as id'])
117
+ .executeTakeFirst());
118
+ log.debug(`inserted epoch ${id}`);
119
+ return id;
120
+ });
121
+ const updateTotalRndr = (db, p, totalRndr, savedAt, log) => __awaiter(void 0, void 0, void 0, function* () {
122
+ const res = (yield db
123
+ .updateTable(exports.EPOCH_TABLE)
124
+ .set({
125
+ total_rndr: totalRndr,
126
+ saved_at: savedAt,
127
+ })
128
+ .where('channel', '=', p.channel)
129
+ .where('ui', '=', String(p.uiEpochId))
130
+ .executeTakeFirst());
131
+ log.info(`set ${res.numUpdatedRows} rows. channel: ${p.channel}, ui: ${p.uiEpochId} -> totalRndr ${totalRndr} `);
132
+ });
133
+ const createPayments = (db, ps, log = logger_1.consoleLogger) => __awaiter(void 0, void 0, void 0, function* () {
134
+ const ids = [];
135
+ const epochDbIds = [];
136
+ for (const p of ps) {
137
+ let liabilityId;
138
+ let transferId;
139
+ if (p.liability) {
140
+ let { id: dbId, solKey, channel, epochId, createdAt, amountDue, deviceId, points, } = p.liability;
141
+ try {
142
+ let entityId;
143
+ if (solKey && solKey != '') {
144
+ entityId = yield getOrInsertEntity(db, { solKey });
145
+ }
146
+ const dbEpochId = yield getOrInsertEpoch(db, {
147
+ channel,
148
+ uiEpochId: epochId,
149
+ }, log);
150
+ epochDbIds.push(BigInt(dbEpochId));
151
+ log.debug(`inserting liability ${JSON.stringify(p.liability)}`);
152
+ const { id } = yield db
153
+ .insertInto(exports.LIABILITY_TABLE)
154
+ .values({
155
+ id: dbId,
156
+ entity_id: entityId,
157
+ epoch_id: dbEpochId,
158
+ channel,
159
+ created_at: createdAt !== null && createdAt !== void 0 ? createdAt : new Date(),
160
+ amount_due: amountDue,
161
+ device_id: deviceId,
162
+ points,
163
+ })
164
+ .returning((eb) => ['id as id'])
165
+ .executeTakeFirstOrThrow();
166
+ log.debug(`inserted liability ${id}`);
167
+ liabilityId = BigInt(id);
168
+ }
169
+ catch (e) {
170
+ throw new Error(`failed inserting solKey ${solKey} epochId ${epochId} ${JSON.stringify(p.liability)}: ${e}`);
171
+ }
172
+ }
173
+ if (p.transfer) {
174
+ let { executedAt, symbol, amountPayed, solTx, channel, fromSolKey, toSolKey, id: dbId, } = p.transfer;
175
+ if (!fromSolKey || !toSolKey || !solTx) {
176
+ log.debug(`skipping transfer. one of undefined: fromKey ${fromSolKey} toKey ${toSolKey} tx ${solTx}`);
177
+ continue;
178
+ }
179
+ log.debug(`inserting transfer ${JSON.stringify(p.transfer)}`);
180
+ const fromEntityId = yield getOrInsertEntity(db, { solKey: fromSolKey });
181
+ const toEntityId = yield getOrInsertEntity(db, { solKey: toSolKey });
182
+ const solTxId = yield getOrInsertTx(db, {
183
+ sig: solTx,
184
+ executedAt,
185
+ }, log);
186
+ const { id } = yield db
187
+ .insertInto(exports.SOL_TRANSFER_TABLE)
188
+ .values({
189
+ id: dbId,
190
+ sol_tx_id: solTxId,
191
+ from_entity_id: fromEntityId,
192
+ to_entity_id: toEntityId,
193
+ channel,
194
+ symbol,
195
+ amount_payed: amountPayed,
196
+ })
197
+ .returning((eb) => ['id as id'])
198
+ .executeTakeFirstOrThrow();
199
+ transferId = BigInt(id);
200
+ }
201
+ ids.push({ transferId, liabilityId });
202
+ }
203
+ return { epochDbIds, inserted: ids };
204
+ });
205
+ return {
206
+ db: {
207
+ commit: () => { },
208
+ rollback: () => { },
209
+ trx: db,
210
+ },
211
+ startTransaction() {
212
+ return __awaiter(this, void 0, void 0, function* () {
213
+ return begin(db);
214
+ });
215
+ },
216
+ createPayments(db, ps, log = logger_1.consoleLogger) {
217
+ return __awaiter(this, void 0, void 0, function* () {
218
+ return createPayments(db.trx, ps, log);
219
+ });
220
+ },
221
+ fetchTransfers(db, f) {
222
+ return __awaiter(this, void 0, void 0, function* () {
223
+ let offset = 0;
224
+ if (f.cursor) {
225
+ offset = Number(atob(f.cursor));
226
+ }
227
+ let q = db.trx
228
+ .selectFrom(exports.SOL_TRANSFER_TABLE)
229
+ .selectAll([exports.SOL_TRANSFER_TABLE])
230
+ .innerJoin('sol_tx', 'sol_tx.id', 'sol_transfer1.sol_tx_id')
231
+ .select(['sol_tx.sig', 'sol_tx.executed_at'])
232
+ .innerJoin('entity as f', 'f.id', 'sol_transfer1.from_entity_id')
233
+ .select(['f.sol_key as from_sol_key'])
234
+ .innerJoin('entity as t', 't.id', 'sol_transfer1.to_entity_id')
235
+ .select(['t.sol_key as to_sol_key']);
236
+ if (f.executedAfter) {
237
+ q = q.where('sol_tx.executed_at', '>=', f.executedAfter);
238
+ }
239
+ if (f.executedBefore) {
240
+ q = q.where('sol_tx.executed_at', '<=', f.executedBefore);
241
+ }
242
+ if (f.channel) {
243
+ q = q.where('sol_transfer1.channel', '=', f.channel);
244
+ }
245
+ let limit = 10000;
246
+ if (f.limit) {
247
+ limit = f.limit;
248
+ }
249
+ q = q.limit(limit).orderBy(`${exports.SOL_TRANSFER_TABLE}.id`);
250
+ if (offset) {
251
+ q = q.offset(offset);
252
+ }
253
+ console.log(`fetching transactions ${q.compile().sql} ps ${JSON.stringify(f)}`);
254
+ const rows = yield q.execute();
255
+ const trs = [];
256
+ for (const r of rows) {
257
+ trs.push({
258
+ id: BigInt(r.id),
259
+ fromSolKey: r.from_sol_key,
260
+ toSolKey: r.to_sol_key,
261
+ symbol: r.symbol,
262
+ channel: r.channel,
263
+ solTx: r.sig,
264
+ executedAt: r.executed_at,
265
+ amountPayed: BigInt(r.amount_payed),
266
+ });
267
+ }
268
+ return {
269
+ transfers: trs,
270
+ cursor: trs.length == limit ? btoa(`${trs.length + offset}`) : undefined,
271
+ };
272
+ });
273
+ },
274
+ getLiabilitiesAndTransfers(f, log = logger_1.consoleLogger) {
275
+ return __awaiter(this, void 0, void 0, function* () {
276
+ let lq = db
277
+ .selectFrom(exports.LIABILITY_TABLE)
278
+ .selectAll()
279
+ .innerJoin(exports.ENTITY_TABLE, `${exports.LIABILITY_TABLE}.entity_id`, 'entity.id')
280
+ .select(['entity.sol_key'])
281
+ .innerJoin(exports.EPOCH_TABLE, `${exports.EPOCH_TABLE}.id`, 'liability.epoch_id')
282
+ .select(['epoch.ui', 'epoch.start_time', 'epoch.end_time'])
283
+ .where('entity.sol_key', '=', f.user);
284
+ let tq = db
285
+ .selectFrom(exports.SOL_TRANSFER_TABLE)
286
+ .selectAll()
287
+ .innerJoin(exports.SOL_TX_TABLE, 'sol_tx.id', 'sol_transfer1.sol_tx_id')
288
+ .select(['sol_tx.sig', 'sol_tx.executed_at'])
289
+ .innerJoin(`${exports.ENTITY_TABLE} as t`, `${exports.SOL_TRANSFER_TABLE}.to_entity_id`, 't.id')
290
+ .select(['t.sol_key as to_sol_key'])
291
+ .innerJoin(`${exports.ENTITY_TABLE} as f`, `${exports.SOL_TRANSFER_TABLE}.from_entity_id`, 'f.id')
292
+ .select(['f.sol_key as from_sol_key'])
293
+ .where('t.sol_key', '=', f.user);
294
+ log.info(`fetch liabilities ${lq.compile().sql} ps ${JSON.stringify(f)}`);
295
+ log.info(`fetch transfers ${tq.compile().sql} ps ${JSON.stringify(f)}`);
296
+ const rows = yield Promise.all([lq.execute(), tq.execute()]);
297
+ const epochs = {};
298
+ const liabilities = [];
299
+ for (const l of rows[0]) {
300
+ epochs[`${l.ui}-${l.channel}`] = {
301
+ startTime: l.start_time,
302
+ endTime: l.end_time,
303
+ channel: l.channel,
304
+ ui: Number(l.ui),
305
+ };
306
+ liabilities.push({
307
+ id: BigInt(l.id),
308
+ solKey: l.sol_key,
309
+ epochId: Number(l.ui),
310
+ channel: l.channel,
311
+ createdAt: l.created_at,
312
+ amountDue: BigInt(l.amount_due),
313
+ deviceId: l.device_id,
314
+ points: l.points ? BigInt(l.points) : undefined,
315
+ });
316
+ }
317
+ const transfers = rows[1].map((r) => ({
318
+ id: BigInt(r.id),
319
+ fromSolKey: r.from_sol_key,
320
+ toSolKey: r.to_sol_key,
321
+ symbol: r.symbol,
322
+ channel: r.channel,
323
+ solTx: r.sig,
324
+ executedAt: r.executed_at,
325
+ amountPayed: BigInt(r.amount_payed),
326
+ }));
327
+ return { transfers, liabilities, epochs: Object.values(epochs) };
328
+ });
329
+ },
330
+ getOutstanding(f, log = logger_1.consoleLogger) {
331
+ return __awaiter(this, void 0, void 0, function* () {
332
+ let q = db
333
+ .selectFrom((eb) => eb
334
+ .selectFrom((eb) => {
335
+ let b = eb
336
+ .selectFrom(exports.SOL_TRANSFER_TABLE)
337
+ .select(({ fn }) => fn.sum(`amount_payed`).as('payed'))
338
+ .innerJoin(exports.ENTITY_TABLE, `${exports.SOL_TRANSFER_TABLE}.to_entity_id`, 'entity.id')
339
+ .select(['entity.sol_key'])
340
+ .groupBy('entity.sol_key');
341
+ if (f.banned) {
342
+ b = b.where('entity.banned', '=', true);
343
+ }
344
+ else {
345
+ b = b.where('entity.banned', '=', false);
346
+ }
347
+ if (f.channels && f.channels.length > 0) {
348
+ b = b.where((eb) => eb.or(f.channels.map((c) => eb('sol_transfer1.channel', '=', c))));
349
+ }
350
+ else {
351
+ b = b.where((eb) => eb.or([
352
+ eb('sol_transfer1.channel', '=', 'node_operator'),
353
+ eb('sol_transfer1.channel', '=', 'availability'),
354
+ ]));
355
+ }
356
+ return b.as('y');
357
+ })
358
+ .fullJoin((eb) => {
359
+ let b = eb
360
+ .selectFrom(exports.LIABILITY_TABLE)
361
+ .select(({ fn }) => fn.sum(`amount_due`).as('due'))
362
+ .innerJoin(exports.ENTITY_TABLE, `${exports.LIABILITY_TABLE}.entity_id`, 'entity.id')
363
+ .select(['entity.sol_key'])
364
+ .groupBy('entity.sol_key');
365
+ if (f.banned) {
366
+ b = b.where('entity.banned', '=', true);
367
+ }
368
+ else {
369
+ b = b.where('entity.banned', '=', false);
370
+ }
371
+ if (f.channels && f.channels.length > 0) {
372
+ b = b.where((eb) => eb.or(f.channels.map((c) => eb('liability.channel', '=', c))));
373
+ }
374
+ else {
375
+ b = b.where((eb) => eb.or([
376
+ eb('liability.channel', '=', 'node_operator'),
377
+ eb('liability.channel', '=', 'availability'),
378
+ ]));
379
+ }
380
+ return b.as('x');
381
+ }, (join) => join.onRef('y.sol_key', '=', 'x.sol_key'))
382
+ .select(({ fn }) => [
383
+ fn.coalesce('y.sol_key', 'x.sol_key').as('sol_key'),
384
+ (0, kysely_1.sql) `${fn.coalesce(`x.due`, (0, kysely_1.sql) `0`)} - ${fn.coalesce(`y.payed`, (0, kysely_1.sql) `0`)}`.as('out'),
385
+ ])
386
+ .as('z'))
387
+ .selectAll();
388
+ if (f.due == 'overpayed') {
389
+ q = q.where('out', '<', '0');
390
+ }
391
+ else if (f.due == 'underpayed') {
392
+ q = q.where('out', '>', '0');
393
+ }
394
+ log.info(`${q.compile().sql} ps ${JSON.stringify(f)}`);
395
+ const res = yield q.execute();
396
+ const out = {};
397
+ for (const r of res) {
398
+ out[r.sol_key] = BigInt(r.out);
399
+ }
400
+ return out;
401
+ });
402
+ },
403
+ fetchNodeOperatorEpoch(epochId, log = logger_1.consoleLogger) {
404
+ var _a;
405
+ return __awaiter(this, void 0, void 0, function* () {
406
+ const q = db
407
+ .selectFrom(exports.JOB_ID_TABLE)
408
+ .innerJoin(exports.EPOCH_TABLE, 'epoch.id', 'job_id.epoch_id')
409
+ .leftJoin(exports.MANUAL_BURN_TABLE, 'manual_burn.epoch_id', 'epoch.id')
410
+ .where('epoch.ui', '=', epochId.toString())
411
+ .where('epoch.channel', '=', 'node_operator')
412
+ .select([
413
+ 'job_id.id',
414
+ 'epoch.total_rndr',
415
+ 'epoch.start_time',
416
+ 'epoch.end_time',
417
+ 'manual_burn.burned',
418
+ 'manual_burn.tx_sig',
419
+ ])
420
+ .orderBy('job_id.id asc');
421
+ log.debug(`fetch epoch info q ${q.compile().sql} epochId ${epochId}`);
422
+ const res = yield q.execute();
423
+ if (res.length == 0) {
424
+ throw new Error(`epoch ${epochId} not found`);
425
+ }
426
+ log.debug(`fetchNodeOperatorEpoch -> fetching liablities`);
427
+ const ks = yield db
428
+ .selectFrom(exports.LIABILITY_TABLE)
429
+ .innerJoin(exports.ENTITY_TABLE, 'liability.entity_id', 'entity.id')
430
+ .select(({ fn }) => [(0, kysely_1.sql) `distinct(entity.sol_key)`.as('sol_key')])
431
+ .innerJoin(exports.EPOCH_TABLE, 'liability.epoch_id', 'epoch.id')
432
+ .where('epoch.ui', '=', epochId.toString())
433
+ .where('epoch.channel', '=', 'node_operator')
434
+ .where('liability.channel', '=', 'node_operator')
435
+ .execute();
436
+ log.debug(`fetchNodeOperatorEpoch -> fetched liablities`);
437
+ const solKeys = ks.reduce((r, k) => {
438
+ r[k.sol_key] = {};
439
+ return r;
440
+ }, {});
441
+ return {
442
+ jobIds: res.map((r) => Number(r.id)),
443
+ totalRndr: BigInt(res[0].total_rndr),
444
+ startTime: res[0].start_time,
445
+ endTime: res[0].end_time,
446
+ burned: BigInt((_a = res[0].burned) !== null && _a !== void 0 ? _a : 0),
447
+ burnTx: res[0].tx_sig,
448
+ solKeys,
449
+ };
450
+ });
451
+ },
452
+ getLatestNodeOperatorEpoch(log = logger_1.consoleLogger) {
453
+ var _a;
454
+ return __awaiter(this, void 0, void 0, function* () {
455
+ const now = new Date(Date.now());
456
+ try {
457
+ const res = yield db
458
+ .selectFrom(exports.EPOCH_TABLE)
459
+ .selectAll()
460
+ .where('channel', '=', 'node_operator')
461
+ .where('end_time', '<=', now)
462
+ .where('saved_at', 'is', null)
463
+ .orderBy('end_time asc')
464
+ .limit(1)
465
+ .executeTakeFirstOrThrow();
466
+ return {
467
+ epochId: BigInt(res.ui),
468
+ startedAt: res.start_time,
469
+ endedAt: res.end_time,
470
+ savedAt: (_a = res.saved_at) !== null && _a !== void 0 ? _a : undefined,
471
+ };
472
+ }
473
+ catch (e) {
474
+ if (e instanceof kysely_1.NoResultError) {
475
+ log.info(`no node operator epoch found`);
476
+ return undefined;
477
+ }
478
+ throw e;
479
+ }
480
+ });
481
+ },
482
+ saveNodeOperatorEpoch(epochId, liabilities, jobIds, totalRndr, log = logger_1.consoleLogger) {
483
+ return __awaiter(this, void 0, void 0, function* () {
484
+ yield db
485
+ .transaction()
486
+ .setIsolationLevel('repeatable read')
487
+ .execute((trx) => __awaiter(this, void 0, void 0, function* () {
488
+ const { epochDbIds } = yield createPayments(trx, liabilities.map((l) => ({
489
+ liability: l,
490
+ })), log);
491
+ log.info(`inserted liabilities`);
492
+ for (const id of jobIds) {
493
+ yield trx
494
+ .insertInto(exports.JOB_ID_TABLE)
495
+ .values({
496
+ id: BigInt(id),
497
+ epoch_id: epochDbIds[0],
498
+ })
499
+ .executeTakeFirstOrThrow();
500
+ }
501
+ const now = new Date();
502
+ yield updateTotalRndr(db, { uiEpochId: epochId, channel: 'node_operator' }, totalRndr, now, log);
503
+ log.debug(`saved epoch`);
504
+ /*const now = new Date(Date.now())
505
+ const res = await trx
506
+ .updateTable(EPOCH_TABLE)
507
+ .set({
508
+ saved_at: now,
509
+ total_rndr: totalRndr,
510
+ })
511
+ .where('channel')
512
+ .where('ui', '=', epochId.toString())
513
+ .where('', '=')
514
+ .executeTakeFirstOrThrow()*/
515
+ }));
516
+ return;
517
+ });
518
+ },
519
+ produceBurnedJobs(jobs, log = logger_1.consoleLogger) {
520
+ return __awaiter(this, void 0, void 0, function* () {
521
+ yield db.transaction().execute((trx) => __awaiter(this, void 0, void 0, function* () {
522
+ var _a;
523
+ let num = BigInt(0);
524
+ for (const { amount, completedAt, jobId } of jobs) {
525
+ const res = yield trx
526
+ .insertInto(exports.JOB_TABLE)
527
+ .values({
528
+ id: jobId,
529
+ render_amt: amount,
530
+ completed_at: completedAt,
531
+ inserted_at: new Date(Date.now()),
532
+ })
533
+ .onConflict((oc) => oc.column('id').doNothing())
534
+ .executeTakeFirstOrThrow();
535
+ num += (_a = res.numInsertedOrUpdatedRows) !== null && _a !== void 0 ? _a : BigInt(0);
536
+ }
537
+ log.debug(`inserted ${num} of ${jobs.length} burn jobs`);
538
+ }));
539
+ });
540
+ },
541
+ markJobsBurnt(trx, p, log = logger_1.consoleLogger) {
542
+ return __awaiter(this, void 0, void 0, function* () {
543
+ const solTxId = yield getOrInsertTx(trx, { sig: p.solTx, executedAt: p.executedAt }, log);
544
+ const { id } = yield trx
545
+ .insertInto(exports.BURN_TABLE)
546
+ .values({
547
+ sol_tx_id: solTxId,
548
+ priced_at: p.pricedAt,
549
+ usdc_spent: p.usdcSpent,
550
+ quote_amt: p.quoteAmt,
551
+ burned: p.burned,
552
+ })
553
+ //.onConflict((oc) => oc.column('sol_tx').doNothing())
554
+ .returning((eb) => ['id as id'])
555
+ .executeTakeFirstOrThrow();
556
+ const jobIdsStr = p.jobsIds.map(String);
557
+ const res = yield trx
558
+ .updateTable(exports.JOB_TABLE)
559
+ .where('id', 'in', jobIdsStr)
560
+ .set('burn_id', id)
561
+ .executeTakeFirstOrThrow();
562
+ log.debug(`set burn_id on ${res.numUpdatedRows} jobs`);
563
+ return;
564
+ });
565
+ },
566
+ markJobsBurned(p, log = logger_1.consoleLogger) {
567
+ return __awaiter(this, void 0, void 0, function* () {
568
+ let { markedAt, solTx } = p;
569
+ let res = yield db
570
+ .updateTable(exports.BURN_TABLE)
571
+ .set({ marked_burned_at: markedAt })
572
+ .from(exports.SOL_TX_TABLE)
573
+ .whereRef('burn.sol_tx_id', '=', 'sol_tx.id')
574
+ .where('sol_tx.sig', '=', solTx)
575
+ .executeTakeFirstOrThrow();
576
+ log.debug(`set ${res.numUpdatedRows} ${solTx} -> marked_burned_at ${markedAt.toISOString()}`);
577
+ });
578
+ },
579
+ consumeAndLockBurnJobs(limit, lowerRndrThreshold, upperRndrThreshold, log = logger_1.consoleLogger) {
580
+ return __awaiter(this, void 0, void 0, function* () {
581
+ const trx = yield begin(db);
582
+ const q = trx.trx
583
+ .selectFrom(trx.trx
584
+ .selectFrom(exports.JOB_TABLE)
585
+ .select(({ fn, val, ref }) => [
586
+ 'id',
587
+ fn
588
+ .sum('render_amt')
589
+ .over((ob) => ob.orderBy(`completed_at`, `asc`))
590
+ .as('total'),
591
+ ])
592
+ .where('burn_id', 'is', null)
593
+ .as('t'))
594
+ .select('id')
595
+ .where('total', '>', lowerRndrThreshold)
596
+ .where('total', '<', upperRndrThreshold);
597
+ log.debug(`outstanding jobs q: ${q.compile().sql} ${JSON.stringify({
598
+ limit,
599
+ lowerRndrThreshold,
600
+ upperRndrThreshold,
601
+ })}`);
602
+ const idRs = yield q.execute();
603
+ const ids = idRs.map((x) => x.id);
604
+ log.debug(`${ids.length} candidate jobs for burn. locking up to ${limit} jobs`);
605
+ if (ids.length == 0) {
606
+ return { trx, jobs: [] };
607
+ }
608
+ const rows = yield trx.trx
609
+ .selectFrom(exports.JOB_TABLE)
610
+ .selectAll()
611
+ .where('id', 'in', ids)
612
+ .limit(limit)
613
+ .forUpdate()
614
+ .skipLocked()
615
+ .execute();
616
+ log.debug(`locked ${rows.length} jobs`);
617
+ const jobs = [];
618
+ for (const r of rows) {
619
+ jobs.push({
620
+ id: Number(r.id),
621
+ completedAt: r.completed_at,
622
+ rndrUsed: BigInt(r.render_amt),
623
+ });
624
+ }
625
+ return { trx, jobs };
626
+ });
627
+ },
628
+ incrBuyBurnMetrics(log = logger_1.consoleLogger) {
629
+ var _a;
630
+ return __awaiter(this, void 0, void 0, function* () {
631
+ const res = yield db
632
+ .selectFrom(exports.JOB_TABLE)
633
+ .select('completed_at')
634
+ .orderBy('completed_at asc')
635
+ .where('burn_id', 'is', null)
636
+ .execute();
637
+ if (res.length == 0) {
638
+ return { outstandingJobs: 0 };
639
+ }
640
+ return {
641
+ outstandingJobs: res.length,
642
+ oldestJobFinishedAt: (_a = res[0].completed_at) !== null && _a !== void 0 ? _a : undefined,
643
+ };
644
+ });
645
+ },
646
+ getLiabilitySolKeys(f) {
647
+ return __awaiter(this, void 0, void 0, function* () {
648
+ let q = db
649
+ .selectFrom(exports.LIABILITY_TABLE)
650
+ .innerJoin(exports.ENTITY_TABLE, `${exports.LIABILITY_TABLE}.entity_id`, 'entity.id')
651
+ .select(({ fn }) => [(0, kysely_1.sql) `distinct(entity.sol_key)`.as('sol_key')])
652
+ .where(`${exports.LIABILITY_TABLE}.channel`, '=', f.channel);
653
+ if (f.epoch) {
654
+ q = q.where('liability.epoch_id', '=', db
655
+ .selectFrom('epoch')
656
+ .select('id')
657
+ .where('channel', '=', f.channel)
658
+ .where('ui', '=', String(f.epoch)));
659
+ }
660
+ const ks = yield q.execute();
661
+ const solKeys = {};
662
+ for (const k of ks) {
663
+ solKeys[k.sol_key] = {};
664
+ }
665
+ return solKeys;
666
+ });
667
+ },
668
+ deleteAll(log = logger_1.consoleLogger) {
669
+ return __awaiter(this, void 0, void 0, function* () {
670
+ if (config.database.includes('render')) {
671
+ throw new Error('cannot nuke from deployed database. call from tests only');
672
+ }
673
+ const tx = yield begin(db);
674
+ try {
675
+ const res = yield Promise.all([
676
+ tx.trx
677
+ .deleteFrom(exports.SOL_TX_TABLE)
678
+ .where('id', 'is not', null)
679
+ .executeTakeFirst(),
680
+ tx.trx.deleteFrom(exports.LIABILITY_TABLE).executeTakeFirstOrThrow(),
681
+ tx.trx.deleteFrom(exports.SOL_TRANSFER_TABLE).executeTakeFirstOrThrow(),
682
+ tx.trx
683
+ .deleteFrom(exports.EPOCH_TABLE)
684
+ .where('id', 'is not', null)
685
+ .executeTakeFirst(),
686
+ tx.trx
687
+ .deleteFrom(exports.ENTITY_TABLE)
688
+ .where('id', 'is not', null)
689
+ .executeTakeFirst(),
690
+ tx.trx
691
+ .deleteFrom(exports.MANUAL_BURN_TABLE)
692
+ .where('epoch_id', 'is not', null)
693
+ .executeTakeFirst(),
694
+ tx.trx
695
+ .deleteFrom(exports.JOB_ID_TABLE)
696
+ .where('id', 'is not', null)
697
+ .executeTakeFirst(),
698
+ tx.trx
699
+ .deleteFrom(exports.JOB_TABLE)
700
+ .where('id', 'is not', null)
701
+ .executeTakeFirst(),
702
+ tx.trx
703
+ .deleteFrom(exports.BURN_TABLE)
704
+ .where('id', 'is not', null)
705
+ .executeTakeFirst(),
706
+ ]);
707
+ tx.commit();
708
+ }
709
+ catch (e) {
710
+ log.error(`caught ${e}`);
711
+ tx.rollback();
712
+ }
713
+ });
714
+ },
715
+ };
716
+ };
717
+ exports.pgClient = pgClient;
718
+ function begin(db) {
719
+ return __awaiter(this, void 0, void 0, function* () {
720
+ const connection = new Deferred();
721
+ const result = new Deferred();
722
+ // Do NOT await this line.
723
+ db.transaction()
724
+ .setIsolationLevel('repeatable read')
725
+ .execute((trx) => {
726
+ connection.resolve(trx);
727
+ return result.promise;
728
+ })
729
+ .catch((err) => {
730
+ // Don't do anything here. Just swallow the exception.
731
+ });
732
+ const trx = yield connection.promise;
733
+ return {
734
+ trx,
735
+ commit() {
736
+ result.resolve(null);
737
+ },
738
+ rollback() {
739
+ result.reject(new Error('rollback'));
740
+ },
741
+ };
742
+ });
743
+ }
744
+ class Deferred {
745
+ constructor() {
746
+ _Deferred_promise.set(this, void 0);
747
+ _Deferred_resolve.set(this, void 0);
748
+ _Deferred_reject.set(this, void 0);
749
+ this.resolve = (value) => {
750
+ if (__classPrivateFieldGet(this, _Deferred_resolve, "f")) {
751
+ __classPrivateFieldGet(this, _Deferred_resolve, "f").call(this, value);
752
+ }
753
+ };
754
+ this.reject = (reason) => {
755
+ if (__classPrivateFieldGet(this, _Deferred_reject, "f")) {
756
+ __classPrivateFieldGet(this, _Deferred_reject, "f").call(this, reason);
757
+ }
758
+ };
759
+ __classPrivateFieldSet(this, _Deferred_promise, new Promise((resolve, reject) => {
760
+ __classPrivateFieldSet(this, _Deferred_reject, reject, "f");
761
+ __classPrivateFieldSet(this, _Deferred_resolve, resolve, "f");
762
+ }), "f");
763
+ }
764
+ get promise() {
765
+ return __classPrivateFieldGet(this, _Deferred_promise, "f");
766
+ }
767
+ }
768
+ exports.Deferred = Deferred;
769
+ _Deferred_promise = new WeakMap(), _Deferred_resolve = new WeakMap(), _Deferred_reject = new WeakMap();
770
+ //# sourceMappingURL=v2Client.js.map