> ## Documentation Index
> Fetch the complete documentation index at: https://docs.darkpool.fun/llms.txt
> Use this file to discover all available pages before exploring further.

# Quote Worker

> Hot-strike predict::get_trade_amounts poller to Redis cache + pubsub.

The quote-worker keeps the Redis quote cache fresh for any (`oracleId`, `strike`) the UI has marked **hot** (someone subscribed via WS or hit `/v1/quotes/…` in the last `HOT_TTL_S`, default 60s).

## Loop

```text theme={"system"}
for each hot (oracle, strike):
  devInspect predict::get_trade_amounts(oracle, strike, isUp=true)
  devInspect predict::get_trade_amounts(oracle, strike, isUp=false)
  if (new !== cached):
    SET  quote:<oracle>:<strike>   { yes_ask, no_ask, fairPerToken, asOf }
    PUBLISH quotes:v1:<oracle>:<strike>  { …payload }
  sleep(QUOTE_POLL_MS)              # default 2000ms
```

The diff check avoids spamming the WS channel with identical updates.

## Hot set maintenance

* WS `sub` to mark `(oracle, strike)` hot, set `HOT_TTL_S` expiry.
* WS `unsub` to leave the TTL to expire; rapid re-sub avoids a re-quote round-trip.
* REST `GET /v1/quotes/:oracle/:strike` cache miss to mark hot + immediate inline quote.

Non-hot strikes are quoted on demand by the api process when the cache misses.

## File

`packages/server/src/workers/quote-poller.ts`.

## Tuning

| Env var             | Default | Effect                                                            |
| ------------------- | ------- | ----------------------------------------------------------------- |
| `QUOTE_POLL_MS`     | `2000`  | Poll interval per hot strike                                      |
| `HOT_TTL_S`         | `60`    | Strike stays hot for this many seconds after last subscriber      |
| `QUOTE_CACHE_TTL_S` | `300`   | How long a cached quote is served stale before forcing a re-quote |

Higher polling rate to lower client-perceived latency but more RPC pressure. The 2s default is a good balance for a hackathon demo.
