Prepare purchase

POST /api/v1/mystery/purchase/prepare packs:purchase

Purchase step 1. Returns the USDC-approve and purchase transactions for the END USER to send from their own wallet. CardOS never touches their funds. Creates nothing.

Try it POST /api/v1/mystery/purchase/prepare write

These inputs are shared across all docs pages, so an id entered here carries over.

request body
object · 2 keys
{
  "wallet_address": "0x0000000000000000000000000000000000000000",
  "tier_id": 1
}
response

Not run yet. Press Run to make a live call against https://service.rip.fun (through this demo's server-side proxy; the API key never reaches the browser).

tracks the inputs above
curl -X POST 'https://service.rip.fun/api/v1/mystery/purchase/prepare' \
  -H 'X-API-Key: rip_…' \
  -H 'Content-Type: application/json' \
  -d '{"wallet_address":"0x0000000000000000000000000000000000000000","tier_id":1}'

Request fields

FieldTypeRequiredDescription
wallet_addressstringyesEnd-user wallet that will sign + pay
tier_idnumberyesTier to purchase
max_price_usdcstringPrice cap; defaults to the last-seen tier price

Response fields (data)

FieldDescription
chain_id / contract / payment_tokenChain + MysteryComboPool + USDC addresses
max_price / max_price_usdcApproval amount (micros + decimal)
calls[]{to, data, kind, description}: approve USDC (kind erc20-approve), then purchase the tier (kind purchase). Dispatch on `kind`, not the description or 4-byte selector — under account abstraction the approve must go as its own userop (see the AA notes on the flows page)

Errors

StatusCodeWhen
400invalid_tierunknown tier_id

See Errors for the response envelope and the full code list.

Flow

  1. Partner: POST /purchase/prepare with the user’s wallet_address + tier_id
  2. End user: sends calls[0] (USDC approve, skip if allowance already covers it) then calls[1] (purchase) from their own wallet
  3. Partner: POST /purchase/submit with the tx hash (+ request_id from the receipt logs) to link it
  4. CardOS: reveals the items; poll GET /purchase/:id until FULFILLED (or use the purchase.fulfilled webhook)