solana-program-library/token-upgrade/program/src/instruction.rs

78 lines
3.0 KiB
Rust

//! Program instructions
use {
crate::get_token_upgrade_authority_address,
num_enum::{IntoPrimitive, TryFromPrimitive},
solana_program::{
instruction::{AccountMeta, Instruction},
pubkey::Pubkey,
},
};
/// Instructions supported by the TokenUpgrade program
#[derive(Clone, Copy, Debug, TryFromPrimitive, IntoPrimitive)]
#[repr(u8)]
pub enum TokenUpgradeInstruction {
/// Burns all of the original tokens in the user's account, and transfers the same
/// amount of tokens from an account owned by a PDA into another account.
///
/// Accounts expected by this instruction:
///
/// 0. `[writeable]` Original token account to burn from
/// 1. `[writeable]` Original token mint
/// 2. `[writeable]` Escrow of new tokens held by or delegated to PDA at address:
/// `get_token_upgrade_authority_address(original_mint, new_mint, program_id)`
/// 3. `[writeable]` New token account to transfer into
/// 4. `[]` New token mint
/// 5. `[]` Transfer authority (owner or delegate) of new token escrow held by PDA, must be:
/// `get_token_upgrade_authority_address(original_mint, new_mint, program_id)`
/// 6. `[]` SPL Token program for original mint
/// 7. `[]` SPL Token program for new mint
/// 8. `[]` Original token account transfer authority (owner or delegate)
/// 9. ..9+M `[signer]` M multisig signer accounts
///
/// Data expected by this instruction:
/// None
///
Exchange,
}
/// Create an `Exchange` instruction
#[allow(clippy::too_many_arguments)]
pub fn exchange(
program_id: &Pubkey,
original_account: &Pubkey,
original_mint: &Pubkey,
new_escrow: &Pubkey,
new_account: &Pubkey,
new_mint: &Pubkey,
original_token_program_id: &Pubkey,
new_token_program_id: &Pubkey,
original_transfer_authority: &Pubkey,
original_multisig_signers: &[&Pubkey],
) -> Instruction {
let escrow_authority = get_token_upgrade_authority_address(original_mint, new_mint, program_id);
let mut accounts = Vec::with_capacity(9usize.saturating_add(original_multisig_signers.len()));
accounts.push(AccountMeta::new(*original_account, false));
accounts.push(AccountMeta::new(*original_mint, false));
accounts.push(AccountMeta::new(*new_escrow, false));
accounts.push(AccountMeta::new(*new_account, false));
accounts.push(AccountMeta::new(*new_mint, false));
accounts.push(AccountMeta::new_readonly(escrow_authority, false));
accounts.push(AccountMeta::new_readonly(*original_token_program_id, false));
accounts.push(AccountMeta::new_readonly(*new_token_program_id, false));
accounts.push(AccountMeta::new_readonly(
*original_transfer_authority,
original_multisig_signers.is_empty(),
));
for signer_pubkey in original_multisig_signers.iter() {
accounts.push(AccountMeta::new_readonly(**signer_pubkey, true));
}
Instruction {
program_id: *program_id,
accounts,
data: vec![TokenUpgradeInstruction::Exchange.into()],
}
}