> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chance.money/llms.txt
> Use this file to discover all available pages before exploring further.

# Place → proof → claim

> End-to-end Chance bet with viem (TypeScript) — networkConfigs, approve, place, proof over socket, claimWithProof.

The minimal integrator path: discover contracts via GraphQL, place on-chain with **viem**, receive the settle result + Groth16 proof from the API, then claim on-chain in one transaction.

Dependencies: `viem`, `socket.io-client`, and `fetch`. No auth, no API keys.

## 1. Fetch network config

```ts TypeScript theme={"theme":"css-variables"}
const API = 'https://api.chance.money/graphql'

const query = /* GraphQL */ `
  query {
    networkConfigs {
      networkId
      chainId
      contracts {
        chancePool
        usdg
        chanceToken
      }
    }
  }
`

const { data } = await fetch(API, {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({ query }),
}).then((r) => r.json())

// Pick your network by networkId: ROBINHOOD_TESTNET or ROBINHOOD_MAINNET
const network = data.networkConfigs.find(
  (n) => n.networkId === 'ROBINHOOD_TESTNET',
)
const { chancePool, usdg } = network.contracts
```

Always resolve `chancePool` and `usdg` from this query — never hardcode addresses. See [Networks & contracts](/integrate/networks).

## 2. Approve USDG

```ts TypeScript theme={"theme":"css-variables"}
import { parseAbi } from 'viem'

const erc20Abi = parseAbi([
  'function approve(address spender, uint256 amount) returns (bool)',
])

await walletClient.writeContract({
  address: usdg,
  abi: erc20Abi,
  functionName: 'approve',
  args: [chancePool, stakeAmount], // USDG units
})
```

## 3. Place a bet

Read the live epoch id, then place. A 2× Strike as the simplest example:

```ts TypeScript theme={"theme":"css-variables"}
import { parseAbi, toHex } from 'viem'

const chancePoolAbi = parseAbi([
  'function currentCommitId() view returns (uint64)',
  'function placeStrike(uint256 stakeAmount, uint256 multipleBps, bytes32 clientSeed, uint64 expectedCommitId, address affiliate, string platform, string game) returns (uint256)',
])

const commitId = await publicClient.readContract({
  address: chancePool,
  abi: chancePoolAbi,
  functionName: 'currentCommitId',
})

const clientSeed = crypto.getRandomValues(new Uint8Array(32)) // non-zero bytes32

const hash = await walletClient.writeContract({
  address: chancePool,
  abi: chancePoolAbi,
  functionName: 'placeStrike',
  args: [
    stakeAmount,        // USDG units
    20_000n,            // 2× multiple (bps)
    toHex(clientSeed),  // your entropy contribution
    commitId,           // expectedCommitId — reverts CommitMismatch if stale
    '0x0000000000000000000000000000000000000000', // affiliate (none)
    'my-game.example',  // platform attribution (optional, ≤ 64 bytes)
    '',                 // game attribution (optional)
  ],
})
```

The `betId` is returned by the call and indexed on the `BetPlaced` event. Check [Bet constraints](/protocol/bet-constraints) before quoting multiples, and [Placing bets](/integrate/placing-bets) for Range / Ladder args.

## 4. Get the result and proof

**Preferred (realtime):** subscribe over Socket.IO and wait for `bets:update`.

```ts TypeScript theme={"theme":"css-variables"}
import { io } from 'socket.io-client'

const socket = io('https://api.chance.money', { path: '/socket.io' })
socket.emit('bets:subscribe', { wallets: [playerAddress] })

socket.on('bets:update', (update) => {
  // update: { betId, status, payout, won, entropy, proof, ... } — never the server seed
  if (update.betId === myBetId && update.proof) {
    claimWithProof(update)
  }
})
```

**Fallback:** poll GraphQL `betResult`.

```graphql GraphQL theme={"theme":"css-variables"}
query ($chainId: Int!, $betId: String!) {
  betResult(chainId: $chainId, betId: $betId) {
    betId
    status
    won
    payout
    entropy
    proof
  }
}
```

`proof: null` means proving is unavailable for that bet — wait for the epoch seed reveal and use plain `claim` instead. See [Results & proofs](/integrate/results-and-proofs).

## 5. Claim with proof

```ts TypeScript theme={"theme":"css-variables"}
const claimAbi = parseAbi([
  'function claimWithProof(uint256 betId, uint256 entropy, bytes proof, bool claimAsChance, uint256 minChanceOut)',
])

await walletClient.writeContract({
  address: chancePool,
  abi: claimAbi,
  functionName: 'claimWithProof',
  args: [
    BigInt(update.betId),
    BigInt(update.entropy),
    update.proof,   // hex proof bytes from the API
    false,          // false = USDG payout; true = claim as CHANCE
    0n,             // minChanceOut — slippage floor, only used when claiming CHANCE
  ],
})
```

`claimWithProof` settles the pending bet from the proof and claims in one transaction. If the bet lost, the call settles it and returns without reverting.

## Next steps

* [Integrate](/integrate/introduction) — modes, history, claiming details
* [API reference](/api-reference/overview) — exact GraphQL + Socket payloads
* [Protocol](/protocol/overview) — constraints and provably fair
