spark_sdk/wallet/handlers/
create_tree.rs

1use std::sync::Arc;
2
3use bitcoin::Transaction;
4use parking_lot::RwLock;
5use spark_protos::spark::TreeNode;
6
7use crate::{
8    error::SparkSdkError, signer::traits::SparkSigner,
9    wallet::internal_handlers::traits::create_tree::CreateTreeInternalHandlers, SparkSdk,
10};
11
12pub struct CreateTreeSdkResponse {
13    pub nodes: Vec<TreeNode>,
14}
15
16impl<S: SparkSigner + Send + Sync + Clone + 'static> SparkSdk<S> {
17    /// Creates a new tree of deposit addresses from either a deposit transaction or parent node.
18    ///
19    /// This function handles the creation of a new tree of deposit addresses by:
20    /// 1. Generating the deposit address tree structure based on the split level
21    /// 2. Finalizing the tree creation by signing all nodes and registering with the Spark network
22    ///
23    /// # Arguments
24    ///
25    /// * `deposit_transaction` - Optional Bitcoin transaction containing the deposit UTXO
26    /// * `parent_node` - Optional parent tree node to create child nodes from
27    /// * `vout` - The output index in the deposit transaction or parent node to use
28    /// * `split_level` - The number of levels to split the tree into (determines number of leaves)
29    /// * `parent_signing_public_key` - The public key of the parent node or deposit UTXO
30    ///
31    /// # Returns
32    ///
33    /// * `Ok(CreateTreeSdkResponse)` - Contains the finalized tree response including data for all created nodes, both branch and leaf nodes.
34    /// * `Err(SparkSdkError)` - If there was an error during tree creation
35    ///
36    /// # Errors
37    ///
38    /// Returns [`SparkSdkError`] if:
39    /// - Neither deposit transaction nor parent node is provided
40    /// - Failed to generate deposit addresses
41    /// - Failed to finalize tree creation with signatures
42    /// - Network errors when communicating with Spark operators
43    ///
44    /// # Example
45    ///
46    /// ```no_run
47    /// # use spark_wallet_sdk::SparkSdk;
48    /// # use bitcoin::Transaction;
49    /// # async fn example(mut sdk: SparkSdk) -> Result<(), Box<dyn std::error::Error>> {
50    /// let deposit_tx = Transaction::default(); // Your deposit transaction
51    /// let split_level = 2; // Creates 4 leaf nodes
52    /// let parent_pubkey = vec![/* public key bytes */];
53    ///
54    /// let tree = sdk.create_tree(
55    ///     Some(deposit_tx),
56    ///     None,
57    ///     0,
58    ///     split_level,
59    ///     parent_pubkey
60    /// ).await?;
61    /// # Ok(())
62    /// # }
63    /// ```
64    pub async fn create_tree(
65        &self,
66        deposit_transaction: Option<Transaction>,
67        parent_node: Option<Arc<RwLock<TreeNode>>>,
68        vout: u32,
69        split_level: u32,
70        parent_signing_public_key: Vec<u8>,
71    ) -> Result<CreateTreeSdkResponse, SparkSdkError> {
72        // generate the tree
73        let time_start = std::time::Instant::now();
74        let deposit_address_response = self
75            .generate_deposit_address_for_tree(
76                deposit_transaction.clone(),
77                parent_node.clone(),
78                vout,
79                parent_signing_public_key.clone(),
80                split_level,
81            )
82            .await?;
83        let duration = time_start.elapsed();
84        println!(
85            "[generate_deposit_address_for_tree] duration: {:?}",
86            duration
87        );
88
89        // finalize the tree
90        let time_start = std::time::Instant::now();
91        let finalize_tree_response = self
92            .finalize_tree_creation(
93                deposit_transaction,
94                parent_node,
95                vout,
96                deposit_address_response.tree,
97            )
98            .await?;
99        let duration = time_start.elapsed();
100        println!("[finalize_tree_creation] duration: {:?}", duration);
101
102        let finalize_tree_response = finalize_tree_response.finalize_tree_response;
103        let nodes = finalize_tree_response.nodes;
104
105        Ok(CreateTreeSdkResponse { nodes })
106    }
107}