spark_sdk/wallet/internal_handlers/traits/
transfer.rs

1use crate::common_types::types::Transaction;
2use crate::error::SparkSdkError;
3use crate::signer::traits::SparkSigner;
4use spark_protos::common::SigningCommitment as ProtoSigningCommitment;
5use spark_protos::spark::ClaimLeafKeyTweak;
6use spark_protos::spark::LeafRefundTxSigningJob;
7use spark_protos::spark::SendLeafKeyTweak;
8use spark_protos::spark::Transfer;
9use spark_protos::spark::TreeNode;
10use std::collections::HashMap;
11use tonic::async_trait;
12
13/// Core struct representing transfer-related key tweaking data
14#[derive(Debug, Clone)]
15pub struct LeafKeyTweak {
16    /// The leaf node
17    pub leaf: TreeNode,
18
19    /// The public key of the leaf
20    pub old_signing_private_key: Vec<u8>,
21
22    /// The new public key of the leaf
23    pub new_signing_public_key: Vec<u8>,
24}
25
26/// Struct to maintain data for refund signing operations
27#[derive(Debug)]
28pub struct LeafRefundSigningData {
29    /// The public key of the leaf
30    pub signing_public_key: Vec<u8>,
31
32    /// The public key of the receiver
33    pub receiving_pubkey: Vec<u8>,
34
35    /// The transaction to be signed
36    pub tx: Transaction,
37
38    /// The refund transaction
39    pub refund_tx: Option<Transaction>,
40
41    /// Signing commitment
42    pub commitment: ProtoSigningCommitment,
43
44    /// The vout of the transaction
45    pub vout: u32,
46}
47
48#[async_trait]
49pub(crate) trait TransferInternalHandlers<S: SparkSigner + Send + Sync> {
50    /// Top-level transfer execution function, given the leaves to transfer. The function expects the leaves to be in [`LeafKeyTweak`] format.
51    ///
52    /// # Arguments
53    ///
54    /// * `leaves` - A vector of [`LeafKeyTweak`] objects representing the leaves to transfer.
55    /// * `receiver_identity_pubkey` - The public key of the receiver.
56    /// * `expiry_time` - The expiry time of the transfer.
57    ///
58    /// # Returns
59    ///
60    /// A [`Transfer`] object representing the transfer. This is an auto-converted protobuf object that is returned by the Spark API as the last step of the transfer for the sender.
61    async fn start_send_transfer(
62        &self,
63        leaves: &Vec<LeafKeyTweak>,
64        receiver_identity_pubkey: Vec<u8>,
65        expiry_time: u64,
66    ) -> Result<Transfer, SparkSdkError>;
67
68    async fn send_transfer_tweak_key(
69        &self,
70        transfer: Transfer,
71        leaves: &Vec<LeafKeyTweak>,
72        refund_signature_map: &HashMap<String, Vec<u8>>,
73    ) -> Result<Transfer, SparkSdkError>;
74
75    async fn send_transfer_sign_refunds(
76        &self,
77        leaves: &Vec<LeafKeyTweak>,
78        receiver_identity_pubkey: Vec<u8>,
79        expiry_time: u64,
80    ) -> Result<(Transfer, HashMap<String, Vec<u8>>), SparkSdkError>;
81
82    fn prepare_send_transfer_key_tweaks(
83        &self,
84        transfer: &Transfer,
85        leaves: &Vec<LeafKeyTweak>,
86        refund_signature_map: &HashMap<String, Vec<u8>>,
87    ) -> Result<HashMap<String, Vec<SendLeafKeyTweak>>, SparkSdkError>;
88
89    fn prepare_single_send_transfer_key_tweak(
90        &self,
91        transfer_id: &str,
92        leaf: &LeafKeyTweak,
93        receiver_pubkey: &Vec<u8>,
94        refund_signature: &Vec<u8>,
95    ) -> Result<HashMap<String, SendLeafKeyTweak>, SparkSdkError>;
96
97    fn prepare_refund_so_signing_jobs(
98        &self,
99        leaves: &Vec<LeafKeyTweak>,
100        leaf_data_map: &mut HashMap<String, LeafRefundSigningData>,
101    ) -> Result<Vec<LeafRefundTxSigningJob>, SparkSdkError>;
102
103    fn create_refund_tx(
104        &self,
105        leaf: &TreeNode,
106        receiving_pubkey: &Vec<u8>,
107    ) -> Result<bitcoin::Transaction, SparkSdkError>;
108
109    // Helper methods
110    fn compare_transfers(&self, t1: &Transfer, t2: &Transfer) -> bool;
111
112    async fn claim_finalize_incoming_transfer(
113        &self,
114        transfer: &Transfer,
115        leaves: &Vec<LeafKeyTweak>,
116    ) -> Result<(), SparkSdkError>;
117
118    async fn claim_transfer_tweak_keys(
119        &self,
120        transfer: &Transfer,
121        leaves: &Vec<LeafKeyTweak>,
122    ) -> Result<(), SparkSdkError>;
123
124    fn prepare_claim_leaves_key_tweaks(
125        &self,
126        leaves: &Vec<LeafKeyTweak>,
127    ) -> Result<HashMap<String, Vec<ClaimLeafKeyTweak>>, SparkSdkError>;
128
129    fn prepare_claim_leaf_key_tweaks(
130        &self,
131        leaf: &LeafKeyTweak,
132    ) -> Result<HashMap<String, ClaimLeafKeyTweak>, SparkSdkError>;
133
134    async fn claim_transfer_sign_refunds(
135        &self,
136        transfer: &Transfer,
137        leaf_keys: &Vec<LeafKeyTweak>,
138    ) -> Result<Vec<spark_protos::spark::NodeSignatures>, SparkSdkError>;
139
140    async fn finalize_transfer(
141        &self,
142        signatures: &[spark_protos::spark::NodeSignatures],
143    ) -> Result<(), SparkSdkError>;
144
145    /// Verifies a pending transfer sent by a remote party. This will:
146    ///   1) Parse and verify the ECDSA signature from the sender.
147    ///   2) Decrypt the leaf secrets for all leaves using our own identity private key.
148    ///
149    /// # Arguments
150    ///
151    /// * `transfer` - The transfer object to verify.
152    ///
153    /// # Returns
154    ///
155    /// A `HashMap` of leaf IDs to the decrypted private keys for each leaf.
156    async fn verify_pending_transfer(
157        &self,
158        transfer: &spark_protos::spark::Transfer,
159    ) -> Result<HashMap<String, Vec<u8>>, SparkSdkError>;
160}