Predict.fun
Step zero — from nothing to your first trade
Section titled “Step zero — from nothing to your first trade”- Create the account. Open predict.fun, connect the EOA you will trade from, and follow the current prompts; the repo sources do not document the identity-check sequence.
- Set up credentials. Create a wallet and secure its seed phrase; never share the private key, which Predictefy never sees. Get the API key in your venue account’s API settings. There is no session token to copy: the SDK has your wallet sign Predict.fun’s dynamic auth message locally and exchanges it directly for the JWT.
- Fund and approve. A practical first test is about $10–$25 of USDT on BNB Smart Chain (
56), plus a little BNB for approval or on-chain cancellation gas—not a venue minimum. If funds start elsewhere, useGET /v1/bridge/quotebefore signing and broadcasting its transaction request. - Allow time. Budget 1–2 hours for a first wallet, bridge, and approval; less if already funded.
The hosted region is blocked; the direct path still requires your connection to be venue-eligible.
What you need first
Section titled “What you need first”- Production status: Armed for build, submit, and cancel as verified on 2026-08-15, but the deployed hosted route remains region-blocked by the venue. The venue-direct SDK path is source-ready and still awaits one eligible submit-to-status live pass.
- Wallet and chain: An EOA on BNB Smart Chain (
56); Safe and proxy identities are rejected. - Venue account: Yes. The working direct path needs a Predict.fun API key and a wallet-authenticated venue session.
- Credentials:
client.accounts.predictfunkeeps the API key and wallet private key in-process, creates the JWT directly with Predict.fun, and sends neither to Predictefy. The hosted path instead accepts the caller’s session bearer transiently for submit, cancel, or refresh. - Funding: BSC USDT in the EOA, with approval to the exchange selected by the market’s exact NegRisk/yield-bearing type. The LI.FI helper can fund the wallet.
Predict.fun is also server-built by default, using the same plain selector and order fields. It is
strictly EOA-only: signature type 0, with maker == signer == owner; any Safe/proxy request is a
typed 400 VALIDATION_ERROR. The lane fetches the exact catalog market from Predict.fun, requires
the selected on-chain outcome token to occur exactly once, reads its current feeRateBps, and
resolves the exchange from the exact (isNegRisk, isYieldBearing) pair. Missing type truth or any
catalog/API/exchange disagreement fails closed with nothing persisted.
LIMIT amounts follow the pinned 1.3.8 SDK: 18-decimal price/size inputs are truncated to three and
five significant digits respectively, and size must be at least 0.01 shares. Omitted expiresAt
uses the SDK’s 2100-01-01 no-expiry sentinel; an explicit Unix timestamp must be in the future and
is carried verbatim. The server uses a full-width 256-bit cryptographic salt because Predict.fun’s
relay also preserves salt as a decimal string. The response includes the venue-shaped unsigned
payload, buildVersion: 1, and complete EIP-712 fields. An active session bearer is needed only
when submitting, cancelling, or refreshing; it is never accepted in this build body. The legacy
echoed buildResult remains accepted unchanged.
Client-side submit route
Section titled “Client-side submit route”Predict.fun rejects order traffic from restricted regions, and hosted submits now route through Predictefy’s eligible regional egress relay (venue reads and order requests verified to reach the venue through it, 2026-08-22 — a live credentialed submit has not yet been verified on that path). The client-side route below stays fully supported for callers who prefer their own eligible connection: it builds at Predictefy, signs in the caller’s wallet, and submits under the caller’s own API key and in-process JWT:
const client = new Predictefy({ apiKey: process.env.PREDICTEFY_API_KEY, execBaseUrl: PREDICTEFY_EXEC_BASE_URL, venueCredentials: { predictfun: { apiKey: process.env.PREDICTFUN_API_KEY!, privateKey: process.env.PREDICTFUN_WALLET_KEY!, }, },});
const placed = await client.accounts.predictfun.createOrder( { idempotencyKey: 'your-stable-build-key', outcome: 12345, outcomeSide: 'YES', isBuy: true, price: 0.4, size: 10, owner: wallet.address, }, wallet,);const status = await client.accounts.predictfun.fetchOrder(placed.orderHash);Before asking the wallet to sign, the SDK independently reconstructs the exact Predict.fun EIP-712
order, then reads the market’s authoritative record from the fixed api.predict.fun origin and
refuses to sign unless everything agrees: the signed token must be the named outcome the caller
requested (outcomes are matched by the venue’s own outcome names — non-binary shapes refuse rather
than guess), the EIP-712 domain.verifyingContract must be the exact exchange contract selected by
the market’s authoritative isNegRisk/isYieldBearing flags among the four known contracts, and
the signed feeRateBps must equal the market’s authoritative fee. A failed or malformed venue read
refuses before signing, and the immutable mapping is cached per client per market. Intent binding
is mandatory: the exported signing helper requires the original order intent and a trusted market
mapping at both the type and runtime level — there is no structural-only signing path for this
venue. String prices and sizes are parsed losslessly (plain decimals up to 18 fractional digits;
anything else refuses), so precision drift can never smuggle different economics past the amount
check.
Submission sends the exact server-lane wire body under the caller’s x-api-key and an in-process
JWT (the dynamic auth message is signed by the caller’s wallet and exchanged directly with the
venue). Every credentialed call goes only to the fixed venue origin and refuses redirects; failures
are typed and generic. A successful create requires only the documented orderId and orderHash;
a missing status field is treated as acknowledged, never as a failure — a placed order is never
reported as failed.
Cancellation is the one verb where this SDK path is narrower than the hosted lane. On this
venue-direct path, client.accounts.predictfun.cancelOrder is honestly refused as unsupported:
the venue’s /v1/orders/remove only removes the book entry while the signed order remains valid,
and full invalidation requires an on-chain CTFExchange.cancelOrders transaction this SDK client
does not send. The hosted lane does both — its registry row is cancelOrder: true, and
POST /v1/exec/predictfun/orders/{executionId}/cancel takes a mode:
mode: "book"(the default) relays the venue’s ownPOST /orders/removeunder your transient session bearer — the book removal, with the same residual the venue itself warns about.mode: "onchain"returns an unsigned BSC transaction encodingCTFExchange.cancelOrders([order]), built from the stored order struct and its stored signature. You sign and broadcast it yourself; Predictefy verifies chain, recovered maker, and byte-equal{to, data, value}, then recordssignedwithout claiming a broadcast. A target that was never submitted has no stored signature and fails closed.
So the honest summary is: no single call fully invalidates a Predict.fun order, but both halves are implemented — one on each hosted cancel mode — and only the venue-direct SDK client refuses.
This implementation is source-ready. One eligible submit → status pass remains pending.