satrush_client/test_utils.rs
1//! Mock swap route support for validation environments.
2//!
3//! Devnet builds of the program (`--features devnet`) hardcode the mock swap
4//! aggregator as their `SWAP_PROGRAM` in place of Jupiter. These helpers build
5//! the mock's route data and account list, shared by the LiteSVM test-suite and
6//! the CLI when cranking devnet rounds. Not for mainnet use.
7
8use crate::builders::{get_associated_token_address, TOKEN_PROGRAM_ID};
9use solana_instruction::AccountMeta;
10use solana_pubkey::Pubkey;
11
12/// Mock swap aggregator program (must match the program's `declare_id!` and
13/// the `devnet` `SWAP_PROGRAM` constant).
14pub const MOCK_SWAP_PROGRAM_ID: Pubkey = Pubkey::from_str_const("FwagBBXsQVcn7iAT3bGV4cHBs8oU2wnazL9Ue9BTVRru");
15
16/// Seed for the mock swap program's pool authority PDA.
17pub const MOCK_POOL_AUTHORITY_SEED: &[u8] = b"pool";
18
19/// Anchor instruction discriminator for the mock swap program's `mock_swap`.
20const MOCK_SWAP_DISCRIMINATOR: [u8; 8] = [132, 118, 185, 134, 25, 56, 106, 10];
21
22/// The mock swap program's pool authority PDA (owner of its liquidity ATAs).
23pub fn get_mock_pool_authority() -> Pubkey {
24 Pubkey::find_program_address(&[MOCK_POOL_AUTHORITY_SEED], &MOCK_SWAP_PROGRAM_ID).0
25}
26
27/// Instruction data for the mock swap program: it moves exactly `amount_in`
28/// USD into the pool and pays exactly `amount_out` BTC from it.
29pub fn get_mock_swap_data(amount_in: u64, amount_out: u64) -> Vec<u8> {
30 let mut swap_data = MOCK_SWAP_DISCRIMINATOR.to_vec();
31 swap_data.extend_from_slice(&amount_in.to_le_bytes());
32 swap_data.extend_from_slice(&amount_out.to_le_bytes());
33 swap_data
34}
35
36/// The mock swap program's account list (order matches its `MockSwap` struct)
37/// for a USD -> BTC swap out of `source_authority`'s ATAs. `source_authority`
38/// is passed as a non-signer at the transaction level (it is a PDA) — the
39/// relaying satrush instruction marks it a signer for the CPI and signs via
40/// `invoke_signed`.
41pub fn get_mock_swap_route_accounts(source_authority: Pubkey, usd_mint: Pubkey, btc_mint: Pubkey) -> Vec<AccountMeta> {
42 let pool_authority = get_mock_pool_authority();
43 vec![
44 AccountMeta::new(get_associated_token_address(&source_authority, &usd_mint), false), // source_ata
45 AccountMeta::new_readonly(source_authority, false), // source_authority
46 AccountMeta::new(get_associated_token_address(&pool_authority, &usd_mint), false), // pool_source_ata
47 AccountMeta::new(get_associated_token_address(&pool_authority, &btc_mint), false), // pool_dest_ata
48 AccountMeta::new(get_associated_token_address(&source_authority, &btc_mint), false), // dest_ata
49 AccountMeta::new_readonly(pool_authority, false), // pool_authority
50 AccountMeta::new_readonly(TOKEN_PROGRAM_ID, false), // token_program
51 ]
52}