Skill: cannedoxygen/edgebets (version 1.0.4)

--- name: edgebets description: AI-powered sports betting simulations with Monte Carlo analysis version: 1.0.0 author: EdgeBets tags: - sports - betting - simulation - monte-carlo - nba - nfl - mlb - mls - x402 - solana requires: env: - SOLANA_PRIVATE_KEY bins: - node --- # EdgeBets Sports Simulation Run professional-grade Monte Carlo simulations for sports betting analysis. Get win probabilities, projected scores, spread predictions, and edge detection for NBA, NFL, MLB, and MLS games. ## Quick Start ```bash npm install edgebets-sdk ``` ```javascript import { createClient } from 'edgebets-sdk'; const client = createClient(JSON.parse(process.env.SOLANA_PRIVATE_KEY)); // Get today's games (FREE) const games = await client.getGames('nba'); // Run simulation ($1.00 USDC) const result = await client.simulate('nba', games[0].id); ``` ## When to Use This Skill Use EdgeBets when the user asks about: - Sports game predictions or analysis - Win probabilities for upcoming games - Betting odds comparison and value detection - Monte Carlo simulations for sports - NBA, NFL, MLB, or MLS game analysis - **Pick of the day** or daily betting picks - Track record of past picks ## Available Actions ### 1. Browse Today's Games (FREE) Show available games without any payment required. **Trigger phrases:** - "What NBA games are on today?" - "Show me today's NFL matchups" - "List MLS games" - "What baseball games are playing?" **Response format:** ``` Today's NBA Games: 1. Lakers vs Celtics - 7:30 PM ET 2. Warriors vs Suns - 10:00 PM ET ... ``` ### 2. Run Simulation ($1.00 USDC) Execute 10,000 Monte Carlo simulations with full analysis. **Trigger phrases:** - "Simulate the Lakers game" - "Run analysis on game 1" - "What are the odds for Warriors vs Suns?" - "Analyze the Chiefs game" **Response format:** ``` Simulation Results: Lakers vs Celtics Win Probabilities: - Lakers: 45.2% - Celtics: 54.8% Projected Score: Lakers 108 - Celtics 112 Projected Total: 220 points Predicted Spread: Celtics -4 Edge Analysis: - Value detected on Lakers ML (+3.2% edge) - Kelly recommends 2.1% bankroll ``` ### 3. Get Pick of the Day (FREE) Get the daily expert pick with analysis. No payment required. **Trigger phrases:** - "What's the pick of the day?" - "Give me today's pick" - "What should I bet on today?" - "Show me the daily pick" **Response format:** ``` Pick of the Day: Lakers ML Game: Celtics @ Lakers - 7:30 PM ET Pick: Lakers Moneyline (-110) Confidence: HIGH Win Probability: 58.2% Edge vs Market: +4.1% Analysis: Lakers are 8-2 at home in their last 10... ``` **If game already played:** ``` Today's pick (Lakers ML) has been graded: WIN New pick available at 2 AM Central. ``` ### 4. Get Track Record (FREE) View the historical performance of daily picks. **Trigger phrases:** - "What's your track record?" - "How are the picks doing?" - "Show me past picks" **Response format:** ``` Track Record: 45-32-3 (58.4%) Current Streak: 4W Recent: W W W W L W L W ``` ### 5. Check Balance Verify USDC balance before running simulations. **Trigger phrases:** - "Check my balance" - "Do I have enough for a simulation?" ## Payment Information - **Cost:** $1.00 USDC per simulation - **Network:** Solana mainnet - **Protocol:** x402 (automatic with SDK) ## Environment Setup Set your Solana wallet private key: ```bash export SOLANA_PRIVATE_KEY='[your_private_key_array]' ``` The wallet needs: - At least $1.00 USDC for each simulation - Small amount of SOL for transaction fees (~0.001 SOL) ## API Reference ### Get Games ```javascript // Today's games const games = await client.getGames('nba'); // Tomorrow's games const tomorrow = await client.getTomorrowGames('nfl'); // Specific game const game = await client.getGameDetails('mlb', 'mlb-2026-03-28-nyy-bos'); ``` ### Run Simulation ```javascript const result = await client.simulate('nba', gameId, { onStatus: (status) => console.log(status), // 'paying', 'processing', 'complete' }); // Result includes: // - homeWinProbability, awayWinProbability // - averageHomeScore, averageAwayScore // - predictedSpread, averageTotalPoints // - edgeAnalysis (value detection) // - bettingInsights (fair odds) // - factorBreakdown (what's driving the prediction) ``` ### Check Balance ```javascript const balance = await client.checkBalance(); // { usdc: 5.25, sol: 0.05, sufficient: true } ``` ### Get Pick of the Day ```javascript const pick = await client.getTodaysPick(); // { // hasPick: true, // isTodaysPick: true, // pick: { // sport: 'nba', // pick: 'Lakers', // pickType: 'moneyline', // winProbability: 0.582, // confidence: 'high', // result: 'pending' // or 'win', 'loss', 'push' // }, // message: null, // nextPickTime: null // } // If game already played: // { // hasPick: true, // pick: { ... result: 'win' ... }, // message: "Today's pick has been graded: WIN. New pick at 2 AM Central.", // nextPickTime: "2:00 AM Central" // } ``` ### Get Track Record ```javascript const record = await client.getTrackRecord(); // { // wins: 45, // losses: 32, // pushes: 3, // winRate: 58.4, // streak: 4, // streakType: 'W', // recentPicks: [...] // } ``` ## Supported Sports | Sport | Code | Endpoint | |-------|------|----------| | NBA | `nba` | Basketball | | NFL | `nfl` | Football | | MLB | `mlb` | Baseball | | MLS | `mls` | Soccer | ## Links - Website: https://edgebets.fun - API Docs: https://api.edgebets.fun/api/v1/x402 - OpenAPI Spec: https://api.edgebets.fun/api/v1/x402/openapi.json - npm Package: https://www.npmjs.com/package/edgebets-sdk

path: README.md
content: # edgebets-sdk

TypeScript SDK for the EdgeBets sports simulation API. Run professional-grade Monte Carlo simulations for NBA, NFL, MLB, and MLS with x402 USDC payments on Solana.

## Features

- **10,000 Monte Carlo simulations** per request
- **Full TypeScript support** with comprehensive types
- **Automatic payment handling** via x402 protocol
- **Auto-polling** for simulation results
- **4 major sports leagues** (NBA, NFL, MLB, MLS)
- **Edge detection** vs market odds
- **OpenClaw compatible** for AI agent integration

## Installation

```bash
npm install edgebets-sdk
```

## Quick Start

```typescript
import { EdgeBetsClient } from 'edgebets-sdk';
import { Keypair } from '@solana/web3.js';
import fs from 'fs';

// Load your Solana wallet
const secretKey = JSON.parse(fs.readFileSync('~/.config/solana/id.json', 'utf-8'));
const keypair = Keypair.fromSecretKey(Uint8Array.from(secretKey));

// Create client
const client = new EdgeBetsClient({
  wallet: keypair,
  debug: true,
});

// Get today's NBA games (FREE)
const games = await client.getGames('nba');
console.log(`Found ${games.length} NBA games today`);

// Run simulation on first game ($1.00 USDC)
const result = await client.simulate('nba', games[0].id, {
  onStatus: (status) => console.log(`Status: ${status}`),
});

// Display results
console.log(`${result.homeTeamName} vs ${result.awayTeamName}`);
console.log(`Home win: ${(result.homeWinProbability * 100).toFixed(1)}%`);
console.log(`Away win: ${(result.awayWinProbability * 100).toFixed(1)}%`);
console.log(`Projected total: ${result.averageTotalPoints.toFixed(1)}`);

if (result.edgeAnalysis?.homeIsValue) {
  console.log('VALUE: Home team has positive edge vs market!');
}
```

## API Reference

### EdgeBetsClient

#### Constructor

```typescript
const client = new EdgeBetsClient({
  wallet: keypair,              // Solana Keypair or WalletAdapter
  rpcEndpoint: '...',           // Custom RPC (default: mainnet-beta)
  apiBaseUrl: '...',            // Custom API URL
  pollingInterval: 3000,        // Poll interval in ms
  pollingTimeout: 120000,       // Max poll time in ms
  debug: false,                 // Enable debug logging
});
```

### Games (FREE)

```typescript
// Get today's games
const games = await client.getGames('nba');     // 'nba' | 'nfl' | 'mlb' | 'mls'

// Get tomorrow's games
const tomorrow = await client.getTomorrowGames('nfl');

// Get specific game
const game = await client.getGameDetails('mlb', 'mlb-2026-03-28-nyy-bos');
```

### Simulations ($1.00 USDC)

```typescript
// Full simulation with auto-polling
const result = await client.simulate('nba', gameId, {
  count: 10000,                               // Simulation count
  onStatus: (status, job) => { ... },         // Status callback
  pollingInterval: 3000,                      // Override poll interval
  pollingTimeout: 120000,                     // Override timeout
});

// Manual flow (advanced)
const job = await client.startSimulation('nba', gameId);
const status = await client.pollResult(job.jobId);
```

### Wallet & Balance

```typescript
// Check balance
const balance = await client.checkBalance();
// { usdc: 5.25, sol: 0.05, sufficient: true }

// Get price quote
const quote = await client.getQuote();
// { price: 0.5, currency: 'USDC', network: 'solana-mainnet', recipient: '...' }

// Check if wallet configured
client.hasWallet();  // boolean

// Get treasury address
client.getTreasuryWallet();  // 'DuDL...'

// Get simulation price
client.getPrice();  // 0.5
```

## Types

### SimulationResult

```typescript
interface SimulationResult {
  gameId: string;
  simulationCount: number;

  // Teams
  homeTeamName: string;
  awayTeamName: string;
  homeTeamAbbr: string;
  awayTeamAbbr: string;

  // Win Probabilities (0-1)
  homeWinProbability: number;
  awayWinProbability: number;

  // Score Projections
  averageHomeScore: number;
  averageAwayScore: number;
  averageTotalPoints: number;
  predictedSpread: number;

  // Advanced Analytics
  elo?: EloRatings;
  fourFactors?: FourFactors;          // NBA only
  edgeAnalysis?: EdgeAnalysis;         // Value vs market
  bettingInsights?: BettingInsights;   // Fair odds
  scoreDistribution?: ScoreDistribution;
  factorBreakdown?: FactorBreakdown[];
}
```

### EdgeAnalysis

```typescript
interface EdgeAnalysis {
  hasOdds: boolean;
  homeEdge: number;         // Positive = value
  awayEdge: number;
  homeIsValue: boolean;
  awayIsValue: boolean;
  spreadEdge: number;
  homeKelly?: number;       // Kelly bet fraction
  awayKelly?: number;
}
```

## Error Handling

```typescript
import {
  EdgeBetsError,
  PaymentRequiredError,
  InsufficientBalanceError,
  WalletNotConfiguredError,
  PollingTimeoutError,
  SimulationFailedError,
} from 'edgebets-sdk';

try {
  const result = await client.simulate('nba', gameId);
} catch (error) {
  if (error instanceof InsufficientBalanceError) {
    console.log(`Need ${error.required} USDC, have ${error.available}`);
  } else if (error instanceof PollingTimeoutError) {
    console.log('Simulation took too long, try again');
  } else if (error instanceof WalletNotConfiguredError) {
    console.log('Please configure a wallet');
  }
}
```

## Helper Function

```typescript
import { createClient } from 'edgebets-sdk';
import fs from 'fs';

// Quick setup from secret key file
const secretKey = JSON.parse(fs.readFileSync('wallet.json', 'utf-8'));
const client = createClient(secretKey, { debug: true });
```

## OpenClaw Integration

This package includes a `SKILL.md` for OpenClaw agents. Install via ClawHub:

```bash
clawhub install edgebets
```

Or give your agent this URL:
```
https://api.edgebets.fun/api/v1/x402/openapi.json
```

## Pricing

| Action | Cost |
|--------|------|
| Get games | FREE |
| Run simulation | $1.00 USDC |

Payments are processed via x402 protocol on Solana mainnet.

## Pick of the Day (FREE)

```typescript
// Get today's pick
const pick = await client.getTodaysPick();

if (pick.hasPick && pick.pick) {
  console.log(`Pick: ${pick.pick.pick} (${pick.pick.confidence})`);
  console.log(`Win probability: ${(pick.pick.winProbability * 100).toFixed(1)}%`);

  if (pick.pick.result && pick.pick.result !== 'pending') {
    console.log(`Result: ${pick.pick.result.toUpperCase()}`);
  }
}

if (pick.message) {
  console.log(pick.message);  // "New pick available at 2 AM Central"
}

// Get track record
const record = await client.getTrackRecord();
console.log(`Record: ${record.wins}-${record.losses} (${record.winRate}%)`);
console.log(`Streak: ${record.streak}${record.streakType}`);
```

## Requirements

- Node.js 18+
- Solana wallet with USDC (for paid simulations)
- Small amount of SOL for transaction fees

## Security Note

You may see npm audit warnings about `bigint-buffer` - this is a known issue in the Solana ecosystem affecting all SPL Token packages. The vulnerability requires specific malicious input that doesn't occur in normal SDK usage. See [Solana SPL Token issues](https://github.com/solana-labs/solana-program-library/issues) for updates

## Links

- [Website](https://edgebets.fun)
- [API Documentation](https://api.edgebets.fun/api/v1/x402)
- [OpenAPI Spec](https://api.edgebets.fun/api/v1/x402/openapi.json)
- [x402 Protocol](https://x402.org)

## License

MIT


path: dist/index.d.ts
content: import { PublicKey, Transaction, VersionedTransaction, Keypair } from '@solana/web3.js';

/**
 * Supported sports leagues
 */
type Sport = 'nba' | 'nfl' | 'mlb' | 'mls';
/**
 * Team information
 */
interface Team {
    name: string;
    abbreviation: string;
    logoUrl?: string;
    record?: string;
}
/**
 * Betting odds for a game
 */
interface GameOdds {
    /** Home team moneyline (American odds, e.g., -150) */
    homeMoneyline?: number;
    /** Away team moneyline (American odds, e.g., +130) */
    awayMoneyline?: number;
    /** Point spread (negative = home favored) */
    spread?: number;
    /** Home spread odds */
    homeSpreadOdds?: number;
    /** Away spread odds */
    awaySpreadOdds?: number;
    /** Over/under total points */
    total?: number;
    /** Over odds */
    overOdds?: number;
    /** Under odds */
    underOdds?: number;
}
/**
 * Game status
 */
type GameStatus = 'scheduled' | 'in_progress' | 'final' | 'postponed' | 'cancelled';
/**
 * Game information
 */
interface Game {
    /** Unique game identifier (e.g., "nba-2026-03-28-lal-bos") */
    id: string;
    /** Sport league */
    sport: Sport;
    /** Home team */
    homeTeam: Team;
    /** Away team */
    awayTeam: Team;
    /** Game start time (ISO 8601) */
    startTime: string;
    /** Current game status */
    status: GameStatus;
    /** Betting odds (if available) */
    odds?: GameOdds;
    /** Venue name */
    venue?: string;
    /** Home team score (if in_progress or final) */
    homeScore?: number;
    /** Away team score (if in_progress or final) */
    awayScore?: number;
}
/**
 * Response from getGames()
 */
interface GamesResponse {
    games: Game[];
    sport: Sport;
    date: string;
}

/**
 * Elo rating system data
 */
interface EloRatings {
    /** Home team Elo rating */
    homeElo: number;
    /** Away team Elo rating */
    awayElo: number;
    /** Win probability based on Elo */
    eloHomeWinProb: number;
    /** Predicted spread from Elo */
    eloSpread: number;
}
/**
 * Four Factors basketball analytics (NBA)
 */
interface FourFactors {
    home: {
        /** Effective field goal percentage */
        efg_pct: number;
        /** Turnover percentage */
        tov_pct: number;
        /** Offensive rebound percentage */
        oreb_pct: number;
        /** Free throw rate */
        ft_rate: number;
    };
    away: {
        efg_pct: number;
        tov_pct: number;
        oreb_pct: number;
        ft_rate: number;
    };
    /** Composite score for home team */
    homeComposite: number;
    /** Composite score for away team */
    awayComposite: number;
}
/**
 * Edge analysis vs market odds
 */
interface EdgeAnalysis {
    /** Whether market odds are available */
    hasOdds: boolean;
    /** Edge on home moneyline (positive = value) */
    homeEdge: number;
    /** Edge on away moneyline */
    awayEdge: number;
    /** Home bet is value */
    homeIsValue: boolean;
    /** Away bet is value */
    awayIsValue: boolean;
    /** Edge on spread bet */
    spreadEdge: number;
    /** Edge on total (over/under) */
    totalEdge?: number;
    /** Kelly fraction for home bet */
    homeKelly?: number;
    /** Kelly fraction for away bet */
    awayKelly?: number;
}
/**
 * Human-readable betting insights
 */
interface BettingInsights {
    /** Fair home moneyline (American odds) */
    fairHomeMoneyline: number;
    /** Fair away moneyline */
    fairAwayMoneyline: number;
    /** Fair spread */
    fairSpread: number;
    /** Fair total */
    fairTotal: number;
    /** Summary bullet points */
    summary: string[];
}
/**
 * Histogram bucket for score distribution
 */
interface HistogramBucket {
    /** Range label (e.g., "100-104") */
    label: string;
    /** Number of simulations in this bucket */
    count: number;
    /** Percentage of total */
    pct: number;
}
/**
 * Distribution statistics
 */
interface DistributionStats {
    mean: number;
    std: number;
    min: number;
    max: number;
    median: number;
    histogram: HistogramBucket[];
}
/**
 * Score distribution from Monte Carlo simulations
 */
interface ScoreDistribution {
    homeScores: DistributionStats;
    awayScores: DistributionStats;
    totals: DistributionStats;
    spreads: DistributionStats;
}
/**
 * Factor impact analysis
 */
interface FactorBreakdown {
    /** Factor name */
    name: string;
    /** Direction of impact: home, away, or neutral */
    direction: 'home' | 'away' | 'neutral' | 'total';
    /** Point impact */
    impact: number;
    /** Category: critical, high, medium, contextual */
    category: 'critical' | 'high' | 'medium' | 'contextual';
    /** Human-readable explanation */
    explanation: string;
}
/**
 * Full simulation result
 */
interface SimulationResult {
    /** Game identifier */
    gameId: string;
    /** Number of Monte Carlo iterations */
    simulationCount: number;
    homeTeamName: string;
    awayTeamName: string;
    homeTeamAbbr: string;
    awayTeamAbbr: string;
    /** Home win probability (0-1) */
    homeWinProbability: number;
    /** Away win probability (0-1) */
    awayWinProbability: number;
    /** Average projected home score */
    averageHomeScore: number;
    /** Average projected away score */
    averageAwayScore: number;
    /** Average projected total points */
    averageTotalPoints: number;
    /** Predicted spread (positive = away favored) */
    predictedSpread: number;
    /** Standard deviation of spread */
    spreadStdDev?: number;
    /** Standard deviation of total */
    totalStdDev?: number;
    /** Probability of overtime */
    overtimeProbability?: number;
    elo?: EloRatings;
    fourFactors?: FourFactors;
    edgeAnalysis?: EdgeAnalysis;
    bettingInsights?: BettingInsights;
    scoreDistribution?: ScoreDistribution;
    factorBreakdown?: FactorBreakdown[];
}
/**
 * Simulation job status
 */
type JobStatus = 'processing' | 'complete' | 'error';
/**
 * Simulation job response (for polling)
 */
interface SimulationJob {
    /** Unique job identifier */
    jobId: string;
    /** Current status */
    status: JobStatus;
    /** URL to poll for results */
    pollUrl: string;
    /** Simulation result (when complete) */
    result?: SimulationResult;
    /** Error message (when error) */
    error?: string;
    /** Estimated completion time in seconds */
    estimatedTime?: number;
}
/**
 * Options for simulate() method
 */
interface SimulateOptions {
    /** Number of Monte Carlo iterations (default: 10000) */
    count?: number;
    /** Auto-poll until complete (default: true) */
    autoPoll?: boolean;
    /** Callback for status updates during polling */
    onStatus?: (status: string, job?: SimulationJob) => void;
    /** Polling interval in ms (default: 3000) */
    pollingInterval?: number;
    /** Polling timeout in ms (default: 120000) */
    pollingTimeout?: number;
}

/**
 * Wallet adapter interface for signing transactions
 * Compatible with @solana/wallet-adapter-base
 */
interface WalletAdapter {
    /** Wallet public key */
    publicKey: PublicKey;
    /** Sign a single transaction */
    signTransaction<T extends Transaction | VersionedTransaction>(transaction: T): Promise<T>;
    /** Sign multiple transactions (optional) */
    signAllTransactions?<T extends Transaction | VersionedTransaction>(transactions: T[]): Promise<T[]>;
}
/**
 * SDK configuration options
 */
interface EdgeBetsConfig {
    /**
     * Solana wallet for signing payments
     * Can be a Keypair or a wallet adapter
     */
    wallet?: WalletAdapter | Keypair;
    /**
     * Solana RPC endpoint
     * @default "https://api.mainnet-beta.solana.com"
     */
    rpcEndpoint?: string;
    /**
     * EdgeBets API base URL
     * @default "https://api.edgebets.fun/api/v1"
     */
    apiBaseUrl?: string;
    /**
     * Polling interval for simulation results (ms)
     * @default 3000
     */
    pollingInterval?: number;
    /**
     * Polling timeout (ms)
     * @default 120000
     */
    pollingTimeout?: number;
    /**
     * Enable debug logging
     * @default false
     */
    debug?: boolean;
    /**
     * Maximum concurrent simulations
     * @default 1
     */
    maxConcurrent?: number;
    /**
     * Minimum delay between requests in ms
     * @default 2000
     */
    delayBetween?: number;
}
/**
 * Balance check result
 */
interface BalanceResult {
    /** USDC balance in human-readable units */
    usdc: number;
    /** SOL balance for transaction fees */
    sol: number;
    /** Whether balance is sufficient for a simulation ($0.50) */
    sufficient: boolean;
}

/**
 * Pick of the day data
 */
interface DailyPick {
    /** Pick date (YYYY-MM-DD) */
    date: string;
    /** Sport (nba, nfl, mlb, mls) */
    sport: string;
    /** Game ID */
    gameId: string;
    /** Home team name */
    homeTeam: string;
    /** Away team name */
    awayTeam: string;
    /** Pick type: moneyline, spread, or total */
    pickType: 'moneyline' | 'spread' | 'total';
    /** The actual pick (team name for ML/spread, "over"/"under" for total) */
    pick: string;
    /** Pick value (spread points or total line) */
    pickValue?: number;
    /** Odds for the pick (American format) */
    odds?: number;
    /** Win probability from simulation */
    winProbability: number;
    /** Edge vs market */
    edge?: number;
    /** Confidence level */
    confidence: 'high' | 'medium' | 'low';
    /** Brief analysis */
    analysis?: string;
    /** Game start time */
    gameTime?: string;
    /** Result after game: win, loss, push, or pending */
    result?: 'win' | 'loss' | 'push' | 'pending';
    /** Actual final score */
    finalScore?: string;
}
/**
 * Response from getTodaysPick()
 */
interface TodaysPickResponse {
    /** Whether a pick is available */
    hasPick: boolean;
    /** Whether this is today's pick (vs yesterday's) */
    isTodaysPick?: boolean;
    /** The pick data */
    pick?: DailyPick;
    /** Status message */
    message?: string;
    /** When the next pick will be available */
    nextPickTime?: string;
}
/**
 * Track record statistics
 */
interface TrackRecord {
    /** Total wins */
    wins: number;
    /** Total losses */
    losses: number;
    /** Total pushes */
    pushes: number;
    /** Total picks made */
    totalPicks: number;
    /** Win rate percentage */
    winRate: number;
    /** Current streak (positive = wins, negative = losses) */
    streak: number;
    /** Streak type: "W" or "L" */
    streakType: 'W' | 'L';
    /** Recent picks */
    recentPicks: DailyPick[];
}

/**
 * EdgeBets SDK Client
 *
 * Main entry point for interacting with the EdgeBets API.
 * Handles games fetching, payments, and simulations.
 *
 * @example
 * ```typescript
 * import { EdgeBetsClient } from '@edgebets/sdk';
 * import { Keypair } from '@solana/web3.js';
 *
 * const client = new EdgeBetsClient({
 *   wallet: Keypair.fromSecretKey(...),
 *   debug: true,
 * });
 *
 * // Get today's NBA games (FREE)
 * const games = await client.getGames('nba');
 *
 * // Run simulation ($0.50 USDC)
 * const result = await client.simulate('nba', games[0].id);
 * ```
 */
declare class EdgeBetsClient {
    private config;
    private gamesService;
    private paymentService;
    private simulationService;
    private picksService;
    private simulationQueue;
    constructor(config?: EdgeBetsConfig);
    /**
     * Resolve configuration with defaults
     */
    private resolveConfig;
    /**
     * Get today's games for a sport
     *
     * @param sport - The sport to get games for ('nba', 'nfl', 'mlb', 'mls')
     * @returns Array of games
     *
     * @example
     * ```typescript
     * const games = await client.getGames('nba');
     * console.log(`Found ${games.length} NBA games today`);
     * ```
     */
    getGames(sport: Sport): Promise<Game[]>;
    /**
     * Get tomorrow's games for a sport
     *
     * @param sport - The sport to get games for
     * @returns Array of games
     */
    getTomorrowGames(sport: Sport): Promise<Game[]>;
    /**
     * Get details for a specific game
     *
     * @param sport - The sport
     * @param gameId - Game identifier
     * @returns Game details
     */
    getGameDetails(sport: Sport, gameId: string): Promise<Game>;
    /**
     * Run a Monte Carlo simulation for a game
     *
     * This method handles the full x402 payment flow:
     * 1. Sends USDC payment to treasury
     * 2. Starts simulation with payment proof
     * 3. Polls until complete
     * 4. Returns result
     *
     * Rate limited to prevent overwhelming the API.
     * Default: 1 concurrent request, 2s delay between requests.
     *
     * @param sport - The sport ('nba', 'nfl', 'mlb', 'mls')
     * @param gameId - Game identifier
     * @param options - Simulation options
     * @returns Simulation result
     *
     * @example
     * ```typescript
     * const result = await client.simulate('nba', 'nba-2026-03-28-lal-bos', {
     *   onStatus: (status) => console.log(`Status: ${status}`),
     * });
     *
     * console.log(`Home win: ${(result.homeWinProbability * 100).toFixed(1)}%`);
     * console.log(`Total: ${result.averageTotalPoints.toFixed(1)}`);
     * ```
     */
    simulate(sport: Sport, gameId: string, options?: SimulateOptions): Promise<SimulationResult>;
    /**
     * Get current queue status
     *
     * @returns Object with queued and running counts
     */
    getQueueStatus(): {
        queued: number;
        running: number;
    };
    /**
     * Start a simulation and get job for manual polling
     * (Advanced use case - prefer simulate() for most cases)
     *
     * @param sport - The sport
     * @param gameId - Game identifier
     * @returns Simulation job with polling URL
     */
    startSimulation(sport: Sport, gameId: string): Promise<SimulationJob>;
    /**
     * Poll for simulation result
     *
     * @param jobId - Job identifier from startSimulation
     * @returns Simulation job with current status
     */
    pollResult(jobId: string): Promise<SimulationJob>;
    /**
     * Get today's pick of the day (FREE)
     *
     * Returns the daily expert pick with analysis.
     * If the game has been played, indicates when the next pick will be available.
     *
     * @returns Today's pick response
     *
     * @example
     * ```typescript
     * const pick = await client.getTodaysPick();
     * if (pick.hasPick) {
     *   console.log(`Today's pick: ${pick.pick.pick} (${pick.pick.confidence})`);
     *   console.log(`Win probability: ${(pick.pick.winProbability * 100).toFixed(1)}%`);
     * } else {
     *   console.log(pick.message);  // "New pick available at 2 AM Central"
     * }
     * ```
     */
    getTodaysPick(): Promise<TodaysPickResponse>;
    /**
     * Get track record and recent picks (FREE)
     *
     * @param limit - Number of recent picks to include (default 30)
     * @returns Track record statistics
     *
     * @example
     * ```typescript
     * const record = await client.getTrackRecord();
     * console.log(`Record: ${record.wins}-${record.losses}`);
     * console.log(`Win rate: ${record.winRate}%`);
     * console.log(`Current streak: ${record.streak}${record.streakType}`);
     * ```
     */
    getTrackRecord(limit?: number): Promise<TrackRecord>;
    /**
     * Check wallet balance (USDC and SOL)
     *
     * @returns Balance information
     *
     * @example
     * ```typescript
     * const balance = await client.checkBalance();
     * console.log(`USDC: ${balance.usdc}`);
     * console.log(`SOL: ${balance.sol}`);
     * console.log(`Can simulate: ${balance.sufficient}`);
     * ```
     */
    checkBalance(): Promise<BalanceResult>;
    /**
     * Get simulation price quote
     *
     * @returns Price information
     */
    getQuote(): Promise<{
        price: number;
        currency: string;
        network: string;
        recipient: string;
    }>;
    /**
     * Check if wallet is configured
     */
    hasWallet(): boolean;
    /**
     * Get treasury wallet address
     */
    getTreasuryWallet(): string;
    /**
     * Get simulation price in USDC
     */
    getPrice(): number;
}
/**
 * Create an EdgeBets client from a secret key
 *
 * @param secretKey - Solana wallet secret key (Uint8Array or number array)
 * @param config - Additional configuration
 * @returns Configured EdgeBets client
 *
 * @example
 * ```typescript
 * import { createClient } from '@edgebets/sdk';
 * import fs from 'fs';
 *
 * const secretKey = JSON.parse(fs.readFileSync('~/.config/solana/id.json', 'utf-8'));
 * const client = createClient(secretKey, { debug: true });
 * ```
 */
declare function createClient(secretKey: Uint8Array | number[], config?: Omit<EdgeBetsConfig, 'wallet'>): EdgeBetsClient;

/**
 * Base error class for EdgeBets SDK
 */
declare class EdgeBetsError extends Error {
    code: string;
    statusCode?: number | undefined;
    details?: Record<string, unknown> | undefined;
    constructor(message: string, code: string, statusCode?: number | undefined, details?: Record<string, unknown> | undefined);
}
/**
 * Payment required error (402)
 */
declare class PaymentRequiredError extends EdgeBetsError {
    paymentInfo: {
        amount: number;
        recipient: string;
        currency: string;
        network: string;
    };
    constructor(paymentInfo: {
        amount: number;
        recipient: string;
        currency: string;
        network: string;
    });
}
/**
 * Insufficient balance error
 */
declare class InsufficientBalanceError extends EdgeBetsError {
    required: number;
    available: number;
    constructor(required: number, available: number);
}
/**
 * Wallet not configured error
 */
declare class WalletNotConfiguredError extends EdgeBetsError {
    constructor();
}
/**
 * Polling timeout error
 */
declare class PollingTimeoutError extends EdgeBetsError {
    constructor(jobId: string, timeout: number);
}
/**
 * Simulation failed error
 */
declare class SimulationFailedError extends EdgeBetsError {
    constructor(jobId: string, reason?: string);
}
/**
 * API error (non-402 HTTP errors)
 */
declare class ApiError extends EdgeBetsError {
    constructor(message: string, statusCode: number, details?: Record<string, unknown>);
}
/**
 * Network/connection error
 */
declare class NetworkError extends EdgeBetsError {
    constructor(message: string, cause?: Error);
}

/**
 * EdgeBets API base URL
 */
declare const EDGEBETS_API_URL = "https://api.edgebets.fun/api/v1";
/**
 * Treasury wallet for receiving payments
 */
declare const TREASURY_WALLET = [REDACTED_SECRET];
/**
 * USDC token mint on Solana mainnet
 */
declare const USDC_MINT = [REDACTED_SECRET];
/**
 * Price per simulation in USDC (human-readable)
 */
declare const PRICE_USDC = 1;
/**
 * Price per simulation in raw USDC units (with 6 decimals)
 */
declare const PRICE_USDC_RAW = 1000000;

export { ApiError, type BalanceResult, type BettingInsights, type DailyPick, type DistributionStats, EDGEBETS_API_URL, type EdgeAnalysis, EdgeBetsClient, type EdgeBetsConfig, EdgeBetsError, type EloRatings, type FactorBreakdown, type FourFactors, type Game, type GameOdds, type GameStatus, type GamesResponse, type HistogramBucket, InsufficientBalanceError, type JobStatus, NetworkError, PRICE_USDC, PRICE_USDC_RAW, PaymentRequiredError, PollingTimeoutError, type ScoreDistribution, type SimulateOptions, SimulationFailedError, type SimulationJob, type SimulationResult, type Sport, TREASURY_WALLET, type Team, type TodaysPickResponse, type TrackRecord, USDC_MINT, type WalletAdapter, WalletNotConfiguredError, createClient };


path: package.json
content: {
  "name": "edgebets-sdk",
  "version": "1.0.4",
  "description": "TypeScript SDK for EdgeBets sports simulation API with x402 payment support",
  "main": "dist/index.js",
  "module": "dist/index.mjs",
  "types": "dist/index.d.ts",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.mjs",
      "require": "./dist/index.js"
    }
  },
  "files": [
    "dist",
    "SKILL.md",
    "README.md"
  ],
  "scripts": {
    "build": "tsup src/index.ts --format cjs,esm --dts --clean",
    "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
    "test": "vitest",
    "lint": "eslint src --ext .ts",
    "typecheck": "tsc --noEmit",
    "prepublishOnly": "npm run build"
  },
  "keywords": [
    "edgebets",
    "sports-betting",
    "monte-carlo",
    "simulation",
    "x402",
    "solana",
    "usdc",
    "nba",
    "nfl",
    "mlb",
    "mls",
    "openclaw",
    "clawhub",
    "ai-agent"
  ],
  "author": "EdgeBets",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/edgebets/sdk"
  },
  "homepage": "https://edgebets.fun",
  "bugs": {
    "url": "https://github.com/edgebets/sdk/issues"
  },
  "dependencies": {
    "@solana/spl-token": "^0.4.14",
    "@solana/web3.js": "^1.98.4"
  },
  "devDependencies": {
    "@types/node": "^20.11.0",
    "tsup": "^8.5.1",
    "typescript": "^5.3.3",
    "vitest": "^4.1.2"
  },
  "peerDependencies": {
    "@solana/web3.js": "^1.87.0"
  },
  "engines": {
    "node": ">=18.0.0"
  }
}


path: src/constants.ts
content: import type { Sport } from './types';

/**
 * EdgeBets API base URL
 */
export const EDGEBETS_API_URL = 'https://api.edgebets.fun/api/v1';

/**
 * Treasury wallet for receiving payments
 */
export const TREASURY_WALLET = [REDACTED_SECRET];

/**
 * USDC token mint on Solana mainnet
 */
export const USDC_MINT = [REDACTED_SECRET];

/**
 * USDC decimals
 */
export const USDC_DECIMALS = 6;

/**
 * Price per simulation in USDC (human-readable)
 */
export const PRICE_USDC = 1.0;

/**
 * Price per simulation in raw USDC units (with 6 decimals)
 */
export const PRICE_USDC_RAW = 1000000;

/**
 * Default Solana RPC endpoint
 */
export const DEFAULT_RPC_ENDPOINT = 'https://api.mainnet-beta.solana.com';

/**
 * Default polling interval in milliseconds
 */
export const DEFAULT_POLLING_INTERVAL = 3000;

/**
 * Default polling timeout in milliseconds
 */
export const DEFAULT_POLLING_TIMEOUT = 120000;

/**
 * Default simulation count
 */
export const DEFAULT_SIMULATION_COUNT = 10000;

/**
 * Games endpoint mapping by sport
 */
export const GAMES_ENDPOINTS: Record<Sport, string> = {
  nba: 'games/basketball',
  nfl: 'games/football',
  mlb: 'games/baseball',
  mls: 'games/soccer',
};

/**
 * Simulation endpoint mapping by sport
 */
export const SIMULATION_ENDPOINTS: Record<Sport, string> = {
  nba: 'x402/simulate/nba',
  nfl: 'x402/simulate/nfl',
  mlb: 'x402/simulate/mlb',
  mls: 'x402/simulate/mls',
};

/**
 * x402 protocol version
 */
export const X402_VERSION = 1;

/**
 * Solana network identifier
 */
export const SOLANA_NETWORK = 'solana-mainnet';


path: src/index.ts
content: /**
 * @edgebets/sdk
 *
 * TypeScript SDK for the EdgeBets sports simulation API.
 * Supports NBA, NFL, MLB, and MLS with x402 USDC payments on Solana.
 *
 * @packageDocumentation
 */

// Main client
export { EdgeBetsClient, createClient } from './client';

// Types
export type {
  // Config
  EdgeBetsConfig,
  WalletAdapter,
  BalanceResult,
  // Games
  Sport,
  Game,
  Team,
  GameOdds,
  GameStatus,
  GamesResponse,
  // Simulation
  SimulationResult,
  SimulationJob,
  SimulateOptions,
  JobStatus,
  EloRatings,
  FourFactors,
  EdgeAnalysis,
  BettingInsights,
  ScoreDistribution,
  DistributionStats,
  HistogramBucket,
  FactorBreakdown,
  // Picks
  DailyPick,
  TodaysPickResponse,
  TrackRecord,
} from './types';

// Errors
export {
  EdgeBetsError,
  PaymentRequiredError,
  InsufficientBalanceError,
  WalletNotConfiguredError,
  PollingTimeoutError,
  SimulationFailedError,
  ApiError,
  NetworkError,
} from './utils/errors';

// Constants (for advanced use cases)
export {
  EDGEBETS_API_URL,
  TREASURY_WALLET,
  USDC_MINT,
  PRICE_USDC,
  PRICE_USDC_RAW,
} from './constants';


path: src/services/games.ts
content: import type { Sport, Game, ResolvedConfig } from '../types';
import { GAMES_ENDPOINTS } from '../constants';
import { ApiError, NetworkError } from '../utils/errors';

/**
 * Games service for fetching game data
 */
export class GamesService {
  constructor(private config: ResolvedConfig) {}

  /**
   * Get today's games for a sport
   */
  async getGames(sport: Sport): Promise<Game[]> {
    const endpoint = GAMES_ENDPOINTS[sport];
    const url = `${this.config.apiBaseUrl}/${endpoint}/today`;

    try {
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
        },
      });

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}));
        throw new ApiError(
          errorData.message || `Failed to fetch games: ${response.status}`,
          response.status,
          errorData
        );
      }

      const data = await response.json();

      // Normalize response - API may return games array directly or nested
      const games = Array.isArray(data) ? data : (data.games || []);

      return this.normalizeGames(games, sport);
    } catch (error) {
      if (error instanceof ApiError) {
        throw error;
      }
      throw new NetworkError(
        `Failed to fetch ${sport.toUpperCase()} games`,
        error instanceof Error ? error : undefined
      );
    }
  }

  /**
   * Get tomorrow's games for a sport
   */
  async getTomorrowGames(sport: Sport): Promise<Game[]> {
    const endpoint = GAMES_ENDPOINTS[sport];
    const url = `${this.config.apiBaseUrl}/${endpoint}/tomorrow`;

    try {
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
        },
      });

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}));
        throw new ApiError(
          errorData.message || `Failed to fetch games: ${response.status}`,
          response.status,
          errorData
        );
      }

      const data = await response.json();
      const games = Array.isArray(data) ? data : (data.games || []);

      return this.normalizeGames(games, sport);
    } catch (error) {
      if (error instanceof ApiError) {
        throw error;
      }
      throw new NetworkError(
        `Failed to fetch ${sport.toUpperCase()} games`,
        error instanceof Error ? error : undefined
      );
    }
  }

  /**
   * Get details for a specific game
   */
  async getGameDetails(sport: Sport, gameId: string): Promise<Game> {
    const endpoint = GAMES_ENDPOINTS[sport];
    const url = `${this.config.apiBaseUrl}/${endpoint}/${gameId}`;

    try {
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
        },
      });

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}));
        throw new ApiError(
          errorData.message || `Failed to fetch game: ${response.status}`,
          response.status,
          errorData
        );
      }

      const data = await response.json();
      return this.normalizeGame(data, sport);
    } catch (error) {
      if (error instanceof ApiError) {
        throw error;
      }
      throw new NetworkError(
        `Failed to fetch game ${gameId}`,
        error instanceof Error ? error : undefined
      );
    }
  }

  /**
   * Normalize games array from API response
   */
  private normalizeGames(games: unknown[], sport: Sport): Game[] {
    return games.map((game) => this.normalizeGame(game, sport));
  }

  /**
   * Normalize a single game from API response
   */
  private normalizeGame(game: unknown, sport: Sport): Game {
    const g = game as Record<string, unknown>;

    return {
      id: String(g.id || g.gameId || g.game_id || ''),
      sport,
      homeTeam: {
        name: String(g.homeTeam || g.home_team || (g.home as Record<string, unknown>)?.name || ''),
        abbreviation: String(g.homeTeamAbbr || g.home_abbr || (g.home as Record<string, unknown>)?.abbreviation || ''),
        logoUrl: g.homeTeamLogo as string | undefined,
      },
      awayTeam: {
        name: String(g.awayTeam || g.away_team || (g.away as Record<string, unknown>)?.name || ''),
        abbreviation: String(g.awayTeamAbbr || g.away_abbr || (g.away as Record<string, unknown>)?.abbreviation || ''),
        logoUrl: g.awayTeamLogo as string | undefined,
      },
      startTime: String(g.startTime || g.start_time || g.gameTime || ''),
      status: this.normalizeStatus(g.status),
      venue: g.venue as string | undefined,
      homeScore: typeof g.homeScore === 'number' ? g.homeScore : undefined,
      awayScore: typeof g.awayScore === 'number' ? g.awayScore : undefined,
      odds: g.odds ? this.normalizeOdds(g.odds as Record<string, unknown>) : undefined,
    };
  }

  /**
   * Normalize game status
   */
  private normalizeStatus(status: unknown): Game['status'] {
    const s = String(status).toLowerCase();
    if (s.includes('progress') || s.includes('live')) return 'in_progress';
    if (s.includes('final') || s.includes('completed')) return 'final';
    if (s.includes('postponed')) return 'postponed';
    if (s.includes('cancelled') || s.includes('canceled')) return 'cancelled';
    return 'scheduled';
  }

  /**
   * Normalize odds object
   */
  private normalizeOdds(odds: Record<string, unknown>): Game['odds'] {
    return {
      homeMoneyline: typeof odds.homeMoneyline === 'number' ? odds.homeMoneyline : undefined,
      awayMoneyline: typeof odds.awayMoneyline === 'number' ? odds.awayMoneyline : undefined,
      spread: typeof odds.spread === 'number' ? odds.spread : undefined,
      total: typeof odds.total === 'number' ? odds.total : undefined,
      overOdds: typeof odds.overOdds === 'number' ? odds.overOdds : undefined,
      underOdds: typeof odds.underOdds === 'number' ? odds.underOdds : undefined,
    };
  }
}


path: src/services/index.ts
content: export { GamesService } from './games';
export { PaymentService } from './payment';
export { SimulationService } from './simulation';
export { PicksService } from './picks';


path: src/utils/index.ts
content: export * from './errors';
export * from './polling';
export * from './queue';


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)