spark_rust/spark_test_utils/
mod.rs

1#![cfg(feature = "integration-tests")]
2
3use std::str::FromStr;
4
5use crate::error::SparkSdkError;
6use crate::signer::default_signer::DefaultSigner;
7use crate::signer::traits::SparkSigner;
8use crate::SparkNetwork;
9use crate::SparkSdk;
10use bitcoin::Transaction;
11use rand::rngs::OsRng;
12
13pub mod bitcoind;
14pub mod faucet;
15
16pub use faucet::MempoolFaucet;
17
18pub async fn init_self_signer_wallet_with_random_seed(
19    network: SparkNetwork,
20) -> Result<(SparkSdk, Vec<u8>), SparkSdkError> {
21    let mut rng = OsRng;
22    let master_seed = bitcoin::secp256k1::SecretKey::new(&mut rng);
23
24    let signer = DefaultSigner::from_master_seed(master_seed.secret_bytes().as_ref(), network)
25        .await
26        .unwrap();
27
28    let sdk = SparkSdk::new(SparkNetwork::Regtest, signer).await?;
29
30    Ok((sdk, master_seed.secret_bytes().to_vec()))
31}
32
33pub async fn init_self_signer_wallet_with_seed(
34    network: SparkNetwork,
35    seed: Vec<u8>,
36) -> Result<SparkSdk, SparkSdkError> {
37    let signer = DefaultSigner::from_master_seed(&seed, network).await?;
38    let sdk = SparkSdk::new(network, signer).await?;
39    Ok(sdk)
40}
41
42/// Creates a test P2TR transaction with a dummy input and output.
43///
44/// This function is useful for testing purposes where we need a valid transaction
45/// with a specific output amount and address. To generate different transaction IDs that run in parallel,
46/// the function randomly selects the actual `amount_sats` value, while the chosen value is always greater than `min_amount_sats`.
47///
48/// # Arguments
49///
50/// * `txid` - The previous output transaction ID.
51/// * `vout` - The previous output transaction index.
52/// * `address` - The P2TR address to send the funds to.
53/// * `amount` - The amount of satoshis to send.
54/// * `network` - The Bitcoin network (mainnet, testnet, etc.).
55///
56/// # Returns
57///
58/// A Bitcoin transaction with a dummy input and output.
59pub fn create_test_p2tr_transaction(
60    txid: &str,
61    vout: u32,
62    address: &str,
63    amount: u64,
64    network: bitcoin::Network,
65    _include_change: bool,
66) -> Transaction {
67    let prev_txid = bitcoin::Txid::from_str(txid).unwrap();
68    let outpoint = bitcoin::OutPoint::new(prev_txid, vout);
69    let addr = bitcoin::Address::from_str(address).unwrap();
70    let addr = addr.require_network(network).unwrap();
71
72    // Calculate a conservative fee (1 sat/vbyte)
73    let fee = 200; // Approximate size of transaction in vbytes * 1 sat/vbyte
74
75    let output_amount = amount.saturating_sub(fee);
76
77    Transaction {
78        version: bitcoin::transaction::Version::TWO,
79        lock_time: bitcoin::absolute::LockTime::ZERO,
80        input: vec![bitcoin::TxIn {
81            previous_output: outpoint,
82            script_sig: bitcoin::ScriptBuf::new(),
83            sequence: bitcoin::Sequence::MAX,
84            witness: bitcoin::Witness::new(),
85        }],
86        output: vec![bitcoin::TxOut {
87            value: bitcoin::Amount::from_sat(output_amount),
88            script_pubkey: addr.script_pubkey(),
89        }],
90    }
91}