The indexer keeps the backend in sync with onchain state so the relayer can resolve accounts quickly.

## Why it exists

Delegate-key authentication does not walk `AccountRegistry`. A cold key is verified against the signed `x-account-id`, or against `MEMWAL_ACCOUNT_ID` when that env is set. The indexer is what fills the `accounts` table the existence check and owner-token lookup read.

## How it works

The indexer is a standalone Rust service (`services/indexer`) that:

1. Connects to the same PostgreSQL database as the relayer
2. Polls Sui blockchain events using `suix_queryEvents`
3. Filters for `AccountCreated` events from the Walrus Memory package
4. Inserts `account_id → owner` mappings into the `accounts` table
5. Stores its event cursor in `indexer_state` so it can resume after restarts

## Auth resolution flow

When the relayer receives a signed request, it resolves the delegate key's account in this order:

1. **PostgreSQL cache** (`delegate_key_cache`), populated after a successful resolution
2. **Signed `x-account-id`**, or **`MEMWAL_ACCOUNT_ID`** when the header is absent, one account object, not a registry walk
3. Otherwise **`401`**. A cold key with no account id is not looked up onchain

After a successful resolution, the mapping is cached in `delegate_key_cache`. The indexed `accounts` table is not part of this chain.

## Configuration

The indexer reads these environment variables:

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `DATABASE_URL` | Yes | | PostgreSQL connection string |
| `MEMWAL_PACKAGE_ID` | Yes | | Walrus Memory contract package ID to filter events |
| `SUI_RPC_URL` | No | Mainnet fullnode | Sui RPC endpoint |
| `POLL_INTERVAL_SECS` | No | `5` | Seconds between event poll cycles |

## Running

[Source: indexer/purpose.md](https://github.com/MystenLabs/MemWal/blob/dev/docs/indexer/purpose.md)

```bash
$ cd services/indexer
$ cargo run
```

The indexer is recommended for production but optional for development, the relayer can fall back to onchain resolution without it.