Endpoints
There is no cancel endpoint
No relayer route cancels, refunds or claims. Every one of those is a permissionless contract call that takes the order’s parameters. The relayer sends them as each becomes possible, and any wallet may send them too.GET /v1/trades/:id/cancel hands out what each call needs, proofs included. The trade page
offers a button for each step that applies, built on this route.
Two settlement routes refuse work once a trade needs the cancel path:
Who is the primary
TheAdManager on the ad chain is the primary. Only there does a clock run, and only there is the
cancel decided. The OrderPortal on the order chain follows. It has no clock after the deadline:
it refunds the bridger only against a proof of the primary’s cancel leaf, and pays the maker against
the primary’s settled or forfeit leaf. Nothing on it can refund on time alone, so nothing can get
ahead of the primary’s decision.
Those proofs are checked against a root of the ad chain published by the
anchor service. If no root is anchored yet, the refund waits until one is.
What happens on chain
None of these calls checks who sends it, and none is stopped by a pause. A pause stops only new ads, funding, locks and deposits, never an exit. EVM names first, Stellar names in brackets.
The dispute calls (
finalizeDispute) are on Disputes.
A few things a client needs to know:
- Payouts keep working into the window, but not equally. The
AdManagerpayout to the bridger is accepted until just before the window ends. TheOrderPortalpayout to the maker stops shortly before the deadline. So past the deadline the maker cannot settle by co-signature, but the bridger still can until the window closes. - The window’s end is a view.
cancelFinalizesAt(params)(cancel_finalizes_at) returns it, grace included, or0when no window is open. The relayer copies it into the trade’sclaimFinalizeAt. When the maker halted settlement on this order, the window gets an extra grace period. See Deadlines and clocks. - A payout that fails to push is credited, not lost. The amount waits in
claimable(recipient, token)and the recipient pulls it withclaim(recipient, token), which works during a pause too.
Every self-serve ending
GET /v1/trades/:id/cancel lists every call a party can send to end the trade: the cancels and
refund, the forfeit payout, and the settled evidence. For each it gives the chain and escrow, the
order’s parameters, when the chain accepts it, and, for the calls that take a proof, the proof the
relayer built.
It needs no auth, although the trade itself is party-only. It is the refund’s liveness path: a party
who lost its session, or anyone it asks for help, can still send the refund. Every field is public,
every call is permissionless, and a refund always pays params.bridger, whoever sends it. The route
has a strict per-IP rate limit.
Paths
Step states
Step states come from the two escrows, so a call you sent yourself shows
done on the next read.
Chain reads are shared between callers for 15 seconds. If a read fails, the states fall back to the
relayer’s records and stateFrom is records-fallback: a step may then show ready although it is
done. Show that as “status unconfirmed”. Sending a call too early, or twice, only reverts.
Sending each call
The escrow iscontractAddress on chainId. On Stellar, the 32-byte fields are BytesN<32>.
targetRoot, nullifierHash and proof come from the step’s package.
Keep the packages
The proofs need nothing secret: each proves a leaf already on the other chain, against a root the target chain has already anchored. Only the relayer builds them, and the route serves a package as soon as the chain allows the call and the relayer has proved it. A package does not expire, so download each one when it appears and keep it with the trade: you can still send it if the relayer’s API is unreachable later.claimCancel and finalizeCancel need no proof and work from the saved
params alone. Packages are removed 24 hours after the trade ends.
What to poll
PollGET /v1/trades/:id for the trade’s progress through the cancel,
and GET /v1/trades/:id/cancel when you want to send a step yourself.
The trade never moves backwards. Once the
AdManager has cancelled and the refund is still to land,
the trade stays CLAIMED with the window’s end in claimFinalizeAt until the refund lands and it
becomes CANCELLED. The cancelReason values are listed on Trades.
GET /v1/trades/:id/settlement follows along: Claimed
while the trade is CLAIMED, Disputed while DISPUTED, and Cancelled with
signaturesCollected: 0 once it is CANCELLED. Both parties also get a TRADE_CANCELLED
notification, with text chosen by the reason.