1pub mod accounts;
8pub mod error;
9
10pub use self::error::TokenError;
11mod approve;
12mod approve_checked;
13mod burn;
14mod burn_checked;
15mod close_account;
16mod create_account;
17mod create_ata;
18mod create_ata_idempotent;
19mod create_mint;
20mod create_multisig;
21#[cfg(not(feature = "token-2022"))]
22mod create_native_mint;
23#[cfg(feature = "token-2022")]
24mod create_native_mint_2022;
25mod freeze_account;
26mod mint_to;
27mod mint_to_checked;
28mod revoke;
29mod set_authority;
30mod sync_native;
31mod thaw_account;
32mod transfer;
33mod transfer_checked;
34
35use solana_address::Address;
36use solana_keypair::Keypair;
37use solana_program_pack::{IsInitialized, Pack};
38use solana_signer::Signer;
39use solana_transaction::Transaction;
40#[cfg(feature = "token-2022")]
41pub use spl_token_2022_interface as spl_token;
42#[cfg(not(feature = "token-2022"))]
43pub use spl_token_interface as spl_token;
44
45#[cfg(feature = "token-2022")]
46use self::create_native_mint_2022 as create_native_mint;
47pub use self::{
48 approve::*, approve_checked::*, burn::*, burn_checked::*, close_account::*, create_account::*,
49 create_ata::*, create_ata_idempotent::*, create_mint::*, create_multisig::*,
50 create_native_mint::*, freeze_account::*, mint_to::*, mint_to_checked::*, revoke::*,
51 set_authority::*, sync_native::*, thaw_account::*, transfer::*, transfer_checked::*,
52};
53use crate::{HPSVM, types::FailedTransactionMetadata};
54
55pub const TOKEN_ID: Address = spl_token::ID;
57
58pub fn get_spl_account<T: Pack + IsInitialized>(
60 svm: &HPSVM,
61 account: &Address,
62) -> Result<T, TokenError> {
63 let account = svm.get_account(account).ok_or(TokenError::AccountNotFound(*account))?;
64 let data = account
65 .data
66 .get(..T::LEN)
67 .ok_or(TokenError::AccountDataTooSmall { expected: T::LEN, actual: account.data.len() })?;
68 let account = T::unpack(data)?;
69
70 Ok(account)
71}
72
73fn get_multisig_signers<'a>(
74 authority: &Address,
75 signing_pubkeys: &'a [Address],
76) -> Vec<&'a Address> {
77 if signing_pubkeys == [*authority] {
78 vec![]
79 } else {
80 signing_pubkeys.iter().collect::<Vec<_>>()
81 }
82}
83
84pub(crate) fn sign_and_send(
85 svm: &mut HPSVM,
86 payer: &Keypair,
87 signers: &[&Keypair],
88 ix: solana_instruction::Instruction,
89) -> Result<(), FailedTransactionMetadata> {
90 let payer_pk = payer.pubkey();
91 let block_hash = svm.latest_blockhash();
92 let mut tx = Transaction::new_with_payer(&[ix], Some(&payer_pk));
93 tx.partial_sign(&[payer], block_hash);
94 tx.partial_sign(signers, block_hash);
95 svm.send_transaction(tx)?;
96 Ok(())
97}