Trading & Settlement
This page covers what happens after a user picks a market: how the order is built, signed, and submitted; what approvals are needed; how positions are redeemed; how MAGMA captures fees/referrals; and how DFlow's gasless path works. The invariant across all eight venues: the user's wallet produces the signature in the browser, and MAGMA never holds the key.
Order lifecycle: build → sign → submit
There are three construction models (see Architecture). The sign step is always the user's browser wallet; build and submit vary.
Model A — backend-built order, client signs, backend relays
Used by Limitless, Predict.fun, and Opinion (CLOB venues with an SDK).
- Build —
POST /v1/<p>/order/build. The backend SDK (@limitless-exchange/sdk,@predictdotfun/sdk, Opinion CLOB) computes the authoritative order (FOK/LIMIT amounts, salt, fee) and returns the unsignedorder+ EIP-712domain/types. No order math runs in the browser. - Approve (see below) and sign — the lib signs the
Ordertyped data with viem (signTypedData). Bigints are rebuilt from the strings the backend returned. - Submit —
POST /v1/<p>/order. The backend relays the signed order to the venue: Limitless under partner HMAC (ownerId/onBehalfOf= the user'sprofileId); Predict and Opinion underx-api-key.
Model B — backend-built transaction, client signs/sends
Used by Rain (AMM) and Kalshi/DFlow (Solana).
- Rain:
POST /v1/rain/trade/buildreturnscontractAddress+txData(an unsigned EVM tx derived from a fresh quote and slippage-derivedminShares). The lib approves the AMM, then sends the prepared tx (walletClient.sendTransactionwith the returnedto+data) on the market's chain. - Kalshi/DFlow:
POST /v1/dflow/tradereturns a base64VersionedTransactionpre-built by DFlow's/order. The lib deserializes and eithersignAndSendTransaction(normal) or signs without sending (sponsored — see Gasless).
Model C — client-built order, client signs/sends
Used by Polymarket and Overtime V2 — the venue SDK/contract is called directly from the browser, so even construction happens on the user's IP.
- Polymarket:
@polymarket/clob-client-v2in the browser;createAndPostMarketOrder(... FOK)posts straight to the Polymarket CLOB. Never proxied server-side. - Overtime V2:
writeContractagainstSportsAMMV2.trade()on Optimism with the assembledTradeDatatuple, expected quote, slippage, and referrer.
Approvals
EVM venues require ERC-20 / ERC-1155 approvals before a trade; the libs check allowance and approve-max once:
| Platform | BUY approves | SELL approves | Collateral |
|---|---|---|---|
| Polymarket | USDC.e → CTF/exchange (collateral allowance) | conditional tokens | USDC.e (Polygon) |
| Limitless | USDC → exchange | CTF setApprovalForAll → exchange (+ adapter) | USDC (Base, 6dp) |
| Predict.fun | USDT → exchange | CTF setApprovalForAll → exchange (+ neg-risk adapter) | USDT (BSC, 18dp) |
| Rain | collateral → AMM (to) | — | per-chain USDC (BNB → USDT) |
| Overtime V2 | USDC → SportsAMMV2 | — | USDC (Optimism, 6dp) |
| Kalshi/DFlow | (handled inside the DFlow tx; ATA/rent can be sponsored) | — | USDC / CASH (6dp) |
Solana (Kalshi/DFlow) has no ERC-style approval; associated-token-account creation and rent are part of the DFlow tx and can be sponsored.
Redemption
Winning positions are redeemed on-chain from the user's own wallet (no MAGMA creds), valid only after settlement:
- Polymarket — CTF
redeemPositions(collateral, parentCollectionId, conditionId, [1,2]); neg-risk markets use the NegRiskAdapterredeemPositions(conditionId, amounts). - Limitless — CTF
redeemPositions(collateral, ZERO_HASH, conditionId, [1,2])(valid oncepayoutDenominator(conditionId) != 0). - Predict.fun — standard CTF redeem, or family-aware neg-risk-adapter / yield-bearing
redeem (the lib picks the right contract from
isNegRisk/isYieldBearing). - Kalshi/DFlow — redeem is a regular sell of the winning outcome mint back to settlement
via
/orderonceredemptionStatusisopen(no special flag, no KYC);POST /v1/dflow/redeem. - Rain / Opinion / Overtime — settlement/redemption follow the venue's own model; positions are surfaced read-only via the proxy.
Fee & referral capture
MAGMA captures revenue per platform without custodying funds:
- Kalshi/DFlow — a builder fee (
platformFeeBps, default20= 0.2%) is attached to the DFlow/orderonly when afeeAccount(MAGMA-owned USDC ATA) is configured. Declaring a fee with no account collects nothing and worsens slippage, so it is skipped otherwise. - Predict.fun — a one-time referral enrolment sets MAGMA as the user's referrer
(
PREDICT_FUN_REFERRAL_CODE), giving MAGMA a fee share on the user's trades. Done via/auth-message→personal_sign→/referral, gated bylocalStorage, non-blocking to the trade. - Limitless — orders are placed under MAGMA's partner account (HMAC); the partner
relationship is the revenue mechanism. The order is signed with the profile's real
feeRateBps. - Polymarket — optional
BUILDER_CODEattribution on each order. - Overtime V2 — the configured
referreraddress is passed intoSportsAMMV2.trade().
Sponsored / gasless (DFlow)
DFlow supports gasless Kalshi trades so users with no SOL (especially embedded wallets) can
trade — MAGMA's sponsor wallet pays the tx fee + ATA/rent. It is off unless
DFLOW_SPONSOR_ENABLED=true and a sponsor secret key is set.
Flow (sponsorExec):
- Backend builds the order with
sponsor=<pubkey>&sponsorExec=true; the fee-payer is the sponsor, so the tx needs both user and sponsor signatures. The backend caches the message bytes of the issued order and returns asponsorOrderId. - The user signs without broadcasting (
signTransactionOnly) and sends the signed tx toPOST /v1/dflow/sponsor-submitwith theorderId. - The backend co-signs with the sponsor key and broadcasts — but only if the submitted tx's message bytes match a recently-issued order (anti blind-sign on the hot sponsor wallet).
Settlement / fill confirmation
- Kalshi/DFlow — fills are async (continuous liquidity provision). Landing on-chain is not
the fill; the lib polls
GET /v1/dflow/order-status?signature=to terminal (closed/filled/expired/failed). - CLOB venues (Polymarket/Limitless/Predict/Opinion) — FOK orders return a fill result from the submit/relay call.
- AMM / on-chain (Rain/Overtime) — the lib
waitForTransactionReceipton the sent tx.
See also
- Platform Integrations — per-platform signing model.
- Architecture — why signing is client-side.
- API Reference — the build/submit/quote endpoints used here.