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