简体   繁体   中英

How to sign a Solana Raydium swap?

I am getting a NotEnoughSigners error using amm_instruction::swap_base_in() for Raydium swap in Solana ( https://github.com/raydium-io/raydium-contract-instructions ). What am I doing wrong here? As far as I can tell, one signer is required and one is being submitted, but I get a NotEnoughSigners error.

// pubkey
use std::{str::FromStr};
use solana_program::{pubkey, pubkey::Pubkey};

// rpc 
use solana_client::rpc_client::RpcClient;

mod amm_instruction;

fn main() {
    // pool info
    let program_id: Pubkey = pubkey!("675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8");
    let amm_id: Pubkey = pubkey!("58oQChx4yWmvKdwLLZzBi4ChoCc2fqCUWBkwMihLYQo2");
    let amm_authority: Pubkey = pubkey!("5Q544fKrFoe6tsEbD7S8EmxGTJYAKtTVhAW5Q5pge4j1");
    let amm_open_orders: Pubkey = pubkey!("HRk9CMrpq7Jn9sh7mzxE8CChHG8dneX9p475QKz4Fsfc");
    let amm_target_orders: Pubkey = pubkey!("CZza3Ej4Mc58MnxWA385itCC9jCo3L1D7zc3LKy1bZMR");
    let pool_coin_token_account: Pubkey = pubkey!("DQyrAcCrDXQ7NeoqGgDCZwBvWDcYmFCjSb9JtteuvPpz");
    let pool_pc_token_account: Pubkey = pubkey!("HLmqeL62xR1QoZ1HKKbXRrdN1p3phKpxRMb2VVopvBBz");
    let serum_program_id: Pubkey = pubkey!("9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin");
    let serum_market: Pubkey = pubkey!("9wFFyRfZBsuAha4YcuxcXLKwMxJR43S7fPfQLusDBzvT");
    let serum_bids: Pubkey = pubkey!("14ivtgssEBoBjuZJtSAPKYgpUK7DmnSwuPMqJoVTSgKJ");
    let serum_asks: Pubkey = pubkey!("CEQdAFKdycHugujQg9k2wbmxjcpdYZyVLfV9WerTnafJ");
    let serum_event_queue: Pubkey = pubkey!("5KKsLVU6TcbVDK4BS6K1DGDxnh4Q9xjYJ8XaDCG5t8ht");
    let serum_coin_vault_account: Pubkey = pubkey!("36c6YqAwyGKQG66XEp2dJc5JqjaBNv7sVghEtJv4c7u6");
    let serum_pc_vault_account: Pubkey = pubkey!("8CFo8bL8mZQK8abbFyypFMwEDd8tVJjHTTojMLgQTUSZ");
    let serum_vault_signer: Pubkey = pubkey!("F8Vyqk3unwxkXukZFQeYyGmFfTG3CAX4v24iyrjEYBJV");
    let uer_source_token_account: Pubkey = pubkey!("AgzZJAiniqwX4MAkf7KGuza4oYk5XNBHUZ4XZeca7osC");
    let uer_destination_token_account: Pubkey = pubkey!("ENJH5ho47pbHmMcoerGtRywQpkcbtWtnCfsKdHesf5E5");
    let user_source_owner: Pubkey = pubkey!("FBH3xoEVNF85pkmpfsgevyTW9ewtL2M1xuHzJwaxdLm5");
    let amount_in: u64 = 1_000_000;
    let minimum_amount_out: u64 = 10_321_182;

    // connect to cluster
    //let url = "https://api.mainnet-beta.solana.com".to_string();
    let url = "https://api.devnet.solana.com".to_string();    
    let rpc_client = RpcClient::new(url);

    let latest_blockhash = rpc_client.get_latest_blockhash().unwrap();
    let alice = solana_sdk::signer::keypair::read_keypair_file("/Users/Me/.config/solana/id.json").unwrap();
    
    let swap_instructions = amm_instruction::swap_base_in(
        &program_id,
        &amm_id,
        &amm_authority,
        &amm_open_orders,
        &amm_target_orders,
        &pool_coin_token_account, 
        &pool_pc_token_account, 
        &serum_program_id, 
        &serum_market, 
        &serum_bids, 
        &serum_asks, 
        &serum_event_queue, 
        &serum_coin_vault_account, 
        &serum_pc_vault_account, 
        &serum_vault_signer, 
        &uer_source_token_account, 
        &uer_destination_token_account, 
        &user_source_owner, 
        amount_in, 
        minimum_amount_out
    ).unwrap();

    let payer: Option<Pubkey> = Some(solana_program::pubkey::Pubkey::from_str("5C8rbEJUuLR2nTkEqiyjzmyBtxAiseS2Aoq7YU3c8cgL").unwrap());

    let tx = solana_sdk::transaction::Transaction::new_signed_with_payer(&[swap_instructions], payer.as_ref(), &[&alice], latest_blockhash);

    let signature = rpc_client.send_and_confirm_transaction(&tx);
    
    println!("swap: {:?}",signature);
}

If you look at the code that you linked, you'll see that this instruction expects only one signature from user_source_owner : https://github.com/raydium-io/raydium-contract-instructions/blob/cbd7affe245166f7baceb7e68d123220e0fcd331/amm_instruction.rs#L594

This means that your transaction must be declared as:

let payer = Keypair::from_bytes(<INSERT_BYTES_HERE>); // this must be a some Signer in order to be declared as a payer, so use whichever method you need to get that keypair
let user_source_owner = Keypair::form_bytes(<PUT_BYTES_HERE>); // same here
let tx = solana_sdk::transaction::Transaction::new_signed_with_payer(&[swap_instructions], Some(&payer.pubkey()), &[&payer, &user_source_owner], latest_blockhash);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM