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