Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,765 changes: 1,765 additions & 0 deletions contracts/test_snapshots/test/test_1_second_session.1.json

Large diffs are not rendered by default.

1,912 changes: 1,912 additions & 0 deletions contracts/test_snapshots/test/test_1_year_session_overflow_check.1.json

Large diffs are not rendered by default.

1,099 changes: 1,099 additions & 0 deletions contracts/test_snapshots/test/test_admin_can_update_fee_tiers.1.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1,332 changes: 1,332 additions & 0 deletions contracts/test_snapshots/test/test_expert_registration_and_availability.1.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1,875 changes: 1,875 additions & 0 deletions contracts/test_snapshots/test/test_flag_dispute_rejects_invalid_cid.1.json

Large diffs are not rendered by default.

2,094 changes: 2,094 additions & 0 deletions contracts/test_snapshots/test/test_flag_dispute_stores_evidence_cid.1.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1,904 changes: 1,904 additions & 0 deletions contracts/test_snapshots/test/test_get_current_earnings_zero_when_paused.1.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1,863 changes: 1,863 additions & 0 deletions contracts/test_snapshots/test/test_only_participants_can_pause_or_resume.1.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1,452 changes: 1,452 additions & 0 deletions contracts/test_snapshots/test/test_protocol_pause_blocks_new_sessions.1.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1,230 changes: 1,230 additions & 0 deletions contracts/test_snapshots/test/test_set_admin_and_fee_round_trip.1.json

Large diffs are not rendered by default.

1,189 changes: 1,189 additions & 0 deletions contracts/test_snapshots/test/test_set_and_get_expert_referrer.1.json

Large diffs are not rendered by default.

1,044 changes: 1,044 additions & 0 deletions contracts/test_snapshots/test/test_set_and_get_expert_staked_balance.1.json

Large diffs are not rendered by default.

977 changes: 977 additions & 0 deletions contracts/test_snapshots/test/test_set_and_get_treasury_address.1.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

977 changes: 977 additions & 0 deletions contracts/test_snapshots/test/test_set_staking_contract_address.1.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1,870 changes: 1,870 additions & 0 deletions contracts/test_snapshots/test/test_start_session_accepts_cid_v1.1.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1,870 changes: 1,870 additions & 0 deletions contracts/test_snapshots/test/test_start_session_stores_metadata_cid.1.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1,989 changes: 1,989 additions & 0 deletions contracts/test_snapshots/test/test_update_session_notes.1.json

Large diffs are not rendered by default.

1,578 changes: 1,578 additions & 0 deletions contracts/test_snapshots/test/test_withdraw_all_treasury_empties_balance.1.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1,103 changes: 1,103 additions & 0 deletions contracts/test_snapshots/test/test_withdraw_treasury_rejects_zero_amount.1.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

119 changes: 119 additions & 0 deletions docs/INDEXER_SETUP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Stellar / Soroban Contract Event Indexer Service

The **SkillSphere Soroban Event Indexer** is a backend service designed to monitor, filter, decode, and synchronize on-chain smart contract events from Stellar/Soroban RPC into PostgreSQL.

## Core Features

- **Interval Polling Engine**: Periodically polls the configured Stellar / Soroban RPC endpoint for contract events emitted by Escrow and Dispute smart contracts.
- **XDR Event Decoder**: Decodes binary XDR event topics and payloads into normalized JSON structures (`fund_session`, `pause_session`, `refund_session`, `complete_session`, `resolve_dispute`).
- **Resilient & Crash-Proof**: Safe XDR parsing wrappers ensure malformed event payloads, invalid topics, or network timeouts never crash the indexer daemon.
- **Idempotent Processing**: Records event IDs in `processed_events` to prevent double-processing or duplicate transaction entries.
- **Ledger Sequence Checkpointing**: Automatically persists the `last_ledger_sequence` in `ledger_checkpoints` so service restarts resume smoothly from the last synchronized block.
- **Database Adapters**: Supports PostgreSQL (`pg.Pool`) with auto-migrating SQL schema and an in-memory fallback for local lightweight development or unit tests.

---

## Environment Variables

Configure the service by setting environment variables in `.env` or system environment:

| Variable | Description | Default Value |
|---|---|---|
| `SOROBAN_RPC_URL` | Soroban RPC endpoint URL | `https://soroban-testnet.stellar.org` |
| `ESCROW_CONTRACT_ID` | Soroban Escrow Contract Address | `CC3W26Q6Q...` |
| `DISPUTE_CONTRACT_ID` | Soroban Dispute Contract Address | `CD3W26Q6Q...` |
Comment on lines +23 to +24

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Truncated contract-ID defaults are not usable as documentation.

CC3W26Q6Q... / CD3W26Q6Q... can't be copied or verified. Either print the full default address or state that these are required with no default.

📝 Proposed doc fix
-| `ESCROW_CONTRACT_ID` | Soroban Escrow Contract Address | `CC3W26Q6Q...` |
-| `DISPUTE_CONTRACT_ID` | Soroban Dispute Contract Address | `CD3W26Q6Q...` |
+| `ESCROW_CONTRACT_ID` | Soroban Escrow contract address (56-char `C...` strkey) | _required_ |
+| `DISPUTE_CONTRACT_ID` | Soroban Dispute contract address (56-char `C...` strkey) | _required_ |
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
| `ESCROW_CONTRACT_ID` | Soroban Escrow Contract Address | `CC3W26Q6Q...` |
| `DISPUTE_CONTRACT_ID` | Soroban Dispute Contract Address | `CD3W26Q6Q...` |
| `ESCROW_CONTRACT_ID` | Soroban Escrow contract address (56-char `C...` strkey) | _required_ |
| `DISPUTE_CONTRACT_ID` | Soroban Dispute contract address (56-char `C...` strkey) | _required_ |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/INDEXER_SETUP.md` around lines 23 - 24, Update the ESCROW_CONTRACT_ID
and DISPUTE_CONTRACT_ID entries in the environment-variable table to replace the
truncated example values with either their complete default contract addresses
or an explicit indication that no default exists and the variables are required.

| `POLL_INTERVAL_MS` | Polling interval in milliseconds | `3000` |
| `BATCH_LIMIT` | Event batch fetch limit | `100` |
| `DATABASE_URL` | PostgreSQL connection string | `postgresql://postgres:postgres@localhost:5432/skillsphere` |
| `START_LEDGER` | Fallback starting ledger if no checkpoint exists | `1` |

---

## Running the Indexer

### 1. Start the Indexer Daemon

To run the indexer in development or production mode:

```bash
npm run indexer
```

### 2. Run the Unit & Integration Test Suite

To run all event parsing, non-crash error handling, idempotency, and checkpoint recovery tests:

```bash
npm run test:indexer
```

---

## PostgreSQL Database Schema

When `DATABASE_URL` is configured, the indexer auto-initializes the following SQL schema:

```sql
-- Ledger Checkpoints Table
CREATE TABLE IF NOT EXISTS ledger_checkpoints (
id VARCHAR(64) PRIMARY KEY,
last_ledger_sequence BIGINT NOT NULL,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

-- Processed Events Table (for Idempotency)
CREATE TABLE IF NOT EXISTS processed_events (
event_id VARCHAR(128) PRIMARY KEY,
contract_id VARCHAR(128) NOT NULL,
topic VARCHAR(64) NOT NULL,
ledger_sequence BIGINT NOT NULL,
transaction_hash VARCHAR(128),
payload JSONB NOT NULL,
processed_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

-- Sessions Table
CREATE TABLE IF NOT EXISTS sessions (
id VARCHAR(128) PRIMARY KEY,
title VARCHAR(256),
expert_id VARCHAR(128),
seeker_id VARCHAR(128),
status VARCHAR(64) NOT NULL,
price VARCHAR(64),
transaction_hash VARCHAR(128),
network VARCHAR(32) DEFAULT 'testnet',
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

-- Transactions Table
CREATE TABLE IF NOT EXISTS transactions (
id VARCHAR(128) PRIMARY KEY,
hash VARCHAR(128) NOT NULL,
type VARCHAR(32) NOT NULL,
amount VARCHAR(64) NOT NULL,
date VARCHAR(32) NOT NULL,
status VARCHAR(32) NOT NULL,
network VARCHAR(32) DEFAULT 'testnet',
session_id VARCHAR(128),
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
```

---

## Supported Contract Events

1. **`fund_session` / `start_session`**
- Updates `Session` status to `'active'`.
- Inserts `Transaction` record with type `'deposit'` and status `'completed'`.
2. **`pause_session`**
- Updates `Session` status to `'paused'`.
3. **`refund_session` / `cancel_session`**
- Updates `Session` status to `'cancelled'`.
- Inserts `Transaction` record with type `'refund'` and status `'completed'`.
4. **`complete_session` / `settle_session`**
- Updates `Session` status to `'completed'`.
- Inserts `Transaction` record with type `'settlement'` and status `'completed'`.
5. **`resolve_dispute`**
- Updates `Session` status to `'completed'`.
- Inserts `Transaction` record with type `'settlement'` and status `'completed'`.
Loading
Loading