@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.
Files changed (133) hide show
  1. package/README.md +43 -4
  2. package/dist/aggregator/cohort.d.ts +30 -0
  3. package/dist/aggregator/cohort.d.ts.map +1 -0
  4. package/dist/aggregator/cohort.js +153 -0
  5. package/dist/aggregator/cohort.js.map +1 -0
  6. package/dist/aggregator/daily.d.ts +71 -0
  7. package/dist/aggregator/daily.d.ts.map +1 -0
  8. package/dist/aggregator/daily.js +249 -0
  9. package/dist/aggregator/daily.js.map +1 -0
  10. package/dist/aggregator/domains.d.ts +20 -0
  11. package/dist/aggregator/domains.d.ts.map +1 -0
  12. package/dist/aggregator/domains.js +38 -0
  13. package/dist/aggregator/domains.js.map +1 -0
  14. package/dist/aggregator/index.d.ts +31 -0
  15. package/dist/aggregator/index.d.ts.map +1 -0
  16. package/dist/aggregator/index.js +100 -0
  17. package/dist/aggregator/index.js.map +1 -0
  18. package/dist/aggregator/lifetime.d.ts +52 -0
  19. package/dist/aggregator/lifetime.d.ts.map +1 -0
  20. package/dist/aggregator/lifetime.js +222 -0
  21. package/dist/aggregator/lifetime.js.map +1 -0
  22. package/dist/aggregator/roi.d.ts +42 -0
  23. package/dist/aggregator/roi.d.ts.map +1 -0
  24. package/dist/aggregator/roi.js +153 -0
  25. package/dist/aggregator/roi.js.map +1 -0
  26. package/dist/aggregator/sources.d.ts +59 -0
  27. package/dist/aggregator/sources.d.ts.map +1 -0
  28. package/dist/aggregator/sources.js +53 -0
  29. package/dist/aggregator/sources.js.map +1 -0
  30. package/dist/aggregator/writers.d.ts +22 -0
  31. package/dist/aggregator/writers.d.ts.map +1 -0
  32. package/dist/aggregator/writers.js +147 -0
  33. package/dist/aggregator/writers.js.map +1 -0
  34. package/dist/api/app.d.ts +177 -13
  35. package/dist/api/app.d.ts.map +1 -1
  36. package/dist/api/app.js +4 -3
  37. package/dist/api/app.js.map +1 -1
  38. package/dist/api/routes/admin-subscriptions.d.ts +11 -11
  39. package/dist/api/routes/analytics.d.ts +205 -0
  40. package/dist/api/routes/analytics.d.ts.map +1 -0
  41. package/dist/api/routes/analytics.js +122 -0
  42. package/dist/api/routes/analytics.js.map +1 -0
  43. package/dist/api/routes/health.d.ts.map +1 -1
  44. package/dist/api/routes/health.js +2 -0
  45. package/dist/api/routes/health.js.map +1 -1
  46. package/dist/api/routes/index.d.ts +1 -0
  47. package/dist/api/routes/index.d.ts.map +1 -1
  48. package/dist/api/routes/index.js +1 -0
  49. package/dist/api/routes/index.js.map +1 -1
  50. package/dist/api/routes/rankings.d.ts +17 -3
  51. package/dist/api/routes/rankings.d.ts.map +1 -1
  52. package/dist/api/routes/rankings.js +44 -5
  53. package/dist/api/routes/rankings.js.map +1 -1
  54. package/dist/api/routes/trader-stats.d.ts +11 -2
  55. package/dist/api/routes/trader-stats.d.ts.map +1 -1
  56. package/dist/api/routes/trader-stats.js +72 -2
  57. package/dist/api/routes/trader-stats.js.map +1 -1
  58. package/dist/client/IndexerClient.d.ts +30 -1
  59. package/dist/client/IndexerClient.d.ts.map +1 -1
  60. package/dist/client/IndexerClient.js.map +1 -1
  61. package/dist/client/IndexerClientLive.d.ts.map +1 -1
  62. package/dist/client/IndexerClientLive.js +50 -1
  63. package/dist/client/IndexerClientLive.js.map +1 -1
  64. package/dist/client/convenience.d.ts +9 -2
  65. package/dist/client/convenience.d.ts.map +1 -1
  66. package/dist/client/convenience.js +9 -1
  67. package/dist/client/convenience.js.map +1 -1
  68. package/dist/client/index.d.ts +3 -2
  69. package/dist/client/index.d.ts.map +1 -1
  70. package/dist/client/index.js +1 -1
  71. package/dist/client/index.js.map +1 -1
  72. package/dist/config.d.ts +17 -1
  73. package/dist/config.d.ts.map +1 -1
  74. package/dist/config.js +39 -3
  75. package/dist/config.js.map +1 -1
  76. package/dist/etl/event-indexer.d.ts +1 -1
  77. package/dist/etl/lp-position-refresher.d.ts +2 -1
  78. package/dist/etl/lp-position-refresher.d.ts.map +1 -1
  79. package/dist/etl/lp-position-refresher.js +24 -11
  80. package/dist/etl/lp-position-refresher.js.map +1 -1
  81. package/dist/index.js +64 -8
  82. package/dist/index.js.map +1 -1
  83. package/dist/layers/ChainReaderLive.d.ts.map +1 -1
  84. package/dist/layers/ChainReaderLive.js +15 -0
  85. package/dist/layers/ChainReaderLive.js.map +1 -1
  86. package/dist/layers/VoyagerClientLive.d.ts +2 -1
  87. package/dist/layers/VoyagerClientLive.d.ts.map +1 -1
  88. package/dist/layers/VoyagerClientLive.js +89 -55
  89. package/dist/layers/VoyagerClientLive.js.map +1 -1
  90. package/dist/services/ChainReader.d.ts +10 -0
  91. package/dist/services/ChainReader.d.ts.map +1 -1
  92. package/dist/services/ChainReader.js.map +1 -1
  93. package/dist/services/VoyagerRateLimit.d.ts +11 -8
  94. package/dist/services/VoyagerRateLimit.d.ts.map +1 -1
  95. package/dist/services/VoyagerRateLimit.js +51 -26
  96. package/dist/services/VoyagerRateLimit.js.map +1 -1
  97. package/dist/types/analytics.d.ts +194 -0
  98. package/dist/types/analytics.d.ts.map +1 -0
  99. package/dist/types/analytics.js +10 -0
  100. package/dist/types/analytics.js.map +1 -0
  101. package/dist/types/api.d.ts +2 -0
  102. package/dist/types/api.d.ts.map +1 -1
  103. package/dist/types/index.d.ts +1 -0
  104. package/dist/types/index.d.ts.map +1 -1
  105. package/dist/warehouse/analytics-helpers.d.ts +36 -0
  106. package/dist/warehouse/analytics-helpers.d.ts.map +1 -0
  107. package/dist/warehouse/analytics-helpers.js +142 -0
  108. package/dist/warehouse/analytics-helpers.js.map +1 -0
  109. package/dist/warehouse/backfill.d.ts +26 -0
  110. package/dist/warehouse/backfill.d.ts.map +1 -0
  111. package/dist/warehouse/backfill.js +77 -0
  112. package/dist/warehouse/backfill.js.map +1 -0
  113. package/dist/warehouse/connection.d.ts +18 -0
  114. package/dist/warehouse/connection.d.ts.map +1 -0
  115. package/dist/warehouse/connection.js +24 -0
  116. package/dist/warehouse/connection.js.map +1 -0
  117. package/dist/warehouse/index.d.ts +14 -0
  118. package/dist/warehouse/index.d.ts.map +1 -0
  119. package/dist/warehouse/index.js +14 -0
  120. package/dist/warehouse/index.js.map +1 -0
  121. package/dist/warehouse/repositories/analytics.d.ts +61 -0
  122. package/dist/warehouse/repositories/analytics.d.ts.map +1 -0
  123. package/dist/warehouse/repositories/analytics.js +418 -0
  124. package/dist/warehouse/repositories/analytics.js.map +1 -0
  125. package/dist/warehouse/schema.d.ts +9 -0
  126. package/dist/warehouse/schema.d.ts.map +1 -0
  127. package/dist/warehouse/schema.js +219 -0
  128. package/dist/warehouse/schema.js.map +1 -0
  129. package/dist/warehouse/seed-domains.d.ts +29 -0
  130. package/dist/warehouse/seed-domains.d.ts.map +1 -0
  131. package/dist/warehouse/seed-domains.js +223 -0
  132. package/dist/warehouse/seed-domains.js.map +1 -0
  133. package/package.json +1 -1
package/README.md CHANGED
@@ -27,15 +27,23 @@ Events will begin appearing within ~15 seconds.
27
27
 
28
28
  | Variable | Required | Default | Description |
29
29
  |----------|----------|---------|-------------|
30
- | `VOYAGER_API_KEY` | Yes | — | Voyager explorer API key |
30
+ | `VOYAGER_API_KEY` | Yes* | — | Single Voyager explorer API key |
31
+ | `VOYAGER_API_KEYS` | Yes* | — | Comma/whitespace-separated Voyager API key pool for redundancy |
31
32
  | `ADMIN_API_KEY` | Yes | — | Bearer token for `/admin/*` endpoints |
32
33
  | `DB_PATH` | No | `./data/indexer.db` | SQLite database file path |
33
34
  | `PORT` | No | `3000` | HTTP server port |
34
- | `STARKNET_RPC_URL` | No | `https://api.cartridge.gg/x/starknet/sepolia` | Starknet RPC endpoint |
35
+ | `STARKNET_NETWORK` | No | `sepolia` | Network default set (`sepolia` or `mainnet`) |
36
+ | `STARKNET_RPC_URL` | No | network default | Starknet RPC endpoint |
37
+ | `VOYAGER_API_BASE_URL` | No | network default | Voyager API base URL |
35
38
  | `EVENT_POLL_INTERVAL_MS` | No | `15000` | Event polling interval (ms) |
36
39
  | `STATE_POLL_INTERVAL_MS` | No | `30000` | Market state refresh interval (ms) |
37
40
  | `POSITION_POLL_INTERVAL_MS` | No | `60000` | Position refresh interval (ms) |
38
41
 
42
+ `VOYAGER_API_KEY` or `VOYAGER_API_KEYS` must be set. When multiple keys are
43
+ configured, the indexer rotates across them. A key that receives a Voyager
44
+ 429/503 response is cooled down independently, and requests continue through
45
+ the remaining keys until every key is cooling down.
46
+
39
47
  ## API Reference
40
48
 
41
49
  ### Public Endpoints
@@ -222,14 +230,14 @@ The indexer is configured for [Fly.io](https://fly.io) with a persistent volume
222
230
  ```bash
223
231
  cd packages/indexer
224
232
 
225
- # Create the app (first time only)
233
+ # Create the Sepolia app (first time only)
226
234
  fly apps create situation-indexer
227
235
 
228
236
  # Create a persistent volume for the database
229
237
  fly volumes create indexer_data --region iad --size 1
230
238
 
231
239
  # Set secrets
232
- fly secrets set VOYAGER_API_KEY=your-key ADMIN_API_KEY=your-key
240
+ fly secrets set VOYAGER_API_KEYS=key-1,key-2,key-3 ADMIN_API_KEY=your-key
233
241
 
234
242
  # Deploy (uses Dockerfile.indexer at repo root)
235
243
  fly deploy
@@ -238,6 +246,37 @@ fly deploy
238
246
  curl https://situation-indexer.fly.dev/health
239
247
  ```
240
248
 
249
+ ### Mainnet Deployment
250
+
251
+ Mainnet uses a separate Fly app and volume so the production database starts
252
+ fresh and cannot mix Sepolia cursor state with mainnet events.
253
+
254
+ ```bash
255
+ cd packages/indexer
256
+
257
+ # Create the mainnet app (first time only)
258
+ fly apps create situation-indexer-mainnet
259
+
260
+ # Create the mainnet database volume
261
+ fly volumes create indexer_mainnet_data --app situation-indexer-mainnet --region iad --size 1
262
+
263
+ # Set secrets on the mainnet app
264
+ fly secrets set --app situation-indexer-mainnet VOYAGER_API_KEYS=key-1,key-2,key-3 ADMIN_API_KEY=your-key
265
+
266
+ # Deploy with mainnet RPC and Voyager API endpoints
267
+ fly deploy --config fly.mainnet.toml
268
+
269
+ # Verify
270
+ curl https://situation-indexer-mainnet.fly.dev/health
271
+ ```
272
+
273
+ `fly.mainnet.toml` is configured with:
274
+
275
+ - `STARKNET_NETWORK=mainnet`
276
+ - `STARKNET_RPC_URL=https://api.cartridge.gg/x/starknet/mainnet`
277
+ - `VOYAGER_API_BASE_URL=https://api.voyager.online/beta`
278
+ - Persistent volume `indexer_mainnet_data` mounted at `/data`
279
+
241
280
  The `fly.toml` is pre-configured with:
242
281
  - `shared-cpu-1x` / 512MB RAM
243
282
  - Persistent volume mounted at `/data`
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Cohort retention builder.
3
+ *
4
+ * For each (cohort_week, week_offset, domain_slug, entity_type) tuple, count
5
+ * the users from the cohort that were active during that week.
6
+ *
7
+ * `domain_slug = 'all'` is the un-segmented total. Per-domain rows are also
8
+ * emitted for every domain a cohort member touched.
9
+ *
10
+ * "Active" definitions:
11
+ * - trader: had >= 1 trade event in the week
12
+ * - lp: had >= 1 deposit or withdraw event in the week
13
+ *
14
+ * The week index is the ISO Monday (UTC). week_offset 0 is the cohort week
15
+ * itself; offsets > 0 are subsequent weeks.
16
+ */
17
+ import { type AggEventRow } from './sources';
18
+ import { type MarketDomainMap } from './domains';
19
+ import type { LPLifetimeRow, TraderLifetimeRow } from './lifetime';
20
+ export interface CohortRetentionRow {
21
+ readonly cohort_week: string;
22
+ readonly week_offset: number;
23
+ readonly domain_slug: string;
24
+ readonly entity_type: 'trader' | 'lp';
25
+ readonly cohort_size: number;
26
+ readonly retained: number;
27
+ }
28
+ export declare function buildCohortRetention(events: readonly AggEventRow[], traderLifetime: readonly TraderLifetimeRow[], lpLifetime: readonly LPLifetimeRow[], marketDomains: MarketDomainMap): readonly CohortRetentionRow[];
29
+ export declare function writeCohortRetention(pg: import('bun').SQL, rows: readonly CohortRetentionRow[]): Promise<void>;
30
+ //# sourceMappingURL=cohort.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cohort.d.ts","sourceRoot":"","sources":["../../src/aggregator/cohort.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EACL,KAAK,WAAW,EAIjB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,KAAK,eAAe,EAAmB,MAAM,WAAW,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEnE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAoBD,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,cAAc,EAAE,SAAS,iBAAiB,EAAE,EAC5C,UAAU,EAAE,SAAS,aAAa,EAAE,EACpC,aAAa,EAAE,eAAe,GAC7B,SAAS,kBAAkB,EAAE,CAqH/B;AAED,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,OAAO,KAAK,EAAE,GAAG,EACrB,IAAI,EAAE,SAAS,kBAAkB,EAAE,GAClC,OAAO,CAAC,IAAI,CAAC,CAcf"}
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Cohort retention builder.
3
+ *
4
+ * For each (cohort_week, week_offset, domain_slug, entity_type) tuple, count
5
+ * the users from the cohort that were active during that week.
6
+ *
7
+ * `domain_slug = 'all'` is the un-segmented total. Per-domain rows are also
8
+ * emitted for every domain a cohort member touched.
9
+ *
10
+ * "Active" definitions:
11
+ * - trader: had >= 1 trade event in the week
12
+ * - lp: had >= 1 deposit or withdraw event in the week
13
+ *
14
+ * The week index is the ISO Monday (UTC). week_offset 0 is the cohort week
15
+ * itself; offsets > 0 are subsequent weeks.
16
+ */
17
+ import { LIQUIDITY_ADD_TYPES, LIQUIDITY_REMOVE_TYPES, TRADE_EVENT_TYPES, } from './sources';
18
+ import { primaryDomainOf } from './domains';
19
+ function isoWeekStart(ts) {
20
+ const d = new Date(ts * 1000);
21
+ const day = d.getUTCDay();
22
+ const diff = day === 0 ? -6 : 1 - day;
23
+ const monday = new Date(d.getTime());
24
+ monday.setUTCDate(d.getUTCDate() + diff);
25
+ const yyyy = monday.getUTCFullYear();
26
+ const mm = String(monday.getUTCMonth() + 1).padStart(2, '0');
27
+ const dd = String(monday.getUTCDate()).padStart(2, '0');
28
+ return `${yyyy}-${mm}-${dd}`;
29
+ }
30
+ function weekDiff(cohortWeekStr, eventWeekStr) {
31
+ const cohort = Date.parse(`${cohortWeekStr}T00:00:00Z`);
32
+ const eventW = Date.parse(`${eventWeekStr}T00:00:00Z`);
33
+ return Math.floor((eventW - cohort) / (7 * 24 * 60 * 60 * 1000));
34
+ }
35
+ export function buildCohortRetention(events, traderLifetime, lpLifetime, marketDomains) {
36
+ const traderCohort = new Map();
37
+ for (const t of traderLifetime) {
38
+ if (t.cohort_week)
39
+ traderCohort.set(t.trader, t.cohort_week);
40
+ }
41
+ const lpCohort = new Map();
42
+ for (const l of lpLifetime) {
43
+ if (l.cohort_week)
44
+ lpCohort.set(l.provider, l.cohort_week);
45
+ }
46
+ const activity = new Map();
47
+ activity.set('trader', new Map());
48
+ activity.set('lp', new Map());
49
+ function record(entityType, domain, cohortWeek, weekOffset, user) {
50
+ const byEntity = activity.get(entityType);
51
+ let byDomain = byEntity.get(domain);
52
+ if (!byDomain) {
53
+ byDomain = new Map();
54
+ byEntity.set(domain, byDomain);
55
+ }
56
+ let byCohort = byDomain.get(cohortWeek);
57
+ if (!byCohort) {
58
+ byCohort = new Map();
59
+ byDomain.set(cohortWeek, byCohort);
60
+ }
61
+ let byOffset = byCohort.get(weekOffset);
62
+ if (!byOffset) {
63
+ byOffset = new Set();
64
+ byCohort.set(weekOffset, byOffset);
65
+ }
66
+ byOffset.add(user);
67
+ }
68
+ for (const event of events) {
69
+ if (!event.trader)
70
+ continue;
71
+ const eventWeek = isoWeekStart(event.timestamp);
72
+ const domain = primaryDomainOf(marketDomains, event.market_address);
73
+ const isTrade = TRADE_EVENT_TYPES.has(event.event_type);
74
+ const isLPEvent = LIQUIDITY_ADD_TYPES.has(event.event_type) ||
75
+ LIQUIDITY_REMOVE_TYPES.has(event.event_type);
76
+ if (isTrade) {
77
+ const cohort = traderCohort.get(event.trader);
78
+ if (cohort) {
79
+ const offset = weekDiff(cohort, eventWeek);
80
+ if (offset >= 0) {
81
+ record('trader', 'all', cohort, offset, event.trader);
82
+ record('trader', domain, cohort, offset, event.trader);
83
+ }
84
+ }
85
+ }
86
+ if (isLPEvent) {
87
+ const cohort = lpCohort.get(event.trader);
88
+ if (cohort) {
89
+ const offset = weekDiff(cohort, eventWeek);
90
+ if (offset >= 0) {
91
+ record('lp', 'all', cohort, offset, event.trader);
92
+ record('lp', domain, cohort, offset, event.trader);
93
+ }
94
+ }
95
+ }
96
+ }
97
+ // Cohort sizes: count distinct users per (entity_type, domain, cohort_week).
98
+ // For 'all' it's the count from lifetime tables. For per-domain, it's the
99
+ // number of cohort members whose activity ever touched that domain
100
+ // (= the size of week_offset=0 PLUS any user whose first activity in the
101
+ // domain happened later — which we approximate by union over all offsets).
102
+ const out = [];
103
+ for (const entityType of ['trader', 'lp']) {
104
+ const byEntity = activity.get(entityType);
105
+ // Build cohort-level totals for the 'all' bucket from lifetime tables.
106
+ const cohortTotalAll = new Map();
107
+ const lifetimeRows = entityType === 'trader' ? traderLifetime : lpLifetime;
108
+ for (const row of lifetimeRows) {
109
+ const cw = row.cohort_week;
110
+ if (!cw)
111
+ continue;
112
+ cohortTotalAll.set(cw, (cohortTotalAll.get(cw) ?? 0) + 1);
113
+ }
114
+ for (const [domain, byDomain] of byEntity) {
115
+ for (const [cohortWeek, byCohort] of byDomain) {
116
+ // Cohort size = union of all users seen in this domain for this cohort.
117
+ const allUsers = new Set();
118
+ for (const users of byCohort.values()) {
119
+ for (const u of users)
120
+ allUsers.add(u);
121
+ }
122
+ const cohortSize = domain === 'all' ? (cohortTotalAll.get(cohortWeek) ?? allUsers.size) : allUsers.size;
123
+ for (const [weekOffset, users] of byCohort) {
124
+ out.push({
125
+ cohort_week: cohortWeek,
126
+ week_offset: weekOffset,
127
+ domain_slug: domain,
128
+ entity_type: entityType,
129
+ cohort_size: cohortSize,
130
+ retained: users.size,
131
+ });
132
+ }
133
+ }
134
+ }
135
+ }
136
+ return out;
137
+ }
138
+ export async function writeCohortRetention(pg, rows) {
139
+ await pg.begin(async (tx) => {
140
+ await tx `TRUNCATE TABLE cohort_retention`;
141
+ for (const r of rows) {
142
+ await tx `
143
+ INSERT INTO cohort_retention
144
+ (cohort_week, week_offset, domain_slug, entity_type,
145
+ cohort_size, retained, updated_at)
146
+ VALUES
147
+ (${r.cohort_week}, ${r.week_offset}, ${r.domain_slug}, ${r.entity_type},
148
+ ${r.cohort_size}, ${r.retained}, now())
149
+ `;
150
+ }
151
+ });
152
+ }
153
+ //# sourceMappingURL=cohort.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cohort.js","sourceRoot":"","sources":["../../src/aggregator/cohort.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Daily fact table builders.
3
+ *
4
+ * Pure in-memory aggregation — input: events + positions + market→domain map.
5
+ * Output: arrays of rows ready to bulk-insert into Postgres.
6
+ *
7
+ * Approach: full recompute per cycle. With ~100k events this is sub-second.
8
+ * Switch to incremental if event count grows past ~10M.
9
+ */
10
+ import { type AggEventRow } from './sources';
11
+ import { type MarketDomainMap } from './domains';
12
+ export interface DailyTraderStatRow {
13
+ readonly date: string;
14
+ readonly trader: string;
15
+ readonly domain_slug: string;
16
+ readonly trade_count: number;
17
+ readonly buy_count: number;
18
+ readonly sell_count: number;
19
+ readonly volume_collateral: number;
20
+ readonly markets_traded: number;
21
+ }
22
+ export interface DailyLPStatRow {
23
+ readonly date: string;
24
+ readonly provider: string;
25
+ readonly domain_slug: string;
26
+ readonly deposit_count: number;
27
+ readonly withdraw_count: number;
28
+ readonly deposited: number;
29
+ readonly withdrawn: number;
30
+ readonly markets_active: number;
31
+ }
32
+ export interface DailyMarketStatRow {
33
+ readonly date: string;
34
+ readonly market_address: string;
35
+ readonly trade_count: number;
36
+ readonly unique_traders: number;
37
+ readonly volume_collateral: number;
38
+ readonly liquidity_added: number;
39
+ readonly liquidity_removed: number;
40
+ readonly unique_lps: number;
41
+ }
42
+ export interface DailyDomainStatRow {
43
+ readonly date: string;
44
+ readonly domain_slug: string;
45
+ readonly trade_count: number;
46
+ readonly unique_traders: number;
47
+ readonly unique_lps: number;
48
+ readonly volume_collateral: number;
49
+ readonly liquidity_net: number;
50
+ readonly active_markets: number;
51
+ }
52
+ export interface DailyPlatformStatRow {
53
+ readonly date: string;
54
+ readonly trade_count: number;
55
+ readonly unique_traders: number;
56
+ readonly unique_lps: number;
57
+ readonly new_traders: number;
58
+ readonly new_lps: number;
59
+ readonly volume_collateral: number;
60
+ readonly liquidity_net: number;
61
+ readonly active_markets: number;
62
+ }
63
+ export interface DailyAggregates {
64
+ readonly trader: readonly DailyTraderStatRow[];
65
+ readonly lp: readonly DailyLPStatRow[];
66
+ readonly market: readonly DailyMarketStatRow[];
67
+ readonly domain: readonly DailyDomainStatRow[];
68
+ readonly platform: readonly DailyPlatformStatRow[];
69
+ }
70
+ export declare function buildDailyAggregates(events: readonly AggEventRow[], marketDomains: MarketDomainMap): DailyAggregates;
71
+ //# sourceMappingURL=daily.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daily.d.ts","sourceRoot":"","sources":["../../src/aggregator/daily.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,249 @@
1
+ /**
2
+ * Daily fact table builders.
3
+ *
4
+ * Pure in-memory aggregation — input: events + positions + market→domain map.
5
+ * Output: arrays of rows ready to bulk-insert into Postgres.
6
+ *
7
+ * Approach: full recompute per cycle. With ~100k events this is sub-second.
8
+ * Switch to incremental if event count grows past ~10M.
9
+ */
10
+ import { LIQUIDITY_ADD_TYPES, LIQUIDITY_REMOVE_TYPES, TRADE_EVENT_TYPES, parseCollateralAmount, } from './sources';
11
+ import { primaryDomainOf } from './domains';
12
+ function dateOf(ts) {
13
+ const d = new Date(ts * 1000);
14
+ const yyyy = d.getUTCFullYear();
15
+ const mm = String(d.getUTCMonth() + 1).padStart(2, '0');
16
+ const dd = String(d.getUTCDate()).padStart(2, '0');
17
+ return `${yyyy}-${mm}-${dd}`;
18
+ }
19
+ export function buildDailyAggregates(events, marketDomains) {
20
+ // Keys for nested maps
21
+ const traderBuckets = new Map(); // key: date|trader|domain
22
+ const lpBuckets = new Map(); // key: date|provider|domain
23
+ const marketBuckets = new Map(); // key: date|market_address
24
+ const domainBuckets = new Map(); // key: date|domain
25
+ const platformBuckets = new Map(); // key: date
26
+ // First-seen trackers for new_traders / new_lps
27
+ const traderFirstDate = new Map();
28
+ const lpFirstDate = new Map();
29
+ for (const event of events) {
30
+ const date = dateOf(event.timestamp);
31
+ const domain = primaryDomainOf(marketDomains, event.market_address);
32
+ const isTrade = TRADE_EVENT_TYPES.has(event.event_type);
33
+ const isLiqAdd = LIQUIDITY_ADD_TYPES.has(event.event_type);
34
+ const isLiqRemove = LIQUIDITY_REMOVE_TYPES.has(event.event_type);
35
+ const collateral = parseCollateralAmount(event.collateral_posted);
36
+ const isSell = (event.is_position_sell ?? 0) === 1;
37
+ // ── platform (date) ──
38
+ let platform = platformBuckets.get(date);
39
+ if (!platform) {
40
+ platform = {
41
+ trade_count: 0,
42
+ traders: new Set(),
43
+ lps: new Set(),
44
+ volume_collateral: 0,
45
+ liquidity_added: 0,
46
+ liquidity_removed: 0,
47
+ markets: new Set(),
48
+ };
49
+ platformBuckets.set(date, platform);
50
+ }
51
+ platform.markets.add(event.market_address);
52
+ // ── domain (date|domain) ──
53
+ const domainKey = `${date}|${domain}`;
54
+ let domainBucket = domainBuckets.get(domainKey);
55
+ if (!domainBucket) {
56
+ domainBucket = {
57
+ trade_count: 0,
58
+ traders: new Set(),
59
+ lps: new Set(),
60
+ volume_collateral: 0,
61
+ liquidity_added: 0,
62
+ liquidity_removed: 0,
63
+ markets: new Set(),
64
+ };
65
+ domainBuckets.set(domainKey, domainBucket);
66
+ }
67
+ domainBucket.markets.add(event.market_address);
68
+ // ── market (date|market) ──
69
+ const marketKey = `${date}|${event.market_address}`;
70
+ let marketBucket = marketBuckets.get(marketKey);
71
+ if (!marketBucket) {
72
+ marketBucket = {
73
+ trade_count: 0,
74
+ traders: new Set(),
75
+ lps: new Set(),
76
+ volume_collateral: 0,
77
+ liquidity_added: 0,
78
+ liquidity_removed: 0,
79
+ };
80
+ marketBuckets.set(marketKey, marketBucket);
81
+ }
82
+ if (isTrade && event.trader) {
83
+ const trader = event.trader;
84
+ platform.trade_count += 1;
85
+ platform.traders.add(trader);
86
+ platform.volume_collateral += collateral;
87
+ domainBucket.trade_count += 1;
88
+ domainBucket.traders.add(trader);
89
+ domainBucket.volume_collateral += collateral;
90
+ marketBucket.trade_count += 1;
91
+ marketBucket.traders.add(trader);
92
+ marketBucket.volume_collateral += collateral;
93
+ const traderKey = `${date}|${trader}|${domain}`;
94
+ let traderBucket = traderBuckets.get(traderKey);
95
+ if (!traderBucket) {
96
+ traderBucket = {
97
+ trade_count: 0,
98
+ buy_count: 0,
99
+ sell_count: 0,
100
+ volume_collateral: 0,
101
+ markets: new Set(),
102
+ };
103
+ traderBuckets.set(traderKey, traderBucket);
104
+ }
105
+ traderBucket.trade_count += 1;
106
+ if (isSell) {
107
+ traderBucket.sell_count += 1;
108
+ }
109
+ else {
110
+ traderBucket.buy_count += 1;
111
+ }
112
+ traderBucket.volume_collateral += collateral;
113
+ traderBucket.markets.add(event.market_address);
114
+ // first-seen trader date
115
+ const prev = traderFirstDate.get(trader);
116
+ if (!prev || date < prev) {
117
+ traderFirstDate.set(trader, date);
118
+ }
119
+ }
120
+ if ((isLiqAdd || isLiqRemove) && event.trader) {
121
+ const provider = event.trader;
122
+ platform.lps.add(provider);
123
+ domainBucket.lps.add(provider);
124
+ marketBucket.lps.add(provider);
125
+ const lpKey = `${date}|${provider}|${domain}`;
126
+ let lpBucket = lpBuckets.get(lpKey);
127
+ if (!lpBucket) {
128
+ lpBucket = {
129
+ deposit_count: 0,
130
+ withdraw_count: 0,
131
+ deposited: 0,
132
+ withdrawn: 0,
133
+ markets: new Set(),
134
+ };
135
+ lpBuckets.set(lpKey, lpBucket);
136
+ }
137
+ lpBucket.markets.add(event.market_address);
138
+ if (isLiqAdd) {
139
+ lpBucket.deposit_count += 1;
140
+ lpBucket.deposited += collateral;
141
+ marketBucket.liquidity_added += collateral;
142
+ domainBucket.liquidity_added += collateral;
143
+ platform.liquidity_added += collateral;
144
+ }
145
+ else {
146
+ lpBucket.withdraw_count += 1;
147
+ lpBucket.withdrawn += collateral;
148
+ marketBucket.liquidity_removed += collateral;
149
+ domainBucket.liquidity_removed += collateral;
150
+ platform.liquidity_removed += collateral;
151
+ }
152
+ const prev = lpFirstDate.get(provider);
153
+ if (!prev || date < prev) {
154
+ lpFirstDate.set(provider, date);
155
+ }
156
+ }
157
+ }
158
+ // ── Materialize ──
159
+ const trader = [];
160
+ for (const [key, b] of traderBuckets) {
161
+ const [date, traderId, domain_slug] = key.split('|');
162
+ if (!date || !traderId || !domain_slug)
163
+ continue;
164
+ trader.push({
165
+ date,
166
+ trader: traderId,
167
+ domain_slug,
168
+ trade_count: b.trade_count,
169
+ buy_count: b.buy_count,
170
+ sell_count: b.sell_count,
171
+ volume_collateral: b.volume_collateral,
172
+ markets_traded: b.markets.size,
173
+ });
174
+ }
175
+ const lp = [];
176
+ for (const [key, b] of lpBuckets) {
177
+ const [date, provider, domain_slug] = key.split('|');
178
+ if (!date || !provider || !domain_slug)
179
+ continue;
180
+ lp.push({
181
+ date,
182
+ provider,
183
+ domain_slug,
184
+ deposit_count: b.deposit_count,
185
+ withdraw_count: b.withdraw_count,
186
+ deposited: b.deposited,
187
+ withdrawn: b.withdrawn,
188
+ markets_active: b.markets.size,
189
+ });
190
+ }
191
+ const market = [];
192
+ for (const [key, b] of marketBuckets) {
193
+ const [date, market_address] = key.split('|');
194
+ if (!date || !market_address)
195
+ continue;
196
+ market.push({
197
+ date,
198
+ market_address,
199
+ trade_count: b.trade_count,
200
+ unique_traders: b.traders.size,
201
+ volume_collateral: b.volume_collateral,
202
+ liquidity_added: b.liquidity_added,
203
+ liquidity_removed: b.liquidity_removed,
204
+ unique_lps: b.lps.size,
205
+ });
206
+ }
207
+ const domain = [];
208
+ for (const [key, b] of domainBuckets) {
209
+ const [date, domain_slug] = key.split('|');
210
+ if (!date || !domain_slug)
211
+ continue;
212
+ domain.push({
213
+ date,
214
+ domain_slug,
215
+ trade_count: b.trade_count,
216
+ unique_traders: b.traders.size,
217
+ unique_lps: b.lps.size,
218
+ volume_collateral: b.volume_collateral,
219
+ liquidity_net: b.liquidity_added - b.liquidity_removed,
220
+ active_markets: b.markets.size,
221
+ });
222
+ }
223
+ const platform = [];
224
+ for (const [date, b] of platformBuckets) {
225
+ let new_traders = 0;
226
+ for (const [, firstDate] of traderFirstDate) {
227
+ if (firstDate === date)
228
+ new_traders += 1;
229
+ }
230
+ let new_lps = 0;
231
+ for (const [, firstDate] of lpFirstDate) {
232
+ if (firstDate === date)
233
+ new_lps += 1;
234
+ }
235
+ platform.push({
236
+ date,
237
+ trade_count: b.trade_count,
238
+ unique_traders: b.traders.size,
239
+ unique_lps: b.lps.size,
240
+ new_traders,
241
+ new_lps,
242
+ volume_collateral: b.volume_collateral,
243
+ liquidity_net: b.liquidity_added - b.liquidity_removed,
244
+ active_markets: b.markets.size,
245
+ });
246
+ }
247
+ return { trader, lp, market, domain, platform };
248
+ }
249
+ //# sourceMappingURL=daily.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daily.js","sourceRoot":"","sources":["../../src/aggregator/daily.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Market → primary domain map, fetched once per aggregator cycle.
3
+ *
4
+ * Returned as a plain Map<marketAddress, primaryDomainSlug>. Markets without
5
+ * any domain assignment fall back to 'other' so every event has a domain to
6
+ * attribute to.
7
+ */
8
+ import type { SQL } from 'bun';
9
+ export type MarketDomainMap = ReadonlyMap<string, string>;
10
+ /** All primary-domain rows. */
11
+ export declare function loadMarketPrimaryDomains(pg: SQL): Promise<MarketDomainMap>;
12
+ /** Lookup with `'other'` fallback. */
13
+ export declare function primaryDomainOf(map: MarketDomainMap, marketAddress: string): string;
14
+ /**
15
+ * Returns all (market, slug) pairs — useful for "user touched N domains"
16
+ * style metrics. A market may be tagged with multiple domains; this returns
17
+ * every assignment.
18
+ */
19
+ export declare function loadAllMarketDomains(pg: SQL): Promise<ReadonlyMap<string, ReadonlySet<string>>>;
20
+ //# sourceMappingURL=domains.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domains.d.ts","sourceRoot":"","sources":["../../src/aggregator/domains.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE/B,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE1D,+BAA+B;AAC/B,wBAAsB,wBAAwB,CAAC,EAAE,EAAE,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAYhF;AAED,sCAAsC;AACtC,wBAAgB,eAAe,CAAC,GAAG,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAEnF;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,GAAG,GACN,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAenD"}