Skip to content

1000xsh/swaps

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

swaps

solana swap-instruction lib for direct DEX integrations. swaps tells you which accounts to read and builds a stack-backed instruction view from those account bytes.

the instruction output is stack-backed and allocation-free.

flow

use swaps::{InstructionBuf, SwapRequest};
use swaps::addresses::WSOL;
use swaps::dex::DexKind;

let req = SwapRequest::new(
    DexKind::PumpFun,
    user,
    /* token_in */ WSOL,
    /* token_out */ pumpfun_mint,
    /* amount_in */ 1_000_000,
    /* min_amount_out */ 0,
);

let initial_plan = swaps::fetch_plan(&req);
let initial_keys: Vec<_> = initial_plan.addresses().copied().collect();
let initial_data: Vec<Vec<u8>> = my_rpc.get_multiple_accounts(&initial_keys).await?;

let followup_data = match swaps::followup_keys(&req, &initial_data)? {
    Some(plan) => {
        let keys: Vec<_> = plan.addresses().copied().collect();
        my_rpc.get_multiple_accounts(&keys).await?
    }
    None => Vec::new(),
};

let snap = swaps::decode_snapshot(&req, &initial_data, &followup_data)?;
let mut buf = InstructionBuf::new();
swaps::build_swap(&req, &snap, &mut buf)?;
let ix = buf.as_view();

decode_snapshot accepts any AsRef<[u8]> account buffer, so callers can pass Vec<Vec<u8>>, arrays of account data, or manually built &[&[u8]] without allocating an intermediate refs vector.

InstructionBuf::as_view() is allocation-free and returns borrowed account and data slices. lib/rpc boundary conversion is caller-owned.

instruction output

the hot path is:

let snap = swaps::decode_snapshot(&req, &initial_data, &followup_data)?;
let mut buf = swaps::InstructionBuf::new();
swaps::build_swap(&req, &snap, &mut buf)?;
let ix = buf.as_view();

ix is an InstructionView<'_>:

  • program_id: Address
  • accounts: &[swaps::AccountMeta]
  • data: &[u8]

this view borrows from InstructionBuf; it does not allocate or copy the account/data arrays. use it directly if your transaction compiler, packet encoder, or arena owns the final serialization step.

request model

a SwapRequest describes a swap as token_in -> token_out.

  • dex: one DexKind variant for the target DEX.
  • user: payer, signer, and token-account owner.
  • token_in, token_out: mint addresses. DEX modules infer direction by matching these against pool state.
  • pool: required for pool/market based DEXes, omitted for PumpFun bonding curves.
  • amount_in, min_amount_out: caller-provided amounts. the lib does not quote or guess slippage.
  • track_volume: PumpFun/PumpSwap volume-tracking option, default Some(true).
  • token_in_program, token_out_program: default classic SPL Token; override for Token-2022 when the DEX uses request-side token programs.
  • scorch_swap_id_le: scorch/jupiter route swap id bytes, set with with_scorch_swap_id_le_bytes.

builder methods: with_pool, with_track_volume, with_token_programs, with_scorch_swap_id_le_bytes.

PumpFun uses WSOL only as the API marker for the native SOL side. the on-chain PumpFun instruction uses raw lamports.

fetch rounds

most DEXes are one-round: fetch the initial plan, pass empty follow-up data, decode and build.

two-round dexes:

dex initial fetch follow-up fetch
Raydium AMM v4 AMM info OpenBook market from AMM state
Meteora Pools DAMM v1 pool Two linked Meteora vault accounts
Meteora DBC Virtual pool Pool config account
Stabble stable swap Pool Linked Stabble vault account
Stabble weighted swap Pool Linked Stabble vault account
Jupiter Perps Pool Linked custody accounts

one-round DEXes include PumpFun, PumpSwap, Raydium CLMM/CPMM/Launchpad, Orca Whirlpool, Meteora DAMM v2/DLMM, Bonkswap, HumidiFi, SolFi V2, PancakeSwap, Byreal, Fusion AMM, GooseFX Gamma, Tessera V1, Obric, BisonFi, and Scorch.

supported features

all DEX features are enabled by default:

[dependencies]
swaps = { path = "../swaps", default-features = false, features = ["pumpfun"] }

available features: pumpfun, pumpswap, raydium-amm-v4, raydium-clmm, raydium-cpmm, raydium-launchpad, orca-whirlpool, meteora-pools, meteora-damm-v2, meteora-dlmm, meteora-dbc, bonkswap, humidifi, stable-swap, stabble-weighted-swap, solfi-v2, pancakeswap, byreal, fusion-amm, goosefx-gamma, jupiter-perps, tessera-v1, obric, bisonfi, and scorch.

notes

see notes.md for protocol quirks, known limitations and reverse-engineered adapter details that callers may need to account for.

testing

cargo test --all-features
cargo clippy --all-features --all-targets -- -D warnings

benchmarks

cargo bench --bench hot_path
SWAPS_BENCH_ITERS=2000 cargo bench --bench hot_path

the hot-path bench reports mean, p50, p95, p99, max latency and allocation counts for stack-backed instruction building + PDA-heavy fetch/build paths.

license

MIT

About

solana swap instructions sdk

Topics

Resources

Stars

Watchers

Forks

Contributors

Languages