use {
dlp_api::{
args::CallHandlerArgs, consts::DELEGATION_PROGRAM_ID, discriminator::DlpDiscriminator,
},
magicblock_magic_program_api::args::BaseActionArgs,
solana_address::Address,
solana_message::{AccountMeta, Instruction},
};
pub(super) fn base_action_instruction(
action: &BaseActionArgs,
escrow_authority: Address,
validator: Address,
) -> Instruction {
let other_accounts: Vec<AccountMeta> = action
.accounts
.iter()
.map(|account| {
let pubkey = Address::new_from_array(account.pubkey.to_bytes());
if account.is_writable {
AccountMeta::new(pubkey, false)
} else {
AccountMeta::new_readonly(pubkey, false)
}
})
.collect();
let validator_fees_vault = validator_fees_vault_pda(validator);
let escrow = escrow_pda(escrow_authority, action.args.escrow_index);
let destination = Address::new_from_array(action.destination_program.to_bytes());
let mut accounts = vec![
AccountMeta::new(validator, true),
AccountMeta::new(validator_fees_vault, false),
AccountMeta::new_readonly(destination, false),
AccountMeta::new(escrow_authority, false),
AccountMeta::new(escrow, false),
];
accounts.extend(other_accounts);
let mut data = DlpDiscriminator::CallHandler.to_vec();
data.extend(
borsh::to_vec(&CallHandlerArgs {
escrow_index: action.args.escrow_index,
data: action.args.data.clone(),
})
.expect("CallHandlerArgs is borsh-serializable"),
);
Instruction {
program_id: DELEGATION_PROGRAM_ID,
accounts,
data,
}
}
pub(super) fn escrow_pda(escrow_authority: Address, index: u8) -> Address {
dlp_api::pda::ephemeral_balance_pda_from_payer(&escrow_authority.to_bytes().into(), index)
.to_bytes()
.into()
}
pub(super) fn validator_fees_vault_pda(validator: Address) -> Address {
dlp_api::pda::validator_fees_vault_pda_from_validator(&validator.to_bytes().into())
.to_bytes()
.into()
}