SDK Guide
The Seesaw TypeScript SDK for building applications on the binary prediction market protocol.
Installation
npm install @seesaw/sdk @solana/web3.js
Overview
Quick Start
import { Connection, PublicKey, Keypair, Transaction } from '@solana/web3.js';
import {
findMarketPda,
findPositionPda,
findOrderbookPda,
findVaultPda,
createPlaceOrderInstruction,
parseMarket,
OrderSide,
OrderType,
} from '@seesaw/sdk';
// Setup
const connection = new Connection('https://api.mainnet-beta.solana.com');
const programId = new PublicKey('SEESAW_PROGRAM_ID');
const durationSeconds = 900; // default; configurable per market (60–604800)
const marketId = BigInt(Math.floor(Date.now() / 1000 / durationSeconds));
// 1. Derive PDAs
const [marketPda] = findMarketPda(marketId, programId);
const [orderbookPda] = findOrderbookPda(marketPda, programId);
const [vaultPda] = findVaultPda(marketPda, programId);
const [positionPda] = findPositionPda(marketPda, wallet.publicKey, programId);
// 2. Read market data
const marketAccount = await connection.getAccountInfo(marketPda);
const market = parseMarket(marketAccount!.data);
console.log('Market ID:', market.marketId);
console.log('Start Time:', new Date(market.tStart * 1000));
console.log('End Time:', new Date(market.tEnd * 1000));
// 3. Build place order instruction
const placeOrderIx = createPlaceOrderInstruction({
market: marketPda,
orderbook: orderbookPda,
vault: vaultPda,
position: positionPda,
user: wallet.publicKey,
userTokenAccount: userUsdcAccount,
side: OrderSide.BuyYes,
priceBps: 6000, // 60%
quantity: BigInt(100), // 100 shares
orderType: OrderType.Limit,
});
// 4. Send transaction
const tx = new Transaction().add(placeOrderIx);
const signature = await sendAndConfirmTransaction(connection, tx, [wallet]);
In This Section
- Installation - Detailed setup instructions
- Reading Data - Fetching market and position data
- Building Transactions - Creating and sending transactions
- Examples - Complete code examples
- AI Agents - Autonomous agent integration
Key Concepts
PDAs (Program Derived Addresses)
All Seesaw accounts are PDAs derived from deterministic seeds:
| Account | Seeds | Purpose |
|---|---|---|
| Config | ["seesaw", "config"] | Protocol configuration |
| Market | ["seesaw", "market", market_id] | Market state |
| Orderbook | ["seesaw", "orderbook", market] | Order book state |
| Vault | ["seesaw", "vault", market] | Token vault |
| Position | ["seesaw", "position", market, user] | User position |
Order Sides
enum OrderSide {
BuyYes = 0, // Buy YES shares (bullish)
SellYes = 1, // Sell YES shares
BuyNo = 2, // Buy NO shares (bearish)
SellNo = 3, // Sell NO shares
}
Order Types
enum OrderType {
Limit = 0, // Match + rest on book
PostOnly = 1, // Reject if would match
ImmediateOrCancel = 2, // Match + cancel rest
}
Core Functions
PDA Derivation
// Config PDA (singleton)
const [configPda, configBump] = findConfigPda(programId);
// Market PDA
const marketId = BigInt(1234567);
const [marketPda, marketBump] = findMarketPda(marketId, programId);
// Orderbook PDA
const [orderbookPda, orderbookBump] = findOrderbookPda(marketPda, programId);
// Vault PDA
const [vaultPda, vaultBump] = findVaultPda(marketPda, programId);
// Position PDA
const [positionPda, positionBump] = findPositionPda(marketPda, userWallet, programId);
Account Parsing
// Parse market
const marketData = await connection.getAccountInfo(marketPda);
const market = parseMarket(marketData!.data);
// Parse orderbook
const orderbookData = await connection.getAccountInfo(orderbookPda);
const orderbook = parseOrderbook(orderbookData!.data);
// Parse position
const positionData = await connection.getAccountInfo(positionPda);
const position = parsePosition(positionData!.data);
// Parse config
const configData = await connection.getAccountInfo(configPda);
const config = parseConfig(configData!.data);
Instruction Builders
// Place order
const placeOrderIx = createPlaceOrderInstruction({...});
// Cancel order
const cancelOrderIx = createCancelOrderInstruction({...});
// Settle position
const settleIx = createSettlePositionInstruction({...});
// Crank operations
const snapshotStartIx = createSnapshotStartInstruction({...});
const snapshotEndIx = createSnapshotEndInstruction({...});
const resolveMarketIx = createResolveMarketInstruction({...});
Data Flow
Error Handling
import { SeesawError, ErrorCode } from '@seesaw/sdk';
try {
const tx = new Transaction().add(placeOrderIx);
await sendAndConfirmTransaction(connection, tx, [wallet]);
} catch (error) {
if (error.message.includes('TradingEnded')) {
console.error('Cannot trade: market has ended');
} else if (error.message.includes('InsufficientCollateral')) {
console.error('Cannot trade: need more USDC');
} else if (error.message.includes('InsufficientShares')) {
console.error('Cannot sell: not enough shares');
} else {
throw error;
}
}
Type Definitions
Market Account
interface MarketAccount {
marketId: bigint;
pythFeed: PublicKey;
settlementMint: PublicKey;
tStart: bigint;
tEnd: bigint;
startPrice: bigint | null;
endPrice: bigint | null;
outcome: Outcome | null;
totalYesShares: bigint;
totalNoShares: bigint;
totalCollateral: bigint;
bump: number;
}
enum Outcome {
Up = 1,
Down = 2,
}
Position Account
interface PositionAccount {
market: PublicKey;
owner: PublicKey;
yesShares: bigint;
noShares: bigint;
lockedYesShares: bigint;
lockedNoShares: bigint;
collateralLocked: bigint;
settled: boolean;
payout: bigint;
bump: number;
}
Order
interface Order {
orderId: bigint;
owner: PublicKey;
priceBps: number;
quantity: bigint;
originalQuantity: bigint;
timestamp: bigint;
originalSide: OrderSide;
isActive: boolean;
}
Requirements
- Node.js 18+
- TypeScript 5.0+ (recommended)
- @solana/web3.js 1.9+