hpsvm_token/
create_ata_idempotent.rs1use hpsvm::{HPSVM, types::FailedTransactionMetadata};
2use solana_address::Address;
3use solana_keypair::Keypair;
4use solana_signer::Signer;
5use spl_associated_token_account_interface::instruction::create_associated_token_account_idempotent;
6
7use super::TOKEN_ID;
8
9#[derive(Debug)]
16pub struct CreateAssociatedTokenAccountIdempotent<'a> {
17 svm: &'a mut HPSVM,
18 payer: &'a Keypair,
19 mint: &'a Address,
20 token_program_id: Option<&'a Address>,
21 owner: Option<Address>,
22}
23
24impl<'a> CreateAssociatedTokenAccountIdempotent<'a> {
25 pub fn new(svm: &'a mut HPSVM, payer: &'a Keypair, mint: &'a Address) -> Self {
27 CreateAssociatedTokenAccountIdempotent {
28 svm,
29 payer,
30 owner: None,
31 token_program_id: None,
32 mint,
33 }
34 }
35
36 pub fn owner(mut self, owner: &'a Address) -> Self {
38 self.owner = Some(*owner);
39 self
40 }
41
42 pub fn token_program_id(mut self, program_id: &'a Address) -> Self {
44 self.token_program_id = Some(program_id);
45 self
46 }
47
48 pub fn send(self) -> Result<Address, FailedTransactionMetadata> {
50 let token_program_id = self.token_program_id.unwrap_or(&TOKEN_ID);
51 let payer_pk = self.payer.pubkey();
52
53 let authority = self.owner.unwrap_or(payer_pk);
54
55 let ix = create_associated_token_account_idempotent(
56 &payer_pk,
57 &authority,
58 self.mint,
59 token_program_id,
60 );
61
62 super::sign_and_send(self.svm, self.payer, &[], ix)?;
63
64 let ata = spl_associated_token_account_interface::address::get_associated_token_address_with_program_id(
65 &authority,
66 self.mint,
67 token_program_id,
68 );
69
70 Ok(ata)
71 }
72}