npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@pump-fun/pump-swap-sdk

v1.20.0

Published

Official SDK for interacting with Pump Swap AMM protocol on Solana

Readme

Pump Swap SDK

TypeScript SDK for the Pump Swap AMM program (pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA).

  • PumpAmmSdk (singleton PUMP_AMM_SDK) builds instructions and decodes accounts fully offline from a "Solana state" object.
  • OnlinePumpAmmSdk fetches those state objects over RPC (swapSolanaState, liquiditySolanaState, createPoolSolanaState, collectCoinCreatorFeeSolanaState) and reads balances.
  • PumpAmmAdminSdk builds the admin-gated instructions.
  • Pure pricing functions (buyBaseInput, buyQuoteInput, sellBaseInput, sellQuoteInput) and fee helpers (computeFeesBps, feesForQuoteMint, poolMarketCap, ...) are exported from the package root for callers that keep their own state.

Installation

npm install @pump-fun/pump-swap-sdk

Usage

import { Connection } from "@solana/web3.js";
import { OnlinePumpAmmSdk, PUMP_AMM_SDK } from "@pump-fun/pump-swap-sdk";

const connection = new Connection(rpcUrl);
const onlineSdk = new OnlinePumpAmmSdk(connection);

All amounts are BNs in the raw base units of the mint they refer to (lamports for wSOL, micro-units for USDC, ...). slippage is a percentage: 1 means 1%.

Create pool

const createPoolSolanaState = await onlineSdk.createPoolSolanaState(
  index,
  creator,
  baseMint,
  quoteMint,
);

const createPoolInstructions = await PUMP_AMM_SDK.createPoolInstructions(
  createPoolSolanaState,
  baseIn,
  quoteIn,
);

// Initial pool price for the UI
const initialPoolPrice = await PUMP_AMM_SDK.createAutocompleteInitialPoolPrice(
  initialBase,
  initialQuote,
);

Deposit

const liquiditySolanaState = await onlineSdk.liquiditySolanaState(
  poolKey,
  user,
);

// When the base input changes
const { quote, lpToken } =
  PUMP_AMM_SDK.depositAutocompleteQuoteAndLpTokenFromBase(
    liquiditySolanaState,
    base,
    slippage,
  );

// When the quote input changes
const { base, lpToken } =
  PUMP_AMM_SDK.depositAutocompleteBaseAndLpTokenFromQuote(
    liquiditySolanaState,
    quote,
    slippage,
  );

const depositInstructions = await PUMP_AMM_SDK.depositInstructions(
  liquiditySolanaState,
  lpToken,
  slippage,
);

Swap

swapSolanaState fetches the pool, its reserves, the global and fee configs, the two token programs (read from the mint owners, so Token-2022 quotes work) and the user's token accounts. The four PUMP_AMM_SDK swap builders price the trade with the pool's quote mint and mayhem flag, apply slippage, wrap and unwrap wSOL when the quote is legacy WSOL, and create the user's missing base ATA (buy) or quote ATA (sell); a buy on a non-wSOL quote expects the user's quote token account to exist.

const swapSolanaState = await onlineSdk.swapSolanaState(poolKey, user);

// Buy `base` tokens, paying at most quote + slippage
const buyInstructions = await PUMP_AMM_SDK.buyBaseInput(
  swapSolanaState,
  base,
  slippage,
);

// Spend `quote` tokens, receiving base - slippage
const buyInstructions2 = await PUMP_AMM_SDK.buyQuoteInput(
  swapSolanaState,
  quote,
  slippage,
);

// Sell `base` tokens, receiving at least quote - slippage
const sellInstructions = await PUMP_AMM_SDK.sellBaseInput(
  swapSolanaState,
  base,
  slippage,
);

// Receive `quote` tokens, selling at most base + slippage
const sellInstructions2 = await PUMP_AMM_SDK.sellQuoteInput(
  swapSolanaState,
  quote,
  slippage,
);

To show a quote before building, or to build with explicit limits, use the pure functions and buyInstructions / sellInstructions:

import { buyBaseInput, sellBaseInput } from "@pump-fun/pump-swap-sdk";

const {
  pool,
  poolBaseAmount,
  poolQuoteAmount,
  globalConfig,
  feeConfig,
  baseMint,
  baseMintAccount,
} = swapSolanaState;

const poolArgs = {
  baseReserve: poolBaseAmount,
  quoteReserve: poolQuoteAmount,
  virtualQuoteReserves: pool.virtualQuoteReserves,
  globalConfig,
  feeConfig,
  baseMint,
  baseMintAccount,
  coinCreator: pool.coinCreator,
  creator: pool.creator,
  quoteMint: pool.quoteMint, // selects the fee schedule, see below
  isMayhemMode: pool.isMayhemMode, // selects the market-cap basis
  creatorFeeBps: pool.creatorFeeBps, // per-pool creator fee, see "Configurable creator fee"
};

const { uiQuote, maxQuote } = buyBaseInput({ ...poolArgs, base, slippage });
const buyInstructions = await PUMP_AMM_SDK.buyInstructions(
  swapSolanaState,
  base,
  maxQuote,
);

const { uiQuote: quoteOut, minQuote } = sellBaseInput({
  ...poolArgs,
  base,
  slippage,
});
const sellInstructions = await PUMP_AMM_SDK.sellInstructions(
  swapSolanaState,
  base,
  minQuote,
);

buyQuoteInput returns { base, maxQuote } and sellQuoteInput returns { base, minQuote } for the quote-driven directions.

Withdraw

const liquiditySolanaState = await onlineSdk.liquiditySolanaState(
  poolKey,
  user,
);

const { base, quote } =
  PUMP_AMM_SDK.withdrawAutoCompleteBaseAndQuoteFromLpToken(
    liquiditySolanaState,
    lpAmount,
    slippage,
  );

const withdrawInstructions = await PUMP_AMM_SDK.withdrawInstructions(
  liquiditySolanaState,
  lpToken,
  slippage,
);

Creator fees

A coin creator's AMM fees accumulate in a vault ATA per quote mint (coinCreatorVaultAtaPda(coinCreatorVaultAuthorityPda(coinCreator), quoteMint, quoteTokenProgram)). collectCoinCreatorFeeSolanaState and getCoinCreatorVaultBalance default the quote mint to legacy WSOL, so existing SOL-only callers are unchanged; getCoinCreatorVaultBalances and transferCreatorFeesToPumpV2Instruction take it explicitly (offline, together with the quote token program). The online methods accept a bonding curve's zero key as WSOL (like canonicalPumpPoolPda) and, when the token program is not passed, read it from the mint account's owner, which must be SPL Token or Token-2022.

import {
  NATIVE_MINT,
  TOKEN_2022_PROGRAM_ID,
  TOKEN_PROGRAM_ID,
} from "@solana/spl-token";
import { USDC_MINT } from "@pump-fun/pump-swap-sdk";

// Collect: SOL-quoted coins (unchanged call) ...
const solState = await onlineSdk.collectCoinCreatorFeeSolanaState(coinCreator);
// ... or a USDC / quote-control / Token-2022-quoted coin
const usdcState = await onlineSdk.collectCoinCreatorFeeSolanaState(
  coinCreator,
  undefined, // destination token account; defaults to the creator's ATA
  USDC_MINT,
);
const collectInstructions = await PUMP_AMM_SDK.collectCoinCreatorFee(
  usdcState,
  payer, // optional; defaults to the creator
);

// Balances
const solFees = await onlineSdk.getCoinCreatorVaultBalance(coinCreator);
const usdcFees = await onlineSdk.getCoinCreatorVaultBalance(
  coinCreator,
  USDC_MINT,
);
const allFees = await onlineSdk.getCoinCreatorVaultBalances(coinCreator, [
  { mint: NATIVE_MINT, tokenProgram: TOKEN_PROGRAM_ID },
  { mint: USDC_MINT, tokenProgram: TOKEN_PROGRAM_ID },
  { mint: xStockMint, tokenProgram: TOKEN_2022_PROGRAM_ID },
]); // Map<base58 quote mint, BN>

// Fee-sharing coins: move the AMM vault into the pump program's creator vault
const transferInstruction =
  await onlineSdk.transferCreatorFeesToPumpV2Instruction(
    payer,
    coinCreator, // the coin's sharing config PDA once fee sharing is enabled
    quoteMint,
  );
// Offline: PUMP_AMM_SDK.transferCreatorFeesToPumpV2Instruction({ payer, coinCreator, quoteMint, quoteTokenProgram })

collectCoinCreatorFee transfers between two token accounts the program does not create: the builder creates the vault ATA and the creator's destination ATA (rent paid by payer) when they are missing, for any quote mint and either token program. A custom destination (coinCreatorTokenAccount, any token account the creator owns) is accepted but must already exist. A wSOL payout is unwrapped by closing the creator's wSOL ATA, only when the creator is the payer.

transferCreatorFeesToPumpV2 unwraps a wSOL vault into the pump creator vault PDA and moves any other quote into that PDA's quote ATA, which the program creates when missing (rent paid by payer). Its account list carries pump_creator_vault_ata even for wSOL; quoteTokenProgram must be the quote mint's owner program.

Which quote mints a creator's vaults may hold is decided by the pump program (its Global whitelist and QuoteControl list, read with @pump-fun/pump-sdk); this SDK keeps no static list of quote mints.

Canonical pump pools

Coins that graduate from a pump bonding curve trade in a canonical pool keyed by the base mint and the quote mint:

import {
  canonicalPumpPoolPda,
  canonicalPoolQuoteMint,
} from "@pump-fun/pump-swap-sdk";

canonicalPumpPoolPda(mint); // SOL coin (quote = legacy WSOL)
canonicalPumpPoolPda(mint, USDC_MINT); // USDC coin
canonicalPumpPoolPda(mint, bondingCurve.quoteMint); // the curve's zero key means WSOL

canonicalPoolQuoteMint maps a bonding curve's quote_mint to the pool's quote mint (the zero key SOL curves store becomes legacy WSOL). PumpAmmAdminSdk.adminSetCoinCreator(mint, newCoinCreator, quoteMint = NATIVE_MINT) targets the pool of the given quote.

A canonical pool without a coin creator gets one through the permissionless set_coin_creator (from the coin's Metaplex metadata, else its bonding curve):

// Reads the pool (any length), derives metadata / bonding_curve from its base mint and
// prepends extend_account (rent paid by payer) when the pool is not grown yet
const setCoinCreator = await onlineSdk.setCoinCreatorInstructions(
  poolKey,
  payer,
);
// Offline: PUMP_AMM_SDK.setCoinCreator(poolKey, baseMint)

Quote mints and fees

pump-fees selects a trade's fee schedule from the pool and its quote mint (FeeConfig::fees_for_quote_mint); feesForQuoteMint mirrors it and the pure pricing functions apply it when given quoteMint:

| Pool | Quote mint | Schedule | | ------------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | | not a canonical pump pool | any | flatFees | | canonical pump pool | SOL-like (SOL_LIKE_QUOTE_MINTS: the zero key, legacy WSOL So111…112, Token-2022 native 9pan9…) | feeTiers by market cap | | canonical pump pool | listed stable (STABLE_QUOTE_MINTS: USDC EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v) | stableFeeTiers by market cap (feeTiers when the FeeConfig predates stable tiers) | | canonical pump pool | anything else (quote-control mints, xStock Token-2022 quotes, devnet USDC) | exoticFlatFees, or flatFees while the exotic schedule is unset (all zero) |

Market cap is poolMarketCap({ baseMintSupply, baseReserve, quoteReserve, isMayhemMode }) = quoteReserve * circulatingSupply / baseReserve, with circulatingSupply the live mint supply, or the fixed PUMP_AMM_TOTAL_TOKEN_SUPPLY (1e15) for mayhem pools. It is denominated in the quote's base units, and so is FeeTier.marketCapLamportsThreshold of the matching tier set: lamports for feeTiers, USDC micro-units for stableFeeTiers. The stable set is hardcoded here because it is hardcoded on-chain; changing it is a program upgrade.

Things to know when a pool is not quoted in SOL:

  • Devnet USDC (4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU) is whitelisted by the devnet pump program but is not a pump-fees stable, so a devnet USDC pool pays exotic/flat fees once the quote-control fee program is deployed there. The SDK mirrors the program; it does not special-case devnet.
  • Amounts are raw base units; the SDK does no decimal scaling. xStock Token-2022 quotes carry the ScaledUiAmount extension (a UI-only multiplier that leaves raw amounts and on-chain math untouched) and Pausable (every trade fails while the issuer has the mint paused).
  • Token-2022 quote token accounts carry extensions and are 170–182 bytes, not 165. Decoding the fixed 165-byte prefix for amount is fine; asserting the length or passing the SPL Token program id to getAccount is not. getCoinCreatorVaultBalance uses unpackAccount.
  • Trades on Token-2022-quoted pools use more compute than SPL-quoted ones. Set an explicit compute budget of roughly 250–300k CU for them.
  • The program validates the buyback fee recipient's quote ATA (the recipient's associated token account for the quote mint under the quote token program) but does not create it; the protocol fee recipient's ATA and the creator vault ATA are created on demand with the trader paying rent. Operators must provision the buyback recipients' ATAs for every new quote mint before the first trade, or every swap on that pool fails.
  • FeeConfig has three layouts. FEE_CONFIG_SIZE_PRE_STABLE (2512), FEE_CONFIG_SIZE_POST_STABLE (4073) and FEE_CONFIG_SIZE_POST_EXOTIC (4097) are the account lengths of each; PUMP_AMM_SDK.decodeFeeConfig reads only the fields the account's length carries, so older accounts decode with stableFeeTiers = [] and exoticFlatFees all zero.

Migration notes

  • Direct callers of buyBaseInput, buyQuoteInput, sellBaseInput, sellQuoteInput and computeFeesBps should pass quoteMint: pool.quoteMint, isMayhemMode: pool.isMayhemMode, virtualQuoteReserves: pool.virtualQuoteReserves and creatorFeeBps: pool.creatorFeeBps. Omitting quoteMint prices with the SOL schedule (byte-identical to earlier versions), which is wrong for USDC and other non-SOL pools; omitting creatorFeeBps prices with the schedule's creator rate, which is wrong for a pool with a configured creator fee. The PUMP_AMM_SDK builders pass them for you.
  • canonicalPumpPoolPda(mint, PublicKey.default) now derives the WSOL pool (it used to derive a pool that does not exist).
  • collectCoinCreatorFeeSolanaState, getCoinCreatorVaultBalance and PumpAmmAdminSdk.adminSetCoinCreator gained trailing quote-mint parameters that default to WSOL. collectCoinCreatorFee now creates missing vault and destination ATAs for non-SOL quotes too (it used to create them for wSOL only).

Configurable creator fee

A canonical pump pool can carry its own creator fee rate, Pool.creatorFeeBps, in place of the creator rate of the pump-fees schedule its trades would otherwise pay (the bonding curve the coin graduated from has the same field on the pump side). The rule, mirrored by computeFeesBps from pump-amm compute_fees:

  • GlobalConfig.creatorFeeConfigurable is a program-wide gate. While it is off, stored per-pool rates are neither accepted by the setters nor read by trades.
  • Pool.creatorFeeBps == 0 means "not configured": the schedule's creator rate applies. Any nonzero value replaces it. LP and protocol rates are never touched, and the has-coin-creator rule still zeroes the creator fee of a pool without one.
  • Cashback coins are excluded: the setters refuse a rate on a Pool.isCashbackCoin pool.
  • Editing is one-shot per CTO flip: admin_set_coin_creator_fee_editable (signed by GlobalConfig.adminSetCoinCreatorAuthority) sets Pool.canEditCreatorFee; one set_coin_creator_fee_bps by the coin creator then writes a rate in 1..=GlobalConfig.maxConfigurableCreatorFeeBps and clears the flag again.
  • When the coin creator is the coin's pump-fees SharingConfig (feeSharingConfigPda(baseMint), fee-sharing coins), the config's admin signs instead and the config is passed as remaining account 0 (it must be Active with the admin not revoked).
  • A new canonical pool receives the bonding curve's values through create_pool's trailing creator_fee_bps / can_edit_creator_fee arguments, passed by pump's migrate_v2 CPI (a canonical pool's creator is pump's pool-authority PDA, which signs only there). PUMP_AMM_SDK.createPoolInstructions creates permissionless pools, so it always encodes the two arguments as 0 / false and accepts { creatorFeeBps, canEditCreatorFee } only to keep the encoding aligned with the IDL: a nonzero / true value built through it fails on-chain with OnlyCanonicalPumpPoolsCanHaveCoinCreator.
import { PumpAmmAdminSdk } from "@pump-fun/pump-swap-sdk";

// Admin: turn the feature on (also grows the GlobalConfig account after the upgrade)
const adminSdk = new PumpAmmAdminSdk(connection);
const enable = await adminSdk.updateCreatorFeeConfig(true, new BN(500)); // max 5%

// CTO authority: let the creator of `poolKey` set the fee once
const [editable] =
  await onlineSdk.adminSetCoinCreatorFeeEditableInstructions(poolKey);

// Creator (or the SharingConfig admin): set 2.5%; rejects gate off / cashback / out of range
const [setFee] = await onlineSdk.setCoinCreatorFeeBpsInstructions(
  creator,
  poolKey,
  new BN(250),
);

// Offline equivalents
PUMP_AMM_SDK.setCoinCreatorFeeBpsInstruction({
  coinCreator,
  pool,
  creatorFeeBps,
  sharingConfig, // only when the coin creator is the SharingConfig PDA
});
PUMP_AMM_SDK.adminSetCoinCreatorFeeEditableInstruction({
  adminSetCoinCreatorAuthority,
  pool,
});

The PUMP_AMM_SDK swap builders price a configured pool correctly. Direct callers of the pure pricing functions and computeFeesBps pass creatorFeeBps: pool.creatorFeeBps; omitting it prices with the schedule, exactly as before.

Deploy-order caveat: accounts written before the upgrade are shorter (Pool 261 instead of POOL_SIZE = 270 bytes, GlobalConfig 940 instead of GLOBAL_CONFIG_SIZE = 949) and read as "not configured" (creatorFeeBps 0, canEditCreatorFee false, gate off). They keep trading, but program instructions that serialize the whole struct fail on them until they are grown: update_creator_fee_config and admin_set_coin_creator_fee_editable grow their own account (the signer pays the rent), and the PUMP_AMM_SDK swap and liquidity builders already prepend the permissionless extend_account when a pool is shorter than POOL_ACCOUNT_NEW_SIZE. decodePool, decodeGlobalConfig and PumpAmmAdminSdk.fetchGlobalConfigAccount read every historical length.

Migration notes (creator fee)

  • Pool gained creatorFeeBps: BN and canEditCreatorFee: boolean; GlobalConfig gained creatorFeeConfigurable: boolean and maxConfigurableCreatorFeeBps: BN. All four are required (the decoders always populate them), so hand-built literals need them.
  • Every create_pool instruction is 9 bytes longer: the two trailing arguments are always encoded, as 0 / false when unset. The deployed program ignores trailing instruction bytes; the upgraded one reads them.
  • PumpAmmAdminSdk.fetchGlobalConfigAccount returns the SDK GlobalConfig type (same field names as before) and reads pre-upgrade accounts; Anchor's raw fetch throws on them with this IDL.
  • CreatePoolEvent logs emitted before the two trailing fields existed no longer decode with the vendored IDL (the trailing bool is read past the end of the log). Append 9 zero bytes before decoding such historical logs; they then read creatorFeeBps 0 and canEditCreatorFee false.
  • With this IDL, Anchor's account resolver decodes a fetched Pool with the 270-byte layout, so a getPumpAmmProgram(connection).methods.*.accountsPartial({ pool }) call that leaves a pool-seeded account to Anchor (set_coin_creator's metadata / bonding_curve, migrate_pool_coin_creator's pool / sharing_config, a swap's coin_creator_vault_authority) fails on a pre-upgrade 261-byte pool with "Reached maximum depth for account resolution". Pass those accounts explicitly, or decode the pool with decodePool; every PUMP_AMM_SDK builder does.
  • PumpAmmSdk.setCoinCreator(pool, baseMint?) gained baseMint, from which it derives metadata and bonding_curve (metadataPda, bondingCurvePda); without it the call still needs a connection, which the offline program does not have. OnlinePumpAmmSdk.setCoinCreatorInstructions(poolKey, payer) reads the pool (any length) and prepends extend_account when it is not grown.
  • claim_cashback.user_wsol_token_account lost its ATA constraint in the IDL (any token account of the quote mint owned by the user); accountsPartial callers must now pass it explicitly. No builder in this SDK uses claimCashback.

License

MIT

Links