---
name: Mneme Watch Condition
description: Subscribe to a Base contract event via Mneme Streams — when the event fires, downstream mandates or notifications can react.
var: "event on <0xcontract> into <target_table>"
tags: [streams, mneme, watcher, base]
---

> **${var}** — One of:
> - `transfer on 0x3FcD…7b07 into mneme_transfers`
> - `swap on 0xPool... into pool_swaps`
> - `"Transfer(address,address,uint256)" on 0xabc... into custom_transfers`
>
> Template aliases: `transfer`, `approval`, `swap`. For custom events, paste the raw signature in quotes.

## Goal

Replace polling RPC calls in your CLI with a server-side subscription. Once you `watch`, Mneme tails Base for you forever (until you `unwatch`). Future trade decisions (or mandate triggers) just `SELECT FROM <target_table>` — no rate-limit dance, no missed blocks, re-org safe.

## Steps

### 1. Auth check

```bash
if [ -z "$MNEME_API_KEY" ]; then echo "MNEME_API_KEY not set"; exit 1; fi
GATEWAY="${MNEME_GATEWAY:-https://gateway.mnemedb.dev}"
```

### 2. Parse the var

Expected: `<event> on <0xcontract> into <table>`

- `<event>` — alias (`transfer` / `approval` / `swap`) OR raw `"Foo(address,uint256)"`
- `<0xcontract>` — 0x + 40 hex
- `<table>` — lowercase snake_case, ≤ 63 chars

If parsing fails, print the usage examples from the frontmatter and exit 1.

### 3. Idempotency check

```bash
EXISTING=$(curl -sS "$GATEWAY/v1/streams" \
  -H "Authorization: ApiKey $MNEME_API_KEY" \
  | jq --arg c "$CONTRACT" --arg t "$TABLE" \
       '.streams[] | select(.contract == ($c | ascii_downcase) and .target_table == $t)')
```

If a matching stream exists, print `(already watching #<id>)` and exit 0.

### 4. Create the subscription

```bash
curl -sS -X POST "$GATEWAY/v1/streams" \
  -H "Authorization: ApiKey $MNEME_API_KEY" \
  -H "Content-Type: application/json" \
  -d "$(jq -n \
        --arg c "$CONTRACT" \
        --arg e "$EVENT" \
        --arg t "$TABLE" \
        '{contract: $c, event: $e, target_table: $t, label: "metamask"}')"
```

The gateway parses the event signature, auto-creates the target table in your schema with the standard chain-event shape (`tx_hash`, `block_number`, `log_index`, `contract`, `event_name`, `args jsonb`, `block_ts`) plus indexes, and starts the 6s polling loop.

### 5. Output

```
✓ stream #<id> active
  event: <event_name> on <contract>
  table: <target_table>
  expected delay: ~6s after block confirmation
```

## Why this matters for MetaMask Agentic Wallet

Your mandate `conditions` can now reference a stream table directly. Example: `{when: "on_event", spec: {table: "mneme_transfers", op: "...", value: "..."}}`. The worker evaluates on every new row in that table. Subscribe once, the entire mandate fleet now reacts to chain truth.

## Notes

- List active streams: `GET /v1/streams`.
- Pause one: `DELETE /v1/streams/:id` (keeps the table, stops new inserts).
- For sub-second latency, run your own Alchemy webhook → `POST /v1/sql` INSERT.
- `args` is JSONB. Use `WHERE args->>'from' = '0x...'` in your condition specs.
