Agent skill

PNP Prediction Markets on Solana

by internet-court in internet-court/internet-court-skill

Creates, trades and settles permissionless prediction markets on Solana with any SPL token as collateral, including social-media and custom-oracle markets.

MITAuto-check: notesBusiness, Finance & HR

Install PNP Prediction Markets on Solana

skills CLI
$ npx skills add internet-court/internet-court-skill --skill pnp-markets-solana -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install internet-court/internet-court-skill pnp-markets-solana --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/internet-court/internet-court-skill.git skills-src && mkdir -p .claude/skills && cp -r skills-src/vendored/pnp/pnp-solana .claude/skills/pnp-markets-solana && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
pnp-markets-solana
GitHub stars
6.6k
Token cost
~7.5k tokens
SKILL.md length
1,445 words
Files
22 (incl. scripts, references)
Skills in repo
80
Repo updated
First seen
Licence
MIT

At a glance

Creates, trades and settles permissionless prediction markets on Solana with any SPL token as collateral, including social-media and custom-oracle markets.

  • Works in 5 steps: Compute Unit Budgets → Priority Fees → Timeout & Retry Pattern → …
  • Creating a prediction market on Solana with a chosen collateral token
  • SKILL.md covers When to Use This Skill, Program IDs & Core Constants, Prerequisites and Quick Start, plus 6 more sections
  • Runs TypeScript scripts from its folder; calls tsx and npm; reaches api.mainnet-beta.solana.com and x.com; needs PRIVATE_KEY

What it does

The agent can create prediction markets in three styles: V2 AMM markets, P2P direct bets, and custom-oracle markets that an AI agent can resolve. It can also build social-media markets on Twitter engagement, YouTube views or DeFiLlama metrics. Trading means buying and selling YES and NO outcome tokens, an oracle settles the market after trading ends, and winners redeem their positions. Any SPL token works as collateral, Token-2022 included.

TypeScript scripts handle the main tasks: creating markets (create-market.ts plus variants for X, YouTube, P2P and custom oracles), reading market data and redeeming. References cover the API, program addresses, types and precision, examples and use cases. The skill lists the mainnet and devnet program IDs and common token mints, and a precision table: USDC and USDT use 6 decimals, wrapped SOL uses 9, and decision tokens use 6, with BigInt conversion helpers.

It is not meant for generic Solana wallet work, token swaps without prediction markets, NFTs or other prediction market protocols, which have their own skills. Running it takes Node.js 18 or newer, a Solana RPC endpoint, a funded wallet for transaction fees and a supported token for collateral. The excerpt is cut off in the precision helpers.

When your agent uses it

  • Creating a prediction market on Solana with a chosen collateral token
  • Settling a custom-oracle market after trading has ended
  • Redeeming winning positions after a market settles
  • Building a market on Twitter engagement or YouTube views
  • Building an autonomous agent that creates, trades and resolves markets

Example prompts

  • “Create a P2P bet on Solana devnet between two wallets about next week's token price.”
  • “Create a YouTube views market for this video that settles at the end of the month.”
  • “Redeem my winning positions from the settled markets.”
  • “Settle the custom oracle market now that trading has ended.”

Requirements

  • Node.js 18 or newer
  • A Solana RPC endpoint (mainnet or devnet)
  • A funded wallet with SOL for transaction fees
  • An SPL token, including Token-2022, as collateral
  • Compatibility (from SKILL.md): Requires Node.js 18+, Solana RPC endpoint (mainnet or devnet), funded wallet with SOL for transaction fees, and any SPL token (including Token-2022) as collateral

Workflow steps

5 steps, taken from the step headings in SKILL.md.

  1. Compute Unit Budgets
  2. Priority Fees
  3. Timeout & Retry Pattern
  4. Input Validation
  5. RPC Failover

What it can do on your machine

Read from SKILL.md and the folder at commit fa89195. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships 8 files in scripts/ (TypeScript, from the files we listed), which the agent can run.

    Shell commands in SKILL.md call:

    • tsx
    • npm

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • api.mainnet-beta.solana.com
    • x.com
    • youtu.be
    • youtube.com
    • twitter.com
    • mainnet.helius-rpc.com
    • solana-mainnet.g.alchemy.com

    Also links to:

    • npmjs.com
    • docs.pnp.exchange
    • solscan.io

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • PRIVATE_KEY

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

  • Compatibility

    Requires Node.js 18+, Solana RPC endpoint (mainnet or devnet), funded wallet with SOL for transaction fees, and any SPL token (including Token-2022) as collateral

    From compatibility in the SKILL.md frontmatter.

Context cost

PNP Prediction Markets on Solana loads about 7.5k tokens when it runs, and up to ~18k if it reads all its reference files. Until then it costs about 99 tokens; SKILL.md has 1,445 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~99
When it runs · the whole SKILL.md, loaded when a task matches
~7.5k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~18k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: notes

The automated check noted patterns worth knowing about, such as sudo or a known installer.

  • NoteMentions a .env fileSKILL.md:733
    ripts/` and use `dotenv/config` to load `.env`.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.

SKILL.md

The full file from internet-court/internet-court-skill at commit fa89195, republished under its MIT licence (© internet-court). 1,445 words, ~7,461 tokens.

Download SKILL.mdSave it as .claude/skills/pnp-markets-solana/SKILL.md (or your agent's skills folder). This skill also uses 21 other files; get the full folder from GitHub.
name
pnp-markets-solana
description
Create, trade, and settle permissionless prediction markets on Solana. Use when building prediction market infrastructure, creating social media markets (Twitter/YouTube/DeFiLlama), setting up custom oracle resolution, P2P betting, or autonomous agent-driven forecasting. Supports V2 AMM, P2P (V3), and custom oracle markets with any SPL token collateral (including Token-2022).
compatibility
Requires Node.js 18+, Solana RPC endpoint (mainnet or devnet), funded wallet with SOL for transaction fees, and any SPL token (including Token-2022) as collateral
license
MIT
metadata.author
pnp-protocol
metadata.version
2.0.0
tags
solana, prediction-markets, oracle, betting, forecast, market-making, autonomous-agents, p2p-markets, social-media, defi, info-finance

PNP Markets (Solana)

Create and manage prediction markets on Solana with any SPL token collateral. Supports V2 AMM markets, P2P direct bets, custom oracle resolution for AI agents, and social media markets (Twitter, YouTube, DeFiLlama).

When to Use This Skill

Use when the user wants to:

  • Create prediction markets on Solana (V2 AMM, P2P, or custom oracle)
  • Trade on markets (buy/sell YES/NO outcome tokens)
  • Settle markets as an oracle after the trading period ends
  • Redeem winning positions after settlement
  • Create social media markets (Twitter engagement, YouTube views, DeFiLlama metrics)
  • Use custom tokens as prediction market collateral (any SPL token including Token-2022)
  • Build autonomous AI agents that create, trade, and resolve markets
  • Build info finance infrastructure using market prices as probability signals

Triggers: prediction market, betting, oracle, settlement, forecast, YES/NO, outcome token, market resolution, P2P bet, custom oracle, social media market, autonomous market, info finance, market creation, prediction, wager, binary outcome

Do not use when:

  • The task is generic Solana wallet operations (use solana-dev-skill instead)
  • The task is token swaps/DEX trading without prediction markets (use jupiter-skill)
  • The task is NFT-related (use metaplex-foundation/skill)
  • The task is about other prediction market protocols (use their specific skill)

Program IDs & Core Constants

ItemAddressNotes
PNP Program (Mainnet)8PyE2dizL52ga7ytqLtqRyjwWp4yXEx8M5Z4BAHgHuTbMain prediction market program
PNP Program (Devnet)pnpkv2qnh4bfpGvTugGDSEhvZC7DP4pVxTuDykV3BGzDevnet testing program
USDC MintEPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1vCommon collateral (6 decimals)
USDT MintEs9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYBAlternative stable (6 decimals)
WSOL MintSo11111111111111111111111111111111111111112Wrapped SOL (9 decimals)
Precision Reference
Token TypeDecimalsExample
USDC / USDT61 USDC = 1_000_000n
SOL (wrapped)91 SOL = 1_000_000_000n
Decision tokens (YES/NO)6Minted per-market by the program
typescript
// Conversion helpers
const usdcToRaw = (amount: number) => BigInt(Math.floor(amount * 1_000_000));
const daysFromNow = (days: number) => BigInt(Math.floor(Date.now() / 1000) + days * 86400);

// Example
const liquidity = usdcToRaw(100);  // 100 USDC -> 100_000_000n
const endTime = daysFromNow(7);    // 7 days from now -> Unix timestamp as bigint

[!IMPORTANT] Collateral can be any SPL token or Token-2022 token. Pass the token's mint address as baseMint or collateralTokenMint. Make sure to use the correct decimals for the chosen token (e.g., USDC/USDT = 6, SOL = 9). Common mints are listed in the table above for reference.


Prerequisites

  1. Solana Wallet: Base58-encoded private key with SOL for fees (~0.05 SOL minimum)
  2. Collateral Tokens: Any SPL token (including Token-2022) for market liquidity — USDC, USDT, SOL, or any custom token
  3. RPC Endpoint: Mainnet RPC URL (public or dedicated like Helius/QuickNode)
bash
# Install dependencies
cd scripts && npm install

# Set environment variables
export PRIVATE_KEY=<base58_private_key>
export RPC_URL=https://api.mainnet-beta.solana.com  # or dedicated RPC

Quick Start

typescript
import { PNPClient } from 'pnp-sdk';
import { PublicKey } from '@solana/web3.js';

const client = new PNPClient(
  process.env.RPC_URL || 'https://api.mainnet-beta.solana.com',
  process.env.PRIVATE_KEY!  // Base58 string or Uint8Array
);

// Collateral can be any SPL token (including Token-2022) — use the mint address of your chosen token
const USDC = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v');

// Create a prediction market
const result = await client.market.createMarket({
  question: 'Will Bitcoin reach $100K by end of 2025?',
  initialLiquidity: 1_000_000n,  // 1 USDC (6 decimals) — adjust decimals for your collateral token
  endTime: BigInt(Math.floor(Date.now() / 1000) + 30 * 24 * 60 * 60),
  baseMint: USDC,  // Any SPL or Token-2022 mint
});

console.log('Market created:', result.market.toBase58());
// Returns: { signature: string, market: PublicKey }

[!TIP] Use PNPClient.parseSecretKey(process.env.PRIVATE_KEY) to handle both Base58 strings and JSON array formats automatically.


Market Lifecycle & State Machine

Markets follow a strict state progression:

V2 AMM Market (Standard)
CREATED ──────► ACTIVE ──────► ENDED ──────► RESOLVED ──────► CLAIMED
   │               │              │               │               │
   │          Trading live    No new trades   Oracle declares  Winners redeem
   │          Users buy/sell  allowed         YES/NO winner    collateral
   │          YES/NO tokens
   │
   └── initialLiquidity locked, PNP global oracle resolves
Custom Oracle Market (Agent-Controlled)
CREATED ──► [15-MIN BUFFER] ──► ACTIVE ──► ENDED ──► RESOLVED ──► CLAIMED
   │               │                │          │           │           │
   │    setMarketResolvable(true)  Trade     Wait for   settleMarket() redeem
   │    MUST call within 15 min!   live      endTime    (oracle only)
   │
   └── Market starts frozen. If not activated within 15 minutes,
       it is PERMANENTLY FROZEN and cannot be recovered.
State Transition Rules
FromToMethodCondition
CREATEDACTIVEsetMarketResolvable(market, true)Custom oracle only; must be within 15 min of creation
ACTIVEENDED(automatic)Unix timestamp reaches endTime
ENDEDRESOLVEDsettleMarket({market, yesWinner})Oracle-only; can only be called after endTime
RESOLVEDCLAIMEDredeemPosition(market)Any winner; available forever after resolution

Core Operations: Read-Only (No Wallet Required)

These operations fetch data without executing transactions. Initialize with just an RPC URL:

typescript
const readOnlyClient = new PNPClient('https://api.mainnet-beta.solana.com');
fetchMarketAddresses() — Discover V2 Markets
typescript
const addresses: string[] = await client.fetchMarketAddresses();
console.log(`Found ${addresses.length} V2 AMM markets`);
// Returns: string[] of market public key base58 addresses
fetchMarket(pubkey) — Get On-Chain Market Data
typescript
const { account } = await client.fetchMarket(new PublicKey('HxnpHygK1v7TqodWqAv6RvcEiK9zxAgw5jPZ6rskgj2E'));

// MarketType fields:
// account.question: string
// account.creator: PubkeyLike
// account.resolvable: boolean
// account.resolved: boolean
// account.end_time: U64Like (Unix timestamp)
// account.winning_token_id: 'yes' | 'no' | 'none' | null
// account.yes_token_mint: PubkeyLike
// account.no_token_mint: PubkeyLike
// account.collateral_token: PubkeyLike
// account.market_reserves: U64Like
// account.initial_liquidity: U64Like
getMarketPriceV2(market) — Get Current Prices & Multipliers
typescript
const priceData = await client.getMarketPriceV2(marketAddress);

console.log({
  yesPrice: priceData.yesPrice,           // 0-1 range (e.g., 0.65 = 65%)
  noPrice: priceData.noPrice,             // 0-1 range (e.g., 0.35 = 35%)
  yesMultiplier: priceData.yesMultiplier, // Payout ratio if YES wins (e.g., 1.54x)
  noMultiplier: priceData.noMultiplier,   // Payout ratio if NO wins (e.g., 2.85x)
  marketReserves: priceData.marketReserves, // Total collateral locked (UI units)
  yesTokenSupply: priceData.yesTokenSupply, // YES tokens minted (UI units)
  noTokenSupply: priceData.noTokenSupply,   // NO tokens minted (UI units)
});

// AMM Price Formulas:
// yesPrice = (marketReserves * yesTokenSupply) / (yesTokenSupply^2 + noTokenSupply^2)
// noPrice  = (marketReserves * noTokenSupply) / (yesTokenSupply^2 + noTokenSupply^2)
// yesMultiplier = 1 + (noTokenSupply / yesTokenSupply)^2
// noMultiplier  = 1 + (yesTokenSupply / noTokenSupply)^2
fetchSettlementCriteria(market) — Get AI Resolution Info
typescript
const criteria = await client.fetchSettlementCriteria(marketAddress);
// Returns: { category, reasoning, resolvable, resolution_sources, settlement_criteria }
fetchSettlementData(market) — Get Settlement Decision
typescript
const data = await client.fetchSettlementData(marketAddress);
// Returns: { answer: 'YES'|'NO', reasoning: string }
trading.getMarketInfo(pubkey) — Extended Market Info
typescript
const info = await client.trading.getMarketInfo(new PublicKey(marketAddress));
// Returns: { address, question, id, creator, initialLiquidity, marketReserves,
//            endTime, resolvable, resolved, winningTokenId,
//            yesTokenMint, noTokenMint, collateralToken,
//            yesTokenSupplyMinted, noTokenSupplyMinted }

Core Operations: Market Creation (Wallet Required)

Standard V2 AMM Market — market.createMarket(params)

Creates a V2 AMM market using PNP's global oracle for resolution.

typescript
const result = await client.market.createMarket({
  question: 'Will SOL hit $250 by end of March?',
  initialLiquidity: 10_000_000n,  // 10 USDC (6 decimals)
  endTime: BigInt(Math.floor(Date.now() / 1000) + 7 * 86400),  // 7 days
  baseMint: new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'),
});

console.log('Market:', result.market.toBase58());
// Returns: { signature: string, market: PublicKey }
ParameterTypeRequiredDescription
questionstringYesThe prediction question
initialLiquiditybigintYesInitial liquidity in raw units (decimals depend on collateral token)
endTimebigintYesUnix timestamp when trading ends
baseMintPublicKeyNoCollateral token mint — any SPL or Token-2022 token
Custom Oracle Market — createMarketWithCustomOracle(params)

When to use: When your AI agent needs full control over market resolution. Your agent's wallet becomes the oracle.

typescript
const result = await client.createMarketWithCustomOracle({
  question: 'Will BTC hit $150K by Dec 2026?',
  initialLiquidity: 10_000_000n,  // 10 USDC (6 decimals)
  endTime: BigInt(Math.floor(Date.now() / 1000) + 30 * 86400),
  collateralMint: new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'),
  settlerAddress: AGENT_WALLET_PUBKEY,  // Your agent's wallet is the oracle
  yesOddsBps: 5000,  // Optional: 50/50 odds (range: 100-9900)
});

// Returns: { market: PublicKey, signature: string }
ParameterTypeRequiredDescription
questionstringYesThe prediction question
initialLiquiditybigintYesInitial liquidity in raw units
endTimebigintYesUnix timestamp when trading ends
collateralMintPublicKeyYesCollateral token mint
settlerAddressPublicKeyYesOracle wallet that will settle the market
yesOddsBpsnumberNoInitial YES odds in basis points (100-9900, default 5000)

[!WARNING] After creation, you must call setMarketResolvable(market, true) within 15 minutes or the market is permanently frozen.

V2 Market with Custom Odds — createMarketV2WithCustomOdds(params)
typescript
const result = await client.createMarketV2WithCustomOdds({
  question: 'Will Ethereum flip Bitcoin by 2026?',
  initialLiquidity: 50_000_000n,  // 50 USDC
  endTime: daysFromNow(90),
  collateralTokenMint: USDC,
  yesOddsBps: 2000,  // 20% YES / 80% NO
  oracle: CUSTOM_ORACLE_PUBKEY,  // Optional: custom oracle
});
// Returns: { signature: string, market: string }

Social Media Markets

Twitter — createMarketTwitter(params)
typescript
const result = await client.createMarketTwitter({
  question: 'Will this tweet cross 5000 replies?',
  tweetUrl: 'https://x.com/username/status/123456789',
  initialLiquidity: 1_000_000n,  // 1 USDC
  endTime: daysFromNow(7),
  collateralTokenMint: USDC,
});
// Returns: { signature: string, market: string, detectedTwitterUrl?, isTweetIdFormat? }

Supported URL formats: https://x.com/user/status/ID, https://twitter.com/user/status/ID

YouTube — createMarketYoutube(params)
typescript
const result = await client.createMarketYoutube({
  question: 'Will this video cross 1B views?',
  youtubeUrl: 'https://youtu.be/VIDEO_ID',
  initialLiquidity: 1_000_000n,
  endTime: daysFromNow(30),
  collateralTokenMint: USDC,
});
// Returns: { signature: string, market: string, detectedYoutubeUrl? }

Supported: https://youtu.be/ID, https://youtube.com/watch?v=ID, https://youtube.com/shorts/ID

DeFiLlama — createMarketDefiLlama(params)
typescript
const result = await client.createMarketDefiLlama({
  question: 'Will Uniswap TVL exceed $5B this quarter?',
  protocolName: 'uniswap-v3',
  metric: 'tvl',
  initialLiquidity: 5_000_000n,
  endTime: daysFromNow(30),
  collateralTokenMint: USDC,
});
// Returns: { signature: string, market: string, detectedProtocol?, detectedMetric? }

P2P Markets (V3)

Create P2P Market — createP2PMarketGeneral(params)

Direct peer-to-peer betting where the creator takes one side.

typescript
const result = await client.createP2PMarketGeneral({
  question: 'Will our DAO pass Proposal #42?',
  initialAmount: 100_000_000n,  // 100 USDC (raw units, 6 decimals)
  side: 'yes',                   // Creator bets YES
  creatorSideCap: 500_000_000n,  // Max 500 USDC on creator's side
  endTime: daysFromNow(14),
  collateralTokenMint: USDC,
});
// Returns: { signature: string, market: PubkeyLike, yesTokenMint: PubkeyLike, noTokenMint: PubkeyLike }
Simple P2P — createP2PMarketSimple(params)

UI-friendly wrapper that handles USDC conversion automatically:

typescript
const result = await client.createP2PMarketSimple({
  question: 'Will it rain tomorrow?',
  side: 'yes',
  amountUsdc: 50,              // 50 USDC (human-readable, SDK converts)
  daysUntilEnd: 1,             // Defaults to 30 days
  creatorSideCapMultiplier: 5, // 5x initial = 250 USDC cap (default)
});
P2P Social Media Variants
  • createP2PMarketTwitter(params) — P2P + Twitter URL detection
  • createP2PMarketYoutube(params) — P2P + YouTube URL detection
  • createP2PMarketDefiLlama(params) — P2P + DeFiLlama metrics
  • createP2PMarketTwitterSimple(params) — UI-friendly P2P Twitter
  • createP2PMarketYoutubeSimple(params) — UI-friendly P2P YouTube
  • createP2PMarketDefiLlamaSimple(params) — UI-friendly P2P DeFiLlama
  • createMarketP2PWithCustomOdds(params) — P2P with custom initial odds

Core Operations: Trading (Wallet Required)

Buy Tokens (V2 AMM) — trading.buyTokensUsdc(params)

Purchases YES or NO outcome tokens using USDC collateral.

typescript
const result = await client.trading.buyTokensUsdc({
  market: marketPubkey,
  buyYesToken: true,   // true = YES, false = NO
  amountUsdc: 10,      // 10 USDC (human-readable, SDK converts using mint decimals)
  minimumOut: 0n,      // Optional: minimum tokens received (slippage protection)
});

// Returns:
// { signature: string, usdcSpent: number, tokensReceived: number,
//   before: BalanceSnapshot, after: BalanceSnapshot }
Sell Tokens (V2 AMM) — trading.sellTokensBase(params)
typescript
const result = await client.trading.sellTokensBase({
  market: marketPubkey,
  burnYesToken: true,                     // true = sell YES, false = sell NO
  amountBaseUnits: 5_000_000n,            // Raw token units (6 decimals)
});
// Returns: { signature: string, tokensSold: number, usdcReceived: number }
Buy Tokens (P2P/V3) — buyV3TokensUsdc(params)
typescript
const result = await client.buyV3TokensUsdc({
  market: marketPubkey,
  buyYesToken: true,
  amountUsdc: 10,       // Human-readable USDC
});
// Returns: { signature: string }

Key Differences:

  • V2 AMM: Uses trading.buyTokensUsdc() — human-readable amountUsdc
  • P2P/V3: Uses buyV3TokensUsdc() — human-readable amountUsdc
  • Selling (V2): Uses trading.sellTokensBase() — raw units amountBaseUnits

Core Operations: Settlement (Oracle Required)

Activate Market — setMarketResolvable(market, resolvable, forceResolve?)

When to use: Immediately after creating a custom oracle market. Activates trading.

typescript
await client.setMarketResolvable(marketAddress, true);
// Signature: setMarketResolvable(market: PublicKey | string, resolvable: boolean, forceResolve?: boolean)
// Returns: { signature: string }

[!CAUTION] Must be called within 15 minutes of creation. After that, the market is permanently frozen and cannot be recovered. Create a new market instead.

For P2P markets: setMarketResolvableP2p(market, resolvable)

Settle Market (Proxy-Assisted)

After endTime passes, use the proxy server to get the AI-suggested resolution, then settle:

typescript
// 1. Wait for settlement criteria (retries every 2s for up to 15 min)
const { resolvable, answer, criteria } = await client.waitForSettlementCriteria(marketAddress);

// 2. Settle the market if resolvable
if (resolvable) {
  // Use the anchorMarket module for V2 settlement
  const result = await client.anchorMarket.settleMarket({
    market: new PublicKey(marketAddress),
    yesWinner: answer === 'YES',
  });
  console.log('Settled:', result.signature);
}

Core Operations: Redemption (Winner Required)

Redeem Position (V2) — redeemPosition(market)

Converts winning outcome tokens back to collateral after market settlement.

typescript
const { account: market } = await client.fetchMarket(marketPubkey);
if (!market.resolved) throw new Error('Market not settled yet');

const result = await client.redeemPosition(marketPubkey);
// Returns: { signature: string }
Redeem P2P Position — redeemP2PPosition(market)
typescript
const result = await client.redeemP2PPosition(marketPubkey);
// Returns: { signature: string }

Error Handling

Show full SKILL.md (581 more words)Show less
Common Errors & Recovery
ErrorCauseSolution
0x1770 (InvalidLiquidity)Liquidity below minimumUse >= 1 USDC (1_000_000n)
Insufficient funds for rentNot enough SOL for account creationEnsure >= 0.05 SOL in wallet
Blockhash not foundTransaction expired before confirmationRetry; use faster RPC (Helius/QuickNode)
15-minute buffer expiredDidn't call setMarketResolvable in timeMarket is permanently frozen; create new one
TokenAccountNotFoundMissing Associated Token AccountSDK auto-creates ATAs, ensure SOL for rent
Oracle mismatchWrong wallet trying to settleOnly designated oracle can settle
Market not endedTrying to settle before end timeWait until market's endTime passes
Market not tradable: endedTrying to trade after endTimeMarket has ended; no more trades allowed
Insufficient collateral balanceWallet balance below trade amountEnsure wallet has enough USDC
VALIDATION_ERRORInvalid parametersCheck input types and ranges
TRANSPORT_ERRORNetwork/RPC failureRetry with exponential backoff
PROGRAM_ERROROn-chain program errorCheck .programErrorCode and .logs for details
Error Handling Code Pattern

The SDK uses typed errors (SdkError, ValidationError, TransportError, ProgramError):

typescript
import { SdkError, ValidationError, TransportError, ProgramError } from 'pnp-sdk';

async function safeMarketOperation<T>(
  operation: () => Promise<T>,
  operationName: string
): Promise<{ ok: boolean; result?: T; error?: { code: string; message: string; retryable: boolean } }> {
  try {
    const result = await operation();
    return { ok: true, result };
  } catch (error: any) {
    console.error(`${operationName} failed:`, error.message);

    if (error instanceof TransportError || error.message?.includes('Blockhash')) {
      return {
        ok: false,
        error: { code: 'TRANSPORT_ERROR', message: 'Network error. Retry with backoff.', retryable: true },
      };
    }

    if (error instanceof ProgramError) {
      return {
        ok: false,
        error: {
          code: `PROGRAM_ERROR_${error.programErrorCode ?? 'UNKNOWN'}`,
          message: error.message,
          retryable: false,
        },
      };
    }

    if (error instanceof ValidationError) {
      return {
        ok: false,
        error: { code: 'VALIDATION_ERROR', message: error.message, retryable: false },
      };
    }

    if (error.message?.includes('Market not tradable')) {
      return {
        ok: false,
        error: { code: 'MARKET_ENDED', message: error.message, retryable: false },
      };
    }

    return {
      ok: false,
      error: { code: 'UNKNOWN', message: error.message || String(error), retryable: false },
    };
  }
}

// Usage
const result = await safeMarketOperation(
  () => client.market.createMarket(params),
  'Create Market'
);
if (!result.ok && result.error?.retryable) {
  // Retry with exponential backoff
}

Production Hardening

1. Compute Unit Budgets

PNP operations use these approximate CU limits internally:

OperationCU Limit
Market creation (V2)400,000
Trading (mint/burn)600,000
Settlement800,000
Set market resolvable800,000

The SDK sets these automatically. For custom transactions, set explicit budgets:

typescript
import { ComputeBudgetProgram, Transaction } from '@solana/web3.js';

const tx = new Transaction();
tx.add(
  ComputeBudgetProgram.setComputeUnitLimit({ units: 400_000 }),
  ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 50_000 })
);
2. Priority Fees

During network congestion, increase priority fees:

CongestionmicroLamports
Normal10,000
Moderate50,000
High100,000+
3. Timeout & Retry Pattern
typescript
async function executeWithRetry(
  action: () => Promise<string>,
  maxRetries = 3,
  timeoutMs = 30_000
): Promise<string> {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await Promise.race([
        action(),
        new Promise<string>((_, reject) =>
          setTimeout(() => reject(new Error('Timeout')), timeoutMs)
        ),
      ]);
    } catch (error: any) {
      if (attempt === maxRetries) throw error;
      const delay = Math.pow(2, attempt - 1) * 1000;
      console.log(`Retry ${attempt} after ${delay}ms...`);
      await new Promise(r => setTimeout(r, delay));
    }
  }
  throw new Error('Max retries exceeded');
}
4. Input Validation
typescript
function validateMarketParams(params: { question: string; initialLiquidity: bigint; endTime: bigint }) {
  if (!params.question || params.question.length === 0) throw new Error('Question cannot be empty');
  if (params.initialLiquidity < 1_000_000n) throw new Error('Min liquidity is 1 USDC (1_000_000n)');
  if (params.endTime <= BigInt(Math.floor(Date.now() / 1000))) throw new Error('End time must be in the future');
}
5. RPC Failover
typescript
const RPC_URLS = [
  process.env.RPC_URL || 'https://api.mainnet-beta.solana.com',
  'https://mainnet.helius-rpc.com/?api-key=YOUR_KEY',
  'https://solana-mainnet.g.alchemy.com/v2/YOUR_KEY',
];

SDK Quick Reference

MethodScopeWhen to Use
market.createMarket({...})WriteStandard V2 AMM markets
createMarketWithCustomOracle({...})WriteAgent-controlled market resolution
createMarketV2WithCustomOdds({...})WriteV2 with non-50/50 starting odds
createP2PMarketGeneral({...})WriteP2P direct bets (raw units)
createP2PMarketSimple({...})WriteP2P direct bets (UI-friendly)
createMarketTwitter({...})WriteV2 markets linked to tweets
createMarketYoutube({...})WriteV2 markets linked to videos
createMarketDefiLlama({...})WriteV2 markets linked to DeFi metrics
setMarketResolvable(market, true)WriteActivate custom oracle markets (15 min!)
setMarketResolvableP2p(market, true)WriteActivate P2P custom oracle markets
trading.buyTokensUsdc({...})WriteBuy YES/NO tokens on V2 markets
trading.sellTokensBase({...})WriteSell YES/NO tokens on V2 markets
buyV3TokensUsdc({...})WriteBuy tokens on P2P/V3 markets
redeemPosition(market)WriteRedeem V2 winning position
redeemP2PPosition(market)WriteRedeem P2P winning position
getMarketPriceV2(market)ReadCurrent prices and multipliers
fetchMarket(pubkey)ReadOn-chain market account data
fetchMarketAddresses()ReadList all V2 market addresses
fetchMarkets()ReadAll V2 markets with full data
fetchSettlementCriteria(market)ReadAI resolution criteria
fetchSettlementData(market)ReadSettlement decision
waitForSettlementCriteria(market)ReadRetry until criteria available
trading.getMarketInfo(pubkey)ReadExtended market info
trading.getBalances(market)ReadUser's token balances for market
trading.getPrices(market)ReadToken supply-based price shares
PNPClient.parseSecretKey(str)StaticParse Base58 or JSON array private key
client.uiToRaw(amount, decimals)UtilConvert UI amount to raw bigint
PNPClient.detectTwitterUrl(text)StaticExtract Twitter URL from question
PNPClient.detectYoutubeUrl(text)StaticExtract YouTube URL from question
PNPClient.detectDefiLlamaUrl(text)StaticExtract DeFiLlama format from question

Script Quick Reference

All scripts are located in scripts/ and use dotenv/config to load .env.

ScriptPurposeRun Command
create-market.tsCreate standard V2 AMM markettsx scripts/create-market.ts
create-market-x.tsCreate Twitter/X engagement markettsx scripts/create-market-x.ts
create-market-yt.tsCreate YouTube views markettsx scripts/create-market-yt.ts
create-market-p2p.tsCreate P2P betting markettsx scripts/create-market-p2p.ts
create-market-custom.tsCreate custom oracle markettsx scripts/create-market-custom.ts
market-data.tsFetch market info & settlement datatsx scripts/market-data.ts
trade.tsBuy/sell outcome tokenstsx scripts/trade.ts --buy --market <addr> --outcome YES --amount 10
settle.tsResolve market as oracletsx scripts/settle.ts --market <addr> --outcome YES
redeem.tsClaim winnings after settlementtsx scripts/redeem.ts --market <addr>

Resources


Skill Structure

solana-skill/
├── SKILL.md                             # Main entry point (this file)
│   ├── When to Use / Triggers
│   ├── Program IDs & Precision
│   ├── Quick Start
│   ├── Market Lifecycle / State Machine
│   ├── Core Operations (Read-Only, Creation, Trading, Settlement, Redemption)
│   ├── Error Handling
│   ├── Production Hardening
│   └── SDK Quick Reference
│
├── README.md                            # Human-facing overview for GitHub
│
├── references/
│   ├── api-reference.md                # Complete method signatures & parameter docs
│   ├── types-and-precision.md          # TypeScript interfaces, decimal constants
│   ├── program-addresses.md            # Program IDs, PDA derivations, token mints
│   ├── examples.md                     # Advanced code patterns
│   └── use-cases.md                    # Real-world prediction market patterns
│
├── scripts/                             # CLI utilities for testing
│   ├── create-market.ts
│   ├── create-market-custom.ts
│   ├── create-market-x.ts
│   ├── create-market-yt.ts
│   ├── create-market-p2p.ts
│   ├── market-data.ts
│   ├── trade.ts
│   ├── settle.ts
│   └── redeem.ts
│
└── package.json

Progressive disclosure: SKILL.md covers 80% of use cases. Reference files handle the deep details.

© internet-court, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 21 other files (scripts, references) in vendored/pnp/pnp-solana of internet-court/internet-court-skill.

  • SKILL.md
  • .gitignore
  • LICENSE
  • README.md
  • package-lock.json
  • package.json
  • references/api-reference.md
  • references/examples.md
  • references/program-addresses.md
  • references/types-and-precision.md
  • references/use-cases.md
  • scripts/create-market-custom.ts
  • scripts/create-market-p2p.ts
  • scripts/create-market-x.ts
  • scripts/create-market-yt.ts
  • scripts/create-market.ts
  • scripts/market-data.ts
  • scripts/package.json
  • scripts/redeem.ts
  • … and 3 more

Open the folder on GitHubat commit fa89195

Compare with similar skills

PNP Prediction Markets on Solana next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

PNP Prediction Markets on Solana compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
PNP Prediction Markets on Solana this skillinternet-court/internet-court-skill6.6k—~7.5kAutomated safety check: NotesMIT
Pump TS Vanitynirholas/pump-fun-sdk134—~738Automated safety check: PassCustom licence
Trust Wallet SDKtrustwallet/tw-agent-skills106—~364Automated safety check: PassMIT
Stock Analysis24mlight/StockClaw1012 repos~2kAutomated safety check: NotesMIT
Swapper Depositswapperfinance/swapper-toolkit852—~1.8kAutomated safety check: PassMIT
Minara Crypto Trading and WalletMinara-AI/minara-skills362—~5.7kAutomated safety check: PassNone

Similar skills

  • Pump TS Vanity

    nirholas/pump-fun-sdk

    Educational single-threaded TypeScript vanity address generator for Solana using @solana/web3.js with async iteration, event-loop yielding, streaming generator API, and best-effort memory zeroization.

    134 GitHub stars~738 tokensUpdated yesterday
    DevelopmentAuto-check passed
  • Trust Wallet SDK

    trustwallet/tw-agent-skills

    Trust Wallet open-source libraries — Wallet Core (HD wallets, address derivation, tx signing in Swift/Kotlin/TypeScript/Go for 140+ chains), Web3 Provider (dApp connection for…

    106 GitHub stars~364 tokensUpdated 4 mo ago
    MobileAuto-check passed
  • Stock Analysis

    24mlight/StockClaw

    Analyze stocks and cryptocurrencies using Yahoo Finance data.

    101 GitHub starsUsed in 2 repos~2k tokens
    Business, Finance & HRAuto-check: notes
  • Swapper Deposit

    swapperfinance/swapper-toolkit

    Deposit and bridge funds into a wallet or protocol using Swapper Finance.

    852 GitHub stars~1.8k tokensUpdated 6 mo ago
    Business, Finance & HRAuto-check passed
  • Minara Crypto Trading and Wallet

    Minara-AI/minara-skills

    Drives the Minara CLI for crypto swaps, perps, limit orders, wallet transfers, deposits and withdrawals, plus AI market analysis.

    362 GitHub stars~5.7k tokensUpdated 24 days ago
    Business, Finance & HRAuto-check passed
  • Okx Cex Market

    dex-original/okx-agent-trade-kit

    A skill your agent uses when the user asks for: price of any asset, ticker, order book, candles, OHLCV, funding rate, open interest, OI change scanner, market screener (top movers, high-volume…

    110 GitHub starsUsed in 1 repo~2.7k tokens
    Business, Finance & HRAuto-check passed

More from internet-court/internet-court-skill

All 80 skills in this repo
  • Kleros IPFS Upload

    internet-court/internet-court-skill

    Uploads one Kleros-related file per paid request to IPFS through the Kleros x402 gateway for 0.01 USDC on Base, returning a CID that Kleros contracts can reference.

    6.6k GitHub stars~4.9k tokensUpdated 1 mo ago
    Auto-check: notes
  • 0G Compute Network Guide

    internet-court/internet-court-skill

    Guides building on the 0G Compute Network, a decentralized GPU marketplace for AI inference and fine-tuning, with SDK patterns and CLI commands.

    6.6k GitHub starsUsed in 1 repo~1.9k tokens
    Auto-check passed
  • BNB Chain MCP Server

    internet-court/internet-court-skill

    Connects an agent to the BNB Chain MCP server to read blocks and contracts, move tokens and NFTs, register ERC-8004 agents and use Greenfield storage.

    6.6k GitHub starsUsed in 1 repo~1.7k tokens
    Auto-check passed
  • GenLayer ERC-7710 Connector

    internet-court/internet-court-skill

    Specifies how a GenLayer Intelligent Contract decision about an agent's performance becomes an ERC-7710 revocation or policy change, through a relayer or bridge and an EVM controller.

    6.6k GitHub starsUsed in 1 repo~2.2k tokens
    Auto-check passed
  • GenLayer Agent Supervision Adapter

    internet-court/internet-court-skill

    Specifies how a GenLayer Intelligent Contract should supervise an AI agent, with review rubrics, evidence schemas and continue, warn, constrain or revoke decisions.

    6.6k GitHub starsUsed in 1 repo~1.8k tokens
    Auto-check passed
  • Heurist Mesh Crypto Data

    internet-court/internet-court-skill

    Pulls live crypto token data, DeFi metrics, wallet holdings, project research and Twitter/X signals through Heurist Mesh agents over a REST API.

    6.6k GitHub starsUsed in 1 repo~1.7k tokens
    Auto-check: notes

Questions about PNP Prediction Markets on Solana

What does PNP Prediction Markets on Solana do?

Creates, trades and settles permissionless prediction markets on Solana with any SPL token as collateral, including social-media and custom-oracle markets. The agent can create prediction markets in three styles: V2 AMM markets, P2P direct bets, and custom-oracle markets that an AI agent can resolve. It can also build social-media markets on Twitter engagement, YouTube views or DeFiLlama metrics.

When should I use PNP Prediction Markets on Solana?

PNP Prediction Markets on Solana fits situations like: creating a prediction market on Solana with a chosen collateral token; settling a custom-oracle market after trading has ended; redeeming winning positions after a market settles; building a market on Twitter engagement or YouTube views.

How do I install PNP Prediction Markets on Solana in Claude Code?

Run `npx skills add internet-court/internet-court-skill --skill pnp-markets-solana -a claude-code`. Or copy the skill folder (vendored/pnp/pnp-solana in internet-court/internet-court-skill) into .claude/skills/pnp-markets-solana in your project. Claude Code loads it when a task matches its description.

How do I install PNP Prediction Markets on Solana in Codex?

Run `npx skills add internet-court/internet-court-skill --skill pnp-markets-solana -a codex`. Or copy the skill folder (vendored/pnp/pnp-solana in internet-court/internet-court-skill) into .agents/skills/pnp-markets-solana in your project. Codex loads it when a task matches its description.

Can I use PNP Prediction Markets on Solana in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add internet-court/internet-court-skill --skill pnp-markets-solana -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/pnp-markets-solana, .gemini/skills/pnp-markets-solana, .github/skills/pnp-markets-solana and .opencode/skills/pnp-markets-solana in your project.

What does PNP Prediction Markets on Solana need to run?

Going by SKILL.md and its folder, PNP Prediction Markets on Solana needs TypeScript for the scripts in its folder, the command-line tools its instructions call (tsx and npm) and credentials named PRIVATE_KEY. Our summary lists: Node.js 18 or newer; A Solana RPC endpoint (mainnet or devnet); A funded wallet with SOL for transaction fees; An SPL token, including Token-2022, as collateral. Compatibility (from SKILL.md): Requires Node.js 18+, Solana RPC endpoint (mainnet or devnet), funded wallet with SOL for transaction fees, and any SPL token (including Token-2022) as collateral.

Does PNP Prediction Markets on Solana access the network?

SKILL.md names 10 domains. In commands or code: api.mainnet-beta.solana.com, x.com, youtu.be, youtube.com, twitter.com, mainnet.helius-rpc.com and solana-mainnet.g.alchemy.com; the agent is likely to contact these when it follows the instructions. As links in the text: npmjs.com, docs.pnp.exchange and solscan.io. This is read from the text; nothing was executed.

Is PNP Prediction Markets on Solana safe to install?

Our automated static check of SKILL.md found notes only (mentions a .env file), nothing it rates as a warning. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.

What licence does PNP Prediction Markets on Solana use?

PNP Prediction Markets on Solana is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does PNP Prediction Markets on Solana use?

About 7.5k tokens (SKILL.md is roughly 30k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 10k tokens, read only when the agent opens those files.

What are the alternatives to PNP Prediction Markets on Solana?

Skills that share tags, products or a category with PNP Prediction Markets on Solana: Pump TS Vanity (nirholas/pump-fun-sdk, 134 stars), Trust Wallet SDK (trustwallet/tw-agent-skills, 106 stars), Stock Analysis (24mlight/StockClaw, 101 stars) and Swapper Deposit (swapperfinance/swapper-toolkit, 852 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains PNP Prediction Markets on Solana?

internet-court (a GitHub organization) maintains it in internet-court/internet-court-skill, which has 6,551 GitHub stars. The repository holds 80 skills in this directory. The repository was last updated on August 19, 2026.

Source: internet-court/internet-court-skill on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.