npm package: @sportsperp/sdk
Description: TypeScript SDK for SportsPerp OBV Index Perpetual Futures on Solana
Latest version: 0.1.0

# @sportsperp/sdk

TypeScript SDK for the SportsPerp OBV Index Perpetual Futures protocol on Solana.

Trade perpetual futures on football (soccer) team and player performance indices powered by on-chain oracle data.

## Installation

```bash
npm install @sportsperp/sdk @coral-xyz/anchor @solana/web3.js
```

## Quick Start

```typescript
import { Connection, Keypair } from "@solana/web3.js";
import { Wallet } from "@coral-xyz/anchor";
import { SportsPerpsClient, Direction } from "@sportsperp/sdk";
import { BN } from "@coral-xyz/anchor";

// Connect to devnet
const connection = new Connection("https://api.devnet.solana.com");
const wallet = new Wallet(Keypair.generate());

const client = new SportsPerpsClient({ connection, wallet });

// Fetch all markets
const markets = await client.getAllMarkets();
console.log(`${markets.length} markets available`);

// Get a specific market (e.g. Liverpool, market ID 0)
const market = await client.getMarket(0);
console.log(`${market.teamName} — Oracle: ${market.oraclePrice.toNumber()}`);

// Open a long position (10 USDC collateral, 5x leverage)
await client.openPosition(0, {
  direction: Direction.Long,
  collateral: new BN(10_000_000),  // 10 USDC (6 decimals)
  leverage: new BN(5_000),         // 5x (3 decimal places)
}, userTokenAccount);

// Check position
const position = await client.getPosition(0);
const pnl = client.calculatePnl(position, market.oraclePrice);
console.log(`PnL: ${pnl.toNumber() / 1e6} USDC`);

// Close position
await client.closePosition(0, userTokenAccount);
```

## API Reference

### `SportsPerpsClient`

The main entry point. Wraps all 11 program instructions with typed methods.

#### Constructor

```typescript
new SportsPerpsClient({
  connection: Connection,       // Solana RPC connection
  wallet: Wallet,               // Anchor wallet (signing keypair)
  programId?: PublicKey,         // Override program ID (defaults to devnet)
  confirmOptions?: ConfirmOptions,
})
```

#### Admin Methods

| Method | Description |
|--------|-------------|
| `initializeMarket(args, usdcMint)` | Create a new perpetual market |
| `initializeInsurance(usdcMint)` | Initialize the global insurance fund |
| `updateOracle(marketId, args)` | Update oracle price for a market |
| `pauseMarket(marketId)` | Emergency pause a market |
| `unpauseMarket(marketId)` | Resume a paused market |

#### Trading Methods

| Method | Description |
|--------|-------------|
| `openPosition(marketId, args, userTokenAccount)` | Open a new position |
| `closePosition(marketId, userTokenAccount)` | Close position and settle P&L |
| `addCollateral(marketId, amount, userTokenAccount)` | Add USDC collateral |
| `withdrawCollateral(marketId, amount, userTokenAccount)` | Withdraw collateral (margin check enforced) |

#### Permissionless Methods

| Method | Description |
|--------|-------------|
| `applyFunding(marketId)` | Crank the funding rate |
| `liquidate(marketId, positionOwner, liquidatorTokenAccount)` | Liquidate underwater position (5% reward) |

#### Account Fetchers

| Method | Description |
|--------|-------------|
| `getMarket(marketId)` | Fetch market config |
| `getAllMarkets()` | Fetch all markets |
| `getPosition(marketId, user?)` | Fetch user position |
| `getAllUserPositions(user?)` | All positions for a user |
| `getAllMarketPositions(marketId)` | All positions in a market |
| `getVault(marketId)` | Fetch vault state |
| `getInsuranceFund()` | Fetch insurance fund state |
| `hasPosition(marketId, user?)` | Check if position exists |

#### Math Utilities

| Method | Description |
|--------|-------------|
| `calculatePnl(position, currentPrice)` | Unrealized P&L |
| `marginRatioBps(position, currentPrice)` | Margin ratio in basis points |
| `isLiquidatable(position, currentPrice)` | Liquidation check |
| `liquidationPrice(position)` | Price at which position liquidates |

### Standalone Exports

All client methods are also available as standalone functions:

```typescript
import {
  // Instruction builders
  buildOpenPositionIx,
  buildClosePositionIx,
  // Account fetchers
  fetchMarketConfig,
  fetchAllMarkets,
  // Math
  calculatePnl,
  isLiquidatable,
  // PDA helpers
  getMarketConfigPda,
  getPositionPda,
  // Types
  Direction,
  MarketType,
  PROGRAM_ID,
} from "@sportsperp/sdk";
```

## OBV Index

The OBV (On-Ball Value) Index is a composite performance metric:

| Component | Weight | Source |
|-----------|--------|--------|
| OBV Score | 50% | Ball-AI analytics engine |
| Form | 30% | Recent match results (rolling window) |
| Results | 20% | Points per game |

Indices are blended with a 4-hour EMA and updated via on-chain oracles. Markets cover the English Premier League (20 teams + 47 players on devnet).

## Network

- **Devnet Program ID:** `5LyQWjrtCyy4B356rXTxadh45c9m866Esrk4uj9Q8TVn`
- **Collateral:** USDC (SPL Token)
- **Oracle:** Crank-updated by the SportsPerp oracle service

## Development

```bash
npm install
npm run build    # Compile TypeScript
npm test         # Run tests (37 tests)
```

## License

MIT