@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
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
|
-
| `
|
|
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
|
|
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"}
|