Skip to main content

Reference

Quick reference for developers integrating with Seesaw.

Constants

Protocol Constants

ConstantValueDescription
DEFAULT_DURATION900Default market duration (15 min); configurable 60–604800
PRICE_SCALE10,000Basis points for price representation
MAX_ORDERS_PER_USER10Maximum open orders per user per market
MIN_ORDER_SIZE1Minimum shares per order
MAX_ORDER_SIZE1,000,000Maximum shares per order
TICK_SIZE100Price tick in basis points (0.01 USDC)

Fee Constants

ConstantValueDescription
TAKER_FEE_BPS30Taker fee (0.30%)
MAKER_REBATE_BPS10Maker rebate (0.10%)
PROTOCOL_FEE_BPS20Net protocol fee (0.20%)
CRANK_REWARD1,000Crank reward in lamports

Time Constants

ConstantValueDescription
CREATE_WINDOW86,400Can create market up to 24h before start
SETTLE_WINDOW604,800Must settle within 7 days
SNAPSHOT_GRACE60Oracle timestamp grace period

PDA Seeds

// TypeScript reference for PDA derivation

const PROGRAM_ID = 'SeesawPredictionMarket1111111111111111';

const seeds = {
  config: ['seesaw', 'config'],
  market: (marketId: bigint) => ['seesaw', 'market', u64ToLeBytes(marketId)],
  orderbook: (market: PublicKey) => ['seesaw', 'orderbook', market.toBytes()],
  vault: (market: PublicKey) => ['seesaw', 'vault', market.toBytes()],
  position: (market: PublicKey, user: PublicKey) => [
    'seesaw',
    'position',
    market.toBytes(),
    user.toBytes(),
  ],
};

Account Layouts

Config Account

Offset  Size  Field
──────────────────────────────────
0       8     discriminator
8       32    authority
40      32    treasury
72      2     taker_fee_bps
74      2     maker_rebate_bps
76      1     paused
77      51    _reserved
──────────────────────────────────
Total: 128 bytes

Market Account

Offset  Size  Field
──────────────────────────────────
0       8     discriminator
8       8     market_id
16      32    pyth_feed
48      8     start_time
56      8     end_time
64      9     start_price (Option<i64>)
73      9     end_price (Option<i64>)
82      1     outcome (Option<Outcome>)
83      8     total_yes_shares
91      8     total_no_shares
99      8     total_collateral
107     1     state
108     148   _reserved
──────────────────────────────────
Total: 256 bytes

Position Account

Offset  Size  Field
──────────────────────────────────
0       8     discriminator
8       32    market
40      32    owner
72      8     yes_shares
80      8     no_shares
88      8     _reserved
──────────────────────────────────
Total: 96 bytes

Error Codes

CodeNameDescription
6000InvalidMarketStateOperation not valid for current state
6001PriceOutOfRangePrice not in [0, 10000]
6002InsufficientSharesNot enough shares to sell
6003InsufficientCollateralNot enough USDC
6004InvalidOracleTimestampPyth timestamp invalid
6005InvalidOraclePricePyth price <= 0
6006OracleConfidenceTooHighPyth confidence exceeds limit
6007SnapshotAlreadyCapturedPrice already recorded
6008MarketNotResolvedMarket still open
6009PositionAlreadySettledAlready claimed
6010OrderNotFoundOrder doesn't exist
6011UnauthorizedWrong signer
6012MathOverflowArithmetic error

Pyth Feed IDs

Mainnet

AssetFeed Address
SOL/USDH6ARHf6YXhG...
BTC/USDGVXRSBjFk6e...
ETH/USDJBu1AL4obB...
BONK/USD8ihFLu5FN...

Devnet

AssetFeed Address
SOL/USDJ83w4HKfq...
BTC/USDHovQMDrbA...
ETH/USDEdVCmQ9F...

Market ID Calculation

// Calculate market ID from timestamp and duration
function getMarketId(timestamp: number, durationSeconds: number = 900): bigint {
  return BigInt(Math.floor(timestamp / durationSeconds));
}

// Get market boundaries
function getMarketBoundaries(
  marketId: bigint,
  durationSeconds: number = 900
): {
  start: number;
  end: number;
} {
  const start = Number(marketId) * durationSeconds;
  return {
    start,
    end: start + durationSeconds,
  };
}

// Get current market
function getCurrentMarket(): bigint {
  return getMarketId(Math.floor(Date.now() / 1000));
}

Order Side Encoding

enum OrderSide {
  BuyYes = 0,
  SellYes = 1,
  BuyNo = 2, // Converted to SellYes internally
  SellNo = 3, // Converted to BuyYes internally
}

Outcome Encoding

enum Outcome {
  Up = 0, // YES wins
  Down = 1, // NO wins
}

Market State Encoding

enum MarketState {
  Created = 0,
  Trading = 1,
  Settling = 2,
  Resolved = 3,
  Closed = 4,
}

RPC Endpoints

Mainnet

https://api.mainnet-beta.solana.com
https://seesaw.helius-rpc.com  (recommended)

Devnet

https://api.devnet.solana.com

SDK Installation

# npm
npm install @seesaw/sdk

# yarn
yarn add @seesaw/sdk

# pnpm
pnpm add @seesaw/sdk

Quick Examples

Read Market

import { getMarket } from '@seesaw/sdk';

const market = await getMarket(connection, marketPubkey);
console.log('State:', market.state);
console.log('YES shares:', market.totalYesShares);

Place Order

import { placeOrder, OrderSide } from '@seesaw/sdk';

const tx = await placeOrder({
  connection,
  market: marketPubkey,
  user: userPubkey,
  side: OrderSide.BuyYes,
  price: 5500, // 0.55 USDC in bps
  quantity: 100,
});

Settle Position

import { settlePosition } from '@seesaw/sdk';

const tx = await settlePosition({
  connection,
  market: marketPubkey,
  user: userPubkey,
});

Glossary

TermDefinition
Basis Point (bps)1/100th of a percent. 10,000 bps = 100%
CrankPermissionless operation advancing protocol state
EpochMarket window (configurable: 60s–7d)
MakerOrder placer whose order rests on book
Market IDfloor(timestamp / duration_seconds)
PDAProgram Derived Address
PythDecentralized oracle network
TakerParty executing against resting orders
TickMinimum price increment