Quotes live on the ledger
A quote is a signed on-ledger commitment, not a row in a database
When you call POST /maker/quotes, the desk does not just record a price. The
quote becomes committed token-standard v2 allocations on the Canton ledger,
signed by your party — one allocation per instrument you send or receive
(typically two: the base and the quote asset). Each names the desk operator as
the settlement executor:
- the asset you send — locked from your holdings the moment you sign (the swap leg, plus the desk fee when that is the quote asset);
- the asset you receive — states the leg you expect. When it is the quote
asset (a
BUYRFQ, where you sell the base) it also carries the desk fee, which is always paid in the quote asset — so keep at least the fee free there: the notional you are about to receive cannot fund it.
The contract ids of those allocations are the quote's anchor (anchorCids).
The desk's book keeps only a cache; the commitment itself lives on the ledger.
Why this matters to you
- Your quote is binding, and funded. A committed allocation locks its holdings: you cannot spend them elsewhere, and the desk verifies nothing of yours at accept. Only the executor can release them — by settling the trade, or by cancelling the allocation once the quote is dead.
- Quoting costs a prepare call plus your signatures. The desk records the
quote at once but shows it to nobody until its allocations land, so a quote
whose signing never happens stays invisible and dies at its
validUntil. - Funding is checked at quoting time. An amount your holdings cannot cover
answers 409
INSUFFICIENT_FUNDSand records nothing. - Capital is committed per quote, and re-quoting recycles it. A re-quote on the same RFQ releases the old quote's allocations first, then funds the new ones from what came back — no headroom for two quotes is needed. The flip side: between the two you have no quote on that RFQ, and if the new one fails (say, the price now needs more than you hold) you are left with none — just quote again.
Anchoring
The desk cannot sign the allocations for you, so POST /maker/quotes returns
before they exist on the ledger. Their hashes come back in the response as
actions (purpose allocate, one per allocation) and wait on
GET /tx/pending too (a passkey maker's browser signs them automatically) —
see The sign queue.
Until every one of them lands, the quote is unanchored: the taker does not
see it, and accepting it answers 409 RETRY_LATER. When they do land,
quote.anchored {quoteId, rfqId, anchorCids} fires on your stream and the
quote is live. Unsigned, it dies at its validUntil — by default the desk's
quote lifetime, capped at the RFQ deadline — and its actions go with it.
Withdrawal
Re-quoting the same RFQ or calling DELETE /maker/quotes/:id marks the old
quote revoked, and the desk — as executor — cancels its allocations on the
ledger (Allocation_Cancel): your holdings are free again within a sweep.
Expired quotes are swept the same way. Once a quote is accepted and settling,
it can no longer be revoked (409).