Sync supported DEX IDLs from bitquery/solana-idl-lib, upgrade protocol builders, and keep trade submission hot paths free of RPC query calls.
Include exact-output coverage, token-account setup fixes for WSOL and stable pairs, and low-latency transaction build improvements.
The patched solana-keypair in the main workspace adds try_from_base58_string,
but sol-safekey and other consumers use the standard crates.io version which
only provides from_base58_string (panics) and TryFrom<&[u8]> (fallible).
Use bs58::decode + Keypair::try_from to keep proper error handling while
remaining compatible with the standard solana-keypair crate.
BondingCurveAccount::try_from_slice requires the entire input slice to
be consumed, which fails with "Not all bytes read" when the on-chain
bonding curve account has been extended with new fields (e.g. after a
protocol upgrade). Switch to BorshDeserialize::deserialize which reads
the known fields and silently ignores any trailing bytes.
In build_sell_v1/v2, the creator_vault was previously derived via
effective_creator_for_trade() passed to resolve_creator_vault_for_ix_with_fee_sharing.
When observed_trade_creator differs from bonding_curve.creator (e.g. creator
updated post-deployment), the derived vault PDA mismatches the on-chain
seeds constraint, causing Anchor error 2006 (ConstraintSeeds) on sell.
The pump.fun sell instruction validates creator_vault seeds as
PDA("creator-vault", bonding_curve.creator), but buy does not check seeds,
so buy succeeds while sell fails with 2006.
Fix: when protocol_params.creator_vault is a valid non-default/non-phantom
value (observed from gRPC / update_fee_shares), use it directly without
re-derivation. Only fall back to resolve via bonding_curve.creator when
creator_vault is missing. This ensures the authoritative observed vault
is never overridden by a stale or mismatched creator.
The Pump.fun IDL explicitly states that user_volume_accumulator is
passed as remaining_accounts[0] for cashback coins during sell.
Using is_mayhem_mode incorrectly omitted the account for cashback
tokens, causing the program to misread bonding_curve_v2 as
user_volume_accumulator and resulting in Custom(6024) Overflow.
- Replace compile-time `pumpfun-v2` feature flag with runtime
`TradeConfig::use_pumpfun_v2(bool)` for flexible V1/V2 switching
- Fix BUYBACK_FEE_RECIPIENTS pool: replace wrong addresses (was reusing
standard pool + FEE_CONFIG) with official buyback pool from
FEE_RECIPIENTS.md
- Fix legacy buy/buy_exact_sol_in ix data encoding: use 2-byte
Option<bool> (option tag + value) matching official Pump SDK, 26 bytes
total instead of broken 25
- Add `SwapParams.use_pumpfun_v2` field and wire through TradingClient
buy/sell paths
- V2 instructions read `quote_mint` from `PumpFunParams` (not
BondingCurveAccount which lacks the field)
- Fix `fetch_bonding_curve_account` to use BorshDeserialize instead of
non-existent `decode_from_chain_account_data`
- Update all examples with `use_pumpfun_v2: false` field
- Update README with unified V1/V2 section showing both enabling methods
Remove non-partner services (Nextblock, ZeroSlot, Bloxroute, Node1).
Update code examples to use partner service configs.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The refactored ix data encoder was producing 25-byte buy instructions
(1-byte track_volume), but the on-chain Pump program expects Anchor's
2-byte Option<bool> encoding (option tag + value), totaling 26 bytes.
The 1-byte shortfall caused instruction data under-read that manifested
as error 0xbbf (ConstraintOwner) for all legacy buy/buy_exact_sol_in.
Restore the 2-byte encoding: option tag (1u8) followed by the cashback
flag as the bool value, matching the pre-refactoring inline encoder.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The `effective_pump_mint_token_program` helper was defaulting to
TOKEN_PROGRAM_2022 when `token_program` was Pubkey::default(), causing
Anchor error 0xbbf (account owned by wrong program) for all legacy
PumpFun coins whose ATAs are owned by the original Token Program.
Fall back to TOKEN_PROGRAM (legacy) when no explicit token program is
provided. Token-2022 must be set explicitly for create_v2 coins.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- resolve_creator_vault_for_ix_with_fee_sharing uses non-placeholder ix vault as-is.
- When ix vault missing, fall back to fee_sharing_creator_vault_if_active then PDA(creator).
- Add Pump troubleshooting CN doc; extend PumpFunParams field documentation.
- Bump to v4.0.7.
Co-authored-by: Cursor <cursoragent@cursor.com>
Adds pumpfun_ix_data / pumpswap_ix_data; exports used by trading::core::params::PumpFunParams.
chore(release): bump version to 4.0.6
Co-authored-by: Cursor <cursoragent@cursor.com>
calculate_with_slippage_sell previously fell through to the branch that
returned 1 when amount <= basis_points/10_000, which is true for amount=0
and typical bps values—yielding a bogus minimum of 1. Short-circuit on
zero input so sell quotes stay correct.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Append pool-v2 in buy/sell remaining accounts only when pool coin_creator
is not default, matching @pump-fun/pump-swap-sdk. Always appending pool-v2
shifted buyback pubkey/ATA and caused BuybackFeeRecipientNotAuthorized (6053).
- Add coin_creator to PumpSwapParams (filled from decoded Pool / from_trade).
Update pumpswap_trading example to pass pool_data.coin_creator.
- Document buyback fee recipient constants against GlobalConfig.buyback_fee_recipients.
- Extend PumpSwap quote math to include cashback_fee_basis_points in creator-side fees.
Co-authored-by: Cursor <cursoragent@cursor.com>
fix(swqos): extend parallel-submit wait/grace windows for late HTTP responses
- Scale primary submit timeout with configured channel count (clamped 3–5s)
- After primary expiry, optionally poll longer so slow providers still land before drain
- Short settle sleeps to reduce counter vs TaskResult races and dropped signatures when
wait_transaction_confirmed is false
Co-authored-by: Cursor <cursoragent@cursor.com>
- PumpFun buy/sell: append bonding-curve-v2 and random extra fee recipient (writable)
- PumpSwap buy/sell: append pool-v2, protocol fee pubkey, and fee quote mint ATA
- Keep utils helpers and constants aligned with on-chain layout (2026-04 upgrade)
Made-with: Cursor
- Enable quinn feature runtime-tokio so QUIC clients (Speedlanding/Soyas) initialize instead of failing with "no async runtime found".
- Align Speedlanding with the official client: use solana_tls_utils new_dummy_x509_certificate and SkipServerVerification; use fixed TLS SNI "speed-landing" (not the PoP hostname).
- Raise per-SWQoS init timeout to 15s; always log init failures/timeouts; if every SWQoS client fails, fall back to Default RPC and print active channel labels.
- Improve SWQoS submission visibility (Default RPC path and related logging); adjust Soyas TLS credential handling where applicable.
Made-with: Cursor
- Pass token_a/token_b program based on swap direction (is_a_in) when
creating the output mint ATA in buy flow, matching ATA address derivation
for SPL Token vs Token-2022 mints.
- Resolve token_a_program and token_b_program from on-chain mint account
owners in MeteoraDammV2Params::from_pool_address_by_rpc instead of
hardcoding the classic SPL Token program.
Fixes incorrect ATA creation for Token-2022 output mints (issue #99).
Made-with: Cursor
- Extend SWQOS regional constants to 10 entries (Dublin, Singapore, Default)
so indices match SwqosRegion 0..9 everywhere
- Document geographic nearest-fill among published PoPs; call out Default and
single-PoP provider constraints in comments
- Fix Node1 QUIC Default endpoint to match HTTP; tune ZeroSlot/Blox/Speedlanding
regional mappings where a closer published PoP exists
- Add unit tests for table length and Astralane/Node1 cross-table consistency
- Update SwqosRegion rustdoc, README, and trading_client example accordingly
Made-with: Cursor
- Always derive bonding curve and associated bonding vault from mint (avoids stale cached PDAs / wrong pool).
- Use non-default fee_recipient from parser/stream as account #2 without extra authorization filtering (addresses Pump 6000 NotAuthorized when event fee was rejected).
- Rework resolve_creator_vault_for_ix: default-creator cases, phantom default PDA, fee-sharing vault; add unit tests.
- PumpFunParams: respect explicit mayhem_mode from events; fallback creator_vault via get_creator_vault_pda when resolve returns None.
- Remove unused lazy_static tip-cache stub and lazy_static dependency.
Made-with: Cursor
- Add get_fee_sharing_config_pda per @pump-fun/pump-sdk (sharing-config + mint under pump-fees)
- resolve_creator_vault_for_ix now takes mint: accept gRPC creator_vault when it matches either
PDA(creator) or PDA(fee_sharing_config(mint)) for migrated / fee-sharing bonding curves
- Mayhem uses the same Pump buy/sell account layout (IDL); Token-2022 + fee pool differ, not creator_vault seeds
Made-with: Cursor
- Add resolve_creator_vault_for_ix: use gRPC creator_vault only when it matches
PDA(['creator-vault', bonding_curve.creator]); on mismatch use derived PDA to
avoid ConstraintSeeds (2006) from stale/wrong stream vaults
- pump_fun_fee_recipient_meta: only use event fee_recipient if authorized for
is_mayhem_mode (avoids 6000 NotAuthorized when standard AMM fee is used on
Mayhem coins)
- Align PumpFunParams::from_trade/from_dev_trade cached creator_vault with the
same resolution logic
Made-with: Cursor
- Use protocol_params.creator_vault for buy/sell when non-default to avoid
ConstraintSeeds (2006) when gRPC/event creator drifts from on-chain bonding curve
- Preserve event creator_vault in PumpFunParams::from_trade/from_dev_trade instead
of always overwriting with PDA(creator)
- Fee recipient: prefer gRPC fee_recipient; else random from CURRENT_FEE_RECIPIENTS
pool (standard) or MAYHEM pool, matching @pump-fun/pump-sdk fees.ts
- Add cold-path helpers: extend_bonding_curve_account_instruction, PUMP_BONDING_CURVE_MIN_DATA_LEN
Made-with: Cursor
- PumpFunParams::from_trade/from_dev_trade: add mayhem_mode Option; infer Mayhem
via is_mayhem_fee_recipient when None (fixes fee recipient / NotAuthorized 6000
when AMM protocol fee pubkey is used).
- Add is_mayhem_fee_recipient and is_amm_fee_recipient helpers in pumpfun utils.
- Bump solana-* crates to 3.1.12; align tonic/prost; use solana-message for
AddressLookupTableAccount; add solana-system-interface 3.0.
- Update examples and latency script for new PumpFunParams signature.
- SWQoS and transaction builder adjustments for dependency changes.
Made-with: Cursor
These incomplete SDK implementations in the Rust repository were outdated
and redundant. The complete versions are maintained in separate repositories:
- sol-trade-sdk-ts (Node.js)
- sol-trade-sdk-python (Python)
🤖 Generated with [Qoder](https://qoder.com)
- Add `mev_protection: bool` to `TradeConfig` and `InfrastructureConfig` (default: false)
- Astralane QUIC: switches to port 9000 (MEV-protected endpoint) when enabled
- BlockRazor HTTP: uses `mode=sandwichMitigation` query param when enabled
- BlockRazor gRPC: uses `mode=sandwichMitigation` when enabled
- Add `SWQOS_ENDPOINTS_ASTRALANE_QUIC_MEV` constants (port 9000) to `constants/swqos.rs`
- Fix `astralane_quic.rs` IP candidates to use the actual port from the address (supports both 7000 and 9000)
- Refactor `TradeConfig` to builder pattern via `TradeConfig::builder()`
- Introduce `TradeConfigBuilder` with all optional fields and clear defaults
- `TradeConfig::new()` kept as a shortcut (calls `builder().build()`) for backward compatibility
- Remove old `with_wsol_ata_config` / `with_check_min_tip` / `with_swqos_cores_from_end` / `with_mev_protection` chain methods
- Update all 16 examples to use `TradeConfig::builder()` with commented-out options so users can discover all available settings at a glance
- Update README.md and README_CN.md code snippets to use builder pattern
🤖 Generated with [Qoder][https://qoder.com]
Changes to src/utils/calc/common.rs:
- Add MAX_SLIPPAGE_BASIS_POINTS constant (9999 = 99.99%)
- Clamp basis_points in calculate_with_slippage_buy to prevent amount doubling
Changes to src/instruction/pumpswap.rs:
- Fix WSOL wrap amount calculation for exact vs non-exact input modes
- Use input_amount for exact mode, sol_amount for non-exact mode
🤖 Generated with [Qoder][https://qoder.com]
- Store gRPC client as Arc<ArcSwap<BlockRazorGrpcClient>> so BlockRazorBackend
can derive Clone (ArcSwap does not implement Clone).
- Cloning the outer Arc gives owned handles for tokio::spawn in start_ping_task,
fixing E0521 (borrowed self escaping to 'static future).
Made-with: Cursor