2026-03-04 02:03:08 -08:00
# Activity Feed — Event Schema and Ingestion
**Purpose:** Canonical event model and ingestion spec for the normalized activity feed: transfers, app events, and bridge stitching. Table: `activity_events` (migration 0014).
**References:** [indexer-architecture.md ](../../explorer-monorepo/docs/specs/indexing/indexer-architecture.md ), [heatmap-chains.ts ](../../smom-dbis-138/services/token-aggregation/src/config/heatmap-chains.ts ) (ALT vs B/SBS), [cross-chain-bridges.ts ](../../smom-dbis-138/services/token-aggregation/src/config/cross-chain-bridges.ts ) (`getRouteFromRegistry` ).
---
## 1. Table: `activity_events`
| Column | Type | Description |
|--------|------|-------------|
| `id` | uuid | Primary key (default gen_random_uuid()) |
| `chain_id` | integer | 138 or 651940 (and others when indexed) |
| `transaction_hash` | varchar(66) | Tx hash |
| `log_index` | integer | Log index (0 for tx-level) |
| `block_number` | bigint | Block number |
| `block_timestamp` | timestamptz | Block time |
| `actor` | varchar(42) | Wallet that initiated the action |
| `subject` | varchar(42) | Optional: user/account/tokenId/resource |
| `event_type` | varchar(32) | TRANSFER, APP_ACTION, CLAIM, BRIDGE_OUT, BRIDGE_IN |
| `contract_address` | varchar(42) | Contract that emitted or was called |
| `data` | jsonb | Parsed event fields |
| `routing` | jsonb | `{ "path": "ALT" | "CCIP", "fromChain", "toChain", "bridgeTxHash"?: string }` |
| `created_at` | timestamptz | Insert time |
**Unique:** `(chain_id, transaction_hash, log_index)` .
---
## 2. Ingestion
### 2.1 Transfers
- **Source:** Existing `token_transfers` (and ERC-721/1155 logs when indexed).
- **Mapping:** For each row: insert into `activity_events` with `event_type = 'TRANSFER'` , `actor = from_address` , `subject = to_address` (or token id for NFT), `data = { from, to, value, tokenContract }` , `contract_address = token_contract` . `routing` = NULL for same-chain transfers.
docs: update master documentation and push to Gitea (2026-03-06)
- MASTER_INDEX: Last Updated 2026-03-06; status 59/59 contracts; add NEXT_STEPS_LIST, CONTRACT_NEXT_STEPS_LIST
- docs/README, NEXT_STEPS_INDEX, 06-besu/MASTER_INDEX: Last Updated 2026-03-06
- Contract check script: 59 addresses (PMM, vault/reserve, CompliantFiatTokens); canonical CCIP/router
- New docs: EXECUTION_CHECKLIST, NEXT_STEPS_LIST, DOTENV_AUDIT, ADDITIONAL_PATHS, deployer gas runbook, WEMIX_ACQUISITION_TABLED, etc.
- Config: deployer-gas-routes, cro-wemix-swap-routes, routing-registry, token-mapping
- Scripts: check-contracts-on-chain-138, check-pmm-pool-balances-chain138, deployer-gas-auto-route, acquire-cro-and-wemix-gas
- Operator rule: operator-lan-access-check.mdc
Made-with: Cursor
2026-03-06 19:11:25 -08:00
- **Backfill:** Migration `0015_activity_events_backfill_from_token_transfers.up.sql` runs a one-time `INSERT ... SELECT` from `token_transfers` with `ON CONFLICT DO NOTHING` . Run after 0014.
- **Real-time:** The Track 2 token indexer (`explorer-monorepo/backend/indexer/track2/token_indexer.go` ) inserts into `activity_events` on each new token transfer (same row as `token_transfers` ), so the feed stays current without a separate job.
2026-03-04 02:03:08 -08:00
### 2.2 App events
- **Source:** Application-lifecycle events (create, complete, settle, redeem, etc.) from your contracts.
- **Registry:** Maintain a mapping (event signature → `event_type` + parser). Example: `0x...` → `APP_ACTION` , parse `data` from log topics/data.
- **Insert:** Decode log; set `event_type` , `actor` (e.g. tx from), `subject` (e.g. orderId), `data` (decoded fields), `contract_address` .
### 2.3 Bridge stitching
- **Source:** Bridge contracts (AlltraAdapter, CCIP WETH9/WETH10); events such as lock/burn on source, mint/release on destination.
- **Routing:** Use [getRouteFromRegistry ](../../smom-dbis-138/services/token-aggregation/src/config/cross-chain-bridges.ts ) or [config/routing-registry.json ](../../config/routing-registry.json ): 138↔651940 → `path: "ALT"` , 138↔others → `path: "CCIP"` .
- **Insert:** For each bridge event, set `routing = { path: "ALT"|"CCIP", fromChain, toChain, bridgeTxHash }` . Optionally correlate "bridge out" and "bridge in" with a shared `data.correlationId` so the API can return one stitched feed item per cross-chain move.
---
## 3. Activity feed API
docs: update master documentation and push to Gitea (2026-03-06)
- MASTER_INDEX: Last Updated 2026-03-06; status 59/59 contracts; add NEXT_STEPS_LIST, CONTRACT_NEXT_STEPS_LIST
- docs/README, NEXT_STEPS_INDEX, 06-besu/MASTER_INDEX: Last Updated 2026-03-06
- Contract check script: 59 addresses (PMM, vault/reserve, CompliantFiatTokens); canonical CCIP/router
- New docs: EXECUTION_CHECKLIST, NEXT_STEPS_LIST, DOTENV_AUDIT, ADDITIONAL_PATHS, deployer gas runbook, WEMIX_ACQUISITION_TABLED, etc.
- Config: deployer-gas-routes, cro-wemix-swap-routes, routing-registry, token-mapping
- Scripts: check-contracts-on-chain-138, check-pmm-pool-balances-chain138, deployer-gas-auto-route, acquire-cro-and-wemix-gas
- Operator rule: operator-lan-access-check.mdc
Made-with: Cursor
2026-03-06 19:11:25 -08:00
**Endpoint:** `GET /api/v1/track2/activity` (Track 2 auth required). Implemented in `explorer-monorepo/backend/api/track2/endpoints.go` (`HandleActivityFeed` ).
**Query params:**
- `address` — filter by actor or subject (user feed).
- `event_type` — filter by event type (e.g. `TRANSFER` , `APP_ACTION` ).
- `chain_id` — filter by chain (default: server chain).
- `page` , `limit` (default 50, max 100) — pagination.
2026-03-04 02:03:08 -08:00
**Queries:**
docs: update master documentation and push to Gitea (2026-03-06)
- MASTER_INDEX: Last Updated 2026-03-06; status 59/59 contracts; add NEXT_STEPS_LIST, CONTRACT_NEXT_STEPS_LIST
- docs/README, NEXT_STEPS_INDEX, 06-besu/MASTER_INDEX: Last Updated 2026-03-06
- Contract check script: 59 addresses (PMM, vault/reserve, CompliantFiatTokens); canonical CCIP/router
- New docs: EXECUTION_CHECKLIST, NEXT_STEPS_LIST, DOTENV_AUDIT, ADDITIONAL_PATHS, deployer gas runbook, WEMIX_ACQUISITION_TABLED, etc.
- Config: deployer-gas-routes, cro-wemix-swap-routes, routing-registry, token-mapping
- Scripts: check-contracts-on-chain-138, check-pmm-pool-balances-chain138, deployer-gas-auto-route, acquire-cro-and-wemix-gas
- Operator rule: operator-lan-access-check.mdc
Made-with: Cursor
2026-03-06 19:11:25 -08:00
- **By user:** `address=0x...` → `WHERE actor = $address OR subject = $address` (paginated).
- **By token/NFT:** Use `event_type=TRANSFER` and `contract_address` or filter client-side by `data.tokenContract` / `data.tokenId` .
- **Global:** Omit `address` ; optional `event_type` ; pagination by `(block_timestamp DESC, id DESC)` .
2026-03-04 02:03:08 -08:00
docs: update master documentation and push to Gitea (2026-03-06)
- MASTER_INDEX: Last Updated 2026-03-06; status 59/59 contracts; add NEXT_STEPS_LIST, CONTRACT_NEXT_STEPS_LIST
- docs/README, NEXT_STEPS_INDEX, 06-besu/MASTER_INDEX: Last Updated 2026-03-06
- Contract check script: 59 addresses (PMM, vault/reserve, CompliantFiatTokens); canonical CCIP/router
- New docs: EXECUTION_CHECKLIST, NEXT_STEPS_LIST, DOTENV_AUDIT, ADDITIONAL_PATHS, deployer gas runbook, WEMIX_ACQUISITION_TABLED, etc.
- Config: deployer-gas-routes, cro-wemix-swap-routes, routing-registry, token-mapping
- Scripts: check-contracts-on-chain-138, check-pmm-pool-balances-chain138, deployer-gas-auto-route, acquire-cro-and-wemix-gas
- Operator rule: operator-lan-access-check.mdc
Made-with: Cursor
2026-03-06 19:11:25 -08:00
**Pagination:** Page/limit (offset-based); limit 50 per page, max 100.
2026-03-04 02:03:08 -08:00
**Example (by user):**
```sql
SELECT * FROM activity_events
WHERE actor = $1 OR subject = $1
ORDER BY block_timestamp DESC, id DESC
LIMIT 50 OFFSET $2;
```
---
## 4. Event type enum (logical)
| event_type | Description |
|------------|-------------|
| TRANSFER | ERC-20/721/1155 transfer |
| APP_ACTION | App-lifecycle (create, complete, settle, etc.) |
| CLAIM | Claim/mint from drop or contract |
| BRIDGE_OUT | Lock/burn on source chain |
| BRIDGE_IN | Mint/release on destination chain |
---
docs: update master documentation and push to Gitea (2026-03-06)
- MASTER_INDEX: Last Updated 2026-03-06; status 59/59 contracts; add NEXT_STEPS_LIST, CONTRACT_NEXT_STEPS_LIST
- docs/README, NEXT_STEPS_INDEX, 06-besu/MASTER_INDEX: Last Updated 2026-03-06
- Contract check script: 59 addresses (PMM, vault/reserve, CompliantFiatTokens); canonical CCIP/router
- New docs: EXECUTION_CHECKLIST, NEXT_STEPS_LIST, DOTENV_AUDIT, ADDITIONAL_PATHS, deployer gas runbook, WEMIX_ACQUISITION_TABLED, etc.
- Config: deployer-gas-routes, cro-wemix-swap-routes, routing-registry, token-mapping
- Scripts: check-contracts-on-chain-138, check-pmm-pool-balances-chain138, deployer-gas-auto-route, acquire-cro-and-wemix-gas
- Operator rule: operator-lan-access-check.mdc
Made-with: Cursor
2026-03-06 19:11:25 -08:00
## 5. Migrations
2026-03-04 02:03:08 -08:00
docs: update master documentation and push to Gitea (2026-03-06)
- MASTER_INDEX: Last Updated 2026-03-06; status 59/59 contracts; add NEXT_STEPS_LIST, CONTRACT_NEXT_STEPS_LIST
- docs/README, NEXT_STEPS_INDEX, 06-besu/MASTER_INDEX: Last Updated 2026-03-06
- Contract check script: 59 addresses (PMM, vault/reserve, CompliantFiatTokens); canonical CCIP/router
- New docs: EXECUTION_CHECKLIST, NEXT_STEPS_LIST, DOTENV_AUDIT, ADDITIONAL_PATHS, deployer gas runbook, WEMIX_ACQUISITION_TABLED, etc.
- Config: deployer-gas-routes, cro-wemix-swap-routes, routing-registry, token-mapping
- Scripts: check-contracts-on-chain-138, check-pmm-pool-balances-chain138, deployer-gas-auto-route, acquire-cro-and-wemix-gas
- Operator rule: operator-lan-access-check.mdc
Made-with: Cursor
2026-03-06 19:11:25 -08:00
- **0014 — table:** [0014_activity_events.up.sql ](../../explorer-monorepo/backend/database/migrations/0014_activity_events.up.sql ) (down: `0014_activity_events.down.sql` ).
- **0015 — backfill:** [0015_activity_events_backfill_from_token_transfers.up.sql ](../../explorer-monorepo/backend/database/migrations/0015_activity_events_backfill_from_token_transfers.up.sql ): one-time backfill from `token_transfers` ; down is no-op.
2026-03-04 02:03:08 -08:00
Run with your existing migration runner (e.g. golang-migrate, node-pg-migrate) against the explorer/backend DB.