use solana_sdk::instruction::{AccountMeta, Instruction};
use solana_sdk::pubkey::Pubkey;
use crate::error::Result;
use super::super::constants::{
ATA_PROGRAM_ID, CORE_PROGRAM_ID, SYSTEM_PROGRAM_ID, TOKEN_BRIDGE_PROGRAM_ID, TOKEN_PROGRAM_ID,
WSOL_MINT,
};
use super::super::rpc::SolanaRpc;
use super::super::types::{
LockSolAccounts, LockSolOptions, LockSolResult, LockSplAccounts, LockSplOptions, LockSplResult,
};
use super::super::utils::{
concat_bytes, derive_rate_limit_state_pda, derive_router_config_pda, derive_router_signer_pda,
derive_token_price_registry_pda, derive_token_registration_pda, encode_borsh_string,
encode_u64_le, generate_discriminator, get_ata,
};
use super::helpers::{build_transaction, parse_pubkey, resolve_recent_blockhash};
pub async fn build_lock_spl_transaction(
options: LockSplOptions,
payer: &Pubkey,
rpc: Option<&dyn SolanaRpc>,
) -> Result<LockSplResult> {
let mint = parse_pubkey(&options.mint, "mint")?;
let (router_signer, _) = derive_router_signer_pda();
let (router_config, _) = derive_router_config_pda();
let (rate_limit_state, _) = derive_rate_limit_state_pda();
let (token_registration, _) = derive_token_registration_pda(&mint);
let user_ata = get_ata(payer, &mint);
let vault_ata = get_ata(&router_signer, &mint);
let discriminator = generate_discriminator("global:lock_spl");
let amount = encode_u64_le(options.amount);
let zera_address = encode_borsh_string(&options.zera_address);
let data = concat_bytes(&[
discriminator.as_ref(),
amount.as_ref(),
zera_address.as_slice(),
]);
let instruction = Instruction {
program_id: *TOKEN_BRIDGE_PROGRAM_ID,
accounts: vec![
AccountMeta::new_readonly(*CORE_PROGRAM_ID, false),
AccountMeta::new_readonly(router_config, false),
AccountMeta::new(*payer, true),
AccountMeta::new(user_ata, false),
AccountMeta::new_readonly(mint, false),
AccountMeta::new_readonly(router_signer, false),
AccountMeta::new(vault_ata, false),
AccountMeta::new(rate_limit_state, false),
AccountMeta::new(token_registration, false),
AccountMeta::new_readonly(*TOKEN_PROGRAM_ID, false),
AccountMeta::new_readonly(*ATA_PROGRAM_ID, false),
AccountMeta::new_readonly(*SYSTEM_PROGRAM_ID, false),
],
data,
};
let recent_blockhash = resolve_recent_blockhash(rpc).await?;
let transaction = build_transaction(payer, vec![instruction.clone()], recent_blockhash);
Ok(LockSplResult {
instruction,
transaction,
accounts: LockSplAccounts {
user_ata,
vault_ata,
router_signer,
router_config,
rate_limit_state,
token_registration,
},
})
}
pub async fn build_lock_sol_transaction(
options: LockSolOptions,
payer: &Pubkey,
rpc: Option<&dyn SolanaRpc>,
) -> Result<LockSolResult> {
let (router_signer, _) = derive_router_signer_pda();
let (router_config, _) = derive_router_config_pda();
let (rate_limit_state, _) = derive_rate_limit_state_pda();
let (token_price_registry, _) = derive_token_price_registry_pda();
let payer_wsol_ata = get_ata(payer, &WSOL_MINT);
let vault_ata = get_ata(&router_signer, &WSOL_MINT);
let discriminator = generate_discriminator("global:lock_sol");
let amount = encode_u64_le(options.amount);
let zera_address = encode_borsh_string(&options.zera_address);
let data = concat_bytes(&[
discriminator.as_ref(),
amount.as_ref(),
zera_address.as_slice(),
]);
let instruction = Instruction {
program_id: *TOKEN_BRIDGE_PROGRAM_ID,
accounts: vec![
AccountMeta::new_readonly(*CORE_PROGRAM_ID, false),
AccountMeta::new_readonly(router_config, false),
AccountMeta::new(*payer, true),
AccountMeta::new(payer_wsol_ata, false),
AccountMeta::new(vault_ata, false),
AccountMeta::new_readonly(router_signer, false),
AccountMeta::new_readonly(*WSOL_MINT, false),
AccountMeta::new(rate_limit_state, false),
AccountMeta::new_readonly(token_price_registry, false),
AccountMeta::new_readonly(*TOKEN_PROGRAM_ID, false),
AccountMeta::new_readonly(*ATA_PROGRAM_ID, false),
AccountMeta::new_readonly(*SYSTEM_PROGRAM_ID, false),
],
data,
};
let recent_blockhash = resolve_recent_blockhash(rpc).await?;
let transaction = build_transaction(payer, vec![instruction.clone()], recent_blockhash);
Ok(LockSolResult {
instruction,
transaction,
accounts: LockSolAccounts {
payer_wsol_ata,
vault_ata,
router_signer,
router_config,
rate_limit_state,
token_price_registry,
},
})
}