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.
| Crank | When to call | What it does |
|---|---|---|
tally | open batch has at least the minimum tickets and its epoch ran out, betting closed, or it is full | asks the cluster for the batch sums |
settle_market | after the deadline | submits the first Pyth print at or after it |
claim | after settlement | pays 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.