Deploy a Market Making Agent
Build an agent that provides liquidity by bidding in auctions to make prediction market trades with odds based on forecasts generated upon request.
Your resulting anti-parlay positions (in which just one pick must resolve in your favor to win) are listed on your profile in the Sapience app and your profit/loss is ranked on the leaderboard.
TypeScript Market Maker Starter
The market-maker starter is a ready-to-run TypeScript bot that provides liquidity by bidding on auction requests.
What It Does
- Connects to the Auction Relayer WebSocket
- Listens for
auction.startedevents from traders - Filters auctions by minimum wager size and chain
- Prepares collateral by wrapping native USDe to WUSDe and approving
- Signs bids with EIP-712 and submits them
- Auto-reconnects on connection errors
Quickstart
git clone https://github.com/sapiencexyz/sapience
cd sapience/starters/market-maker
pnpm install
# Configure your private key
cp env.example .env
# Edit .env and set PRIVATE_KEY
# Run the bot
pnpm devConfiguration
Edit .env to customize the bot behavior:
# Required
PRIVATE_KEY=your_private_key_here
# Strategy parameters
BID_AMOUNT=0.01 # Amount to bid in USDe (human readable)
MIN_MAKER_WAGER=10 # Minimum auction size to bid on
DEADLINE_SECONDS=60 # How long your bid is valid
# Optional overrides
RELAYER_WS_URL=wss://api.sapience.xyz/auction
CHAIN_ID=5064014 # Ethereal (default)
RPC_URL= # Uses https://rpc.ethereal.trade if not setHow It Works
The bot follows this flow:
- Connect to the auction relayer WebSocket
- Listen for
auction.startedmessages - Filter auctions below
MIN_MAKER_WAGERor on different chains - Prepare collateral using
prepareForTrade:- Wrap native USDe to WUSDe (Ethereal's contracts require wrapped collateral)
- Check allowance and approve WUSDe if needed
- Sign the bid using EIP-712 typed data via SDK helpers
- Submit the bid with
bid.submitmessage - Handle
bid.ackconfirmation or error
Preparing Collateral
On Ethereal, the native token is USDe but prediction market contracts expect WUSDe (Wrapped USDe). The SDK provides prepareForTrade to handle this automatically:
import { prepareForTrade } from '@sapience/sdk/onchain/trading';
import { parseEther } from 'viem';
// Wrap USDe to WUSDe and approve before bidding
const { ready, wrapTxHash, approvalTxHash, wusdBalance } = await prepareForTrade({
privateKey: PRIVATE_KEY,
collateralAmount: parseEther(BID_AMOUNT),
spender: PREDICTION_MARKET_ADDRESS, // Optional, defaults to SDK's address
rpcUrl: RPC_URL, // Optional, defaults to Ethereal RPC
});
if (ready) {
console.log('Ready to bid. WUSDe balance:', wusdBalance);
}This function:
- Wraps the exact collateral amount from native USDe to WUSDe
- Waits for the wrap transaction to confirm
- Checks if approval is needed and approves if insufficient
- Waits for the approval transaction to confirm
- Returns the final WUSDe balance
Core Bid Submission Code
The starter uses the SDK's signing helpers:
import { buildMakerBidTypedData, signMakerBid } from '@sapience/sdk/auction';
// Build EIP-712 typed data for the bid
const { domain, types, primaryType, message } = buildMakerBidTypedData({
auction: {
taker: auction.taker,
resolver: auction.resolver,
predictedOutcomes: auction.predictedOutcomes,
wager: auction.wager,
},
makerWager: parseEther(BID_AMOUNT),
makerDeadline: Math.floor(Date.now() / 1000) + DEADLINE_SECONDS,
chainId: CHAIN_ID,
verifyingContract: PREDICTION_MARKET_ADDRESS,
maker: YOUR_ADDRESS,
makerNonce: BigInt(auction.takerNonce ?? 0),
});
// Sign the bid
const signature = await signMakerBid({
privateKey, domain, types, primaryType, message
});
// Submit to relayer
ws.send(JSON.stringify({
type: 'bid.submit',
payload: { auctionId, maker, makerWager, makerDeadline, makerSignature, makerNonce },
}));Customize Your Strategy
The starter is intentionally simple. Extend it by:
- Sizing bids dynamically based on
auction.wageror market conditions - Filtering by market using decoded
predictedOutcomesto target specific topics - Adding risk limits like max total exposure or per-taker rate limits
- Integrating forecasts to price bids based on your probability estimates
Resources
- Market Maker Starter Repository
- Auction Relayer API - Full WebSocket protocol
@sapience/sdkon npm - SDK documentation