@the-situation/indexer 0.17.0 → 0.18.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.
- package/README.md +43 -4
- package/dist/aggregator/cohort.d.ts +30 -0
- package/dist/aggregator/cohort.d.ts.map +1 -0
- package/dist/aggregator/cohort.js +153 -0
- package/dist/aggregator/cohort.js.map +1 -0
- package/dist/aggregator/daily.d.ts +71 -0
- package/dist/aggregator/daily.d.ts.map +1 -0
- package/dist/aggregator/daily.js +249 -0
- package/dist/aggregator/daily.js.map +1 -0
- package/dist/aggregator/domains.d.ts +20 -0
- package/dist/aggregator/domains.d.ts.map +1 -0
- package/dist/aggregator/domains.js +38 -0
- package/dist/aggregator/domains.js.map +1 -0
- package/dist/aggregator/index.d.ts +31 -0
- package/dist/aggregator/index.d.ts.map +1 -0
- package/dist/aggregator/index.js +100 -0
- package/dist/aggregator/index.js.map +1 -0
- package/dist/aggregator/lifetime.d.ts +52 -0
- package/dist/aggregator/lifetime.d.ts.map +1 -0
- package/dist/aggregator/lifetime.js +222 -0
- package/dist/aggregator/lifetime.js.map +1 -0
- package/dist/aggregator/roi.d.ts +42 -0
- package/dist/aggregator/roi.d.ts.map +1 -0
- package/dist/aggregator/roi.js +153 -0
- package/dist/aggregator/roi.js.map +1 -0
- package/dist/aggregator/sources.d.ts +59 -0
- package/dist/aggregator/sources.d.ts.map +1 -0
- package/dist/aggregator/sources.js +53 -0
- package/dist/aggregator/sources.js.map +1 -0
- package/dist/aggregator/writers.d.ts +22 -0
- package/dist/aggregator/writers.d.ts.map +1 -0
- package/dist/aggregator/writers.js +147 -0
- package/dist/aggregator/writers.js.map +1 -0
- package/dist/api/app.d.ts +177 -13
- package/dist/api/app.d.ts.map +1 -1
- package/dist/api/app.js +4 -3
- package/dist/api/app.js.map +1 -1
- package/dist/api/routes/admin-subscriptions.d.ts +11 -11
- package/dist/api/routes/analytics.d.ts +205 -0
- package/dist/api/routes/analytics.d.ts.map +1 -0
- package/dist/api/routes/analytics.js +122 -0
- package/dist/api/routes/analytics.js.map +1 -0
- package/dist/api/routes/health.d.ts.map +1 -1
- package/dist/api/routes/health.js +2 -0
- package/dist/api/routes/health.js.map +1 -1
- package/dist/api/routes/index.d.ts +1 -0
- package/dist/api/routes/index.d.ts.map +1 -1
- package/dist/api/routes/index.js +1 -0
- package/dist/api/routes/index.js.map +1 -1
- package/dist/api/routes/rankings.d.ts +17 -3
- package/dist/api/routes/rankings.d.ts.map +1 -1
- package/dist/api/routes/rankings.js +44 -5
- package/dist/api/routes/rankings.js.map +1 -1
- package/dist/api/routes/trader-stats.d.ts +11 -2
- package/dist/api/routes/trader-stats.d.ts.map +1 -1
- package/dist/api/routes/trader-stats.js +72 -2
- package/dist/api/routes/trader-stats.js.map +1 -1
- package/dist/client/IndexerClient.d.ts +30 -1
- package/dist/client/IndexerClient.d.ts.map +1 -1
- package/dist/client/IndexerClient.js.map +1 -1
- package/dist/client/IndexerClientLive.d.ts.map +1 -1
- package/dist/client/IndexerClientLive.js +50 -1
- package/dist/client/IndexerClientLive.js.map +1 -1
- package/dist/client/convenience.d.ts +9 -2
- package/dist/client/convenience.d.ts.map +1 -1
- package/dist/client/convenience.js +9 -1
- package/dist/client/convenience.js.map +1 -1
- package/dist/client/index.d.ts +3 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/config.d.ts +17 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +39 -3
- package/dist/config.js.map +1 -1
- package/dist/etl/event-indexer.d.ts +1 -1
- package/dist/etl/lp-position-refresher.d.ts +2 -1
- package/dist/etl/lp-position-refresher.d.ts.map +1 -1
- package/dist/etl/lp-position-refresher.js +24 -11
- package/dist/etl/lp-position-refresher.js.map +1 -1
- package/dist/index.js +64 -8
- package/dist/index.js.map +1 -1
- package/dist/layers/ChainReaderLive.d.ts.map +1 -1
- package/dist/layers/ChainReaderLive.js +15 -0
- package/dist/layers/ChainReaderLive.js.map +1 -1
- package/dist/layers/VoyagerClientLive.d.ts +2 -1
- package/dist/layers/VoyagerClientLive.d.ts.map +1 -1
- package/dist/layers/VoyagerClientLive.js +89 -55
- package/dist/layers/VoyagerClientLive.js.map +1 -1
- package/dist/services/ChainReader.d.ts +10 -0
- package/dist/services/ChainReader.d.ts.map +1 -1
- package/dist/services/ChainReader.js.map +1 -1
- package/dist/services/VoyagerRateLimit.d.ts +11 -8
- package/dist/services/VoyagerRateLimit.d.ts.map +1 -1
- package/dist/services/VoyagerRateLimit.js +51 -26
- package/dist/services/VoyagerRateLimit.js.map +1 -1
- package/dist/types/analytics.d.ts +194 -0
- package/dist/types/analytics.d.ts.map +1 -0
- package/dist/types/analytics.js +10 -0
- package/dist/types/analytics.js.map +1 -0
- package/dist/types/api.d.ts +2 -0
- package/dist/types/api.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/warehouse/analytics-helpers.d.ts +36 -0
- package/dist/warehouse/analytics-helpers.d.ts.map +1 -0
- package/dist/warehouse/analytics-helpers.js +142 -0
- package/dist/warehouse/analytics-helpers.js.map +1 -0
- package/dist/warehouse/backfill.d.ts +26 -0
- package/dist/warehouse/backfill.d.ts.map +1 -0
- package/dist/warehouse/backfill.js +77 -0
- package/dist/warehouse/backfill.js.map +1 -0
- package/dist/warehouse/connection.d.ts +18 -0
- package/dist/warehouse/connection.d.ts.map +1 -0
- package/dist/warehouse/connection.js +24 -0
- package/dist/warehouse/connection.js.map +1 -0
- package/dist/warehouse/index.d.ts +14 -0
- package/dist/warehouse/index.d.ts.map +1 -0
- package/dist/warehouse/index.js +14 -0
- package/dist/warehouse/index.js.map +1 -0
- package/dist/warehouse/repositories/analytics.d.ts +61 -0
- package/dist/warehouse/repositories/analytics.d.ts.map +1 -0
- package/dist/warehouse/repositories/analytics.js +418 -0
- package/dist/warehouse/repositories/analytics.js.map +1 -0
- package/dist/warehouse/schema.d.ts +9 -0
- package/dist/warehouse/schema.d.ts.map +1 -0
- package/dist/warehouse/schema.js +219 -0
- package/dist/warehouse/schema.js.map +1 -0
- package/dist/warehouse/seed-domains.d.ts +29 -0
- package/dist/warehouse/seed-domains.d.ts.map +1 -0
- package/dist/warehouse/seed-domains.js +223 -0
- package/dist/warehouse/seed-domains.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Histogram bucket boundaries in percent. The last bucket is [200, +Inf).
|
|
3
|
+
* The first is (-Inf, -100]. Centered on 0 with finer granularity near it.
|
|
4
|
+
*/
|
|
5
|
+
const BUCKET_BOUNDARIES = [
|
|
6
|
+
-Infinity,
|
|
7
|
+
-100,
|
|
8
|
+
-75,
|
|
9
|
+
-50,
|
|
10
|
+
-25,
|
|
11
|
+
-10,
|
|
12
|
+
0,
|
|
13
|
+
10,
|
|
14
|
+
25,
|
|
15
|
+
50,
|
|
16
|
+
75,
|
|
17
|
+
100,
|
|
18
|
+
200,
|
|
19
|
+
Infinity,
|
|
20
|
+
];
|
|
21
|
+
function bucketIndexFor(roiPct) {
|
|
22
|
+
for (let i = 0; i < BUCKET_BOUNDARIES.length - 1; i++) {
|
|
23
|
+
const lo = BUCKET_BOUNDARIES[i] ?? -Infinity;
|
|
24
|
+
const hi = BUCKET_BOUNDARIES[i + 1] ?? Infinity;
|
|
25
|
+
if (roiPct >= lo && roiPct < hi)
|
|
26
|
+
return i;
|
|
27
|
+
}
|
|
28
|
+
return BUCKET_BOUNDARIES.length - 2;
|
|
29
|
+
}
|
|
30
|
+
function percentile(sorted, p) {
|
|
31
|
+
if (sorted.length === 0)
|
|
32
|
+
return null;
|
|
33
|
+
const idx = (sorted.length - 1) * p;
|
|
34
|
+
const lo = Math.floor(idx);
|
|
35
|
+
const hi = Math.ceil(idx);
|
|
36
|
+
if (lo === hi)
|
|
37
|
+
return sorted[lo] ?? null;
|
|
38
|
+
const a = sorted[lo];
|
|
39
|
+
const b = sorted[hi];
|
|
40
|
+
if (a == null || b == null)
|
|
41
|
+
return null;
|
|
42
|
+
return a + (b - a) * (idx - lo);
|
|
43
|
+
}
|
|
44
|
+
export function buildRoi(traderLifetime, lpLifetime) {
|
|
45
|
+
// For traders: domain attribution is via domains_json (every domain touched).
|
|
46
|
+
// For LPs: same idea, via lp domains_json.
|
|
47
|
+
const traderRoiByDomain = new Map();
|
|
48
|
+
traderRoiByDomain.set('all', []);
|
|
49
|
+
for (const t of traderLifetime) {
|
|
50
|
+
if (t.roi_pct == null)
|
|
51
|
+
continue;
|
|
52
|
+
traderRoiByDomain.get('all').push(t.roi_pct);
|
|
53
|
+
for (const d of t.domains_json) {
|
|
54
|
+
let arr = traderRoiByDomain.get(d);
|
|
55
|
+
if (!arr) {
|
|
56
|
+
arr = [];
|
|
57
|
+
traderRoiByDomain.set(d, arr);
|
|
58
|
+
}
|
|
59
|
+
arr.push(t.roi_pct);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const lpRoiByDomain = new Map();
|
|
63
|
+
lpRoiByDomain.set('all', []);
|
|
64
|
+
for (const l of lpLifetime) {
|
|
65
|
+
if (l.roi_pct == null)
|
|
66
|
+
continue;
|
|
67
|
+
lpRoiByDomain.get('all').push(l.roi_pct);
|
|
68
|
+
for (const d of l.domains_json) {
|
|
69
|
+
let arr = lpRoiByDomain.get(d);
|
|
70
|
+
if (!arr) {
|
|
71
|
+
arr = [];
|
|
72
|
+
lpRoiByDomain.set(d, arr);
|
|
73
|
+
}
|
|
74
|
+
arr.push(l.roi_pct);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const distribution = [];
|
|
78
|
+
const summary = [];
|
|
79
|
+
function emitForBucket(domain, entityType, values) {
|
|
80
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
81
|
+
const total = sorted.length;
|
|
82
|
+
const positive = sorted.filter((v) => v > 0).length;
|
|
83
|
+
const positivePct = total > 0 ? (positive / total) * 100 : 0;
|
|
84
|
+
const mean = total > 0 ? sorted.reduce((s, v) => s + v, 0) / total : null;
|
|
85
|
+
summary.push({
|
|
86
|
+
domain_slug: domain,
|
|
87
|
+
entity_type: entityType,
|
|
88
|
+
total_users: total,
|
|
89
|
+
positive_roi_users: positive,
|
|
90
|
+
positive_roi_pct: positivePct,
|
|
91
|
+
median_roi_pct: percentile(sorted, 0.5),
|
|
92
|
+
p25_roi_pct: percentile(sorted, 0.25),
|
|
93
|
+
p75_roi_pct: percentile(sorted, 0.75),
|
|
94
|
+
p90_roi_pct: percentile(sorted, 0.9),
|
|
95
|
+
mean_roi_pct: mean,
|
|
96
|
+
});
|
|
97
|
+
// Histogram
|
|
98
|
+
const counts = new Array(BUCKET_BOUNDARIES.length - 1).fill(0);
|
|
99
|
+
for (const v of sorted) {
|
|
100
|
+
counts[bucketIndexFor(v)] += 1;
|
|
101
|
+
}
|
|
102
|
+
for (let i = 0; i < counts.length; i++) {
|
|
103
|
+
distribution.push({
|
|
104
|
+
domain_slug: domain,
|
|
105
|
+
entity_type: entityType,
|
|
106
|
+
bucket_index: i,
|
|
107
|
+
bucket_lower_pct: BUCKET_BOUNDARIES[i] ?? -Infinity,
|
|
108
|
+
bucket_upper_pct: BUCKET_BOUNDARIES[i + 1] ?? Infinity,
|
|
109
|
+
user_count: counts[i],
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
for (const [domain, values] of traderRoiByDomain) {
|
|
114
|
+
emitForBucket(domain, 'trader', values);
|
|
115
|
+
}
|
|
116
|
+
for (const [domain, values] of lpRoiByDomain) {
|
|
117
|
+
emitForBucket(domain, 'lp', values);
|
|
118
|
+
}
|
|
119
|
+
return { distribution, summary };
|
|
120
|
+
}
|
|
121
|
+
export async function writeRoi(pg, out) {
|
|
122
|
+
await pg.begin(async (tx) => {
|
|
123
|
+
await tx `TRUNCATE TABLE roi_distribution`;
|
|
124
|
+
for (const r of out.distribution) {
|
|
125
|
+
const lower = Number.isFinite(r.bucket_lower_pct) ? r.bucket_lower_pct : -1e9;
|
|
126
|
+
const upper = Number.isFinite(r.bucket_upper_pct) ? r.bucket_upper_pct : 1e9;
|
|
127
|
+
await tx `
|
|
128
|
+
INSERT INTO roi_distribution
|
|
129
|
+
(domain_slug, entity_type, bucket_index, bucket_lower_pct,
|
|
130
|
+
bucket_upper_pct, user_count, computed_at)
|
|
131
|
+
VALUES
|
|
132
|
+
(${r.domain_slug}, ${r.entity_type}, ${r.bucket_index}, ${lower},
|
|
133
|
+
${upper}, ${r.user_count}, now())
|
|
134
|
+
`;
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
await pg.begin(async (tx) => {
|
|
138
|
+
await tx `TRUNCATE TABLE roi_summary`;
|
|
139
|
+
for (const r of out.summary) {
|
|
140
|
+
await tx `
|
|
141
|
+
INSERT INTO roi_summary
|
|
142
|
+
(domain_slug, entity_type, total_users, positive_roi_users,
|
|
143
|
+
positive_roi_pct, median_roi_pct, p25_roi_pct, p75_roi_pct,
|
|
144
|
+
p90_roi_pct, mean_roi_pct, computed_at)
|
|
145
|
+
VALUES
|
|
146
|
+
(${r.domain_slug}, ${r.entity_type}, ${r.total_users}, ${r.positive_roi_users},
|
|
147
|
+
${r.positive_roi_pct}, ${r.median_roi_pct}, ${r.p25_roi_pct}, ${r.p75_roi_pct},
|
|
148
|
+
${r.p90_roi_pct}, ${r.mean_roi_pct}, now())
|
|
149
|
+
`;
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=roi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roi.js","sourceRoot":"","sources":["../../src/aggregator/roi.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Aggregator data sources — synchronous reads from SQLite.
|
|
3
|
+
*
|
|
4
|
+
* These functions extract the minimum columns needed for analytics rollups.
|
|
5
|
+
* Keeping the projection narrow keeps memory usage bounded even at 10M+ events.
|
|
6
|
+
*/
|
|
7
|
+
import type { Database as SqliteDatabase } from 'bun:sqlite';
|
|
8
|
+
/** Magnitude divisor for `collateral_posted` raw values (token has 18 decimals). */
|
|
9
|
+
export declare const TOKEN_DECIMALS = 1000000000000000000;
|
|
10
|
+
export interface AggEventRow {
|
|
11
|
+
readonly id: number;
|
|
12
|
+
readonly market_address: string;
|
|
13
|
+
readonly event_type: string;
|
|
14
|
+
readonly trader: string | null;
|
|
15
|
+
readonly timestamp: number;
|
|
16
|
+
readonly collateral_posted: string | null;
|
|
17
|
+
readonly is_position_sell: number | null;
|
|
18
|
+
}
|
|
19
|
+
export interface AggPositionRow {
|
|
20
|
+
readonly market_address: string;
|
|
21
|
+
readonly trader: string;
|
|
22
|
+
readonly has_position: number;
|
|
23
|
+
readonly settlement_state: string;
|
|
24
|
+
readonly unrealized_pnl: number | null;
|
|
25
|
+
readonly realized_pnl: number | null;
|
|
26
|
+
readonly expected_value: number | null;
|
|
27
|
+
readonly delta_count: number;
|
|
28
|
+
readonly claimed: number;
|
|
29
|
+
}
|
|
30
|
+
export interface AggLPPositionRow {
|
|
31
|
+
readonly market_address: string;
|
|
32
|
+
readonly provider: string;
|
|
33
|
+
readonly total_deposited: number;
|
|
34
|
+
readonly total_withdrawn: number;
|
|
35
|
+
readonly current_value: number | null;
|
|
36
|
+
readonly unrealized_pnl: number | null;
|
|
37
|
+
readonly deposit_count: number;
|
|
38
|
+
readonly withdrawal_count: number;
|
|
39
|
+
readonly first_deposit_at: number | null;
|
|
40
|
+
readonly last_activity_at: number | null;
|
|
41
|
+
readonly claimed_at: number | null;
|
|
42
|
+
readonly claim_payout: number | null;
|
|
43
|
+
}
|
|
44
|
+
export declare function readAllEvents(db: SqliteDatabase): readonly AggEventRow[];
|
|
45
|
+
export declare function readAllPositions(db: SqliteDatabase): readonly AggPositionRow[];
|
|
46
|
+
export declare function readAllLPPositions(db: SqliteDatabase): readonly AggLPPositionRow[];
|
|
47
|
+
/**
|
|
48
|
+
* Parse the raw SQ128x128-style magnitude string into a human-readable token
|
|
49
|
+
* amount. Mirrors `parseCollateral` in services/ActivityEnricher.ts.
|
|
50
|
+
*/
|
|
51
|
+
export declare function parseCollateralAmount(raw: string | null): number;
|
|
52
|
+
/**
|
|
53
|
+
* Trade-like events count toward trader volume. Liquidity events are tracked
|
|
54
|
+
* separately for LPs.
|
|
55
|
+
*/
|
|
56
|
+
export declare const TRADE_EVENT_TYPES: Set<string>;
|
|
57
|
+
export declare const LIQUIDITY_ADD_TYPES: Set<string>;
|
|
58
|
+
export declare const LIQUIDITY_REMOVE_TYPES: Set<string>;
|
|
59
|
+
//# sourceMappingURL=sources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sources.d.ts","sourceRoot":"","sources":["../../src/aggregator/sources.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,YAAY,CAAC;AAE7D,oFAAoF;AACpF,eAAO,MAAM,cAAc,sBAAO,CAAC;AAEnC,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,cAAc,GAAG,SAAS,WAAW,EAAE,CASxE;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,cAAc,GAAG,SAAS,cAAc,EAAE,CAQ9E;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,cAAc,GAAG,SAAS,gBAAgB,EAAE,CASlF;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAKhE;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,aAI5B,CAAC;AAEH,eAAO,MAAM,mBAAmB,aAI9B,CAAC;AAEH,eAAO,MAAM,sBAAsB,aAAiC,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** Magnitude divisor for `collateral_posted` raw values (token has 18 decimals). */
|
|
2
|
+
export const TOKEN_DECIMALS = 1e18;
|
|
3
|
+
export function readAllEvents(db) {
|
|
4
|
+
return db
|
|
5
|
+
.query(`SELECT id, market_address, event_type, trader, timestamp,
|
|
6
|
+
collateral_posted, is_position_sell
|
|
7
|
+
FROM market_events
|
|
8
|
+
ORDER BY id ASC`)
|
|
9
|
+
.all();
|
|
10
|
+
}
|
|
11
|
+
export function readAllPositions(db) {
|
|
12
|
+
return db
|
|
13
|
+
.query(`SELECT market_address, trader, has_position, settlement_state,
|
|
14
|
+
unrealized_pnl, realized_pnl, expected_value, delta_count, claimed
|
|
15
|
+
FROM user_positions`)
|
|
16
|
+
.all();
|
|
17
|
+
}
|
|
18
|
+
export function readAllLPPositions(db) {
|
|
19
|
+
return db
|
|
20
|
+
.query(`SELECT market_address, provider, total_deposited, total_withdrawn,
|
|
21
|
+
current_value, unrealized_pnl, deposit_count, withdrawal_count,
|
|
22
|
+
first_deposit_at, last_activity_at, claimed_at, claim_payout
|
|
23
|
+
FROM lp_positions`)
|
|
24
|
+
.all();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Parse the raw SQ128x128-style magnitude string into a human-readable token
|
|
28
|
+
* amount. Mirrors `parseCollateral` in services/ActivityEnricher.ts.
|
|
29
|
+
*/
|
|
30
|
+
export function parseCollateralAmount(raw) {
|
|
31
|
+
if (raw == null || raw.length === 0)
|
|
32
|
+
return 0;
|
|
33
|
+
const val = Number(raw);
|
|
34
|
+
if (!Number.isFinite(val))
|
|
35
|
+
return 0;
|
|
36
|
+
return val / TOKEN_DECIMALS;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Trade-like events count toward trader volume. Liquidity events are tracked
|
|
40
|
+
* separately for LPs.
|
|
41
|
+
*/
|
|
42
|
+
export const TRADE_EVENT_TYPES = new Set([
|
|
43
|
+
'trade_executed',
|
|
44
|
+
'trade_moved',
|
|
45
|
+
'multinoulli_trade_executed',
|
|
46
|
+
]);
|
|
47
|
+
export const LIQUIDITY_ADD_TYPES = new Set([
|
|
48
|
+
'liquidity_added',
|
|
49
|
+
'market_initialized',
|
|
50
|
+
'bootstrapped',
|
|
51
|
+
]);
|
|
52
|
+
export const LIQUIDITY_REMOVE_TYPES = new Set(['liquidity_removed']);
|
|
53
|
+
//# sourceMappingURL=sources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sources.js","sourceRoot":"","sources":["../../src/aggregator/sources.ts"],"names":[],"mappings":"AAQA,oFAAoF;AACpF,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC;AAuCnC,MAAM,UAAU,aAAa,CAAC,EAAkB;IAC9C,OAAO,EAAE;SACN,KAAK,CACJ;;;uBAGiB,CAClB;SACA,GAAG,EAA4B,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,EAAkB;IACjD,OAAO,EAAE;SACN,KAAK,CACJ;;2BAEqB,CACtB;SACA,GAAG,EAA+B,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,EAAkB;IACnD,OAAO,EAAE;SACN,KAAK,CACJ;;;yBAGmB,CACpB;SACA,GAAG,EAAiC,CAAC;AAC1C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAkB;IACtD,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACxB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IACpC,OAAO,GAAG,GAAG,cAAc,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IACvC,gBAAgB;IAChB,aAAa;IACb,4BAA4B;CAC7B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IACzC,iBAAiB;IACjB,oBAAoB;IACpB,cAAc;CACf,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bulk-write builders.
|
|
3
|
+
*
|
|
4
|
+
* Each writer truncates its target table and re-inserts. Truncate-and-reload
|
|
5
|
+
* is fine while the data set is small (~100k events) and avoids subtle
|
|
6
|
+
* incremental-update bugs. Switch to UPSERT-by-key once event volume justifies it.
|
|
7
|
+
*
|
|
8
|
+
* All writes happen inside a single transaction per table so readers never
|
|
9
|
+
* see a partially-written warehouse state.
|
|
10
|
+
*/
|
|
11
|
+
import type { SQL } from 'bun';
|
|
12
|
+
import type { DailyDomainStatRow, DailyLPStatRow, DailyMarketStatRow, DailyPlatformStatRow, DailyTraderStatRow } from './daily';
|
|
13
|
+
import type { LPLifetimeRow, TraderLifetimeRow } from './lifetime';
|
|
14
|
+
export declare function writeDailyTraderStats(pg: SQL, rows: readonly DailyTraderStatRow[]): Promise<void>;
|
|
15
|
+
export declare function writeDailyLPStats(pg: SQL, rows: readonly DailyLPStatRow[]): Promise<void>;
|
|
16
|
+
export declare function writeDailyMarketStats(pg: SQL, rows: readonly DailyMarketStatRow[]): Promise<void>;
|
|
17
|
+
export declare function writeDailyDomainStats(pg: SQL, rows: readonly DailyDomainStatRow[]): Promise<void>;
|
|
18
|
+
export declare function writeDailyPlatformStats(pg: SQL, rows: readonly DailyPlatformStatRow[]): Promise<void>;
|
|
19
|
+
export declare function writeTraderLifetime(pg: SQL, rows: readonly TraderLifetimeRow[]): Promise<void>;
|
|
20
|
+
export declare function writeLPLifetime(pg: SQL, rows: readonly LPLifetimeRow[]): Promise<void>;
|
|
21
|
+
export declare function recordAggregatorRun(pg: SQL, jobName: string, ok: boolean, error: string | null): Promise<void>;
|
|
22
|
+
//# sourceMappingURL=writers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writers.d.ts","sourceRoot":"","sources":["../../src/aggregator/writers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC/B,OAAO,KAAK,EACV,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAKnE,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,GAAG,EACP,IAAI,EAAE,SAAS,kBAAkB,EAAE,GAClC,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,GAAG,EACP,IAAI,EAAE,SAAS,cAAc,EAAE,GAC9B,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,GAAG,EACP,IAAI,EAAE,SAAS,kBAAkB,EAAE,GAClC,OAAO,CAAC,IAAI,CAAC,CAef;AAED,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,GAAG,EACP,IAAI,EAAE,SAAS,kBAAkB,EAAE,GAClC,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,wBAAsB,uBAAuB,CAC3C,EAAE,EAAE,GAAG,EACP,IAAI,EAAE,SAAS,oBAAoB,EAAE,GACpC,OAAO,CAAC,IAAI,CAAC,CAef;AAED,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,GAAG,EACP,IAAI,EAAE,SAAS,iBAAiB,EAAE,GACjC,OAAO,CAAC,IAAI,CAAC,CAsBf;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,GAAG,EACP,IAAI,EAAE,SAAS,aAAa,EAAE,GAC7B,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,GAAG,EACP,OAAO,EAAE,MAAM,EACf,EAAE,EAAE,OAAO,EACX,KAAK,EAAE,MAAM,GAAG,IAAI,GACnB,OAAO,CAAC,IAAI,CAAC,CAmBf"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
const TIMESTAMP_OR_NULL = (ts) => ts == null ? null : new Date(ts * 1000).toISOString();
|
|
2
|
+
export async function writeDailyTraderStats(pg, rows) {
|
|
3
|
+
await pg.begin(async (tx) => {
|
|
4
|
+
await tx `TRUNCATE TABLE daily_trader_stats`;
|
|
5
|
+
for (const r of rows) {
|
|
6
|
+
await tx `
|
|
7
|
+
INSERT INTO daily_trader_stats
|
|
8
|
+
(date, trader, domain_slug, trade_count, buy_count, sell_count,
|
|
9
|
+
volume_collateral, markets_traded, updated_at)
|
|
10
|
+
VALUES
|
|
11
|
+
(${r.date}, ${r.trader}, ${r.domain_slug}, ${r.trade_count}, ${r.buy_count},
|
|
12
|
+
${r.sell_count}, ${r.volume_collateral}, ${r.markets_traded}, now())
|
|
13
|
+
`;
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export async function writeDailyLPStats(pg, rows) {
|
|
18
|
+
await pg.begin(async (tx) => {
|
|
19
|
+
await tx `TRUNCATE TABLE daily_lp_stats`;
|
|
20
|
+
for (const r of rows) {
|
|
21
|
+
await tx `
|
|
22
|
+
INSERT INTO daily_lp_stats
|
|
23
|
+
(date, provider, domain_slug, deposit_count, withdraw_count,
|
|
24
|
+
deposited, withdrawn, net_position, markets_active, updated_at)
|
|
25
|
+
VALUES
|
|
26
|
+
(${r.date}, ${r.provider}, ${r.domain_slug}, ${r.deposit_count}, ${r.withdraw_count},
|
|
27
|
+
${r.deposited}, ${r.withdrawn}, ${r.deposited - r.withdrawn}, ${r.markets_active}, now())
|
|
28
|
+
`;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
export async function writeDailyMarketStats(pg, rows) {
|
|
33
|
+
await pg.begin(async (tx) => {
|
|
34
|
+
await tx `TRUNCATE TABLE daily_market_stats`;
|
|
35
|
+
for (const r of rows) {
|
|
36
|
+
await tx `
|
|
37
|
+
INSERT INTO daily_market_stats
|
|
38
|
+
(date, market_address, trade_count, unique_traders, volume_collateral,
|
|
39
|
+
liquidity_added, liquidity_removed, unique_lps, updated_at)
|
|
40
|
+
VALUES
|
|
41
|
+
(${r.date}, ${r.market_address}, ${r.trade_count}, ${r.unique_traders},
|
|
42
|
+
${r.volume_collateral}, ${r.liquidity_added}, ${r.liquidity_removed},
|
|
43
|
+
${r.unique_lps}, now())
|
|
44
|
+
`;
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
export async function writeDailyDomainStats(pg, rows) {
|
|
49
|
+
await pg.begin(async (tx) => {
|
|
50
|
+
await tx `TRUNCATE TABLE daily_domain_stats`;
|
|
51
|
+
for (const r of rows) {
|
|
52
|
+
await tx `
|
|
53
|
+
INSERT INTO daily_domain_stats
|
|
54
|
+
(date, domain_slug, trade_count, unique_traders, unique_lps,
|
|
55
|
+
volume_collateral, liquidity_net, active_markets, updated_at)
|
|
56
|
+
VALUES
|
|
57
|
+
(${r.date}, ${r.domain_slug}, ${r.trade_count}, ${r.unique_traders}, ${r.unique_lps},
|
|
58
|
+
${r.volume_collateral}, ${r.liquidity_net}, ${r.active_markets}, now())
|
|
59
|
+
`;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
export async function writeDailyPlatformStats(pg, rows) {
|
|
64
|
+
await pg.begin(async (tx) => {
|
|
65
|
+
await tx `TRUNCATE TABLE daily_platform_stats`;
|
|
66
|
+
for (const r of rows) {
|
|
67
|
+
await tx `
|
|
68
|
+
INSERT INTO daily_platform_stats
|
|
69
|
+
(date, trade_count, unique_traders, unique_lps, new_traders, new_lps,
|
|
70
|
+
volume_collateral, liquidity_net, active_markets, updated_at)
|
|
71
|
+
VALUES
|
|
72
|
+
(${r.date}, ${r.trade_count}, ${r.unique_traders}, ${r.unique_lps},
|
|
73
|
+
${r.new_traders}, ${r.new_lps}, ${r.volume_collateral}, ${r.liquidity_net},
|
|
74
|
+
${r.active_markets}, now())
|
|
75
|
+
`;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
export async function writeTraderLifetime(pg, rows) {
|
|
80
|
+
await pg.begin(async (tx) => {
|
|
81
|
+
await tx `TRUNCATE TABLE trader_lifetime`;
|
|
82
|
+
for (const r of rows) {
|
|
83
|
+
const domainsJson = JSON.stringify(r.domains_json);
|
|
84
|
+
await tx `
|
|
85
|
+
INSERT INTO trader_lifetime
|
|
86
|
+
(trader, first_trade_at, last_trade_at, cohort_week,
|
|
87
|
+
total_trades, buy_count, sell_count, markets_traded,
|
|
88
|
+
domains_traded, domains_json, total_volume, total_collateral_at_risk,
|
|
89
|
+
realized_pnl, unrealized_pnl, total_pnl, roi_pct, active_days, updated_at)
|
|
90
|
+
VALUES
|
|
91
|
+
(${r.trader}, ${TIMESTAMP_OR_NULL(r.first_trade_at)},
|
|
92
|
+
${TIMESTAMP_OR_NULL(r.last_trade_at)}, ${r.cohort_week},
|
|
93
|
+
${r.total_trades}, ${r.buy_count}, ${r.sell_count}, ${r.markets_traded},
|
|
94
|
+
${r.domains_traded}, ${domainsJson}::jsonb,
|
|
95
|
+
${r.total_volume}, ${r.total_collateral_at_risk},
|
|
96
|
+
${r.realized_pnl}, ${r.unrealized_pnl}, ${r.total_pnl},
|
|
97
|
+
${r.roi_pct}, ${r.active_days}, now())
|
|
98
|
+
`;
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
export async function writeLPLifetime(pg, rows) {
|
|
103
|
+
await pg.begin(async (tx) => {
|
|
104
|
+
await tx `TRUNCATE TABLE lp_lifetime`;
|
|
105
|
+
for (const r of rows) {
|
|
106
|
+
const domainsJson = JSON.stringify(r.domains_json);
|
|
107
|
+
await tx `
|
|
108
|
+
INSERT INTO lp_lifetime
|
|
109
|
+
(provider, first_deposit_at, last_activity_at, cohort_week,
|
|
110
|
+
deposit_count, withdraw_count, total_deposited, total_withdrawn,
|
|
111
|
+
net_position, current_value, unrealized_pnl, realized_pnl,
|
|
112
|
+
markets_provided, domains_provided, domains_json, active_days,
|
|
113
|
+
roi_pct, updated_at)
|
|
114
|
+
VALUES
|
|
115
|
+
(${r.provider}, ${TIMESTAMP_OR_NULL(r.first_deposit_at)},
|
|
116
|
+
${TIMESTAMP_OR_NULL(r.last_activity_at)}, ${r.cohort_week},
|
|
117
|
+
${r.deposit_count}, ${r.withdraw_count}, ${r.total_deposited},
|
|
118
|
+
${r.total_withdrawn}, ${r.net_position}, ${r.current_value},
|
|
119
|
+
${r.unrealized_pnl}, ${r.realized_pnl}, ${r.markets_provided},
|
|
120
|
+
${r.domains_provided}, ${domainsJson}::jsonb, ${r.active_days},
|
|
121
|
+
${r.roi_pct}, now())
|
|
122
|
+
`;
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
export async function recordAggregatorRun(pg, jobName, ok, error) {
|
|
127
|
+
if (ok) {
|
|
128
|
+
await pg `
|
|
129
|
+
INSERT INTO aggregator_state (job_name, last_run_at, last_success_at, last_error)
|
|
130
|
+
VALUES (${jobName}, now(), now(), NULL)
|
|
131
|
+
ON CONFLICT (job_name) DO UPDATE SET
|
|
132
|
+
last_run_at = EXCLUDED.last_run_at,
|
|
133
|
+
last_success_at = EXCLUDED.last_success_at,
|
|
134
|
+
last_error = NULL
|
|
135
|
+
`;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
await pg `
|
|
139
|
+
INSERT INTO aggregator_state (job_name, last_run_at, last_error)
|
|
140
|
+
VALUES (${jobName}, now(), ${error})
|
|
141
|
+
ON CONFLICT (job_name) DO UPDATE SET
|
|
142
|
+
last_run_at = EXCLUDED.last_run_at,
|
|
143
|
+
last_error = EXCLUDED.last_error
|
|
144
|
+
`;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=writers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writers.js","sourceRoot":"","sources":["../../src/aggregator/writers.ts"],"names":[],"mappings":"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"}
|