JSPM

@pit-protocol/sdk

0.0.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 7
  • Score
    100M100P100Q26965F
  • License Apache-2.0

TypeScript SDK for the PIT Protocol - prediction market on Solana

Package Exports

  • @pit-protocol/sdk

Readme

@pit-protocol/sdk

TypeScript SDK for interacting with the PIT prediction market protocol on Solana.

Installation

npm install @pit-protocol/sdk
# or
pnpm add @pit-protocol/sdk

Design Principles

  • SDK provides instruction builders only - Transaction sending/signing is user's responsibility
  • Keeper module handles RPC/signing - Only for automation use cases
  • Maximum flexibility - Users can compose, batch, simulate as they wish

Quick Start

Creating Instructions

import { createTradeInstruction, PoolType, getMarketAddress, WSOL_MINT } from "@pit-protocol/sdk";
import { Connection, Transaction, sendAndConfirmTransaction } from "@solana/web3.js";
import BN from "bn.js";
import { TOKEN_PROGRAM_ID } from "@solana/spl-token";

// Create a trade instruction
const ix = createTradeInstruction({
  weekNumber: 1,
  poolType: PoolType.High,
  strikeIndex: 0,
  isHit: true,
  amount: new BN(1_000_000_000), // 1 token (9 decimals)
  isBuy: true,
  user: wallet.publicKey,
  userTokenAccount: hitTokenAta,
  userWsolAccount: wsolAta,
  wsolVault: market.wsolVault,
  tokenMint: hitMint,
  wsolMint: WSOL_MINT,
  tokenProgram: TOKEN_PROGRAM_ID,
});

// User sends the transaction themselves
const tx = new Transaction().add(ix);
await sendAndConfirmTransaction(connection, tx, [wallet]);

Fetching Market State

import { getMarketAddress, parseMarketAccount } from "@pit-protocol/sdk";

// Get market PDA
const marketPda = getMarketAddress(1); // week number

// Fetch and parse account
const accountInfo = await connection.getAccountInfo(marketPda);
if (accountInfo) {
  const market = parseMarketAccount(accountInfo.data.slice(8)); // skip discriminator
  console.log(`Week: ${market.weekNumber}`);
  console.log(`End: ${new Date(market.endTimestamp.toNumber() * 1000)}`);
  console.log(`High Pool Outcome: ${market.highPool.winningOutcome}`);
}

Getting Pyth Price

import { PythPriceService } from "@pit-protocol/sdk";

const priceService = new PythPriceService();

// Get latest SOL/USD price
const price = await priceService.getLatestPrice();
console.log(`SOL/USD: $${price.price}`);
console.log(`Price in cents: ${price.priceInCents}`);

// Calculate expected outcome based on price
const outcome = priceService.calculateOutcome(price.priceInCents, strikes);
console.log(`High outcome: ${outcome.highOutcome}`);
console.log(`Low outcome: ${outcome.lowOutcome}`);

Keeper Bot (Automated Market Watching)

import { MarketWatcher } from "@pit-protocol/sdk";
import { Connection, Keypair } from "@solana/web3.js";

const connection = new Connection(RPC_URL);
const signer = Keypair.fromSecretKey(/* ... */);

const watcher = new MarketWatcher({
  connection,
  signer,
  weekNumber: 1,
  verbose: true,
});

watcher.on("priceUpdate", (price) => {
  console.log(`Price: $${price.price}`);
});

watcher.on("outcomeChange", (event) => {
  console.log(`${event.poolType} outcome changed: ${event.outcome}`);
  console.log(`TX: ${event.signature}`);
});

watcher.on("settled", (event) => {
  console.log(`Market ${event.weekNumber} settled!`);
});

watcher.on("error", (err) => {
  console.error(`Error: ${err.message}`);
});

// Start watching (runs until both pools settled)
await watcher.start();

API Reference

Instruction Builders

All builders return TransactionInstruction - user handles transaction sending.

// Trading
createTradeInstruction(params: TradeInstructionParams): TransactionInstruction

// Market operations (operator only)
createInitializeMarketInstruction(params: InitializeMarketParams): TransactionInstruction
createInitializePoolInstruction(params: InitializePoolParams): TransactionInstruction
createClaimFeesInstruction(params: ClaimFeesParams): TransactionInstruction
createWithdrawSubsidyInstruction(params: WithdrawSubsidyParams): TransactionInstruction
createPauseMarketInstruction(params: PauseMarketParams): TransactionInstruction
createUnpauseMarketInstruction(params: PauseMarketParams): TransactionInstruction

// Permissionless operations (anyone/keeper)
createMarkExtremeInstruction(params: MarkExtremeParams): TransactionInstruction
createSettleMarketInstruction(params: SettleMarketParams): TransactionInstruction
createRedeemInstruction(params: RedeemParams): TransactionInstruction

Account Utilities

// PDA derivation
getMarketAddress(weekNumber: number): PublicKey
getMarketAddressWithBump(weekNumber: number): [PublicKey, number]
getWsolVaultAddress(marketPda: PublicKey, wsolMint: PublicKey): PublicKey
getUserTokenAddress(owner: PublicKey, mint: PublicKey, programId?: PublicKey): PublicKey

// Account parsing
parseMarketAccount(data: Buffer): MarketState
isMarketEnded(market: MarketState): boolean
isFullySettled(market: MarketState): boolean
getTokenMint(pool: PoolState, strikeIndex: number, isHit: boolean): PublicKey

Pyth Price Service

class PythPriceService {
  constructor(hermesUrl?: string, feedId?: string);

  // Get current price
  getLatestPrice(): Promise<PythPrice>;

  // Get VAA data for on-chain posting
  getPriceUpdateData(): Promise<string[]>;

  // Calculate outcome from price
  calculateOutcome(priceInCents: number, strikes: [BN, BN, BN]): OutcomeResult;

  // Check if mark_extreme should be called
  shouldMarkExtreme(currentOutcome: number, newOutcome: number): boolean;
}

Keeper Module

class MarketWatcher extends EventEmitter {
  constructor(config: MarketWatcherConfig)

  start(): Promise<void>  // Start watching
  stop(): void            // Stop watching
  getStatus(): WatcherStatus

  // Events
  on('priceUpdate', (price: PythPrice) => void)
  on('outcomeChange', (event: OutcomeChangeEvent) => void)
  on('settled', (event: SettledEvent) => void)
  on('error', (error: WatcherError) => void)
  on('stopped', () => void)
}

Constants

import {
  PROGRAM_ID, // PIT program ID
  OPERATOR, // Hardcoded operator address
  WAD, // 10^18 precision
  TRADE_FEE_PERCENTAGE, // 3% in WAD
  SOL_USD_FEED_ID, // Pyth feed ID (bytes)
  SOL_USD_PRICE_FEED_ACCOUNT, // Sponsored push feed account (PublicKey)
  HERMES_URL, // Pyth Hermes API
  WSOL_MINT, // wSOL mint address
  TOKEN_2022_PROGRAM_ID,
  PYTH_RECEIVER_PROGRAM_ID,
} from "@pit-protocol/sdk";

Types

enum PoolType {
  High = 0,
  Low = 1,
}

interface MarketState {
  weekNumber: number;
  operator: PublicKey;
  wsolVault: PublicKey;
  startTimestamp: BN;
  endTimestamp: BN;
  totalSubsidy: BN;
  feesCollected: BN;
  isPaused: boolean;
  highPool: PoolState;
  lowPool: PoolState;
  bump: number;
}

interface PoolState {
  isInitialized: boolean;
  isSettled: boolean;
  winningOutcome: number;
  qVector: [BN, BN, BN, BN];
  b: BN;
  strikes: [BN, BN, BN];
  hitMints: [PublicKey, PublicKey, PublicKey];
  missMints: [PublicKey, PublicKey, PublicKey];
  claimedWinnings: BN;
}

interface PythPrice {
  price: number; // USD
  priceInCents: number; // For strike comparison
  confidence: number;
  timestamp: number;
}

interface TradeSimulationResult {
  grossCost: BN; // Cost before fees (lamports)
  fee: BN; // Trading fee (lamports)
  netCost: BN; // Total after fees
  tokensAmount: BN; // Token amount
  pricePerToken: number; // Average price
  priceImpact: number; // Impact %
}

Trade Simulation Functions

The SDK provides functions to simulate trades before executing them:

import {
  tokensForSolBudget,
  solCostForTokens,
  solRefundForTokens,
  tokensForSolTarget,
} from "@pit-protocol/sdk";

// Calculate how many tokens you can buy with X SOL
const result = tokensForSolBudget(poolState, strikeIndex, isHit, solBudget);
console.log(`Can buy ${result.tokensAmount} tokens for ${result.netCost} lamports`);

// Calculate how much SOL to buy X tokens
const buyCost = solCostForTokens(poolState, strikeIndex, isHit, tokenAmount);
console.log(`Buying ${tokenAmount} tokens costs ${buyCost.netCost} lamports`);

// Calculate how much SOL you'll get for selling X tokens
const sellRefund = solRefundForTokens(poolState, strikeIndex, isHit, tokenAmount);
console.log(`Selling ${tokenAmount} tokens returns ${sellRefund.netCost} lamports`);

Development

# Install dependencies
pnpm install

# Build
pnpm build

# Clean
pnpm clean

License

Apache-2.0