chordDocs

Solvers

Submitting a quote

The candidate format, its signature, and the commit co-signature.

#The candidate

POST /candidates takes one JSON object. Every integer is a canonical decimal string.

JSON
{
  "batchId": "4247",
  "solver": "SoLvEr1111111111111111111111111111111111111",
  "solution": {
    "priceNumerator": "711",
    "priceDenominator": "5000",
    "reserveA": "8438818566",
    "reserveB": "0",
    "surplus": "33566433714",
    "surplusScale": "tokenB-at-reference-price",
    "policy": "my-solver-v1",
    "fills": [
      { "orderId": "9c1e…", "sellAmount": "1200000000", "buyAmount": "8438818565" }
    ]
  },
  "signature": "base64…"
}

This example quotes a single order: a buy paying 1,200 B with a limit of 143.00, filled at 142.20 for a 9-decimal A and a 6-decimal B.

FieldMeaning
batchIdThe batch you’re quoting
solverYour solver key, base58
priceNumerator, priceDenominatorThe clearing price, raw B per raw A
fills[].orderIdThe order’s hash, as returned by the collector
fills[].sellAmountHow much of the order you fill
fills[].buyAmountWhat the order receives: exactly floor(sell × price)
reserveA, reserveBWhat you will escrow at commit; must cover every output, rounded up
surplusYour quote’s score, in the units described on Clearing and selection
policyA free-form label for how the quote was made

#Signing

The signed message is the domain tag, the deployment’s identity, then a fixed JSON serialization of the candidate without its signature:

Text
"CHORD_CANDIDATE_V1" ‖ programId (32) ‖ config (32) ‖ chainDomain (32) ‖ JSON

The JSON in the signed message has exactly these keys, in this order: batchId, solver, priceNumerator, priceDenominator, reserveA, reserveB, surplus, surplusScale, policy, fills (each with orderId, sellAmount, buyAmount). Sign it with your solver key’s Ed25519 private key and send the 64-byte signature as base64.

The collector exports the same function it verifies with, candidateMessage, so you can build the bytes exactly as it does.

#When quotes are accepted

CheckError
Signature verifies against solverBAD_SOLVER_SIGNATURE
The batch is knownUNKNOWN_BATCH
Current slot is in [collectEndSlot, solveEndSlot)SOLVE_WINDOW_CLOSED
Every filled order is open and unchanged on chainORDER_INVALIDATED
Price, fills, reserves and surplus are consistent400 with the reason

#Co-signing the commit

The commit needs your signature as well as the collector’s. When your quote wins:

  1. GET /batches/:id/solver-signature-request returns { id, wire, lastValidBlockHeight, solver }. wire is the unsigned transaction, base64.
  2. Deserialize it and check it: the commit instruction, your price and budgets, and reserve transfers from your accounts only.
  3. Sign the message and POST /transactions/:id/solver-signature with { "signature": "<64 bytes, base64>" }.

The collector verifies your signature against the exact prepared message, adds its own, and broadcasts. If the blockhash expires before you sign, it prepares a fresh request.