IDL files
The program source is private. The IDLs, generated from the source of the deployed programs, are published in the docs repository (browse).address field holds the program ID, and Anchor 0.32 reads it from there. Three details trip people up:
- Pass the type explicitly, as in
new Program<MintRedeem>(idl as MintRedeem, provider). Without it TypeScript falls back to the genericIdltype andprogram.account.marketdoesn’t type-check. - Anchor TS decodes
base_price_1e6,gamma_day_decay_1e9andshort_payoff_cap_c_1e9asbasePrice1E6,gammaDayDecay1E9andshortPayoffCapC1E9, butanchor idl typenames them with a lowercasee. Read those three fields by their runtime names. - The registry IDL has no PDA seeds, so Anchor can’t fill in
registryormarketEntryfor you. Pass them explicitly, using the seeds below.
PDA derivation cheatsheet
Every PDA isPublicKey.findProgramAddressSync(seeds, programId). This script derives them all for one market and one wallet, then checks them with a single getMultipleAccountsInfo call. It needs only @solana/web3.js. Save it as pdas.ts, set your wallet, and run npx tsx pdas.ts.
orderandescrowexist only while that order is open.settle_swapandcancel_swapclose both, except for a held order, which stays open untilclaim. Aclaimaccount, PDA[b"claim", order], exists only while a settle holds a payout.dripRecordexists after the wallet’s first faucet drip.faucetMintAuthorityis a signing PDA that holds no data. It is the cUSDC mint’s mint authority.registryEntryis empty because the Registry holds no markets yet. Get market addresses from Addresses.
Market account is allocated 891 bytes on devnet, and the struct can need up to 899. Its collateral_vaults list is variable-length, so read Market fields through the IDL, never at fixed offsets (see Market account).
The two market seeds differ. mint-redeem uses the raw symbol bytes (QQQ), while the Registry uses the symbol uppercased and zero-padded to 16 bytes.
Token accounts (ATAs)
Associated token accounts aren’t PDAs of Continuum’s programs, but you derive them constantly:true as the third argument when the owner can be a PDA, as market.feeRecipient can. As of 10 Oct 2026 QQQ’s fee recipient is the GlobalClp PDA, and without the flag getAssociatedTokenAddressSync throws TokenOwnerOffCurveError.
Composing a mint call
mint_paired takes 11 accounts. You derive the Market PDA from the symbol, fetch the market once, and derive the rest from its fields:
AccountNotInitialized (3012). Add createAssociatedTokenAccountIdempotentInstruction for each one to the same transaction. In production, batch the market fetch with the user’s token-account reads through getMultipleAccountsInfo.
Account-fetch helpers
WithmintRedeem and clp as typed Program instances and the PDAs from the script above:
OracleConfig for prices: the oracle program isn’t updated on devnet. The live price is market.userTwapPrice.
Discriminators
Every Anchor account and instruction starts with an 8-byte discriminator: the first 8 bytes ofsha256("account:<AccountName>") for accounts and sha256("global:<instruction_name>") for instructions. The IDLs list them, and Anchor checks them for you. Market’s discriminator is [219, 190, 213, 55, 0, 227, 198, 154].
To decode raw account data without fetch, use the program’s coder with the camelCase account name:
See also
SDK setup
Project bootstrap and a first read.
End-to-end example
Mint and redeem in one script.

