A Python SDK to help developers interface with the Predict.fun protocol.
pip install predict-sdkfrom predict_sdk import (
OrderBuilder,
ChainId,
Side,
BuildOrderInput,
LimitHelperInput,
)
# Create an OrderBuilder without a signer (read-only)
builder = OrderBuilder.make(ChainId.BNB_MAINNET)
# Calculate order amounts for a LIMIT order
amounts = builder.get_limit_order_amounts(
LimitHelperInput(
side=Side.BUY,
price_per_share_wei=500000000000000000, # 0.5 USDT per share
quantity_wei=10000000000000000000, # 10 shares
)
)
print(f"Maker Amount: {amounts.maker_amount}")
print(f"Taker Amount: {amounts.taker_amount}")
# Build an order
order = builder.build_order(
"LIMIT",
BuildOrderInput(
side=Side.BUY,
token_id="YOUR_TOKEN_ID",
maker_amount=str(amounts.maker_amount),
taker_amount=str(amounts.taker_amount),
fee_rate_bps=100, # Get from GET /markets endpoint
),
)from eth_account import Account
from predict_sdk import OrderBuilder, ChainId
# Create from private key
private_key = "0x..." # Your private key
signer = Account.from_key(private_key)
# Or pass private key directly
builder = OrderBuilder.make(ChainId.BNB_MAINNET, private_key)
# Now you can sign orders and interact with contracts
typed_data = builder.build_typed_data(
order,
is_neg_risk=False,
is_yield_bearing=False,
)
signed_order = builder.sign_typed_data_order(typed_data)
print(f"Signature: {signed_order.signature}")Before trading, you need to set approvals for the exchange contracts:
# Set all approvals at once
result = builder.set_approvals(is_yield_bearing=False)
if result.success:
print("All approvals set successfully!")
else:
print("Some approvals failed")
for tx in result.transactions:
if not tx.success:
print(f"Failed: {tx.cause}")
# Or set individual approvals
builder.set_ctf_exchange_approval(is_neg_risk=False, is_yield_bearing=False)
builder.set_ctf_exchange_allowance(is_neg_risk=False, is_yield_bearing=False)from predict_sdk import OrderBuilder, ChainId, OrderBuilderOptions
builder = OrderBuilder.make(
ChainId.BNB_MAINNET,
private_key, # Must be the Privy exported wallet
OrderBuilderOptions(
predict_account="0x...", # Your Predict account address
),
)When using a Predict account (smart wallet), you can sign arbitrary messages that can be verified on-chain:
from predict_sdk import OrderBuilder, ChainId, OrderBuilderOptions
builder = OrderBuilder.make(
ChainId.BNB_MAINNET,
private_key,
OrderBuilderOptions(predict_account="0x..."),
)
# Sign a string message
signature = builder.sign_predict_account_message("Hello, world!")
# Or sign a pre-computed hash (useful for EIP-712 typed data)
signature = builder.sign_predict_account_message({"raw": "0x1234..."})
# Async version available
signature = await builder.sign_predict_account_message_async("Hello, world!")The signature is formatted for Kernel smart wallet verification, including the ECDSA validator address prefix.
from predict_sdk import MarketHelperInput, MarketHelperValueInput
# Market order by quantity (number of shares)
amounts = builder.get_market_order_amounts(
MarketHelperInput(
side=Side.BUY,
quantity_wei=10000000000000000000, # 10 shares
),
orderbook, # From GET /orderbook/{marketId}
)
# Market BUY by value (total USDT to spend)
amounts = builder.get_market_order_amounts(
MarketHelperValueInput(
side=Side.BUY,
value_wei=5000000000000000000, # 5 USDT
),
orderbook,
)
print(f"Maker Amount: {amounts.maker_amount}")
print(f"Taker Amount: {amounts.taker_amount}")
print(f"Amount: {amounts.amount}")
print(f"Price Per Share: {amounts.price_per_share}")
print(f"Slippage Applied: {amounts.slippage_bps} bps")
print(f"Is Min Amount Out: {amounts.is_min_amount_out}")By default, no additional slippage is applied to the order maker/taker amounts. You can specify a slippage tolerance in basis points (1 bps = 0.01%) to adjust the amounts:
- BUY orders: slippage deflates the
taker_amount(minimum shares out), keeping the USD commitment minimal so users can spend their full wallet balance. Requiresis_min_amount_out=True. - SELL orders: slippage decreases the
taker_amount(you're willing to receive less)
# BUY with slippage
amounts = builder.get_market_order_amounts(
MarketHelperInput(
side=Side.BUY,
quantity_wei=10000000000000000000, # 10 shares
slippage_bps=100, # 1% slippage tolerance
is_min_amount_out=True,
),
orderbook,
)
print(f"Maker Amount (cost): {amounts.maker_amount}")
print(f"Taker Amount (min shares out): {amounts.taker_amount}")
print(f"Amount (actual shares): {amounts.amount}")
print(f"Slippage: {amounts.slippage_bps} bps") # 100
# Value-based BUY with slippage
amounts = builder.get_market_order_amounts(
MarketHelperValueInput(
side=Side.BUY,
value_wei=5000000000000000000, # 5 USDT
slippage_bps=50, # 0.5% slippage tolerance
is_min_amount_out=True,
),
orderbook,
)Note: You must forward is_min_amount_out=True, the amount field, and slippageBps in your REST API request body for slippage to be applied.
# For standard markets
result = builder.redeem_positions(
condition_id="0x...",
index_set=1, # 1 or 2
is_neg_risk=False,
is_yield_bearing=False,
)
# For NegRisk (winner-takes-all) markets
result = builder.redeem_positions(
condition_id="0x...",
index_set=1,
amount=1000000000000000000, # Required for NegRisk
is_neg_risk=True,
is_yield_bearing=False,
)Merge both outcome tokens back into collateral (USDT). Useful when holding equal amounts of both YES and NO positions.
# For standard markets
result = builder.merge_positions(
condition_id="0x...",
amount=1000000000000000000, # Amount to merge (in wei)
is_neg_risk=False,
is_yield_bearing=False,
)
# For NegRisk (winner-takes-all) markets
result = builder.merge_positions(
condition_id="0x...",
amount=1000000000000000000,
is_neg_risk=True,
is_yield_bearing=False,
)from predict_sdk import CancelOrdersOptions
result = builder.cancel_orders(
orders=[order1, order2],
options=CancelOrdersOptions(
is_neg_risk=False,
is_yield_bearing=False,
),
)balance = builder.balance_of("USDT")
print(f"USDT Balance: {balance}")All contract interaction methods have async versions:
import asyncio
async def main():
balance = await builder.balance_of_async("USDT")
result = await builder.set_approvals_async(is_yield_bearing=False)
asyncio.run(main())The main class for building and signing orders.
OrderBuilder.make(
chain_id: ChainId,
signer: LocalAccount | str | None = None,
options: OrderBuilderOptions | None = None,
) -> OrderBuilderget_limit_order_amounts(data: LimitHelperInput) -> OrderAmountsget_market_order_amounts(data: MarketHelperInput | MarketHelperValueInput, book: Book) -> OrderAmountsbuild_order(strategy: "MARKET" | "LIMIT", data: BuildOrderInput) -> Orderbuild_typed_data(order: Order, *, is_neg_risk: bool, is_yield_bearing: bool) -> EIP712TypedDatabuild_typed_data_hash(typed_data: EIP712TypedData) -> strsign_typed_data_order(typed_data: EIP712TypedData) -> SignedOrdersign_predict_account_message(message: str | dict) -> str- Sign a message for a Predict accountsign_predict_account_message_async(message: str | dict) -> str- Async version
set_approvals(*, is_yield_bearing: bool = False) -> SetApprovalsResultset_ctf_exchange_approval(*, is_neg_risk: bool, is_yield_bearing: bool, approved: bool = True) -> TransactionResultset_neg_risk_adapter_approval(*, is_yield_bearing: bool, approved: bool = True) -> TransactionResultset_ctf_exchange_allowance(*, is_neg_risk: bool, is_yield_bearing: bool, amount: int = MAX_UINT256) -> TransactionResult
balance_of(token: "USDT" = "USDT", address: str | None = None) -> intredeem_positions(condition_id: str, index_set: 1 | 2, amount: int | None = None, *, is_neg_risk: bool, is_yield_bearing: bool) -> TransactionResultmerge_positions(condition_id: str, amount: int, *, is_neg_risk: bool, is_yield_bearing: bool) -> TransactionResult
cancel_orders(orders: list[Order], options: CancelOrdersOptions) -> TransactionResultvalidate_token_ids(token_ids: list[int], *, is_neg_risk: bool, is_yield_bearing: bool) -> bool
from predict_sdk import (
ChainId, # BNB_MAINNET (56), BNB_TESTNET (97)
Side, # BUY (0), SELL (1)
SignatureType, # Only supports EOA (0)
Order,
SignedOrder,
BuildOrderInput,
OrderAmounts,
LimitHelperInput,
MarketHelperInput,
MarketHelperValueInput,
Book,
EIP712TypedData,
TransactionResult,
SetApprovalsResult,
CancelOrdersOptions,
OrderBuilderOptions,
)- Python >= 3.10
- web3.py >= 6.0.0
MIT