Skip to content

Latest commit

 

History

19 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

prism-client-sdk

Self-contained Rust builders for Prism find_arb_v2 and find_arb_v3 instructions.

Prism is an on-chain Solana arbitrage execution program with a just-in-time routing engine. Callers submit a pool menu plus the required market accounts in a fully specified instruction; at execution time, Prism reads those supplied pools on-chain, finds an executable route across them, automatically chooses the swap input amount to maximize value for the submitted arb opportunity, and executes it through the supported DEX programs. The live program is Prism8hsRo6Ww5jiN5Zeh3YDPLZHqHduCPSAV7JF7qv. Use find_arb_v2 for direct walk-depth control. V3 accepts the same pool menus and adds budget-based sizing when the winning candidate is Pump/DLMM.

image

This crate is intentionally narrow. Callers must provide every account pubkey from their own indexer, parser, cache, or configuration. The SDK does not fetch accounts, discover pools, create ATAs, infer markets, send transactions, choose lookup tables, manage compute budget, or validate account-lock limits.

Contents

Supported Programs

DEX Program ID
Raydium v4 675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8
Raydium CP CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C
Raydium CLMM CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK
Whirlpool whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc
Meteora DLMM LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo
Meteora DAMM V2 cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG
Meteora Pools Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB
PumpfunAmm pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA
PancakeSwap HpNfyc2Saw7RKkQd8nEL4khUcuPhQ7WwY1B2qjx8jxFq
Byreal REALQqNEomY6cQGZJUGwywTBD2UmDT32rZcNnfxQ5N2
Humidifi 9H6tua7jkLhdm3w8BvgpTn5LZNU7g4ZynDmCiNN3q6Rp
Manifest MNFSTqtC93rEfYHB6hF82sKdZpUDFWkViLByLd1k1Ms
AlphaQ ALPHAQmeA7bjrVuccPsYPiCvsi428SNwte66Srvs4pHA
GoonFi v2 (SPL Token / Token-2022) goonuddtQRrWqqn5nFyczVKaie28f3kDkHWkHtURSLE
SolFi v2 SV2EYYJyRz2YhfXwXnhNAevDEui5Q6yrfyo13WtupPF
Futarchy FUTARELBfJfQ8RDGhg1wdhddq1odMAJUePHFuBYfUxKq
Fusion fUSioN9YKKSa3CUC2YUc4tPkHJ5Y6XW1yz8y6F7qWz9
BisonFi BiSoNHVpsVZW2F7rx2eQ59yQwKxzU5NvBcmKshCSUypi
Tessera TessVdML9pBGgG9yGks7o4HewRaXVAMuoVj4x83GLQH
ZeroFi ZERor4xhbUycZ6gb9ntrhqscUcZmAbQDjEAtCf4hbZY

Route Shape

find_arb_v2 and find_arb_v3 support up to 3-hop arbitrage. They do not build or execute routes with more than three swap legs.

The base mint and route_mints fields have the same meaning for both shapes. base is the cycle's base token, and route_mints contains every non-base mint the submitted pool graph may touch. For a 2-hop route, that is usually one target mint. For a 3-hop route, include both non-base mints in the triangle.

pools is an unordered pool menu, not an ordered route. Prism reads each pool's endpoint mints on-chain, builds the candidate graph, and chooses the executable route order itself. Pools that touch base can become direct edges for 2-hop routes. Pools that do not touch base, but connect two submitted route_mints, can become the middle bridge edge of a 3-hop route. Submitting bridge pools for possible 3-hop routes does not disable 2-hop evaluation; Prism evaluates direct 2-hop candidates from the same pool menu when matching base-touching pools are present. The order of pools only controls instruction serialization; it does not force route execution order.

Rust Examples

The SDK does no account discovery. With the required pubkeys in scope, put them into the typed parameters:

V2: manual walk depth

In V2, max_dynamic_walk_steps controls dynamic liquidity walks on the selected route. It caps Meteora DLMM bin scans and Raydium CLMM, Orca Whirlpool, PancakeSwap, and Byreal tick-walk steps per direction; constant-product pools do not use it. Higher values can reach deeper liquidity but use more compute, while lower values save compute but can miss deeper routes.

use prism_client_sdk::{
    build_find_arb_v2_instruction, FindArbV2Params, MintAccount,
    markets::{
        meteora::MeteoraDlmmAccounts,
        raydium::{RaydiumCpAccounts, RaydiumV4Accounts},
        MarketAccounts,
    },
};
use solana_pubkey::Pubkey;

const WSOL_MINT: Pubkey = Pubkey::from_str_const("So11111111111111111111111111111111111111112");
const USDC_MINT: Pubkey = Pubkey::from_str_const("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
const TRUMP_MINT: Pubkey = Pubkey::from_str_const("6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN");
const SPL_TOKEN: Pubkey = Pubkey::from_str_const("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");

let ix = build_find_arb_v2_instruction(FindArbV2Params {
    signer,
    base: MintAccount {
        mint: WSOL_MINT,
        token_program: SPL_TOKEN,
        user_ata: wsol_user_ata,
    },
    flashloan: true,
    fail_if_no_profit: true,
    min_profit_base_units: 10_000,
    max_dynamic_walk_steps: 12,
    route_mints: vec![MintAccount {
        mint: USDC_MINT,
        token_program: SPL_TOKEN,
        user_ata: usdc_user_ata,
    }],
    pools: vec![
        MarketAccounts::RaydiumV4(RaydiumV4Accounts {
            pool_state: Pubkey::from_str_const("58oQChx4yWmvKdwLLZzBi4ChoCc2fqCUWBkwMihLYQo2"),
            coin_vault: Pubkey::from_str_const("DQyrAcCrDXQ7NeoqGgDCZwBvWDcYmFCjSb9JtteuvPpz"),
            pc_vault: Pubkey::from_str_const("HLmqeL62xR1QoZ1HKKbXRrdN1p3phKpxRMb2VVopvBBz"),
        }),
        MarketAccounts::RaydiumCp(RaydiumCpAccounts {
            pool_state: Pubkey::from_str_const("47hq28mcL7q5GhBg7epyGF2dnuJd4MKFt8QhT7CzYUp4"),
            amm_config: Pubkey::from_str_const("BgxH5ifebqHDuiADWKhLjXGP5hWZeZLoCdmeWJLkRqLP"),
            token_0_vault: Pubkey::from_str_const("9tAoQUNB1wKnBSUyc6ukg2pWbeofZJVHxur2UaRBZNZc"),
            token_1_vault: Pubkey::from_str_const("BArWLNarRzS7N1GCwBjNgVnC4866c8oJNRqhb5axf6y4"),
            token_0_mint: WSOL_MINT,
            token_1_mint: USDC_MINT,
            observation_state: Pubkey::from_str_const("AwXcFysn5vntDyiGo9hXDhTMFSg2in7hxj8ED51oZgqo"),
        }),
    ],
})?;

This builds a two-pool menu for a 2-hop candidate. The SDK assembles the instruction; the caller chooses pools whose endpoint mints match base and route_mints.

V3: budget-based walk sizing

V3 accepts every pool menu supported by V2. When the winning candidate is Pump/DLMM, Prism uses the explicit CU budget to size its DLMM walk. Other winners use max_dynamic_walk_steps.

use prism_client_sdk::{
    build_find_arb_v3_instruction, FindArbV3Params,
    markets::{
        meteora::MeteoraDlmmAccounts,
        pumpfun::PumpfunAmmAccounts,
        raydium::RaydiumCpAccounts,
        MarketAccounts,
    },
};

let ix = build_find_arb_v3_instruction(FindArbV3Params {
    signer,
    base,
    flashloan: true,
    fail_if_no_profit: true,
    min_profit_base_units: 10_000,
    max_dynamic_walk_steps: 12,
    prism_cu_budget: 320_000,
    route_mints,
    pools: vec![
        MarketAccounts::PumpfunAmm(PumpfunAmmAccounts { /* ... */ }),
        MarketAccounts::RaydiumCp(RaydiumCpAccounts { /* ... */ }),
        MarketAccounts::MeteoraDlmm(MeteoraDlmmAccounts { /* ... */ }),
    ],
})?;

V2 and V3 accept the same account prefix and unordered pool menu. Both support 2-hop and 3-hop routes.

Three-hop pool menu

For either builder, a 3-hop candidate supplies both non-base mints and three markets that form BASE ↔ A ↔ B ↔ BASE:

let route_mints = vec![
    MintAccount {
        mint: USDC_MINT,
        token_program: SPL_TOKEN,
        user_ata: usdc_user_ata,
    },
    MintAccount {
        mint: TRUMP_MINT,
        token_program: SPL_TOKEN,
        user_ata: trump_user_ata,
    },
];

let pools = vec![
    // WSOL ↔ USDC
    MarketAccounts::RaydiumV4(RaydiumV4Accounts { /* ... */ }),
    // USDC ↔ TRUMP (the bridge market)
    MarketAccounts::MeteoraDlmm(MeteoraDlmmAccounts { /* ... */ }),
    // TRUMP ↔ WSOL
    MarketAccounts::MeteoraDlmm(MeteoraDlmmAccounts { /* ... */ }),
];

The pool entries remain unordered; their mint connectivity determines the executable route.

Instruction Data

V2

V2 uses max_dynamic_walk_steps as the caller's walk-depth request.

[7, flags, max_dynamic_walk_steps, num_mints, num_pools, min_profit_base_units_le_u64, market_ids...]

V3

V3 supports the same pools and account metas as V2, and adds a nonzero Prism CU budget. The budget sizes the DLMM walk only when the winning candidate is Pump/DLMM; other winners use max_dynamic_walk_steps.

[11, flags, max_dynamic_walk_steps, num_mints, num_pools, min_profit_base_units_le_u64, prism_cu_budget_le_u32, market_ids...]

prism_cu_budget is for the Prism instruction alone, not the transaction CU limit:

prism_cu_budget =
    requested_transaction_cu_limit
  - conservative_reserve_for_all_non_prism_instructions
  - caller_transaction_margin

The caller chooses the reserve and margin. The SDK only validates that the budget is nonzero and serializes it.

min_profit_base_units is denominated in the submitted base mint's atomic units. For WSOL this is native lamports. For USDC, USDT, and USD1 it is 6-decimal token units; callers that use a native SOL lander tip must convert that tip value into base units before building the instruction.

Flags:

bit 0: flashloan
bit 1: fail_if_no_profit

num_mints must be non-zero. The route mint list must not contain the base mint and must not contain duplicate mint pubkeys. The SDK does not expose Prism's high internal safety caps as client-side routing limits.

Settlement Accounts

Prism has one vault authority:

VAULT_AUTH = PDA([b"vault_auth", WSOL_MINT], PRISM_PROGRAM_ID)
           = 6jM8tJbomfcjgP343TsT13duo7bxvEVq5jftjPytDq6M

Prism supports four SPL Token base mints for settlement: WSOL, USDC, USDT, and USD1. Any other base mint is rejected before route execution.

Flashloan mode is available only for WSOL and USDC base mints. The vault account is the SPL-token ATA owned by VAULT_AUTH for the selected base mint:

WSOL vault = ATA(VAULT_AUTH, WSOL_MINT, SPL_TOKEN)
           = AsnFKUNo4oXzHuu91WTgB2mUT1bcsx9kKyurhAyeur56

USDC vault = ATA(VAULT_AUTH, USDC_MINT, SPL_TOKEN)
           = ApvRzpyA7EXKqGaZ78JPXyjyFUFTqRaSDenPj95dPows

When flashloan = true, the SDK emits the selected vault ATA plus VAULT_AUTH in the account prefix. Prism borrows the current vault balance into the signer's base ATA, executes the selected route, then transfers principal plus protocol fee from the signer's base ATA back into the same vault. That means successful flashloan fees accrue directly in the WSOL or USDC flashloan vault.

When flashloan = false, there is no vault authority account in the prefix. FEE_OWNER is the same pubkey as VAULT_AUTH, and the SDK emits only the writable fee recipient ATA:

WSOL fee ATA = ATA(FEE_OWNER, WSOL_MINT, SPL_TOKEN)
             = AsnFKUNo4oXzHuu91WTgB2mUT1bcsx9kKyurhAyeur56

USDC fee ATA = ATA(FEE_OWNER, USDC_MINT, SPL_TOKEN)
             = ApvRzpyA7EXKqGaZ78JPXyjyFUFTqRaSDenPj95dPows

USDT fee ATA = ATA(FEE_OWNER, USDT_MINT, SPL_TOKEN)
             = 9a76tENsmkTumYbA46r6FD9raFb74RKNcJ4ey4R61gwt

USD1 fee ATA = ATA(FEE_OWNER, USD1_MINT, SPL_TOKEN)
             = Egv1XeHAL4LxU59jDgQm3Q7jeqAm5SSyq8xGjEdHDZzh

This non-flashloan path supports WSOL, USDC, USDT, and USD1. The transfer is fee-only; no principal is repaid because Prism did not borrow from a vault.

Prism charges a 10% protocol fee only on realized profit from profitable arbitrage. The fee is paid through the selected flashloan vault or non-flashloan fee-recipient ATA. Failed attempts and attempts where Prism finds no profitable route do not pay this protocol fee.

The SDK computes these addresses internally. It also exposes prism_flashloan_vault_accounts(base_mint), prism_fee_recipient_ata(base_mint, base_token_program), prism_base_mint_supported(base_mint), and associated_token_address(owner, mint, token_program) for callers that want to inspect or pre-create the same accounts.

Account Prefix

Base prefix:

0 signer                 writable signer
1 base user ATA          writable
2 base mint              readonly
3 base token program     readonly

Flashloan prefix appends:

4 Prism base vault ATA   writable
5 Prism base vault auth  readonly

Non-flashloan prefix appends:

4 Prism fee ATA          writable

The flashloan prefix supports WSOL and USDC. The non-flashloan prefix supports WSOL, USDC, USDT, and USD1.

Each route mint appends:

token program            readonly
user ATA                 writable

Market IDs

0  RaydiumV4
1  RaydiumCp
2  RaydiumClmm
3  OrcaWhirlpool
5  MeteoraDammV2
6  MeteoraPools
7  PumpfunAmm
8  Pancakeswap
9  MeteoraDlmm
10 RaydiumClmmT22
11 PancakeswapT22
12 OrcaWhirlpoolT22
13 ByrealClmm
14 ByrealClmmT22
15 HumidifiSwapV2
16 HumidifiSwap
17 Manifest
18 AlphaQ
19 AlphaQT22
20 GoonfiV2
21 SolfiV2
22 FutarchySpot
23 Fusion
24 BisonFi
25 Tessera
26 ZeroFi
28 GoonfiV2T22
29 ByrealDynamic

These are wire IDs emitted by this SDK. Legacy DLMM wire ID 4 is intentionally not exposed: MeteoraDlmm always emits wire ID 9 and the 16-account swap2 layout, including for SPL/SPL pools. The deprecated MarketAccounts::MeteoraDlmmT22 and MarketId::MeteoraDlmmT22 names remain source aliases for the same wire ID 9 and layout; they do not emit ID 4.

Market Accounts

Callers pass FindArbV2Params or FindArbV3Params with pools: Vec<MarketAccounts>, where MarketAccounts lives under prism_client_sdk::markets. Each variant wraps a market-specific struct from its family module, such as markets::raydium::RaydiumV4Accounts or markets::meteora::MeteoraDlmmAccounts, with only the dynamic pubkeys the caller must know. The SDK derives the wire market ID, inserts Prism's fixed program IDs, authorities, sysvars, event authorities, and token-program constants, then emits the full remaining-account list in Prism's order with the correct writable/readonly flags.

There is no separate market id field to keep in sync with a raw pubkey slice. If the variant is MarketAccounts::RaydiumV4, the instruction data receives market id 0 and the Raydium v4 account layout is emitted.

The following paired families use one caller-facing variant for SPL Token and Token-2022 pools:

MarketAccounts::RaydiumClmm
MarketAccounts::OrcaWhirlpool
MarketAccounts::MeteoraDlmm
MarketAccounts::Pancakeswap
MarketAccounts::ByrealClmm
MarketAccounts::AlphaQ
MarketAccounts::GoonfiV2

Supply both endpoint mint addresses and their exact token program IDs in the account struct. DLMM validates both IDs but always emits its swap2 wire ID and slice. For the other paired families, both SPL Token programs select the normal wire ID and either Token-2022 program selects the T22 wire ID and slice. AlphaQ is narrower: it supports SPL/SPL and Token-2022-left/SPL-right only. Unsupported program IDs and unsupported AlphaQ orientations return BuildError.

This selection is deterministic and performs no RPC calls. The caller remains responsible for reading the mint owners or otherwise supplying the correct token program IDs. MarketAccounts::try_market_id() and try_account_count() expose the same checked resolution used by both arb builders; invalid token programs never produce a public wire ID or count.

The remaining explicit MarketAccounts::*T22 variants are temporarily available as deprecated compatibility aliases. The deprecated MeteoraDlmmT22 alias accepts either SPL or Token-2022 programs and resolves to the canonical ID 9 Swap2 layout. Other checked aliases reject an all-SPL selection, and AlphaQT22 specifically requires Token-2022-left/SPL-right. The legacy RaydiumClmmT22Accounts, PancakeswapT22Accounts, and ByrealClmmT22Accounts structs do not carry token-program fields, so those three aliases retain forced-T22 behavior that the SDK cannot validate from their inputs.

Documented optional placeholders are represented as Option<Pubkey>:

MeteoraDlmmAccounts.host_fee_in
  None emits the DLMM program id placeholder.

MeteoraDammV2Accounts.instructions_sysvar_or_program_sentinel
  Some(SYSVAR_INSTRUCTIONS) for rate-limiter pools.
  None emits the DAMM v2 program id sentinel.

PumpfunAmmAccounts.user_volume_accumulator_wsol_ata
  Some(account) for cashback pools.
  None emits the Pumpfun AMM program id placeholder.

PumpfunAmmAccounts.pool_v2
  Some(account) for creator-feature pools.
  None emits the Pumpfun AMM program id placeholder.

CLMM current tick-array placeholder:

RaydiumClmm, Pancakeswap, and ByrealClmm also accept the family's DEX program id in tick_array_cur. Use this only after checking that the mathematical current tick-array PDA does not exist, or when another supplied tick-array slot intentionally carries the first valid tick array for the swap direction. tick_array_prev and tick_array_next must not be program-id placeholders; any slot Prism may use as the first CPI tick array must be a loadable tick-array account.

All other fields are required. The SDK does not invent dynamic pool accounts, derive user ATAs, discover token programs, choose tick arrays, check tick-array existence, or fetch state. It only selects a wire layout from the token programs the caller supplied.

Emitted Pool Slices

The SDK emits each pool as one contiguous account slice. The slice order must match the MarketAccounts variant order in FindArbV2Params.pools or FindArbV3Params.pools, because Prism slices the remaining accounts by the emitted market_ids.

Legend:

W   writable
    read-only
SDK constant  inserted by the SDK
caller        supplied through the typed account struct

Raydium V4

0  W   pool_state                         caller
1      Raydium v4 authority               SDK constant
2  W   coin_vault                         caller
3  W   pc_vault                           caller
4      Raydium v4 program                 SDK constant

Raydium CP

0  W   pool_state                         caller
1      amm_config                         caller
2      Raydium CP vault authority         SDK constant
3  W   token_0_vault                      caller
4  W   token_1_vault                      caller
5      token_0_mint                       caller
6      token_1_mint                       caller
7  W   observation_state                  caller
8      Raydium CP program                 SDK constant

CLMM Base

Used by RaydiumClmm, Pancakeswap, and ByrealClmm.

0      amm_config                         caller
1  W   pool_state                         caller
2  W   token_vault_0                      caller
3  W   token_vault_1                      caller
4  W   observation_state                  caller
5      SPL Token program                  SDK constant
6      DEX program                        SDK constant for variant
7  W   tick_array_bitmap_ext              caller
8  W   tick_array_prev                    caller
9  W   tick_array_cur                     caller, or DEX program id placeholder
10 W   tick_array_next                    caller

CLMM Token-2022

Automatically selected for RaydiumClmm, Pancakeswap, and ByrealClmm when either supplied endpoint token program is Token-2022.

0      amm_config                         caller
1  W   pool_state                         caller
2  W   token_vault_0                      caller
3  W   token_vault_1                      caller
4  W   observation_state                  caller
5      SPL Token program                  SDK constant
6      Token-2022 program                 SDK constant
7      Memo v3 program                    SDK constant
8      token_mint_0                       caller
9      token_mint_1                       caller
10     DEX program                        SDK constant for variant
11 W   tick_array_bitmap_ext              caller
12 W   tick_array_prev                    caller
13 W   tick_array_cur                     caller, or DEX program id placeholder
14 W   tick_array_next                    caller

Orca Whirlpool

0      SPL Token program                  SDK constant
1  W   whirlpool                          caller
2  W   vault_a                            caller
3  W   vault_b                            caller
4  W   tick_array_prev                    caller
5  W   tick_array_cur                     caller
6  W   tick_array_next                    caller
7  W   oracle                             caller
8      Orca Whirlpool program             SDK constant

Orca Whirlpool Token-2022

Automatically selected for OrcaWhirlpool when either supplied endpoint token program is Token-2022.

0      token_program_a                    caller
1      token_program_b                    caller
2      Memo v3 program                    SDK constant
3  W   whirlpool                          caller
4      token_mint_a                       caller
5      token_mint_b                       caller
6  W   vault_a                            caller
7  W   vault_b                            caller
8  W   tick_array_prev                    caller
9  W   tick_array_cur                     caller
10 W   tick_array_next                    caller
11 W   oracle                             caller
12     Orca Whirlpool program             SDK constant

Meteora DLMM (wire MarketId 9, Swap2)

MeteoraDlmm always emits this layout for both SPL Token and Token-2022 pools. The SDK does not expose or emit legacy wire ID 4. Its deprecated MeteoraDlmmT22 source alias emits this same layout and wire ID 9.

0  W   lb_pair                            caller
1  W   bin_array_bitmap_ext               caller
2  W   reserve_x                          caller
3  W   reserve_y                          caller
4      token_x_mint                       caller
5      token_y_mint                       caller
6  W   oracle                             caller
7  W   host_fee_in or DLMM placeholder    caller option or SDK constant
8      token_x_program                    caller
9      token_y_program                    caller
10     Memo v3 program                    SDK constant
11     DLMM event authority               SDK constant
12     DLMM program                       SDK constant
13 W   bin_array_prev                     caller
14 W   bin_array_cur                      caller
15 W   bin_array_next                     caller

The prev/cur/next field names are retained API names for the three fixed slots. Bitmap-aware callers may supply a compact directional live-array union there, including duplicated or gap-shifted arrays; Prism validates and orders the accounts for Swap2 on-chain.

Meteora DAMM v2

0      pool authority                     SDK constant
1  W   pool                               caller
2  W   token_a_vault                      caller
3  W   token_b_vault                      caller
4      token_a_mint                       caller
5      token_b_mint                       caller
6      token_a_program                    caller
7      token_b_program                    caller
8      DAMM v2 event authority            SDK constant
9      DAMM v2 program                    SDK constant
10     instructions sysvar or sentinel    caller option or SDK constant

Meteora Pools

0  W   pool                               caller
1  W   a_vault                            caller
2  W   b_vault                            caller
3  W   a_token_vault                      caller
4  W   b_token_vault                      caller
5  W   a_vault_lp_mint                    caller
6  W   b_vault_lp_mint                    caller
7  W   a_vault_lp                         caller
8  W   b_vault_lp                         caller
9  W   protocol_fee_a                     caller
10 W   protocol_fee_b                     caller
11     vault_program                      caller
12     SPL Token program                  SDK constant
13     Meteora Pools program              SDK constant

Pumpfun AMM

0  W   pool                               caller
1      global config                      SDK constant
2      base_mint                          caller
3      quote_mint                         caller
4  W   pool_base_vault                    caller
5  W   pool_quote_vault                   caller
6      fee_recipient                      caller
7  W   fee_recipient_ata                  caller
8      base_token_program                 caller
9      quote_token_program                caller
10     system program                     SDK constant
11     associated token program           SDK constant
12     event authority                    SDK constant
13     Pumpfun AMM program                SDK constant
14 W   creator_vault_ata                  caller
15     creator_vault_authority            caller
16     global accumulator                 SDK constant
17 W   user_volume_accumulator            caller
18     fee_config                         SDK constant
19     fee_program                        SDK constant
20 W   user_volume_accumulator_wsol_ata   caller option when present
20     Pumpfun AMM placeholder            SDK constant when option is None
21     pool_v2 or Pumpfun placeholder     caller option or SDK constant
22     swap_fee_recipient                 caller
23 W   swap_fee_ata                       caller

HumidiFi Swap v2

0  W   pool                               caller
1  W   base_vault                         caller
2  W   quote_vault                        caller
3      clock sysvar                       SDK constant
4      instructions sysvar                SDK constant
5      base_mint                          caller
6      quote_mint                         caller
7  W   side_table                         caller
8      jito_vote                          caller
9      HumidiFi program                   SDK constant

HumidiFi Swap

0  W   pool                               caller
1  W   base_vault                         caller
2  W   quote_vault                        caller
3      clock sysvar                       SDK constant
4      instructions sysvar                SDK constant
5      jito_vote                          caller
6      HumidiFi program                   SDK constant

Manifest

0  W   market                             caller
1  W   base_vault                         caller
2  W   quote_vault                        caller
3      base_mint                          caller
4      quote_mint                         caller
5      system program                     SDK constant
6      Manifest program                   SDK constant

AlphaQ

0  W   pool                               caller
1  W   market_stats                       caller
2  W   vault_left                         caller
3  W   vault_right                        caller
4      instructions sysvar                SDK constant
5      SPL Token program                  SDK constant
6      mint_left                          caller
7      mint_right                         caller
8      AlphaQ program                     SDK constant

AlphaQ Token-2022

Automatically selected for AlphaQ when token_program_left is Token-2022 and token_program_right is SPL Token.

0  W   pool                               caller
1  W   market_stats                       caller
2  W   vault_left                         caller
3  W   vault_right                        caller
4      instructions sysvar                SDK constant
5      SPL Token program                  SDK constant
6      mint_left                          caller
7      mint_right                         caller
8      AlphaQ program                     SDK constant
9      Token-2022 program                 SDK constant

GoonFi v2

0  W   pair                               caller
1  W   vault_a                            caller
2  W   vault_b                            caller
3      mint_a                             caller
4      mint_b                             caller
5      side_price                         caller
6  W   global_state                       caller
7      instructions sysvar                SDK constant
8      SPL Token program                  SDK constant
9      GoonFi v2 program                  SDK constant

GoonFi v2 Token-2022

Automatically selected for GoonfiV2 when either supplied endpoint token program is Token-2022.

0  W   pair                               caller
1  W   vault_a                            caller
2  W   vault_b                            caller
3      mint_a                             caller
4      mint_b                             caller
5      side_price                         caller
6  W   global_state                       caller
7      instructions sysvar                SDK constant
8      SPL Token program                  SDK constant
9      Token-2022 program                 SDK constant
10     GoonFi v2 program                  SDK constant

ZeroFi

0  W   pool                               caller
1      oracle                             caller
2  W   side_a                             caller
3  W   vault_a                            caller
4  W   side_b                             caller
5  W   vault_b                            caller
6      mint_a                             caller
7      mint_b                             caller
8      instructions sysvar                SDK constant
9      ZeroFi program                     SDK constant

SolFi v2

0  W   pair                               caller
1      oracle                             caller
2      global_config                      caller
3  W   base_vault                         caller
4  W   quote_vault                        caller
5      instructions sysvar                SDK constant
6      base_mint                          caller
7      quote_mint                         caller
8      base_token_program                 caller
9      quote_token_program                caller
10     SolFi v2 program                   SDK constant

Futarchy Spot

0  W   dao                                caller
1  W   amm_base_vault                     caller
2  W   amm_quote_vault                    caller
3      event authority                    SDK constant
4      Futarchy program                   SDK constant

Fusion

0      token_program_a                    caller
1      token_program_b                    caller
2      Memo v3 program                    SDK constant
3  W   pool                               caller
4      token_mint_a                       caller
5      token_mint_b                       caller
6  W   token_vault_a                      caller
7  W   token_vault_b                      caller
8  W   tick_array_cur                     caller
9  W   tick_array_above_1                 caller
10 W   tick_array_above_2                 caller
11 W   tick_array_below_1                 caller
12 W   tick_array_below_2                 caller
13     Fusion program                     SDK constant

BisonFi

0  W   pool                               caller
1  W   vault_a                            caller
2  W   vault_b                            caller
3      instructions sysvar                SDK constant
4      trailing account                   SDK constant
5      BisonFi program                    SDK constant
6      Prism program                      SDK constant

To comply with BisonFi's account enforcement, the SDK automatically includes the Jito vote account J1to1yufRnoWn81KYg1XkTWzmKjnYSnmE2VY8DGUJ9Qv. Because Jito bundles reject transactions containing vote accounts, routes that include BisonFi cannot be submitted through Jito bundles.

Only the pool's canonical mint A -> mint B direction is supported. Supply BisonFiAccounts only when the desired route consumes mint A and produces mint B; Prism does not scout or execute the reverse mint B -> mint A edge.

Tessera

0      global_authority                   caller
1  W   pool                               caller
2  W   mint_a_vault                       caller
3  W   mint_b_vault                       caller
4      mint_a                             caller
5      mint_b                             caller
6      instructions sysvar                SDK constant
7      Tessera program                    SDK constant

Tessera uses the public opcode 0x10 path. The instructions sysvar is quote-critical because Tessera scans top-level instruction program ids to determine whether its pool fee is waived. The alternate router-profile opcode 0x11 is intentionally not part of Prism's adapter contract.

The caller is responsible for using the correct dynamic pool, vault, mint, token program, tick/bin array, side-table, fee, and optional sentinel accounts for the selected market.

Common On-chain Errors

These are Prism Custom(u32) errors callers commonly see after simulating or sending a find_arb_v2 or find_arb_v3 instruction. Solana logs the same value in hexadecimal as custom program error: 0x....

Account and pool layout errors:

  • Custom(2000) / 0x7d0 / NotEnoughAccounts: the account list is shorter than the declared market layouts require.
  • Custom(2012) / 0x7dc / UnsupportedBaseMint: the submitted base mint is not WSOL, USDC, USDT, or USD1.
  • Custom(2013) / 0x7dd / InvalidRouteTokenAccount: a submitted route_mints[].user_ata is missing, uninitialized, malformed, or owned by a different token program. Refresh it after closing/recreating the account, and supply its matching SPL Token or Token-2022 program.
  • Custom(2014) / 0x7de / InvalidSignerBaseTokenAccount: the submitted base token account is missing, uninitialized, malformed, or has a different mint from base.mint.
  • Custom(2015) / 0x7df / InvalidFlashloanVaultAccount: the canonical flashloan vault account is missing, uninitialized, malformed, or has a different mint from base.mint.
  • Custom(2016) / 0x7e0 / DuplicateRouteMint: two route_mints entries resolve to the same mint, or one resolves to base.mint.
  • Custom(3000) / 0xbb8 / PoolOwnerMismatch: a pool account is not owned by the expected DEX program, usually because the market variant does not match the pool.
  • Custom(3001) / 0xbb9 / PoolDataSize: a pool account is too short for the expected layout, or the supplied account is stale/wrong for that market.
  • Custom(3003) / 0xbbb / PoolMintMismatch: a pool's endpoint mints do not match the submitted base mint and route mint set.
  • Custom(3005) / 0xbbd / BinArrayOutOfRange: a Meteora DLMM walk exhausted the supplied bin arrays.
  • Custom(3007) / 0xbbf / BinArrayOrderInvalid: Meteora DLMM bin arrays were supplied in the wrong order.
  • Custom(3008) / 0xbc0 / TickArrayWindowStale: a CLMM tick-array window is stale for the pool's current tick.
  • Custom(3009) / 0xbc1 / TickArrayDirectionDead: a CLMM pool has no initialized tick arrays on one side, so that direction cannot be executed.

Arb outcome and execution errors:

  • Custom(5000) / 0x1388 / NoProfit: Prism found no profitable route. This reverts only when fail_if_no_profit = true; otherwise the instruction can succeed as a no-op.
  • Custom(5004) / 0x138c / Unprofitable: the strict post-swap actual-profit gate failed after execution checks.
  • Custom(5005) / 0x138d / SwapCpiFailed: a downstream DEX CPI failed; inspect the transaction logs for the DEX-level cause.
  • Custom(5006) / 0x138e / FeeShortfall: the signer's base ATA cannot cover the required settlement transfer after the swaps.

Build Errors

BuildError is a client-side construction error. It means the SDK refused to build an instruction that Prism would reject or that the SDK cannot represent.

Error When Notes
UnsupportedBaseMint(pubkey) The V2 or V3 base.mint is not WSOL, USDC, USDT, or USD1, or the base token program is not SPL Token. Choose one of Prism's supported settlement base mints.
UnsupportedFlashloanBaseMint(pubkey) flashloan = true and the V2 or V3 base.mint is not WSOL or USDC. Disable flashloan for USDT/USD1 routes, or use a WSOL/USDC base mint with an initialized and funded Prism vault.
RouteMintCountOverflow(count) route_mints.len() does not fit the u8 count field in the instruction data. This is the wire-format ceiling, not a routing-size recommendation. Real transactions should hit account, byte, or compute budgets first.
MissingRouteMints route_mints is empty. Prism needs at least one route mint header to map pool endpoints to user token accounts. Add one MintAccount for each target or bridge mint used by the pool graph.
BaseMintInRouteMints(pubkey) A route mint entry repeats base.mint. The base mint is already represented by the V2/V3 params base; remove it from route_mints.
DuplicateRouteMint(pubkey) The same route mint appears more than once. Deduplicate by mint pubkey and keep the matching token program plus user ATA in the remaining MintAccount.
MissingPools pools is empty. Add at least one MarketAccounts variant. The SDK does not infer pools from mints or route intent.
PoolCountOverflow(count) pools.len() does not fit the u8 count field in the instruction data. This is the wire-format ceiling, not a routing-size recommendation. Real transactions should hit account, byte, or compute budgets first.
UnsupportedMarketId(byte) markets::MarketId::try_from(byte) received a byte outside the SDK's supported market id range. This does not occur when building with typed MarketAccounts variants, because the variant supplies the market id.
UnsupportedMarketTokenProgram { market, token_program } A unified market struct contains a token program other than SPL Token or Token-2022. Supply the actual owner program of each endpoint mint.
UnsupportedMarketTokenProgramPair { market, token_program_a, token_program_b } The individual programs are recognized, but that market does not support the orientation. Currently this guards AlphaQ, which supports SPL/SPL and Token-2022-left/SPL-right only.
InvalidPrismCuBudget FindArbV3Params.prism_cu_budget is zero. Supply a nonzero Prism-only CU allowance. Use V2 if the caller cannot provide one.

The SDK does not validate account existence, token account ownership, pool state, pool endpoint mints, route profitability, lookup table fit, compute budget, or transaction account-lock count. Those checks belong to the caller's indexer, simulator, transaction builder, or Prism itself.

Byreal dynamic fees

Use MarketAccounts::ByrealDynamic(ByrealDynamicAccounts { clmm, token0_pyth_oracle, token1_pyth_oracle }) for pools with decay_fee_flag & 0x10 != 0. clmm is the existing ByrealClmmAccounts struct, including both endpoint token programs. This always emits market 29 and 17 accounts, including for SPL/SPL pools. The first 15 slots are the mint-aware CLMM layout; the final two are read-only Pyth PriceUpdateV2 accounts in pool token0/token1 order, independent of direction.

Both token programs are checked. Callers resolve oracle accounts matching the pool's feed IDs and ensure they are updated; the SDK does not fetch pool/oracle state. Prism validates the oracle identity and freshness on chain. Existing ByrealClmm selection continues emitting legacy 13/14 and cannot represent dynamic-fee pools. Market 29 requires the Prism deployment supporting this layout.

About

Rust SDK for building instructions for Prism, the on-chain Solana JIT arb router.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages