Skip to main content
A dispute is how the maker or the bridger says a trade went wrong before its window closes. Filing, answering, ruling and finalizing are contract calls on the ad chain’s AdManager; the relayer has no route for them. Its dispute routes are the evidence store, where you upload the files behind your evidence and get the hash to commit. See Disputes for the bond, the rules and the outcomes.

Endpoints

The contract calls

Disputes live on the AdManager on the ad chain. The OrderPortal on the order chain has no dispute of its own; it follows the outcome once a proof of the ad chain’s result reaches it. On Soroban the same calls are dispute(params, filer, evidence), respond_to_dispute(params, responder, evidence) and finalize_dispute(params) on the ad-manager, where filer and responder must sign.
  • params is the order’s full parameter set from GET /v1/trades/:id/params. The order hash is recomputed from it, so the amount and the parties cannot be faked.
  • evidence is a bytes32 you commit to. Post your files to the evidence store first and commit the hash it returns, so the other party and the arbiter service can open what it points to. A hash committed without the store still works on chain, but nobody else can read it.
  • The bond. Quote it on chain before the wallet signs: DisputeManager.routeBond(peerChainId, adToken, adAmount) returns (bondToken, bond) on EVM (a zero bondToken means native), route_bond on Soroban. A native bond on EVM is sent as msg.value and must be exact.
  • Windows. You can file while the order is Open or Claimed, up to the order’s deadline plus its buffer. The answer must come before the challenge deadline, and before a ruling. The arbiter service rules before the same deadline. Proof that the trade settled ends the dispute at any point before finalize, over any ruling.
  • Finalize opens at disputeFinalizeAt on the trade. With no ruling the outcome is MutualRefund.
The relayer watches for filings, presents settlement proof when it exists, finalizes once the window is over and carries the outcome to the order chain. You do not need to send those calls yourself.

Upload a file

PUT /v1/trades/:id/evidence/files/:sha256 Upload one file. The body is the raw bytes (not JSON, not multipart), Content-Type is the file’s type, and the path carries the file’s SHA-256 as 0x + 64 hex. Uploading the same file again is accepted.
  • Types: image/jpeg, image/png, video/mp4 or application/pdf. The leading bytes must match the type.
  • At most 10 MiB per file and 10 files per party per trade.
  • Accepted while the trade is LOCKED, CLAIMED or DISPUTED.
  • Until you commit its hash on chain, only you can see the upload.
This route has a strict per-IP rate limit.

Post the manifest

POST /v1/trades/:id/evidence Describe your case and list the files you uploaded. The answer’s evidenceHash is the bytes32 your wallet commits in dispute or respondToDispute. You act for your own side only.
The hash is keccak-256 of { v: 1, description, files } as JSON, with the description trimmed and the files sorted by hash, so you can recompute it yourself.

Read the evidence

GET /v1/trades/:id/evidence Both sides’ committed evidence, plus your own uncommitted manifests, oldest first. Each file carries a download link that expires after 5 minutes; read the list again for fresh links. Evidence shows as committed within a minute or so of the hash landing on chain. Only the two parties and the arbiter service can read it.
Every evidence route answers 503 evidence-store-disabled on a relayer without an evidence store. You can still commit a hash of your own on chain. Evidence is kept while the trade is open. Once the trade ends, everything is deleted after 90 days; a manifest that was never committed may go sooner.

What the frontend reads

A dispute shows up on the ordinary trade object from GET /v1/trades/:id, and both parties get a notification at each step (DISPUTE_FILED, DISPUTE_ANSWERED, DISPUTE_RULED, then TRADE_CANCELLED when it ends that way). The relayer writes these fields from chain state.
Offer “Answer” only to the role that did not file, while disputeAnswered is false, disputeOutcome is null, and before disputeChallengeDeadline. Never label disputeFinalizeAt as the end of the challenge: it can be later. disputeOutcome can also be Resolved when the dispute ended without a ruling the relayer saw.

Outcomes at a glance

The arbiter service can rule only MutualRefund, BridgerForfeit or MakerForfeit. TradeProceeds comes only from proof that the trade settled. A bond that cannot be pushed to its recipient is credited instead, and withdrawn with claim.

Dispute states

These are the AdManager’s order statuses around a dispute. The OrderPortal never shows Disputed. It stays Open until the ad chain’s result is proven to it, then moves to Filled (forfeit to the maker) or Cancelled (refund to the bridger).