Reference

API

Read the program's accounts, build unsigned transactions and relay signed ones over HTTP.

The Crest API serves a copy of the program's accounts, read at finality, and builds transactions for wallets to sign. It holds no keys and signs nothing. The app reaches it under its own address at /api/crest; the examples below use $CREST for that base.

Shell
CREST="https://crest.is/api/crest"
curl "$CREST/v1/status"

All 64-bit integers are decimal strings. Lists are pages of up to 100 accounts; pass the previous page's next as after to continue.

Status#

GET /v1/status returns the cluster, the program, the configuration this deployment serves, how current the API's copy of the chain is, and the epoch clock.

JSON
{
  "cluster": "mainnet",
  "genesisHash": "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d",
  "programId": "…",
  "mirror": { "ready": true, "slot": "…", "lastSuccessAt": "…", "generation": 1 },
  "clock": { "epoch": "…", "slotIndex": "…", "slotsInEpoch": "432000", "absoluteSlot": "…", "msPerSlot": 400 },
  "positionRentLamports": "1976640",
  "airdrop": false,
  "governance": { "programId": "GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw", "realm": "…" }
}

GET /health answers while the process runs; GET /ready answers 200 only while that copy is current.

Accounts#

RouteReturns
GET /v1/configsConfigurations.
GET /v1/markets?config=Markets, optionally of one configuration.
GET /v1/checkpoints?config=&proposer=Checkpoints, by address.
GET /v1/configs/:config/checkpoints?limit=&before=One configuration's checkpoints by epoch, newest first. limit is 1 to 200.
GET /v1/positions?market=&owner=&status=Positions. owner matches maker or taker; status is 0 open, 1 active, 2 closed.
GET /v1/accounts/:addressOne account: decoded fields, raw bytes, data hash, lamports and context slot.
GET /v1/wallets/:addressA wallet's SOL and CREST balances at confirmed commitment.

Each list item has the account's address, slot, lamports and decoded fields, named as on Program accounts in camelCase.

Shell
curl "$CREST/v1/positions?owner=<your wallet>&status=1"

CREST and governance#

RouteReturns
GET /v1/tokenThe CREST mint as the chain reports it: supply, decimals and authorities. Per configuration, the stake vault, its balance and the CREST locked behind posts.
GET /v1/governanceThe realm, and each governance account with its native treasury, the configuration it administers and its voting rules.
GET /v1/governance/proposals?governance=&state=Proposals. state is draft, voting, succeeded, executing, completed, defeated or cancelled.
GET /v1/governance/proposals/:addressOne proposal, its transactions with the Crest instruction each runs, and its votes.
GET /v1/governance/voters/:walletA wallet's deposited CREST, its votes, and the stakes it has locked behind posts.

The API reads these accounts from SPL Governance and the token program about once a minute. Deposits, proposals and votes are SPL Governance instructions: build them with its SDK and send them to any RPC.

Shell
curl "$CREST/v1/governance/proposals?state=voting"

Building a transaction#

POST /v1/transactions returns an unsigned legacy transaction, base64, with its blockhash and last valid block height. The API reads final chain state and checks every address before building it.

JSON
{
  "action": "open",
  "wallet": "<maker>",
  "market": "<market>",
  "orderId": "1759302000000",
  "makerLong": true,
  "notionalLamports": "1000000000000",
  "fixedRatePpb": "60000"
}
actionAlso needs
openorderId, makerLong, notionalLamports, fixedRatePpb
matchposition, and the order's makerLong, notionalLamports and fixedRatePpb as you saw them
cancel, settle, liquidate, expire, closeposition

Fields that don't belong to the action are rejected. cancel must come from the maker. match is refused if the terms no longer match the order, and the program checks them again when the transaction runs. close takes both payout addresses from the position itself.

Sending it#

Sign the transaction in the wallet, then either send it to any RPC yourself or relay it:

POST /v1/transactions/submit with { "transaction": "<signed, base64>" } returns { "signature": "…" }. The relay accepts only transactions whose every instruction is for the Crest program and whose every signature verifies, and sends them with preflight. A program error comes back as 400 with the reason.

GET /v1/transactions/:signature returns unknown, processed, confirmed, finalized or failed, with the slot once known.

TypeScript
const { transaction } = await post("/v1/transactions", body);
const tx = Transaction.from(Buffer.from(transaction, "base64"));
const signed = await wallet.signTransaction(tx);
const { signature } = await post("/v1/transactions/submit", {
  transaction: signed.serialize().toString("base64"),
});

Evidence#

GET /v1/evidence/:definitionHash/:epoch returns the archived evidence behind an epoch's checkpoint and the verifier's result. Whether a checkpoint is final is decided on chain, not here.