Skip to main content

hpsvm_token/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2//! Token operations for the HPSVM
3
4/// Account snapshot factories for fast fixture and test setup.
5pub mod accounts;
6mod approve;
7mod approve_checked;
8mod burn;
9mod burn_checked;
10mod close_account;
11mod create_account;
12mod create_ata;
13mod create_ata_idempotent;
14mod create_mint;
15mod create_multisig;
16#[cfg(not(feature = "token-2022"))]
17mod create_native_mint;
18#[cfg(feature = "token-2022")]
19mod create_native_mint_2022;
20mod freeze_account;
21mod mint_to;
22mod mint_to_checked;
23mod revoke;
24mod set_authority;
25mod sync_native;
26mod thaw_account;
27mod transfer;
28mod transfer_checked;
29
30pub use approve::*;
31pub use approve_checked::*;
32pub use burn::*;
33pub use burn_checked::*;
34pub use close_account::*;
35pub use create_account::*;
36pub use create_ata::*;
37pub use create_ata_idempotent::*;
38pub use create_mint::*;
39pub use create_multisig::*;
40pub use create_native_mint::*;
41#[cfg(feature = "token-2022")]
42use create_native_mint_2022 as create_native_mint;
43pub use freeze_account::*;
44use hpsvm::{HPSVM, types::FailedTransactionMetadata};
45pub use mint_to::*;
46pub use mint_to_checked::*;
47pub use revoke::*;
48pub use set_authority::*;
49use solana_address::Address;
50use solana_keypair::Keypair;
51use solana_program_pack::{IsInitialized, Pack};
52use solana_signer::Signer;
53use solana_transaction::Transaction;
54use solana_transaction_error::TransactionError;
55#[cfg(feature = "token-2022")]
56pub use spl_token_2022_interface as spl_token;
57#[cfg(not(feature = "token-2022"))]
58pub use spl_token_interface as spl_token;
59pub use sync_native::*;
60pub use thaw_account::*;
61pub use transfer::*;
62pub use transfer_checked::*;
63
64/// SPL Token program ID
65pub const TOKEN_ID: Address = spl_token::ID;
66
67/// Get an SPL account from the SVM
68pub fn get_spl_account<T: Pack + IsInitialized>(
69    svm: &HPSVM,
70    account: &Address,
71) -> Result<T, FailedTransactionMetadata> {
72    let account = svm.get_account(account).ok_or(FailedTransactionMetadata {
73        err: TransactionError::AccountNotFound,
74        meta: Default::default(),
75    })?;
76    let data = account.data.get(..T::LEN).ok_or(FailedTransactionMetadata {
77        err: TransactionError::InstructionError(
78            0,
79            solana_instruction::error::InstructionError::AccountDataTooSmall,
80        ),
81        meta: Default::default(),
82    })?;
83    let account = T::unpack(data)?;
84
85    Ok(account)
86}
87
88fn get_multisig_signers<'a>(
89    authority: &Address,
90    signing_pubkeys: &'a [Address],
91) -> Vec<&'a Address> {
92    if signing_pubkeys == [*authority] {
93        vec![]
94    } else {
95        signing_pubkeys.iter().collect::<Vec<_>>()
96    }
97}
98
99pub(crate) fn sign_and_send(
100    svm: &mut HPSVM,
101    payer: &Keypair,
102    signers: &[&Keypair],
103    ix: solana_instruction::Instruction,
104) -> Result<(), FailedTransactionMetadata> {
105    let payer_pk = payer.pubkey();
106    let block_hash = svm.latest_blockhash();
107    let mut tx = Transaction::new_with_payer(&[ix], Some(&payer_pk));
108    tx.partial_sign(&[payer], block_hash);
109    tx.partial_sign(signers, block_hash);
110    svm.send_transaction(tx)?;
111    Ok(())
112}