CurtainMarketsDocs
curtain/docs/integrationLaunch app

Integration

Everything here runs against the program's public accounts and events. Sealed values can only be read by their owner's key.

Read the board

The odds of a market are two fields on the Market account:

const m = await program.account.market.fetch(marketPda)
const yesPrice = Number(m.yesPool) / Number(m.yesPool + m.noPool)

Derive the market address from its question:

const [marketPda] = PublicKey.findProgramAddressSync(
  [Buffer.from("market"), feedId, i64le(strike), i64le(expiry)],
  PROGRAM_ID,
)

strike is in the feed's own fixed-point units (price = strike x 10^expo).

Follow the odds as they publish

Subscribe to the program's logs and decode OddsPublished { market, batch, tickets, yes_pool, no_pool }. Each event is one batch: the pools after it and the number of tickets inside it.

Run the cranks

Three instructions are permissionless and keep markets moving. Anyone may run them; they need no key beyond a fee payer.

CrankWhen to callWhat it does
tallyopen batch has at least the minimum tickets and its epoch ran out, betting closed, or it is fullasks the cluster for the batch sums
settle_marketafter the deadlinesubmits the first Pyth print at or after it
claimafter settlementpays one position into its owner's purse

To find the settling print, take the first price Pyth pushed on Solana at or after expiry, which the program accepts while its publish_time is within 15 seconds of expiry. The site rebuilds it from Solana's own history at /api/print?feed=SOL&deadline=<unix>: the push transaction carries the price message and its Merkle proof, and the Wormhole transaction that wrote the matching encoded VAA carries the guardian-signed root. Post the result through the Pyth Solana Receiver and pass that account to settle_market. A print whose prev_publish_time is before expiry is accepted whenever it was published, which is what a print taken from Pyth's Hermes service carries.

Place a bet from your own client

Encrypt [yes_side, amount] with the shared secret between a fresh x25519 key and the cluster's key (the Arcium client's RescueCipher), then send place_bet(computation_offset, bet, bet_key, bet_nonce). Use a fresh random nonce for every bet.

Next: API reference