CRXDocs

Request a Quote

Goal

Price a forward and read the quote. You will open a directed RFQ, wait for the maker to answer, and pull the bundle that holds the maker's signed Terms. This page stops at the quote in hand — binding is the next page.

Testnet only. Sonic Testnet, chain 14601.

No login required here. The trade path authenticates by signature, not session.

Before you start

  • Your wallet is approved as a TAKER.
  • You know the relayer base URL and the deployed core address (API reference, ~4 min).
  • You have a maker address from GET /makers.

Step 1 — Size the margin first (optional, no state change)

Call GET /margin?pair=&notional= to read the vol-scaled initial margin before you commit. It changes nothing; it tells you what the position will cost in collateral.

const m = await fetch(
  `${RELAYER}/margin?pair=USD/PHP&notional=100000`
).then((r) => r.json());
// → { im: "..." }  — IM in quote units

Step 2 — Open the request

POST /rfq. Direct it to one maker. The relayer routes it to that maker's inbox.

const res = await fetch(`${RELAYER}/rfq`, {
  method: "POST",
  headers: { "Content-Type": "application/json", "X-CRX-Address": taker },
  body: JSON.stringify({
    counterparty: maker,
    pair,                  // keccak256("USD/PHP")
    notional: notionalWad, // "100000" * 1e18, as a string
    direction: "long",
    tenor_days: 7,
    quote_window_secs: 600,
  }),
}).then((r) => r.json());

const rfqId = res.rfq_id ?? res.rfqId;

You hold an rfqId.

Step 3 — Wait for the maker to price and sign

The maker prices the request, signs the Terms, and confirms. On confirm the relayer anchors the agreed quote on-chain. Poll GET /rfq/:id/bundle until it returns.

let bundle = null;
for (let i = 0; i < 12 && !bundle; i++) {
  const r = await fetch(`${RELAYER}/rfq/${rfqId}/bundle`, {
    headers: { "X-CRX-Address": taker },
  });
  bundle = r.ok ? await r.json() : null;
  if (!bundle) await sleep(1000);
}

Anchoring takes a few seconds. Poll with a delay. One call and a giveup reads as "no maker answered" when the anchor was simply still confirming.

Step 4 — Read the quote

The bundle carries the maker's signed Terms. Read the rate and the margin schedule off it.

const terms = termsFromWire(bundle.terms);
// terms.lockedRate  — the forward rate the maker stands behind
// terms.imLongBps / terms.imShortBps  — the margin each side posts
// terms.sigDeadline — bind before this, or re-request

What happens — and the branch

Two outcomes:

  • A quote returns. The bundle holds the maker's signature over canonical Terms. The quote is yours to accept until sigDeadline. Bind it in Binding & Terms (~5 min), or let it expire.
  • No quote returns. The maker declined or the request window closed. The inbox item expired; nothing is bound and nothing is owed. Pick another maker from GET /makers and open a fresh RFQ.

Stop at the quote. Do not bind a quote whose sigDeadline has passed — re-request instead.

Next: Binding & Terms (~5 min) — sign the Terms and open the position.