1use std::sync::Arc;
8
9use bitcoin::secp256k1::{PublicKey, ecdsa, schnorr};
10use spark_wallet::{
11 FrostJob, FrostShareResult, PrepareClaimRequest, PrepareLightningReceiveRequest,
12 PrepareStaticDepositClaimRequest, PrepareStaticDepositRequest, PrepareTokenTransactionRequest,
13 PrepareTransferRequest, PreparedClaim, PreparedLightningReceive, PreparedStaticDeposit,
14 PreparedStaticDepositClaim, PreparedTokenTransaction, PreparedTransfer,
15 SignSparkInvoiceRequest, SignStaticDepositRefundRequest, SignedSparkInvoice, SignerError,
16 StartStaticDepositRefundRequest, StartedStaticDepositRefund, TreeNodeId,
17};
18
19use super::ExternalSparkSigner;
20use super::external_spark_types::{
21 ExternalFrostJob, ExternalFrostShareResult, ExternalPrepareClaimRequest,
22 ExternalPrepareLightningReceiveRequest, ExternalPrepareStaticDepositClaimRequest,
23 ExternalPrepareStaticDepositRequest, ExternalPrepareTokenTransactionRequest,
24 ExternalPrepareTransferRequest, ExternalSignSparkInvoiceRequest,
25 ExternalSignStaticDepositRefundRequest, ExternalStartStaticDepositRefundRequest,
26};
27use super::external_types::ExternalTreeNodeId;
28
29pub struct ExternalSparkSignerAdapter {
32 inner: Arc<dyn ExternalSparkSigner>,
33}
34
35impl ExternalSparkSignerAdapter {
36 pub fn new(inner: Arc<dyn ExternalSparkSigner>) -> Self {
37 Self { inner }
38 }
39}
40
41fn to_spark_err<E: std::fmt::Display>(e: E) -> SignerError {
42 SignerError::Generic(e.to_string())
43}
44
45#[macros::async_trait]
46impl spark_wallet::SparkSigner for ExternalSparkSignerAdapter {
47 async fn get_identity_public_key(&self) -> Result<PublicKey, SignerError> {
48 self.inner
49 .get_identity_public_key()
50 .await
51 .map_err(to_spark_err)?
52 .to_public_key()
53 .map_err(to_spark_err)
54 }
55
56 async fn get_public_key_for_leaf(
57 &self,
58 leaf_id: &TreeNodeId,
59 ) -> Result<PublicKey, SignerError> {
60 let ext = ExternalTreeNodeId::from_tree_node_id(leaf_id).map_err(to_spark_err)?;
61 self.inner
62 .get_public_key_for_leaf(ext)
63 .await
64 .map_err(to_spark_err)?
65 .to_public_key()
66 .map_err(to_spark_err)
67 }
68
69 fn is_remote(&self) -> bool {
70 self.inner.is_remote()
71 }
72
73 async fn get_static_deposit_public_key(&self, index: u32) -> Result<PublicKey, SignerError> {
74 self.inner
75 .get_static_deposit_public_key(index)
76 .await
77 .map_err(to_spark_err)?
78 .to_public_key()
79 .map_err(to_spark_err)
80 }
81
82 async fn sign_authentication_challenge(
83 &self,
84 challenge: &[u8],
85 ) -> Result<ecdsa::Signature, SignerError> {
86 self.inner
87 .sign_authentication_challenge(challenge.to_vec())
88 .await
89 .map_err(to_spark_err)?
90 .to_signature()
91 .map_err(to_spark_err)
92 }
93
94 async fn sign_message(&self, message: &[u8]) -> Result<ecdsa::Signature, SignerError> {
95 self.inner
96 .sign_message(message.to_vec())
97 .await
98 .map_err(to_spark_err)?
99 .to_signature()
100 .map_err(to_spark_err)
101 }
102
103 async fn sign_leaf_refund_spend(
104 &self,
105 leaf_id: &TreeNodeId,
106 sighash: &[u8],
107 ) -> Result<schnorr::Signature, SignerError> {
108 let ext = ExternalTreeNodeId::from_tree_node_id(leaf_id).map_err(to_spark_err)?;
109 self.inner
110 .sign_leaf_refund_spend(ext, sighash.to_vec())
111 .await
112 .map_err(to_spark_err)?
113 .to_signature()
114 .map_err(to_spark_err)
115 }
116
117 async fn sign_frost(&self, jobs: Vec<FrostJob>) -> Result<Vec<FrostShareResult>, SignerError> {
118 let ext_jobs = jobs
119 .iter()
120 .map(ExternalFrostJob::from_frost_job)
121 .collect::<Result<Vec<_>, _>>()
122 .map_err(to_spark_err)?;
123 let results = self
124 .inner
125 .sign_frost(ext_jobs)
126 .await
127 .map_err(to_spark_err)?;
128 results
129 .iter()
130 .map(ExternalFrostShareResult::to_frost_share_result)
131 .collect::<Result<Vec<_>, _>>()
132 .map_err(to_spark_err)
133 }
134
135 async fn prepare_transfer(
136 &self,
137 request: PrepareTransferRequest,
138 ) -> Result<PreparedTransfer, SignerError> {
139 let ext = ExternalPrepareTransferRequest::from_prepare_transfer_request(&request)
140 .map_err(to_spark_err)?;
141 self.inner
142 .prepare_transfer(ext)
143 .await
144 .map_err(to_spark_err)?
145 .to_prepared_transfer()
146 .map_err(to_spark_err)
147 }
148
149 async fn prepare_claim(
150 &self,
151 request: PrepareClaimRequest,
152 ) -> Result<PreparedClaim, SignerError> {
153 let ext = ExternalPrepareClaimRequest::from_prepare_claim_request(&request)
154 .map_err(to_spark_err)?;
155 self.inner
156 .prepare_claim(ext)
157 .await
158 .map_err(to_spark_err)?
159 .to_prepared_claim()
160 .map_err(to_spark_err)
161 }
162
163 async fn prepare_lightning_receive(
164 &self,
165 request: PrepareLightningReceiveRequest,
166 ) -> Result<PreparedLightningReceive, SignerError> {
167 let ext = ExternalPrepareLightningReceiveRequest::from_prepare_lightning_receive_request(
168 &request,
169 )
170 .map_err(to_spark_err)?;
171 self.inner
172 .prepare_lightning_receive(ext)
173 .await
174 .map_err(to_spark_err)?
175 .to_prepared_lightning_receive()
176 .map_err(to_spark_err)
177 }
178
179 async fn prepare_static_deposit(
180 &self,
181 request: PrepareStaticDepositRequest,
182 ) -> Result<PreparedStaticDeposit, SignerError> {
183 let ext =
184 ExternalPrepareStaticDepositRequest::from_prepare_static_deposit_request(&request)
185 .map_err(to_spark_err)?;
186 self.inner
187 .prepare_static_deposit(ext)
188 .await
189 .map_err(to_spark_err)?
190 .to_prepared_static_deposit()
191 .map_err(to_spark_err)
192 }
193
194 async fn start_static_deposit_refund(
195 &self,
196 request: StartStaticDepositRefundRequest,
197 ) -> Result<StartedStaticDepositRefund, SignerError> {
198 let ext =
199 ExternalStartStaticDepositRefundRequest::from_start_static_deposit_refund_request(
200 &request,
201 )
202 .map_err(to_spark_err)?;
203 self.inner
204 .start_static_deposit_refund(ext)
205 .await
206 .map_err(to_spark_err)?
207 .to_started_static_deposit_refund()
208 .map_err(to_spark_err)
209 }
210
211 async fn sign_static_deposit_refund(
212 &self,
213 request: SignStaticDepositRefundRequest,
214 ) -> Result<frost_secp256k1_tr::Signature, SignerError> {
215 let ext = ExternalSignStaticDepositRefundRequest::from_sign_static_deposit_refund_request(
216 &request,
217 )
218 .map_err(to_spark_err)?;
219 self.inner
220 .sign_static_deposit_refund(ext)
221 .await
222 .map_err(to_spark_err)?
223 .to_frost_signature()
224 .map_err(to_spark_err)
225 }
226
227 async fn sign_spark_invoice(
228 &self,
229 request: SignSparkInvoiceRequest,
230 ) -> Result<SignedSparkInvoice, SignerError> {
231 let ext = ExternalSignSparkInvoiceRequest::from_sign_spark_invoice_request(&request)
232 .map_err(to_spark_err)?;
233 self.inner
234 .sign_spark_invoice(ext)
235 .await
236 .map_err(to_spark_err)?
237 .to_signed_spark_invoice()
238 .map_err(to_spark_err)
239 }
240
241 async fn prepare_token_transaction(
242 &self,
243 request: PrepareTokenTransactionRequest,
244 ) -> Result<PreparedTokenTransaction, SignerError> {
245 let ext = ExternalPrepareTokenTransactionRequest::from_prepare_token_transaction_request(
246 &request,
247 )
248 .map_err(to_spark_err)?;
249 self.inner
250 .prepare_token_transaction(ext)
251 .await
252 .map_err(to_spark_err)?
253 .to_prepared_token_transaction()
254 .map_err(to_spark_err)
255 }
256
257 async fn prepare_static_deposit_claim(
258 &self,
259 request: PrepareStaticDepositClaimRequest,
260 ) -> Result<PreparedStaticDepositClaim, SignerError> {
261 let ext =
262 ExternalPrepareStaticDepositClaimRequest::from_prepare_static_deposit_claim_request(
263 &request,
264 )
265 .map_err(to_spark_err)?;
266 self.inner
267 .prepare_static_deposit_claim(ext)
268 .await
269 .map_err(to_spark_err)?
270 .to_prepared_static_deposit_claim()
271 .map_err(to_spark_err)
272 }
273}