BentoSDK

Place a bet

Estimate, place, and reconcile a market bet on the Bento markets host.

By the end: you'll have estimated a bet, placed it with placeBetFromEstimate, and read your position back.

Prerequisites

Flow

import { createBentoSdk, walletAuthProvider } from '@bento.fun/sdk';

const sdk = createBentoSdk({
  baseUrl: process.env.BENTO_URL!, // https://internal-server.bento.fun
  apiKey: process.env.BENTO_BUILDER_API_KEY!,
  auth: walletAuthProvider(() => ({ Authorization: `Bearer ${token}` })),
});

const duelId = 'your-duel-id'; // from listDuels row.duelId — NOT row.id
const market = await sdk.public.getDuelById({ duelId });

// 1. Estimate (optionIndex is 0|1; amount is collateral wei)
// Platform minimum bet is **5** collateral units, in the collateral's decimals
// (18 for credits / BSC USDC, 6 for Base USDC).
// `estimateBuy` does not enforce the floor: a sub-5 amount can quote then 500 at place.
const stake = '10000000000000000000'; // 10 units
const est = await sdk.user.bets.estimateBuy({
  duelId,
  optionIndex: 0,
  betAmountUsdc: stake,
  slippageBps: 100,
});
if (!est.success) throw new Error('estimate rejected'); // narrows to success variant

// 2. Place (HTTP acceptance). Prefer `placeBetFromEstimate`: it maps the quote
// and derives the slippage floor from `sharesOut`. Do NOT hand-build from
// `estimate.min_shares_out` — on larger bets the engine returns it ABOVE
// `sharesOut`, emptying the slippage window ("Slippage exceeded").
// `bet` is the option label text (prediction often YES/NO; versus uses optionA/optionB text).
await sdk.user.placeBetFromEstimate(
  {
    estimate: est.estimate,
    duelId,
    duelType: market.duelType ?? 'PREDICTION', // or 'VERSUS'
    bet: market.options?.[0] ?? 'YES',
    optionIndex: 0,
    betAmount: stake,
    betAmountUsdc: stake,
    slippageBps: 100,
    tokenDecimals: 18,
  },
  { idempotencyKey: crypto.randomUUID() }, // stable per attempt, not Date.now()
);

// 3. Reconcile — `address` is the managed account from login, not your EOA
const shares = await sdk.user.bets.getUserShares({
  duelId,
  address: managedAccountAddress,
});

A write returns when the server accepted it, not when the chain settled. Poll reads to confirm. → Acceptance vs finality

On this page