buy / sell instruction discriminators.
For pre-graduation curve trading, see the Pump.fun bonding curve program. Solana Tracker market filter for these pools: pumpfun-amm.
Need swaps without assembling AMM accounts? Use the Raptor Swap API — it routes graduated Pump.fun tokens through PumpSwap and other DEXes.
Official program IDs
| Program | Address | Role |
|---|---|---|
| Pump.fun AMM (PumpSwap) | pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA | Buy/sell, create_pool, deposit, withdraw |
| Pump.fun (bonding curve) | 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P | Pre-graduation curve + migrate into AMM |
| Pump Fees | pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ | Fee config for buy/sell |
Well-known accounts
| Account | Notes |
|---|---|
global_config | PDA with seeds ["global_config"] — commonly ADyA8hdefvWN2dbGGWFotbzWxrAvLW83WG6QCVXvJKqw |
event_authority | PDA seeds ["__event_authority"] on the AMM program |
pool | Per-market pool account (passed into buy/sell) |
| Quote mint (typical) | So11111111111111111111111111111111111111112 (WSOL) |
migrate instruction after the curve completes.
Anchor IDL
Download the official Anchor IDL (mirrored from pump-fun/pump-public-docs):- JSON IDL: /idl/pump_amm.json
- Upstream: idl/pump_amm.json
import idl from "./idl/pump_amm.json" assert { type: "json" };
console.log(idl.address);
// pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA
Instruction discriminators
| Instruction | Discriminator (bytes) | Hex |
|---|---|---|
buy | [102, 6, 61, 18, 1, 218, 235, 234] | 0x66063d1201daebea |
sell | [51, 230, 133, 164, 1, 127, 131, 173] | 0x33e685a4017f83ad |
buy_exact_quote_in | [198, 46, 21, 82, 180, 217, 232, 112] | 0xc62e1552b4d9e870 |
create_pool | [233, 146, 209, 142, 207, 104, 64, 188] | 0xe992d18ecf6840bc |
deposit | [242, 35, 198, 137, 82, 225, 242, 182] | 0xf223c68952e1f2b6 |
withdraw | [183, 18, 70, 156, 148, 109, 161, 34] | 0xb712469c946da122 |
AMM
buy / sell use the same Anchor sighashes as bonding-curve buy / sell. Disambiguate by program ID: pAMMBay… (AMM) vs 6EF8rrecth… (curve).Detect AMM buy vs sell in Rust
const PUMP_AMM: &str = "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA";
const BUY: [u8; 8] = [102, 6, 61, 18, 1, 218, 235, 234];
const SELL: [u8; 8] = [51, 230, 133, 164, 1, 127, 131, 173];
fn is_amm_buy(program_id: &str, data: &[u8]) -> bool {
program_id == PUMP_AMM && data.get(..8) == Some(&BUY)
}
buy instruction
Args
| Arg | Type | Meaning |
|---|---|---|
base_amount_out | u64 | Tokens to receive |
max_quote_amount_in | u64 | Max quote (e.g. WSOL lamports) to spend |
track_volume | OptionBool | { 0 } / { 1 } |
| # | Account | Writable | Signer |
|---|---|---|---|
| 0 | pool | ✓ | |
| 1 | user | ✓ | ✓ |
| 2 | global_config | ||
| 3 | base_mint | ||
| 4 | quote_mint | ||
| 5 | user_base_token_account | ✓ | |
| 6 | user_quote_token_account | ✓ | |
| 7 | pool_base_token_account | ✓ | |
| 8 | pool_quote_token_account | ✓ | |
| 9 | protocol_fee_recipient | ||
| 10 | protocol_fee_recipient_token_account | ✓ | |
| 11 | base_token_program | ||
| 12 | quote_token_program | ||
| 13 | system_program | ||
| 14 | associated_token_program | ||
| 15 | event_authority | ||
| 16 | program | ||
| 17 | coin_creator_vault_ata | ✓ | |
| 18 | coin_creator_vault_authority | ||
| 19 | global_volume_accumulator | ||
| 20 | user_volume_accumulator | ✓ | |
| 21 | fee_config | ||
| 22 | fee_program |
sell instruction
Args
| Arg | Type | Meaning |
|---|---|---|
base_amount_in | u64 | Tokens to sell |
min_quote_amount_out | u64 | Min quote out (slippage) |
buy through coin_creator_vault_authority (indices 0–18), then fee_config (19) and fee_program (20). Sell does not pass the volume accumulator accounts.
Buy / sell with @solana/web3.js
import {
PublicKey,
TransactionInstruction,
SystemProgram,
} from "@solana/web3.js";
import {
TOKEN_PROGRAM_ID,
ASSOCIATED_TOKEN_PROGRAM_ID,
getAssociatedTokenAddressSync,
} from "@solana/spl-token";
export const PUMP_AMM_PROGRAM_ID = new PublicKey(
"pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA"
);
export const PUMP_FEE_PROGRAM_ID = new PublicKey(
"pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ"
);
export const GLOBAL_CONFIG = new PublicKey(
"ADyA8hdefvWN2dbGGWFotbzWxrAvLW83WG6QCVXvJKqw"
);
const BUY_DISC = Buffer.from([102, 6, 61, 18, 1, 218, 235, 234]);
const SELL_DISC = Buffer.from([51, 230, 133, 164, 1, 127, 131, 173]);
function u64le(n) {
const b = Buffer.alloc(8);
b.writeBigUInt64LE(BigInt(n));
return b;
}
export function ammEventAuthority() {
return PublicKey.findProgramAddressSync(
[Buffer.from("__event_authority")],
PUMP_AMM_PROGRAM_ID
)[0];
}
export function ammFeeConfigPda() {
return PublicKey.findProgramAddressSync(
[Buffer.from("fee_config"), PUMP_AMM_PROGRAM_ID.toBuffer()],
PUMP_FEE_PROGRAM_ID
)[0];
}
export function coinCreatorVaultAuthority(coinCreator) {
return PublicKey.findProgramAddressSync(
[Buffer.from("creator_vault"), coinCreator.toBuffer()],
PUMP_AMM_PROGRAM_ID
)[0];
}
/**
* Minimal PumpSwap buy. Resolve pool vaults, fee recipient, and coin_creator
* from the pool account / a recent mainnet tx before production use.
*/
export function buildAmmBuyIx({
pool,
user,
baseMint,
quoteMint,
poolBaseTokenAccount,
poolQuoteTokenAccount,
protocolFeeRecipient,
coinCreator,
baseAmountOut,
maxQuoteAmountIn,
trackVolume = false,
baseTokenProgram = TOKEN_PROGRAM_ID,
quoteTokenProgram = TOKEN_PROGRAM_ID,
}) {
const userBase = getAssociatedTokenAddressSync(
baseMint,
user,
false,
baseTokenProgram
);
const userQuote = getAssociatedTokenAddressSync(
quoteMint,
user,
false,
quoteTokenProgram
);
const protocolFeeAta = getAssociatedTokenAddressSync(
quoteMint,
protocolFeeRecipient,
true,
quoteTokenProgram
);
const creatorAuthority = coinCreatorVaultAuthority(coinCreator);
const creatorAta = getAssociatedTokenAddressSync(
quoteMint,
creatorAuthority,
true,
quoteTokenProgram
);
const [globalVolume] = PublicKey.findProgramAddressSync(
[Buffer.from("global_volume_accumulator")],
PUMP_AMM_PROGRAM_ID
);
const [userVolume] = PublicKey.findProgramAddressSync(
[Buffer.from("user_volume_accumulator"), user.toBuffer()],
PUMP_AMM_PROGRAM_ID
);
const data = Buffer.concat([
BUY_DISC,
u64le(baseAmountOut),
u64le(maxQuoteAmountIn),
Buffer.from([trackVolume ? 1 : 0]),
]);
return new TransactionInstruction({
programId: PUMP_AMM_PROGRAM_ID,
keys: [
{ pubkey: pool, isSigner: false, isWritable: true },
{ pubkey: user, isSigner: true, isWritable: true },
{ pubkey: GLOBAL_CONFIG, isSigner: false, isWritable: false },
{ pubkey: baseMint, isSigner: false, isWritable: false },
{ pubkey: quoteMint, isSigner: false, isWritable: false },
{ pubkey: userBase, isSigner: false, isWritable: true },
{ pubkey: userQuote, isSigner: false, isWritable: true },
{ pubkey: poolBaseTokenAccount, isSigner: false, isWritable: true },
{ pubkey: poolQuoteTokenAccount, isSigner: false, isWritable: true },
{ pubkey: protocolFeeRecipient, isSigner: false, isWritable: false },
{ pubkey: protocolFeeAta, isSigner: false, isWritable: true },
{ pubkey: baseTokenProgram, isSigner: false, isWritable: false },
{ pubkey: quoteTokenProgram, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
{ pubkey: ammEventAuthority(), isSigner: false, isWritable: false },
{ pubkey: PUMP_AMM_PROGRAM_ID, isSigner: false, isWritable: false },
{ pubkey: creatorAta, isSigner: false, isWritable: true },
{ pubkey: creatorAuthority, isSigner: false, isWritable: false },
{ pubkey: globalVolume, isSigner: false, isWritable: false },
{ pubkey: userVolume, isSigner: false, isWritable: true },
{ pubkey: ammFeeConfigPda(), isSigner: false, isWritable: false },
{ pubkey: PUMP_FEE_PROGRAM_ID, isSigner: false, isWritable: false },
],
data,
});
}
export function buildAmmSellIx({
pool,
user,
baseMint,
quoteMint,
poolBaseTokenAccount,
poolQuoteTokenAccount,
protocolFeeRecipient,
coinCreator,
baseAmountIn,
minQuoteAmountOut,
baseTokenProgram = TOKEN_PROGRAM_ID,
quoteTokenProgram = TOKEN_PROGRAM_ID,
}) {
const userBase = getAssociatedTokenAddressSync(
baseMint,
user,
false,
baseTokenProgram
);
const userQuote = getAssociatedTokenAddressSync(
quoteMint,
user,
false,
quoteTokenProgram
);
const protocolFeeAta = getAssociatedTokenAddressSync(
quoteMint,
protocolFeeRecipient,
true,
quoteTokenProgram
);
const creatorAuthority = coinCreatorVaultAuthority(coinCreator);
const creatorAta = getAssociatedTokenAddressSync(
quoteMint,
creatorAuthority,
true,
quoteTokenProgram
);
const data = Buffer.concat([
SELL_DISC,
u64le(baseAmountIn),
u64le(minQuoteAmountOut),
]);
return new TransactionInstruction({
programId: PUMP_AMM_PROGRAM_ID,
keys: [
{ pubkey: pool, isSigner: false, isWritable: true },
{ pubkey: user, isSigner: true, isWritable: true },
{ pubkey: GLOBAL_CONFIG, isSigner: false, isWritable: false },
{ pubkey: baseMint, isSigner: false, isWritable: false },
{ pubkey: quoteMint, isSigner: false, isWritable: false },
{ pubkey: userBase, isSigner: false, isWritable: true },
{ pubkey: userQuote, isSigner: false, isWritable: true },
{ pubkey: poolBaseTokenAccount, isSigner: false, isWritable: true },
{ pubkey: poolQuoteTokenAccount, isSigner: false, isWritable: true },
{ pubkey: protocolFeeRecipient, isSigner: false, isWritable: false },
{ pubkey: protocolFeeAta, isSigner: false, isWritable: true },
{ pubkey: baseTokenProgram, isSigner: false, isWritable: false },
{ pubkey: quoteTokenProgram, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
{ pubkey: ammEventAuthority(), isSigner: false, isWritable: false },
{ pubkey: PUMP_AMM_PROGRAM_ID, isSigner: false, isWritable: false },
{ pubkey: creatorAta, isSigner: false, isWritable: true },
{ pubkey: creatorAuthority, isSigner: false, isWritable: false },
{ pubkey: ammFeeConfigPda(), isSigner: false, isWritable: false },
{ pubkey: PUMP_FEE_PROGRAM_ID, isSigner: false, isWritable: false },
],
data,
});
}
Live PumpSwap
buy instructions often append remaining accounts after the 23 IDL accounts (observed +3 on mainnet). sell may append +2. Base mints are frequently Token-2022 (TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb) while quote is WSOL on the legacy token program. Decode the pool with /idl/pump_amm.json or copy accounts from a recent successful swap before mainnet use.Easier path: Raptor + Data API
# Find graduated Pump.fun / PumpSwap markets
curl "https://data.solanatracker.io/search?market=pumpfun-amm&limit=20" \
-H "x-api-key: YOUR_API_KEY"
// Swap a graduated token (Raptor picks PumpSwap / best route)
await fetch("https://swap-v2.solanatracker.io/swap", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
wallet: "YOUR_WALLET_ADDRESS",
from: "TOKEN_MINT_ADDRESS",
to: "So11111111111111111111111111111111111111112",
amount: 1000000,
slippage: 15,
}),
});
Stream & index with Solana Tracker
| Product | Use for |
|---|---|
| Pump.fun API | Graduated token data, trades, OHLCV |
| Data API | market=pumpfun-amm, /tokens/multi/graduated |
| Datastream | graduated room + per-token trade streams |
| Memescope | Migrated / PumpSwap column in the live feed |
| Raptor | Execute sells/buys on PumpSwap pools |
| Yellowstone gRPC | Subscribe to pAMMBay… program transactions |
| Solana RPC | Fetch pool accounts and confirm swaps |
- Pump.fun bonding curve program —
6EF8rrecth…buy/sell/create - Pump.fun lifecycle — discover → curve → graduate → swap
- Token discovery — graduating / graduated endpoints
- gRPC buy/sell detection
Pump.fun program
Bonding curve program ID, IDL, create/buy/sell discriminators.
Pump.fun lifecycle
Track launches and graduations with Solana Tracker APIs.
Swap API
Buy and sell without building AMM instructions.
Memescope
Live migrated / PumpSwap token feed.