Common patterns & pitfalls
Practical tips for integrating @bento.fun/sdk — IDs, response shapes, auth, and errors.
Answers to questions that come up often when wiring the SDK against live APIs.
Two hosts, one factory
const sdk = createBentoSdk({
baseUrl: process.env.BENTO_URL!,
tournamentsBaseUrl: process.env.PARLAY_TOURNMENT_URL,
auth: walletAuthProvider(() => ({ /* x-wallet-* */ })),
tournamentsAuth: jwtAuthProvider({ getAccessToken: () => token }),
});| Client | Host env | Typical auth |
|---|---|---|
sdk.public / sdk.user | BENTO_URL | Wallet headers on user |
sdk.tournaments | PARLAY_TOURNMENT_URL | JWT on tournamentsAuth |
See Two API hosts.
id vs duelId on market rows
listDuels / listMarkets return rows with two identifiers:
| Field | Example | Use for |
|---|---|---|
id | 6a1ef4329676cfd69ceec4f0 | Database row id — do not pass to getDuelById |
duelId | 94c88855f750… | On-chain duel id — use this for detail, bets, charts |
const { data } = await sdk.public.listDuels({ page: 1, limit: 10 });
const row = data[0];
// ✓ Correct
await sdk.public.getDuelById({ duelId: row.duelId });
// ✗ 404 — wrong id type
await sdk.public.getDuelById({ duelId: row.id });Wrapped API responses
Some tournaments endpoints return objects, not bare arrays:
// Parlay markets
const { markets } = await sdk.tournaments!.parlay.listMarkets() as {
markets: unknown[];
};
// Bracket tournaments list
const { tournaments, total } = await sdk.tournaments!.tournaments.list({
status: 'active',
}) as { tournaments: unknown[]; total: number };Check the Tournaments OpenAPI schema when typing responses.
HTTP acceptance ≠ on-chain finality
placeBet, sellBet, createDuel, pack picks, and tournament enters return when the server accepted the request — not when the chain finalized.
After mutations:
- Poll reads (
getDuelById,getUserShares, tournament status) - Use
waitFor*helpers where provided - Subscribe via
sdk.realtimeor tournament chat/Ably
See Mutation semantics.
Auth providers by integration
| Your app | Provider | Pass as |
|---|---|---|
| Browser wallet | walletAuthProvider | auth |
| JWT session (tournaments) | jwtAuthProvider | tournamentsAuth |
| Bulk user registration | bulkRegisterAuthProvider(apiKey) | auth on user.bulkRegister |
| Agent v1 API | agentV1AuthProvider | tournamentsAuth or client headers |
| External agent API | externalAgentAuthProvider | tournamentsAuth |
See Authentication.
Idempotency for bets
Always pass an idempotency key when placing bets:
await sdk.user.placeBet(
{ duelId, option: 'YES', amount: '10' },
{ idempotencyKey: `bet-${duelId}-${Date.now()}` },
);Errors
Failed HTTP calls throw BentoSdkErrorException with error.sdkError:
import { isGeoblockError } from '@bento.fun/sdk';
try {
await sdk.user.placeBet(/* … */);
} catch (error) {
if (isGeoblockError(error)) {
// show geo-blocked UI
}
// error.sdkError.status, .message, .correlationId
}Where to look next
| Need | Page |
|---|---|
| Every SDK method + route | SDK API reference |
| JSON request/response shapes | Markets · Tournaments OpenAPI |
| Smoke-test published npm package | Test the SDK |
| End-to-end flows | Quickstart · Guides |