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}