Predict.fun runs on BNB Chain and supports two wallet models: a Predict Account (a Kernel-based smart wallet, the default for users who signed up via Privy) and a direct EOA. Most users will use the Predict Account flow.Documentation Index
Fetch the complete documentation index at: https://docs.delphimarkets.com/llms.txt
Use this file to discover all available pages before exploring further.
At a glance
| Chain | BNB Chain (chainId 56) |
| Wallet model | Predict Account (Kernel smart wallet) or EOA |
| Quote token | USDT (18 decimals on BSC) |
| Signing | Client-side (EIP-712, Kernel-wrapped for smart wallets) |
| Auth | Predict.fun API key + Privy private key + Predict Account address |
Prerequisites
- A Predict.fun account
- Your Predict.fun API key
- The Privy wallet private key that controls your Predict Account
- Your Predict Account address (the deposit/trading address shown in the Predict.fun UI)
- USDT on BNB Chain in your Predict Account
The Privy private key is the EOA that owns your Kernel smart wallet (Predict Account). The Predict Account is the address that holds positions and pays fees; the Privy EOA is what signs.
One-time setup
1. Approve exchange contracts
The Predict Account must approve the right CTF Exchange contract to spend USDT and Conditional Tokens. There are four exchange contract variants depending on the market type, so the approval needs to match the market you’re trading.isNegRisk | isYieldBearing | Exchange contract |
|---|---|---|
false | false | 0x8BC070BEdAB741406F4B1Eb65A72bee27894B689 (CTF) |
true | false | 0x365fb81bd4A24D6303cd2F19c349dE6894D8d58A (NegRisk) |
false | true | 0x6bEb5a40C032AFc305961162d8204CDA16DECFa5 (YieldBearing) |
true | true | 0x8A289d458f5a134bA40015085A8F50Ffb681B41d (Both) |
marketFlags.
2. Register credentials with Delphi
Build and place an order
Build parameters
| Field | Type | Description |
|---|---|---|
tokenId | string | Outcome token ID, from market.outcomes[i].onChainId. |
side | 'BUY' | 'SELL' | |
price | number | Price per share in [0.01, 0.99]. |
size | string | Shares in 1e18 base units. 50 shares = "50000000000000000000". |
feeRateBps | string | From market.feeRateBps. Must match the market. |
isNegRisk | boolean | From market.isNegRisk. Must match the market. |
isYieldBearing | boolean | From market.isYieldBearing. Must match the market. |
predictAccount | 0x${string}? | Pass to enable Kernel-wrapped signing. Omit to sign as the EOA directly. |
strategy | 'LIMIT' | 'MARKET'? | Default 'LIMIT'. |
slippageBps | string? | For market orders only. |
expiration | number? | Unix seconds. Default 0 (no expiry). |
EOA vs Predict Account flow
If your Predict.fun account is an EOA (no smart wallet), omitpredictAccount from buildPredictFunOrder and use a different env var:
predictAccount is omitted.
Query and cancel
Common pitfalls
Order rejected: 'invalid signature'
Order rejected: 'invalid signature'
Almost always a mismatch between the market flags you passed (
isNegRisk, isYieldBearing) and the actual market. There are four exchange contracts; the signature is only valid against one. Re-fetch the market and copy the flags directly:USDT amounts look wrong
USDT amounts look wrong
USDT on BNB Chain uses 18 decimals. The SDK takes
size in base units (1e18 = 1 share). 50 shares = (50n * 10n ** 18n).toString(). Don’t confuse this with the 6-decimal USDT on Ethereum.ApprovalForAll for Conditional Tokens fails
ApprovalForAll for Conditional Tokens fails
The CTF approval is an
ERC-1155 setApprovalForAll from your Predict Account to the right exchange contract. If your Predict Account has zero ETH/BNB to pay gas (it’s a smart wallet, so it sponsors its own gas via Kernel), the approval transaction will fail. Top up the Predict Account with a small amount of BNB (~0.001) for gas before approving.signatureType differences
signatureType differences
0(EOA) — used whenpredictAccountis omitted2(POLY_GNOSIS_SAFE) — used whenpredictAccountis set, even though Predict.fun uses a Kernel wallet rather than a Gnosis Safe. The signature wrapping is Kernel-specific (uses the ECDSA validator at0x845ADb2C711129d4f3966735eD98a9F09fC4cE57) but reuses the2signatureType slot.
predictAccount.JWT auth keeps expiring
JWT auth keeps expiring
Predict.fun’s JWT tokens expire after a short window. The Delphi server handles refreshes automatically using your stored Privy private key. If you keep getting 401s on Predict.fun specifically, your registered
api_secret (Privy key) might be wrong — re-register it.API reference
POST /api/v1/orders— accepts aPredictFunOrderPayloadinsigned_orderPOST /api/v1/users/{userID}/credentials— pass_as the path segment

