use crate::pubkey::{ids, Pubkey};
use crate::token::TokenProgram;
use crate::tx::{AccountMeta, Instruction};
mod system_ix {
pub const TRANSFER: u32 = 2;
pub const ADVANCE_NONCE_ACCOUNT: u32 = 4;
}
mod token_ix {
pub const TRANSFER_CHECKED: u8 = 12;
pub const SYNC_NATIVE: u8 = 17;
}
mod compute_ix {
pub const SET_COMPUTE_UNIT_LIMIT: u8 = 2;
pub const SET_COMPUTE_UNIT_PRICE: u8 = 3;
}
pub fn transfer_sol(from: &Pubkey, to: &Pubkey, lamports: u64) -> Instruction {
let mut data = Vec::with_capacity(12);
data.extend_from_slice(&system_ix::TRANSFER.to_le_bytes());
data.extend_from_slice(&lamports.to_le_bytes());
Instruction {
program_id: ids::SYSTEM_PROGRAM,
accounts: vec![
AccountMeta::writable_signer(*from),
AccountMeta::writable(*to),
],
data,
}
}
pub fn transfer_checked(
program: TokenProgram,
source: &Pubkey,
mint: &Pubkey,
destination: &Pubkey,
authority: &Pubkey,
amount: u64,
decimals: u8,
) -> Instruction {
let mut data = Vec::with_capacity(10);
data.push(token_ix::TRANSFER_CHECKED);
data.extend_from_slice(&amount.to_le_bytes());
data.push(decimals);
Instruction {
program_id: program.id(),
accounts: vec![
AccountMeta::writable(*source),
AccountMeta::readonly(*mint),
AccountMeta::writable(*destination),
AccountMeta::readonly_signer(*authority),
],
data,
}
}
pub fn create_associated_token_account_idempotent(
payer: &Pubkey,
ata: &Pubkey,
owner: &Pubkey,
mint: &Pubkey,
program: TokenProgram,
) -> Instruction {
Instruction {
program_id: ids::ASSOCIATED_TOKEN_PROGRAM,
accounts: vec![
AccountMeta::writable_signer(*payer),
AccountMeta::writable(*ata),
AccountMeta::readonly(*owner),
AccountMeta::readonly(*mint),
AccountMeta::readonly(ids::SYSTEM_PROGRAM),
AccountMeta::readonly(program.id()),
],
data: vec![1],
}
}
pub fn memo(text: &str, signers: &[Pubkey]) -> Instruction {
Instruction {
program_id: ids::MEMO_PROGRAM,
accounts: signers
.iter()
.map(|s| AccountMeta::readonly_signer(*s))
.collect(),
data: text.as_bytes().to_vec(),
}
}
pub fn advance_nonce_account(
nonce_account: &Pubkey,
nonce_authority: &Pubkey,
) -> Instruction {
Instruction {
program_id: ids::SYSTEM_PROGRAM,
accounts: vec![
AccountMeta::writable(*nonce_account),
AccountMeta::readonly(ids::SYSVAR_RECENT_BLOCKHASHES),
AccountMeta::readonly_signer(*nonce_authority),
],
data: system_ix::ADVANCE_NONCE_ACCOUNT.to_le_bytes().to_vec(),
}
}
pub fn sync_native(program: TokenProgram, account: &Pubkey) -> Instruction {
Instruction {
program_id: program.id(),
accounts: vec![AccountMeta::writable(*account)],
data: vec![token_ix::SYNC_NATIVE],
}
}
pub fn set_compute_unit_limit(units: u32) -> Instruction {
let mut data = Vec::with_capacity(5);
data.push(compute_ix::SET_COMPUTE_UNIT_LIMIT);
data.extend_from_slice(&units.to_le_bytes());
Instruction {
program_id: ids::COMPUTE_BUDGET_PROGRAM,
accounts: Vec::new(),
data,
}
}
pub fn set_compute_unit_price(micro_lamports: u64) -> Instruction {
let mut data = Vec::with_capacity(9);
data.push(compute_ix::SET_COMPUTE_UNIT_PRICE);
data.extend_from_slice(µ_lamports.to_le_bytes());
Instruction {
program_id: ids::COMPUTE_BUDGET_PROGRAM,
accounts: Vec::new(),
data,
}
}