@render-foundation/utils 0.0.254 → 0.0.255
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.
- package/lib/cjs/burn/burnCalculations.js +140 -0
- package/lib/cjs/burn/burnCalculations.js.map +1 -0
- package/lib/cjs/client/pg/v2Client.js +168 -97
- package/lib/cjs/client/pg/v2Client.js.map +1 -1
- package/lib/cjs/index.js +4 -2
- package/lib/cjs/index.js.map +1 -1
- package/lib/esm/src/burn/burnCalculations.js +124 -0
- package/lib/esm/src/burn/burnCalculations.js.map +1 -0
- package/lib/esm/src/client/pg/v2Client.js +158 -89
- package/lib/esm/src/client/pg/v2Client.js.map +1 -1
- package/lib/esm/src/index.js +1 -1
- package/lib/esm/src/index.js.map +1 -1
- package/lib/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/lib/types/src/burn/burnCalculations.d.ts +52 -0
- package/lib/types/src/burn/burnCalculations.d.ts.map +1 -0
- package/lib/types/src/client/pg/v2Client.d.ts +62 -11
- package/lib/types/src/client/pg/v2Client.d.ts.map +1 -1
- package/lib/types/src/dbTypesV2.d.ts +3 -0
- package/lib/types/src/dbTypesV2.d.ts.map +1 -1
- package/lib/types/src/index.d.ts +2 -2
- package/lib/types/src/index.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.calculateBurnAmounts = exports.batchFinishedAtMedian = void 0;
|
|
15
|
+
const spl_utils_1 = require("@render-foundation/spl-utils");
|
|
16
|
+
const logger_1 = require("../logger");
|
|
17
|
+
// Utility function copied from cron-server
|
|
18
|
+
const batchFinishedAtMedian = (jobs) => {
|
|
19
|
+
const pricedAt = jobs.length % 2 == 0
|
|
20
|
+
? new Date(Math.trunc((Date.parse(jobs[jobs.length / 2].finishedAt) +
|
|
21
|
+
Date.parse(jobs[jobs.length / 2 - 1].finishedAt)) /
|
|
22
|
+
2))
|
|
23
|
+
: new Date(Date.parse(jobs[Math.floor(jobs.length / 2)].finishedAt));
|
|
24
|
+
return pricedAt;
|
|
25
|
+
};
|
|
26
|
+
exports.batchFinishedAtMedian = batchFinishedAtMedian;
|
|
27
|
+
/**
|
|
28
|
+
* Pure function that calculates burn amounts without side effects
|
|
29
|
+
* This is the core logic extracted from consumeIncrBuyAndBurnRenderPG
|
|
30
|
+
*/
|
|
31
|
+
const calculateBurnAmounts = (input, opts = {
|
|
32
|
+
perpetual: true,
|
|
33
|
+
}, log = logger_1.consoleLogger) => {
|
|
34
|
+
const { jobs, userGrantSpends, burnAdjustments, params, decimals, priceAtDate, eurToUSDC, } = input;
|
|
35
|
+
// Apply grant/buy split logic to jobs
|
|
36
|
+
const processedJobs = jobs.map((j) => {
|
|
37
|
+
const { buyRenderAmt, grantRenderAmt } = j, rest = __rest(j, ["buyRenderAmt", "grantRenderAmt"]);
|
|
38
|
+
return rest;
|
|
39
|
+
}); // Deep copy to avoid mutations
|
|
40
|
+
for (const j of processedJobs) {
|
|
41
|
+
const userGrantSpend = userGrantSpends[j.userId];
|
|
42
|
+
if (userGrantSpend) {
|
|
43
|
+
if (opts.perpetual ||
|
|
44
|
+
userGrantSpend.userGrantSpend.perpetual ||
|
|
45
|
+
j.rndrUsed <= userGrantSpend.currAllot) {
|
|
46
|
+
j.grantRenderAmt = Number(j.rndrUsed);
|
|
47
|
+
log.debug(`job ${j.id} grant split: ${j.rndrUsed}`);
|
|
48
|
+
userGrantSpend.currAllot -= BigInt(j.rndrUsed);
|
|
49
|
+
}
|
|
50
|
+
else if (userGrantSpend.currAllot <= BigInt(0)) {
|
|
51
|
+
log.debug(`job ${j.id} buy split: ${j.rndrUsed}`);
|
|
52
|
+
j.buyRenderAmt = Number(j.rndrUsed);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
log.debug(`job ${j.id} buy + grant split: ${j.rndrUsed} grant: ${Number(userGrantSpend.currAllot)} buy: ${Number(j.rndrUsed) - Number(userGrantSpend.currAllot)}`);
|
|
56
|
+
j.grantRenderAmt = Number(userGrantSpend.currAllot);
|
|
57
|
+
j.buyRenderAmt = Number(j.rndrUsed) - Number(userGrantSpend.currAllot);
|
|
58
|
+
userGrantSpend.currAllot = BigInt(0);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
log.debug(`job ${j.id} no grant split: ${j.rndrUsed}`);
|
|
63
|
+
j.buyRenderAmt = Number(j.rndrUsed);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const totalRenderUsed = processedJobs.reduce((tot, job) => tot + Number(job.rndrUsed.toString()), 0);
|
|
67
|
+
log.debug(`jobs buy + grant split: ${JSON.stringify(processedJobs)}`);
|
|
68
|
+
// Check minimum threshold
|
|
69
|
+
if (totalRenderUsed < (0, spl_utils_1.toBN)(params.minTotalRndrThreshold, decimals).toNumber()) {
|
|
70
|
+
throw new Error(`totalRenderUsed ${totalRenderUsed / Math.pow(10, decimals)} < total threshold ${params.minTotalRndrThreshold}`);
|
|
71
|
+
}
|
|
72
|
+
const totalRenderBuyAndBurn = processedJobs.reduce((tot, job) => { var _a; return tot + Number((_a = job.buyRenderAmt) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
73
|
+
const totalRender = processedJobs.reduce((tot, job) => tot + Number(job.rndrUsed.toString()), 0);
|
|
74
|
+
log.debug(`Burn calculation inputs:`);
|
|
75
|
+
log.debug(` totalRenderUsed: ${totalRenderUsed}`);
|
|
76
|
+
log.debug(` totalRenderBuyAndBurn: ${totalRenderBuyAndBurn}`);
|
|
77
|
+
log.debug(` totalRender: ${totalRender}`);
|
|
78
|
+
log.debug(` priceAtDate: ${priceAtDate}`);
|
|
79
|
+
log.debug(` eurToUSDC: ${eurToUSDC}`);
|
|
80
|
+
const pricedAt = (0, exports.batchFinishedAtMedian)(processedJobs.map((job) => ({
|
|
81
|
+
finishedAt: job.completedAt.toISOString(),
|
|
82
|
+
jobId: job.id,
|
|
83
|
+
rndrUsed: Number(job.rndrUsed.toString()),
|
|
84
|
+
})));
|
|
85
|
+
// Core burn calculation logic
|
|
86
|
+
const toBurn = Math.trunc((totalRender / priceAtDate / 4) * 0.95 * eurToUSDC);
|
|
87
|
+
let renderToBuyAndBurn = Math.trunc((totalRenderBuyAndBurn / totalRender) * toBurn);
|
|
88
|
+
const origRenderToBuyAndBurn = renderToBuyAndBurn;
|
|
89
|
+
log.debug(`Core burn calculation:`);
|
|
90
|
+
log.debug(` toBurn: ${toBurn}`);
|
|
91
|
+
log.debug(` renderToBuyAndBurn: ${renderToBuyAndBurn}`);
|
|
92
|
+
log.debug(` origRenderToBuyAndBurn: ${origRenderToBuyAndBurn}`);
|
|
93
|
+
let burnAdjustmentId = undefined;
|
|
94
|
+
// Apply burn adjustments
|
|
95
|
+
if (burnAdjustments.length > 0) {
|
|
96
|
+
const adjustment = burnAdjustments[0];
|
|
97
|
+
burnAdjustmentId = adjustment.id;
|
|
98
|
+
const adjLeft = adjustment.downAdjToBurn - adjustment.adjusted;
|
|
99
|
+
const minBurnRndrThreshold = (0, spl_utils_1.toBN)(params.minBurnRndrThreshold, decimals).toNumber();
|
|
100
|
+
const available = renderToBuyAndBurn - minBurnRndrThreshold;
|
|
101
|
+
if (adjLeft > available) {
|
|
102
|
+
renderToBuyAndBurn = minBurnRndrThreshold;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
renderToBuyAndBurn -= adjLeft;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Validate burn thresholds
|
|
109
|
+
const toBuyAndBurnUI = renderToBuyAndBurn / Math.pow(10, decimals);
|
|
110
|
+
if (renderToBuyAndBurn != 0) {
|
|
111
|
+
if (toBuyAndBurnUI > params.maxBurnRndrThreshold) {
|
|
112
|
+
throw new Error(`buy and burn RENDER ${toBuyAndBurnUI} too high`);
|
|
113
|
+
}
|
|
114
|
+
if (toBuyAndBurnUI < params.minBurnRndrThreshold) {
|
|
115
|
+
throw new Error(`buy and burn RENDER ${toBuyAndBurnUI} too low < ${params.minBurnRndrThreshold}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const renderToBurnFromEmissions = toBurn - origRenderToBuyAndBurn;
|
|
119
|
+
const totalToBurn = renderToBuyAndBurn + renderToBurnFromEmissions;
|
|
120
|
+
log.debug(`Final burn calculation results:`);
|
|
121
|
+
log.debug(` renderToBuyAndBurn: ${renderToBuyAndBurn}`);
|
|
122
|
+
log.debug(` renderToBurnFromEmissions: ${renderToBurnFromEmissions}`);
|
|
123
|
+
log.debug(` totalToBurn: ${totalToBurn}`);
|
|
124
|
+
log.debug(` toBurn: ${toBurn}`);
|
|
125
|
+
return {
|
|
126
|
+
totalRenderUsed,
|
|
127
|
+
totalRenderBuyAndBurn,
|
|
128
|
+
totalRender,
|
|
129
|
+
renderToBuyAndBurn,
|
|
130
|
+
renderToBurnFromEmissions,
|
|
131
|
+
totalToBurn,
|
|
132
|
+
toBurn,
|
|
133
|
+
origRenderToBuyAndBurn,
|
|
134
|
+
burnAdjustmentId,
|
|
135
|
+
pricedAt,
|
|
136
|
+
processedJobs,
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
exports.calculateBurnAmounts = calculateBurnAmounts;
|
|
140
|
+
//# sourceMappingURL=burnCalculations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"burnCalculations.js","sourceRoot":"","sources":["../../../src/burn/burnCalculations.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.
|
|
38
|
+
exports.pgClient = exports.batchFinishedAtMedian = exports.foldGrantWindow = exports.GRANT_LOOKBACK_MS = exports.GRANT_LOOKBACK_DAYS = exports.CREDIT_DECIMALS = exports.GRANT_WINDOW_START = exports.EUR_TO_CREDITS = exports.DISPERSED_BURN_CORRECTION_TABLE = exports.DISPERSED_SETTLEMENT_TABLE = exports.GRANT_BURN_TABLE = exports.GRANT_BURN_ID_TABLE = exports.OTOY_GRANT_TABLE = exports.USER_GRANT_SPEND_TABLE = exports.CURRENT_USER_GRANT_SPEND_TABLE = exports.POLYGON_UPGRADE_TABLE = exports.ENTITY_EPOCH_INFO_TABLE = exports.BURN_CORRECTION_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");
|
|
@@ -71,36 +71,117 @@ BigInt.prototype.toJSON = function () {
|
|
|
71
71
|
// confirmed_amount = EUR, despite the column name); 1 render credit = EUR 0.25, so credits = EUR x 4.
|
|
72
72
|
// job.render_amt / user_grant_spend.render_spent_delta are credits x 1e8.
|
|
73
73
|
exports.EUR_TO_CREDITS = BigInt(4);
|
|
74
|
+
// Grant accounting window: otoy_grant mirrors OTOY RFG issuances from this date. Consumption against the
|
|
75
|
+
// window counts EVERY job the user ran in it — buy-and-burn jobs consumed OTOY credits exactly like
|
|
76
|
+
// emissions-funded ones (counting only emissions-attributed spend over-issued ~2.58M credits, 2026-08-04).
|
|
77
|
+
exports.GRANT_WINDOW_START = '2025-05-01';
|
|
74
78
|
exports.CREDIT_DECIMALS = BigInt(100000000); // 1e8
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
79
|
+
// A grant is consumable for this long after issuance; whatever is left after that EXPIRES (2026-08-05
|
|
80
|
+
// model change). A job can only draw grants issued within the lookback window before it ran.
|
|
81
|
+
exports.GRANT_LOOKBACK_DAYS = 60;
|
|
82
|
+
exports.GRANT_LOOKBACK_MS = exports.GRANT_LOOKBACK_DAYS * 24 * 3600 * 1000;
|
|
83
|
+
const foldGrantWindow = (events, opts = {}) => {
|
|
84
|
+
var _a, _b, _c;
|
|
85
|
+
const lookback = (_a = opts.lookbackMs) !== null && _a !== void 0 ? _a : exports.GRANT_LOOKBACK_MS;
|
|
86
|
+
const now = (_b = opts.now) !== null && _b !== void 0 ? _b : Date.now();
|
|
87
|
+
const sorted = [...events].sort((a, b) => a.t - b.t || (a.amt > b.amt ? -1 : 1)); // credits first on ties
|
|
88
|
+
const buckets = [];
|
|
89
|
+
const jobs = [];
|
|
90
|
+
const remaining = (b) => b.amount - b.reversed - b.drawnEmissions - b.drawnMisrouted;
|
|
91
|
+
let beyond = BigInt(0);
|
|
92
|
+
for (const e of sorted) {
|
|
93
|
+
if (e.src === 'grant') {
|
|
94
|
+
if (e.amt > BigInt(0)) {
|
|
95
|
+
buckets.push({
|
|
96
|
+
grantId: e.grantId,
|
|
97
|
+
t: e.t,
|
|
98
|
+
amount: e.amt,
|
|
99
|
+
reversed: BigInt(0),
|
|
100
|
+
drawnEmissions: BigInt(0),
|
|
101
|
+
drawnMisrouted: BigInt(0),
|
|
102
|
+
expired: BigInt(0),
|
|
103
|
+
left: BigInt(0),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
let claw = -e.amt; // clawback hits remaining capacity oldest-first; excess is dropped
|
|
108
|
+
for (const b of buckets) {
|
|
109
|
+
if (claw <= BigInt(0))
|
|
110
|
+
break;
|
|
111
|
+
const take = remaining(b) < claw ? remaining(b) : claw;
|
|
112
|
+
if (take > BigInt(0)) {
|
|
113
|
+
b.reversed += take;
|
|
114
|
+
claw -= take;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
let need = -e.amt;
|
|
121
|
+
const total = need;
|
|
122
|
+
let emissionsLeft = (_c = e.emissions) !== null && _c !== void 0 ? _c : need; // no split provided -> count it all as emissions
|
|
123
|
+
let jobEm = BigInt(0);
|
|
124
|
+
let jobMis = BigInt(0);
|
|
125
|
+
for (const b of buckets) {
|
|
126
|
+
if (need <= BigInt(0))
|
|
127
|
+
break;
|
|
128
|
+
if (b.t + lookback < e.t)
|
|
129
|
+
continue; // grant expired before this job ran
|
|
130
|
+
const take = remaining(b) < need ? remaining(b) : need;
|
|
131
|
+
if (take <= BigInt(0))
|
|
132
|
+
continue;
|
|
133
|
+
const em = emissionsLeft < take ? emissionsLeft : take;
|
|
134
|
+
b.drawnEmissions += em;
|
|
135
|
+
b.drawnMisrouted += take - em;
|
|
136
|
+
jobEm += em;
|
|
137
|
+
jobMis += take - em;
|
|
138
|
+
emissionsLeft -= em;
|
|
139
|
+
need -= take;
|
|
140
|
+
}
|
|
141
|
+
beyond += need;
|
|
142
|
+
jobs.push({
|
|
143
|
+
id: e.id,
|
|
144
|
+
t: e.t,
|
|
145
|
+
need: total,
|
|
146
|
+
drawnEmissions: jobEm,
|
|
147
|
+
drawnMisrouted: jobMis,
|
|
148
|
+
beyond: need,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
let avail = BigInt(0);
|
|
153
|
+
let expired = BigInt(0);
|
|
154
|
+
let usedEmissions = BigInt(0);
|
|
155
|
+
let usedMisrouted = BigInt(0);
|
|
93
156
|
let fifoGrantId;
|
|
94
|
-
for (const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
157
|
+
for (const b of buckets) {
|
|
158
|
+
usedEmissions += b.drawnEmissions;
|
|
159
|
+
usedMisrouted += b.drawnMisrouted;
|
|
160
|
+
const rem = remaining(b);
|
|
161
|
+
if (b.t + lookback < now) {
|
|
162
|
+
b.expired = rem;
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
b.left = rem;
|
|
166
|
+
avail += rem;
|
|
167
|
+
if (fifoGrantId === undefined && rem > BigInt(0) && b.grantId !== undefined)
|
|
168
|
+
fifoGrantId = b.grantId;
|
|
98
169
|
}
|
|
99
|
-
|
|
170
|
+
expired += b.expired;
|
|
100
171
|
}
|
|
101
|
-
return {
|
|
172
|
+
return {
|
|
173
|
+
avail,
|
|
174
|
+
beyondGrants: beyond,
|
|
175
|
+
jobCharged: usedEmissions + usedMisrouted,
|
|
176
|
+
usedEmissions,
|
|
177
|
+
usedMisrouted,
|
|
178
|
+
expired,
|
|
179
|
+
buckets,
|
|
180
|
+
jobs,
|
|
181
|
+
fifoGrantId,
|
|
182
|
+
};
|
|
102
183
|
};
|
|
103
|
-
exports.
|
|
184
|
+
exports.foldGrantWindow = foldGrantWindow;
|
|
104
185
|
const base_2 = require("./base");
|
|
105
186
|
const moment_1 = __importDefault(require("moment"));
|
|
106
187
|
pg.types.setTypeParser(1114, (str) => moment_1.default.utc(str).toDate());
|
|
@@ -228,66 +309,54 @@ const pgClient = (config) => {
|
|
|
228
309
|
// Spendable grant per user, straight off otoy_grant (FIFO), net of what's already been spent or
|
|
229
310
|
// already settled by a burn correction. See GrantAllotment for the units + the double-spend guard.
|
|
230
311
|
const getGrantAllotments = (db, p, log = logger_1.consoleLogger) => __awaiter(void 0, void 0, void 0, function* () {
|
|
231
|
-
var _b, _c
|
|
312
|
+
var _b, _c;
|
|
232
313
|
const out = {};
|
|
233
314
|
if (!p.userIds.length)
|
|
234
315
|
return out;
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
.
|
|
258
|
-
.
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
.innerJoin(`${exports.BURN_CORRECTION_TABLE} as bc`, 'bc.job_id', 'j.id')
|
|
264
|
-
.select((eb) => ['j.user_id as user_id', eb.fn.sum('j.render_amt').as('amt')])
|
|
265
|
-
.where('j.user_id', 'in', p.userIds)
|
|
266
|
-
.groupBy('j.user_id')
|
|
267
|
-
.execute();
|
|
268
|
-
const spentBy = new Map(spent.map((r) => { var _a; return [r.user_id, BigInt((_a = r.net) !== null && _a !== void 0 ? _a : 0)]; }));
|
|
269
|
-
const corrBy = new Map(corrected.map((r) => { var _a; return [r.user_id, BigInt((_a = r.amt) !== null && _a !== void 0 ? _a : 0)]; }));
|
|
270
|
-
for (const g of grants) {
|
|
271
|
-
const u = g.user_id;
|
|
272
|
-
const cur = (_b = out[u]) !== null && _b !== void 0 ? _b : (out[u] = { userId: u, granted: BigInt(0), consumed: BigInt(0), avail: BigInt(0), grants: [] });
|
|
273
|
-
// amount_credits is numeric EUR — truncate to whole base units after the x4 conversion
|
|
274
|
-
const credits = (BigInt(Math.round(Number(g.amount_credits) * 1e8)) * exports.EUR_TO_CREDITS);
|
|
275
|
-
cur.granted += credits;
|
|
276
|
-
cur.grants.push({
|
|
277
|
-
id: Number(g.id),
|
|
278
|
-
amountCredits: credits,
|
|
279
|
-
createdAt: g.otoy_created_at ? new Date(g.otoy_created_at) : null,
|
|
316
|
+
// Raw event stream, folded in code (foldGrantWindow — per-grant buckets, 60-day consumable window,
|
|
317
|
+
// reversals clamp capacity, only jobs create beyond-grants). SQL can't express the bucketed clamp.
|
|
318
|
+
const evRes = yield (0, kysely_1.sql) `
|
|
319
|
+
select user_id::text as u, coalesce(otoy_created_at, ${exports.GRANT_WINDOW_START}::timestamp) as t,
|
|
320
|
+
(amount_credits * 4 * 1e8)::numeric::text as amt, 'grant' as src, id as gid
|
|
321
|
+
from otoy_grant where user_id = any(${p.userIds}::uuid[])
|
|
322
|
+
union all
|
|
323
|
+
select user_id::text, ${exports.GRANT_WINDOW_START}::timestamp, sum(render_spent_delta)::text, 'grant', null
|
|
324
|
+
from user_grant_spend
|
|
325
|
+
where user_id = any(${p.userIds}::uuid[]) and render_spent_delta > 0 and otoy_grant_id is null
|
|
326
|
+
group by user_id
|
|
327
|
+
union all
|
|
328
|
+
select user_id::text, created_at, (-render_spent_delta)::text, 'grant', null
|
|
329
|
+
from user_grant_spend
|
|
330
|
+
where user_id = any(${p.userIds}::uuid[]) and render_spent_delta > 0 and otoy_grant_id is not null
|
|
331
|
+
union all
|
|
332
|
+
select user_id, completed_at, (-render_amt)::text, 'job', null
|
|
333
|
+
from job
|
|
334
|
+
where user_id = any(${p.userIds}::text[]) and completed_at >= ${exports.GRANT_WINDOW_START}::timestamp
|
|
335
|
+
`.execute(db); // db is always a Kysely trx at runtime
|
|
336
|
+
const byUser = new Map();
|
|
337
|
+
for (const r of evRes.rows) {
|
|
338
|
+
const arr = (_b = byUser.get(r.u)) !== null && _b !== void 0 ? _b : [];
|
|
339
|
+
arr.push({
|
|
340
|
+
t: new Date(r.t).getTime(),
|
|
341
|
+
amt: BigInt(Math.round(Number(r.amt))),
|
|
342
|
+
src: r.src,
|
|
343
|
+
grantId: (_c = r.gid) !== null && _c !== void 0 ? _c : undefined,
|
|
280
344
|
});
|
|
345
|
+
byUser.set(r.u, arr);
|
|
281
346
|
}
|
|
282
|
-
for (const u of
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
347
|
+
for (const [u, events] of byUser) {
|
|
348
|
+
const f = (0, exports.foldGrantWindow)(events);
|
|
349
|
+
out[u] = {
|
|
350
|
+
userId: u,
|
|
351
|
+
granted: events.reduce((a, e) => (e.src === 'grant' && e.amt > BigInt(0) ? a + e.amt : a), BigInt(0)),
|
|
352
|
+
consumed: f.jobCharged,
|
|
353
|
+
avail: f.avail,
|
|
354
|
+
expired: f.expired,
|
|
355
|
+
fifoGrantId: f.fifoGrantId,
|
|
356
|
+
};
|
|
357
|
+
if (f.beyondGrants > BigInt(0)) {
|
|
358
|
+
log.info(`grant allotment ${u}: ${f.beyondGrants} beyond grants (purchase-paid at the time), ` +
|
|
359
|
+
`${f.expired} expired past the ${exports.GRANT_LOOKBACK_DAYS}d window — avail ${f.avail}`);
|
|
291
360
|
}
|
|
292
361
|
}
|
|
293
362
|
return out;
|
|
@@ -372,7 +441,7 @@ const pgClient = (config) => {
|
|
|
372
441
|
const sequenceNumbers = [];
|
|
373
442
|
const dbEpochIds = [];
|
|
374
443
|
for (const bt of bts) {
|
|
375
|
-
let { solKey: toSolKey, seq, createdAt, amount, upgradeBracket, priorSupply, points, epochId, } = bt;
|
|
444
|
+
let { solKey: toSolKey, seq, createdAt, amount, upgradeBracket, priorSupply, points, epochId, sender, } = bt;
|
|
376
445
|
let entityId;
|
|
377
446
|
if (toSolKey && toSolKey != '') {
|
|
378
447
|
entityId = yield getOrInsertEntity(db, { solKey: toSolKey });
|
|
@@ -393,6 +462,7 @@ const pgClient = (config) => {
|
|
|
393
462
|
prior_supply: priorSupply,
|
|
394
463
|
points: points,
|
|
395
464
|
epoch_id: dbEpochId,
|
|
465
|
+
sender: sender,
|
|
396
466
|
})
|
|
397
467
|
.onConflict((oc) => oc.column('sequence').doUpdateSet({
|
|
398
468
|
created_at: createdAt,
|
|
@@ -402,6 +472,7 @@ const pgClient = (config) => {
|
|
|
402
472
|
points: points,
|
|
403
473
|
epoch_id: dbEpochId,
|
|
404
474
|
entity_id: entityId,
|
|
475
|
+
sender: sender,
|
|
405
476
|
}))
|
|
406
477
|
.returning('sequence');
|
|
407
478
|
const c = q.compile();
|
|
@@ -1156,7 +1227,7 @@ const pgClient = (config) => {
|
|
|
1156
1227
|
});
|
|
1157
1228
|
},
|
|
1158
1229
|
insertGrantSpend(db, p, log = logger_1.consoleLogger) {
|
|
1159
|
-
var _a, _b, _c;
|
|
1230
|
+
var _a, _b, _c, _d;
|
|
1160
1231
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1161
1232
|
const existing = yield getCurrentUserGrantSpend(db.trx, { userId: p.userId }, log);
|
|
1162
1233
|
const diff = {
|
|
@@ -1183,16 +1254,13 @@ const pgClient = (config) => {
|
|
|
1183
1254
|
return;
|
|
1184
1255
|
}
|
|
1185
1256
|
}
|
|
1186
|
-
// FIFO-attribute this spend to the user's oldest OTOY grant that still has room
|
|
1187
|
-
//
|
|
1188
|
-
// would leave the grant looking unspent
|
|
1257
|
+
// FIFO-attribute this spend to the user's oldest LIVE OTOY grant that still has room (the fold
|
|
1258
|
+
// already applies the lookback window). Stamping otoy_grant_id is what shows the draw in the
|
|
1259
|
+
// admin drill-down — an unattributed row would leave the grant looking unspent there.
|
|
1189
1260
|
let otoyGrantId = p.otoyGrantId;
|
|
1190
1261
|
if (otoyGrantId === undefined && p.renderSpentDelta < BigInt(0)) {
|
|
1191
1262
|
const allots = yield getGrantAllotments(db.trx, { userIds: [p.userId] }, log);
|
|
1192
|
-
|
|
1193
|
-
if (a) {
|
|
1194
|
-
otoyGrantId = (0, exports.foldGrantAllotment)(a.grants, a.consumed, BigInt(0)).fifoGrantId;
|
|
1195
|
-
}
|
|
1263
|
+
otoyGrantId = (_c = allots[p.userId]) === null || _c === void 0 ? void 0 : _c.fifoGrantId;
|
|
1196
1264
|
}
|
|
1197
1265
|
const v = {
|
|
1198
1266
|
user_id: p.userId,
|
|
@@ -1218,7 +1286,7 @@ const pgClient = (config) => {
|
|
|
1218
1286
|
user_id: p.userId,
|
|
1219
1287
|
render_spent: p.renderSpentDelta,
|
|
1220
1288
|
description: p.description,
|
|
1221
|
-
perpetual: (
|
|
1289
|
+
perpetual: (_d = p.perpetual) !== null && _d !== void 0 ? _d : false,
|
|
1222
1290
|
})
|
|
1223
1291
|
.onConflict((oc) => oc.column('user_id').doUpdateSet(diff))
|
|
1224
1292
|
.returning((eb) => [
|
|
@@ -1490,7 +1558,7 @@ const pgClient = (config) => {
|
|
|
1490
1558
|
});
|
|
1491
1559
|
},
|
|
1492
1560
|
fetchBurns(db, f, log = logger_1.consoleLogger) {
|
|
1493
|
-
var _a, _b;
|
|
1561
|
+
var _a, _b, _c;
|
|
1494
1562
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1495
1563
|
let q = db.trx
|
|
1496
1564
|
.selectFrom('burn')
|
|
@@ -1538,6 +1606,7 @@ const pgClient = (config) => {
|
|
|
1538
1606
|
eurToUsdc: r.eur_to_usdc,
|
|
1539
1607
|
markedBurnedAt: r.marked_burned_at,
|
|
1540
1608
|
tags: r.tags ? r.tags.split(',') : [],
|
|
1609
|
+
fromEscrowUsdc: BigInt((_c = r.from_escrow_usdc) !== null && _c !== void 0 ? _c : 0),
|
|
1541
1610
|
});
|
|
1542
1611
|
burnIdToIdx[r.id] = burns.length - 1;
|
|
1543
1612
|
}
|
|
@@ -1717,8 +1786,8 @@ const pgClient = (config) => {
|
|
|
1717
1786
|
.innerJoin('sol_tx', 'sol_tx.id', 'burn.sol_tx_id')
|
|
1718
1787
|
.select(({ fn }) => [
|
|
1719
1788
|
dayExpr.as('day'),
|
|
1720
|
-
|
|
1721
|
-
|
|
1789
|
+
(0, kysely_1.sql) `SUM(CASE WHEN burn.burned > 0 THEN burn.burned WHEN COALESCE(burn.from_escrow_usdc, 0) > 0 AND burn.render_to_usdc > 0 THEN (burn.from_escrow_usdc::numeric / burn.render_to_usdc * 100)::bigint ELSE 0 END)`.as('render_burned'),
|
|
1790
|
+
(0, kysely_1.sql) `SUM(CASE WHEN burn.usdc_spent > 0 THEN burn.usdc_spent ELSE COALESCE(burn.from_escrow_usdc, 0) END)`.as('usdc_spent'),
|
|
1722
1791
|
fn.count('burn.id').as('burn_count'),
|
|
1723
1792
|
])
|
|
1724
1793
|
.groupBy((0, kysely_1.sql) `date_trunc('day', sol_tx.executed_at)`)
|
|
@@ -2026,7 +2095,7 @@ const pgClient = (config) => {
|
|
|
2026
2095
|
// took the room), the whole txn rolls back and we return {inserted:false} — the caller must NOT
|
|
2027
2096
|
// broadcast (no row, no counter change, no burn).
|
|
2028
2097
|
return yield db.transaction().execute((trx) => __awaiter(this, void 0, void 0, function* () {
|
|
2029
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
2098
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
2030
2099
|
const res = yield trx
|
|
2031
2100
|
.insertInto(exports.DISPERSED_SETTLEMENT_TABLE)
|
|
2032
2101
|
.values({
|
|
@@ -2041,10 +2110,12 @@ const pgClient = (config) => {
|
|
|
2041
2110
|
usdc_spent: (_c = p.usdcSpent) !== null && _c !== void 0 ? _c : null,
|
|
2042
2111
|
correction_id: (_d = p.correctionId) !== null && _d !== void 0 ? _d : null,
|
|
2043
2112
|
correction_render: (_e = p.correctionRender) !== null && _e !== void 0 ? _e : null,
|
|
2113
|
+
usage_from: (_f = p.usageFrom) !== null && _f !== void 0 ? _f : null,
|
|
2114
|
+
usage_to: (_g = p.usageTo) !== null && _g !== void 0 ? _g : null,
|
|
2044
2115
|
})
|
|
2045
2116
|
.onConflict((oc) => oc.column('tx_signature').doNothing())
|
|
2046
2117
|
.executeTakeFirst();
|
|
2047
|
-
const inserted = ((
|
|
2118
|
+
const inserted = ((_h = res.numInsertedOrUpdatedRows) !== null && _h !== void 0 ? _h : BigInt(0)) > BigInt(0);
|
|
2048
2119
|
// Only reserve when the row was actually inserted (a tx_signature conflict is a no-op → no double
|
|
2049
2120
|
// count) and it drew a correction.
|
|
2050
2121
|
if (inserted &&
|
|
@@ -2059,7 +2130,7 @@ const pgClient = (config) => {
|
|
|
2059
2130
|
.where('id', '=', String(p.correctionId))
|
|
2060
2131
|
.where((eb) => eb((0, kysely_1.sql) `consumed_render + ${p.correctionRender}::numeric`, '<=', eb.ref('amount_render')))
|
|
2061
2132
|
.executeTakeFirst();
|
|
2062
|
-
if (((
|
|
2133
|
+
if (((_j = upd.numUpdatedRows) !== null && _j !== void 0 ? _j : BigInt(0)) === BigInt(0)) {
|
|
2063
2134
|
// Would exceed amount_render (concurrent draw won the room) — roll back the whole txn.
|
|
2064
2135
|
log.warn(`dispersed correction ${p.correctionId}: draw ${p.correctionRender} would over-consume; rejecting outbox insert for tx ${p.txSignature}`);
|
|
2065
2136
|
throw new DispersedCorrectionRejected();
|