Quote — Get Started
What you build here
A desk that answers. By the end you will have logged in to read your inbox, pulled a directed RFQ, priced it, signed the Terms, and watched the relayer anchor your quote on-chain. This is the smallest complete maker integration.
Follow every step in order. Nothing branches.
Testnet only. Sonic Testnet, chain 14601.
Reads need a login; the quote itself is authenticated by your signature. You log in to read your inbox. The bind authority is the Terms signature you produce in step 4.
What you need first
- A wallet approved as a
MAKERon the venue. See API → Get Started (~4 min). - Test USDC deposited into your general balance, and gas.
- The relayer base URL and the deployed core address.
Step 1 — Log in to read your inbox
The inbox is a private read. Get a challenge, sign it with personal_sign, exchange it for a one-hour token.
const { message } = await fetch(`${RELAYER}/auth/challenge`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ address: maker }),
}).then((r) => r.json());
const signature = await wallet.signMessage({ message });
const { token } = await fetch(`${RELAYER}/auth/login`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ address: maker, signature }),
}).then((r) => r.json());
Step 2 — Poll the inbox
GET /rfq/inbox?maker=<addr> with your token. Each item is an RFQ aimed at your desk, on a short expiry timer.
const inbox = await fetch(`${RELAYER}/rfq/inbox?maker=${maker}`, {
headers: { Authorization: `Bearer ${token}` },
}).then((r) => r.json());
const item = inbox[0];
const rfqId = item.rfq_id ?? item.rfqId;
Step 3 — Price the request
POST /rfq/:id/quote with your rate and margin schedule. This is unsigned — the relayer returns canonical Terms for you to sign.
const priced = await fetch(`${RELAYER}/rfq/${rfqId}/quote`, {
method: "POST",
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
body: JSON.stringify({
quote: {
rfq_id: rfqId,
locked_rate: rate, // quote-ccy per USD, scaled
im_taker_bps: 200,
im_maker_bps: 100,
threshold_bps: 0,
mta_bps: 10,
tol_bps: 50,
valid_until: nowSecs + 600,
quote_nonce: String(nowSecs),
},
}),
}).then((r) => r.json());
const terms = termsFromWire(priced.terms);
Step 4 — Sign the Terms and confirm
Sign the returned Terms (EIP-712), then POST /rfq/:id/confirm with the signature. On confirm the relayer anchors the quote on-chain.
const makerSig = await wallet.signTypedData({
domain: { name: "CRX", version: "1", chainId: 14601, verifyingContract: CRX },
types: TERMS_TYPES,
primaryType: "Terms",
message: terms,
});
await fetch(`${RELAYER}/rfq/${rfqId}/confirm`, {
method: "POST",
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
body: JSON.stringify({ signature: makerSig }),
});
Anchoring takes a few seconds. Once it confirms, the taker can fetch the bundle and bind.
Step 5 — Allocate margin once bound
When the taker binds, post your side's initial margin into the agreement's SCA.
await crx.write.allocate([maId, USDC, imMaker]);
What you have now
A live position you stand on the other side of, marked continuously. From here:
- The inbox model in full: Maker Inbox (~4 min).
- How your collateral is posted and held: Margin & Allocation (~5 min).
Next: Maker Inbox (~4 min) — the expiry timers and quote-lock you just touched.