Skip to main content

RFQ Quoting with the CLI

overcast quote is a complete RFQ quoter in one command: it connects to the RFQ channel as TAKER, prices every incoming RFQ, and submits signed quotes until you hit Ctrl-C. You choose the brain — the built-in Black-Scholes pricer, or your own strategy behind a local webhook.

Setup checklist​

  1. Configure OVERCAST_API_KEY (currently required — how to get one), OVERCAST_KEYPAIR, OVERCAST_RPC_URL, OVERCAST_BACKEND_URL, and a target (--chain / OVERCAST_CHAIN or --protocol + deployment flags) (configuration).

  2. overcast assets — find the cash token (e.g. USDC).

  3. Hold that token in your wallet, then fund your escrow account:

    overcast deposit --token usdc --amount 10
    overcast balance --token usdc

    Premiums are paid from the escrow account. A quoter that connects but can't fill is almost always one that skipped this step.

  4. Run it:

    overcast quote

Built-in Black-Scholes pricer​

With no webhook configured, quote prices each RFQ itself:

FlagDefaultMeaning
-s, --spread0.02Your edge over fair value, as a fraction
--vol0.8Annualized implied volatility fallback
--rate0Annualized risk-free rate

How it prices: it identifies the single cash (stablecoin) leg — preferring Asset.cashLike before the symbol heuristic — cash settlement means a covered call, cash collateral means a cash-secured put — derives the strike from the two amounts, pulls spot from CoinGecko (falling back to the backend's last known price), uses the asset's implied volatility when the backend provides one (else --vol), computes Black-Scholes fair value, applies a 0.95–1.0 jitter plus 20% surcharges for oracle settlement / borrowAllowed, and quotes it plus your spread. RFQs it can't price (no single cash leg, no spot price, already expired, partially-specified legs) are skipped.

Bring your own strategy: the webhook​

To keep your pricing logic in your own process — any language, any framework — point quote at a local HTTP endpoint:

overcast quote --webhook-url http://127.0.0.1:9000/quote --webhook-timeout 5000

(OVERCAST_QUOTE_WEBHOOK_URL works as the env-var equivalent.)

The CLI POSTs every RFQ lifecycle event to your endpoint as a JSON envelope:

{
"type": "newRfq",
"timestamp": 1767225600000,
"maker": "<your quoter public key>",
"data": { "rfqId": "…", "details": { "…": "curated partial details" } }
}

with headers X-Overcast-Event and X-Overcast-Timestamp. Event types are newRfq, newQuote, quoteAccepted, rfqCancelled, rfqExpired, and error — but only newRfq is actionable. Your reply to it drives the quote:

{
"action": "quote",
"premium": { "premiumAsset": "<mint>", "premiumAmount": "12500000" }
}

or

{ "action": "skip", "reason": "outside my risk limits" }

Amounts are decimal strings in native units. A 204, a non-2xx status, a timeout, or malformed JSON all safely count as skip. Your endpoint supplies only the premium — the CLI remains authoritative over every other term, builds the offer, and signs it.

A machine-readable contract lives in the repo under packages/overcast-cli/webhook-contract/ — TypeScript declarations (overcast-quote-webhook.d.ts), a JSON schema, and a runnable example handler (example/webhook.mjs). A minimal Express handler:

app.post("/quote", (req, res) => {
const event = req.body;
if (event.type !== "newRfq") return res.status(204).end();

const premium = myPricer(event.data.details);
if (!premium) return res.json({ action: "skip" });

res.json({ action: "quote", premium });
});

When you outgrow the CLI​

The webhook gives you custom pricing; for custom everything (inventory management, hedging, multi-venue) build directly on the SDK — the entire loop the CLI runs is about forty lines.