Skip to content
All docs

API

Contracts

Desk (one per trader)

FunctionCallerNotes
trade(Order)traderself-submitted order
tradeWithSig(Order, nonce, deadline, sig)anyone (relayer)EIP-712 TradeIntent, domain {name: "Imprest Desk", version: "1", chainId, verifyingContract: desk}; signer must be the trader; nonce must exceed lastNonce
graduate()anyonesucceeds only if the next tier's rule holds; reverts GraduationNotEligible(code) (1 profit, 2 trades, 3 time, 4 claims, 5 unpaid fees)
claim()traderflat only; realized profit above HWM net of fees
close()traderflat only; split once, repay, settle, no keeper bounty
enforce()anyonetrading floor, daily loss or fee cap; partial closes repeatable; bounty once at settlement
checkpoint()anyoneaccrue fees and refresh the exposure flag
equity(), riskState(), policy(), floorEquity(), dailyFloor()viewsdisplay only

Order { perpId, side (0 buy, 1 sell), priceLimit (PNS), lots (LNS), leverage (hundredths), reduceOnly, fillOrKill }.

Events: DeskActivated, TradeExecuted, FeesAccrued, Graduated, Claimed, EnforcementStarted, EnforceCloseFailed, PartialClose, SettlementPending, Settled.

DeskFactory

openDesk(stake, cohortId), predictDesk(trader, cohortId), getCohort(id), cohortCount(), getDesks(trader), allDesks(i), deskTotal(), isDesk(addr); operator: addCohort, setCohortActive, setPaused.

ImprestPool (ERC-4626, shares ipAUSD)

LP: deposit, withdraw/redeem (idle only), maxWithdraw. Desks: fundDesk, recordExposure, releaseExposure, receiveIncome, settleDesk. Views: idleAssets, deployedPrincipal, totalPrincipalLoss, totalFeesCollected, totalFeesWrittenOff, totalProfitShare, grossExposure(perp), grossCap(perp), deskExposure(desk, perp), deskGross(desk), deskNotionalCap. Operator: setGrossCap, setDeskNotionalCap (increases timelocked 24 h after factory wiring), applyGrossCap, applyDeskNotionalCap, setPaused, setTreasury, setFactory (once).

All errors: contracts/src/libraries/ImprestTypes.sol (ImprestErrors); user-facing text in packages/core/src/errors.ts.

Relayer (HTTP)

MethodPathBody / result
GET/health{ ok, chainId, relayer, balanceWei }
POST/v1/intents{ chainId, desk, order: {perpId, side, priceLimit, lots, leverage, reduceOnly, fillOrKill}, nonce, deadline, signature } (integers as decimal strings) -> 202 { txHash, gas, operation_id }
GET/v1/tx/:hash`{ state: submittedexecutedfailed, blockNumber }`

Errors: 400 malformed / wrong chain / deadline too far; 401 bad signature or altered fields; 404 not an Imprest desk; 409 nonce used; 410 deadline passed; 422 simulation reverted (named code) or gas above cap; 429 quota; 502 RPC failure. A 202 means submitted, not final.

Keeper (HTTP)

GET / -> { ok, chainId, keeper, dryRun, loops, lastLoopAt, actionsSent, simulationsRejected, errors, watched }.

Web

GET /api/perpl/<path>: read-only proxy to Perpl's market data API. Allowlist: pub/context, market-data/:id/{ticker,book,candles/:res/:from-:to,funding/:from-:to}.

Indexer (GraphQL, Envio/Hasura)

Entities: Desk, DeskEvent, Trade, Settlement, PoolTotals, PerpExposure, VenueLiquidation, AccountIndex (indexer/schema.graphql). Example:

query ($desk: String!) {
  DeskEvent(where: { desk_id: { _eq: $desk } }, order_by: { blockNumber: desc }, limit: 100) {
    kind txHash blockNumber argsJson
  }
}