Complete reference for all program IDs, token mints, and Program Derived Addresses (PDAs) used by the PNP Protocol on Solana.
| Network | Program ID | Usage |
|---|---|---|
| Mainnet | 8PyE2dizL52ga7ytqLtqRyjwWp4yXEx8M5Z4BAHgHuTb |
Production prediction market program |
| Devnet | pnpkv2qnh4bfpGvTugGDSEhvZC7DP4pVxTuDykV3BGz |
Testing & development |
The SDK auto-detects the network from the RPC URL:
- URLs containing
devnet,dev., or:8899→ Devnet program ID - All other URLs → Mainnet program ID
| Token | Mint Address | Decimals | Notes |
|---|---|---|---|
| USDC | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v |
6 | Common stablecoin collateral |
| USDT | Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB |
6 | Alternative stablecoin |
| WSOL | So11111111111111111111111111111111111111112 |
9 | Wrapped SOL |
Any SPL token (including Token-2022) can be used as collateral. Decision tokens (YES/NO) are always standard SPL Token.
All PDA functions are exported from pnp-sdk under the pdas namespace:
import { pdas } from 'pnp-sdk';
import { PublicKey } from '@solana/web3.js';
const PROGRAM_ID = new PublicKey('8PyE2dizL52ga7ytqLtqRyjwWp4yXEx8M5Z4BAHgHuTb');Singleton account storing protocol-wide settings (fees, admin, metadata URIs).
const [globalConfigPda, bump] = pdas.deriveGlobalConfigPda(PROGRAM_ID);
// Seeds: ["global_config"]Derives the market account address from its YES and NO token mints.
const [marketPda, bump] = pdas.deriveMarketPdaFromMints(
yesMint, // PublicKey — YES token mint
noMint, // PublicKey — NO token mint
PROGRAM_ID
);
// Seeds: ["market", yesMint, noMint]Alternative derivation using base and quote mint addresses.
const [marketPda, bump] = pdas.deriveMarketPda(
baseMint, // PublicKey — Base token mint
quoteMint, // PublicKey — Quote token mint
PROGRAM_ID
);
// Seeds: ["market", baseMint, quoteMint]Derives a user's position account for a specific market.
const [positionPda, bump] = pdas.derivePositionPda(
marketPubkey, // PublicKey — Market address
ownerPubkey, // PublicKey — User's wallet
PROGRAM_ID
);
// Seeds: ["position", market, owner]Derives the YES decision token mint from the global market ID.
const [yesTokenMint, bump] = pdas.deriveYesTokenMint(
globalId, // bigint — Global incrementing market ID (from GlobalConfig.global_id)
PROGRAM_ID
);
// Seeds: ["yes_token", globalId (u64 LE)]Derives the NO decision token mint from the global market ID.
const [noTokenMint, bump] = pdas.deriveNoTokenMint(
globalId, // bigint — Global incrementing market ID
PROGRAM_ID
);
// Seeds: ["no_token", globalId (u64 LE)]Derives the creator's fee treasury for collecting market creator fees.
// Current format (multi-collateral — use for all new markets)
const [treasuryPda, bump] = pdas.deriveCreatorFeeTreasuryPda(
creatorPubkey, // PublicKey — Market creator's wallet
PROGRAM_ID,
collateralMint // PublicKey — Collateral token mint
);
// Seeds: ["creator_fee_treasury", creator, collateralMint]
// Legacy format (pre-multi-collateral — USDC-only markets created before update)
const [legacyTreasuryPda, bump] = pdas.deriveCreatorFeeTreasuryPdaLegacy(
creatorPubkey, // PublicKey — Market creator's wallet
PROGRAM_ID
);
// Seeds: ["creator_fee_treasury", creator]Derives the Metaplex token metadata account for a mint.
const METAPLEX_METADATA_PROGRAM = new PublicKey('metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s');
const [metadataPda, bump] = pdas.deriveTokenMetadataPda(
mintPubkey, // PublicKey — Token mint
METAPLEX_METADATA_PROGRAM
);
// Seeds: ["metadata", metadataProgramId, mint]Derives the ATA for a given owner and mint. Used for all token balance lookups and transfers.
const ata = pdas.deriveAta(
ownerPubkey, // PublicKey — Wallet address
mintPubkey, // PublicKey — Token mint
allowOwnerOffCurve, // boolean (default: false) — True for PDAs
tokenProgramId, // PublicKey (default: TOKEN_PROGRAM_ID)
ataProgramId // PublicKey (default: ASSOCIATED_TOKEN_PROGRAM_ID)
);
// Standard ATA derivation using @solana/spl-token| PDA | Seeds | Notes |
|---|---|---|
| Global Config | ["global_config"] |
Singleton — one per program |
| Market (from mints) | ["market", yesMint, noMint] |
Primary market lookup |
| Market (alt) | ["market", baseMint, quoteMint] |
Alternative derivation |
| Position | ["position", market, owner] |
Per-user, per-market |
| YES Token Mint | ["yes_token", globalId(u64 LE)] |
One per market |
| NO Token Mint | ["no_token", globalId(u64 LE)] |
One per market |
| Creator Fee Treasury | ["creator_fee_treasury", creator, collateralMint] |
Current format (multi-collateral) |
| Creator Fee Treasury (Legacy) | ["creator_fee_treasury", creator] |
Legacy format (USDC-only, pre-update) |
| Token Metadata | ["metadata", metadataProgramId, mint] |
Metaplex standard |
| Program | Address | Usage |
|---|---|---|
| SPL Token | TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA |
Standard token operations |
| SPL Associated Token Account | ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL |
ATA derivation |
| Token-2022 | TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb |
Extended token standard (collateral support) |
| Metaplex Token Metadata | metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s |
Token metadata |
| System Program | 11111111111111111111111111111111 |
Account creation |
import { PNPClient, pdas } from 'pnp-sdk';
import { PublicKey } from '@solana/web3.js';
const client = new PNPClient('https://api.mainnet-beta.solana.com');
const PROGRAM_ID = new PublicKey('8PyE2dizL52ga7ytqLtqRyjwWp4yXEx8M5Z4BAHgHuTb');
// Fetch a market
const marketAddress = new PublicKey('HxnpHygK1v7TqodWqAv6RvcEiK9zxAgw5jPZ6rskgj2E');
const { account } = await client.fetchMarket(marketAddress);
// Derive the user's token accounts
const userWallet = new PublicKey('YourWalletAddress');
const yesAta = pdas.deriveAta(userWallet, new PublicKey(account.yes_token_mint));
const noAta = pdas.deriveAta(userWallet, new PublicKey(account.no_token_mint));
const collateralAta = pdas.deriveAta(userWallet, new PublicKey(account.collateral_token));
console.log('YES token ATA:', yesAta.toBase58());
console.log('NO token ATA:', noAta.toBase58());
console.log('Collateral ATA:', collateralAta.toBase58());// If you know the global market ID, derive the mints
const globalId = 42n;
const [yesMint] = pdas.deriveYesTokenMint(globalId, PROGRAM_ID);
const [noMint] = pdas.deriveNoTokenMint(globalId, PROGRAM_ID);
const [marketPda] = pdas.deriveMarketPdaFromMints(yesMint, noMint, PROGRAM_ID);
console.log('Market #42:', marketPda.toBase58());