Skip to main content
This guide opens a wager on devnet from a Node script with @solana/kit and a client generated from Fade’s IDL. The wallet plays every role: app, payer, stake owner and beneficiary.
Requirements: Node 20 or later, a devnet keypair with about 0.02 devnet SOL and some test USDC. Claim both from the faucet in app.fade.finance, or call the faucet API (step 2).
1

Install and generate the client

The IDL is the Anchor IDL of the devnet deployment, served as a text file: its program address is the devnet program and its USDC mint the devnet test mint. Generate the client:
generate.mjs
You now have src/generated/fade with a builder for every instruction (getOpenWagerInstructionAsync, …), account fetchers (fetchConfig, fetchMaybeWager, …), PDA helpers, error codes and event decoders.
2

Get test USDC

The faucet sends 1 000 test USDC, and a little SOL when the wallet has almost none. One claim per wallet and per IP every 5 minutes.
If the wallet still lacks SOL, use faucet.solana.com.
3

Set up the connection

src/fade.ts
The generated builders default to a program address taken from the IDL. Pass cfg anyway, so the code says which deployment it targets.
4

Build a paytable

Probabilities are integers in billionths and must sum to exactly 1 000 000 000. Multipliers are integers in basis points: 10 000 is 1×. Compute in bigint, never in floating point.
src/paytable.ts
allOrNothing(1_000_000n, 10_000_000n, 350n) returns [{ p: 96_500_000n, m: 100_000n }, { p: 903_500_000n, m: 0n }]: 10× at 9.65 %, a 3.5 % edge. More shapes and the sizing rules are on Paytables.
5

Open the wager

src/open.ts
The builder derives config, pool, integrator, vaultUsdc, wager, vrfPayer and ORAO’s network state for you. If a check fails, sending throws with the program’s error; see Errors.
6

Hand it to a keeper

The randomness request and the settlement are permissionless. The public keeper sends both:
src/keeper.ts
Even without the POST, the keeper sweeps for open wagers about every 30 seconds; posting just starts it at once.
7

Run it

src/main.ts
bucket is the index of the paytable row that was drawn: 0 is the 10× row here, 1 is nothing. A payout is in USDC base units and has already reached the beneficiary.

Settling without a keeper

Anyone may send the two remaining steps, including your own server or the user’s wallet. Request the randomness from two slots after the open, wait for ORAO to fulfil, then settle.
src/settle-yourself.ts
The caller of each step is paid its share of the crank fee (50 000 lamports to request, 200 000 to settle). If ORAO has not fulfilled within T_SETTLE (150 slots), settle_wager is impossible and anyone may call expire_wager instead. See Settlement and keepers.

Reading the result

  • From the keeper: GET /v1/wagers/:address returns bucket, payout and the settle signature.
  • From the chain: the wager account closes at settlement. The settle transaction carries a WagerSettled event with bucket, payout and pending (true when the payout was parked because the beneficiary could not receive). See Events for decoding.
  • While open: fetchMaybeWager returns the stored paytable, status (Open, Requested or PayoutPending), openSlot, expirySlot, the bound randomness account and the reserved liability.

Next