Skip to main content

bsv/wallet/substrates/
wallet_wire_transceiver.rs

1//! WalletWireTransceiver: implements WalletInterface by serializing calls
2//! and transmitting them over a WalletWire transport.
3//!
4//! This is the client-side half of the wire protocol. Each wallet method
5//! serializes its arguments, builds a request frame, transmits via the
6//! WalletWire, reads the result frame, and deserializes the result.
7//!
8//! Translated from Go SDK wallet/substrates/wallet_wire_transceiver.go.
9
10use crate::wallet::error::WalletError;
11use crate::wallet::interfaces::*;
12use crate::wallet::serializer::frame::{read_result_frame, write_request_frame, RequestFrame};
13use crate::wallet::substrates::wallet_wire_calls::WalletWireCall;
14use crate::wallet::substrates::WalletWire;
15
16/// Implements WalletInterface by serializing each call and sending it over
17/// a WalletWire transport. Pairs with WalletWireProcessor on the server side.
18pub struct WalletWireTransceiver<W: WalletWire> {
19    wire: W,
20}
21
22impl<W: WalletWire> WalletWireTransceiver<W> {
23    /// Create a new transceiver wrapping the given wire transport.
24    pub fn new(wire: W) -> Self {
25        Self { wire }
26    }
27
28    /// Transmit a call: build frame, send over wire, read result.
29    async fn transmit(
30        &self,
31        call: WalletWireCall,
32        originator: Option<&str>,
33        params: Vec<u8>,
34    ) -> Result<Vec<u8>, WalletError> {
35        let frame = write_request_frame(&RequestFrame {
36            call: call as u8,
37            originator: originator.unwrap_or("").to_string(),
38            params,
39        });
40
41        let result = self.wire.transmit_to_wallet(&frame).await?;
42        read_result_frame(&result)
43    }
44}
45
46/// Macro to reduce boilerplate for the 28 method implementations.
47/// Pattern: serialize args -> transmit -> deserialize result.
48/// Uses desugared async-trait form so it works inside #[async_trait] impl blocks.
49macro_rules! impl_wire_method {
50    // Methods with args
51    ($method:ident, $call:ident, $args_type:ty, $result_type:ty,
52     $serialize:path, $deserialize:path) => {
53        fn $method<'life0, 'life1, 'async_trait>(
54            &'life0 self,
55            args: $args_type,
56            originator: Option<&'life1 str>,
57        ) -> ::core::pin::Pin<
58            Box<
59                dyn ::core::future::Future<Output = Result<$result_type, WalletError>>
60                    + ::core::marker::Send
61                    + 'async_trait,
62            >,
63        >
64        where
65            'life0: 'async_trait,
66            'life1: 'async_trait,
67            Self: 'async_trait,
68        {
69            Box::pin(async move {
70                let data = $serialize(&args)?;
71                let resp = self
72                    .transmit(WalletWireCall::$call, originator, data)
73                    .await?;
74                $deserialize(&resp)
75            })
76        }
77    };
78    // Methods without args (only originator)
79    (no_args $method:ident, $call:ident, $result_type:ty, $deserialize:path) => {
80        fn $method<'life0, 'life1, 'async_trait>(
81            &'life0 self,
82            originator: Option<&'life1 str>,
83        ) -> ::core::pin::Pin<
84            Box<
85                dyn ::core::future::Future<Output = Result<$result_type, WalletError>>
86                    + ::core::marker::Send
87                    + 'async_trait,
88            >,
89        >
90        where
91            'life0: 'async_trait,
92            'life1: 'async_trait,
93            Self: 'async_trait,
94        {
95            Box::pin(async move {
96                let resp = self
97                    .transmit(WalletWireCall::$call, originator, Vec::new())
98                    .await?;
99                $deserialize(&resp)
100            })
101        }
102    };
103}
104
105use crate::wallet::serializer::{
106    abort_action, acquire_certificate, authenticated, certificate_ser, create_action, create_hmac,
107    create_signature, decrypt, discover_by_attributes, discover_by_identity_key,
108    discover_certificates_result, encrypt, get_header, get_height, get_network, get_public_key,
109    get_version, internalize_action, list_actions, list_certificates, list_outputs,
110    prove_certificate, relinquish_certificate, relinquish_output, reveal_counterparty_key_linkage,
111    reveal_specific_key_linkage, sign_action, verify_hmac, verify_signature,
112};
113
114#[async_trait::async_trait]
115impl<W: WalletWire> WalletInterface for WalletWireTransceiver<W> {
116    impl_wire_method!(
117        create_action,
118        CreateAction,
119        CreateActionArgs,
120        CreateActionResult,
121        create_action::serialize_create_action_args,
122        create_action::deserialize_create_action_result
123    );
124
125    impl_wire_method!(
126        sign_action,
127        SignAction,
128        SignActionArgs,
129        SignActionResult,
130        sign_action::serialize_sign_action_args,
131        sign_action::deserialize_sign_action_result
132    );
133
134    impl_wire_method!(
135        abort_action,
136        AbortAction,
137        AbortActionArgs,
138        AbortActionResult,
139        abort_action::serialize_abort_action_args,
140        abort_action::deserialize_abort_action_result
141    );
142
143    impl_wire_method!(
144        list_actions,
145        ListActions,
146        ListActionsArgs,
147        ListActionsResult,
148        list_actions::serialize_list_actions_args,
149        list_actions::deserialize_list_actions_result
150    );
151
152    impl_wire_method!(
153        internalize_action,
154        InternalizeAction,
155        InternalizeActionArgs,
156        InternalizeActionResult,
157        internalize_action::serialize_internalize_action_args,
158        internalize_action::deserialize_internalize_action_result
159    );
160
161    impl_wire_method!(
162        list_outputs,
163        ListOutputs,
164        ListOutputsArgs,
165        ListOutputsResult,
166        list_outputs::serialize_list_outputs_args,
167        list_outputs::deserialize_list_outputs_result
168    );
169
170    impl_wire_method!(
171        relinquish_output,
172        RelinquishOutput,
173        RelinquishOutputArgs,
174        RelinquishOutputResult,
175        relinquish_output::serialize_relinquish_output_args,
176        relinquish_output::deserialize_relinquish_output_result
177    );
178
179    impl_wire_method!(
180        get_public_key,
181        GetPublicKey,
182        GetPublicKeyArgs,
183        GetPublicKeyResult,
184        get_public_key::serialize_get_public_key_args,
185        get_public_key::deserialize_get_public_key_result
186    );
187
188    impl_wire_method!(
189        reveal_counterparty_key_linkage,
190        RevealCounterpartyKeyLinkage,
191        RevealCounterpartyKeyLinkageArgs,
192        RevealCounterpartyKeyLinkageResult,
193        reveal_counterparty_key_linkage::serialize_reveal_counterparty_key_linkage_args,
194        reveal_counterparty_key_linkage::deserialize_reveal_counterparty_key_linkage_result
195    );
196
197    impl_wire_method!(
198        reveal_specific_key_linkage,
199        RevealSpecificKeyLinkage,
200        RevealSpecificKeyLinkageArgs,
201        RevealSpecificKeyLinkageResult,
202        reveal_specific_key_linkage::serialize_reveal_specific_key_linkage_args,
203        reveal_specific_key_linkage::deserialize_reveal_specific_key_linkage_result
204    );
205
206    impl_wire_method!(
207        encrypt,
208        Encrypt,
209        EncryptArgs,
210        EncryptResult,
211        encrypt::serialize_encrypt_args,
212        encrypt::deserialize_encrypt_result
213    );
214
215    impl_wire_method!(
216        decrypt,
217        Decrypt,
218        DecryptArgs,
219        DecryptResult,
220        decrypt::serialize_decrypt_args,
221        decrypt::deserialize_decrypt_result
222    );
223
224    impl_wire_method!(
225        create_hmac,
226        CreateHmac,
227        CreateHmacArgs,
228        CreateHmacResult,
229        create_hmac::serialize_create_hmac_args,
230        create_hmac::deserialize_create_hmac_result
231    );
232
233    impl_wire_method!(
234        verify_hmac,
235        VerifyHmac,
236        VerifyHmacArgs,
237        VerifyHmacResult,
238        verify_hmac::serialize_verify_hmac_args,
239        verify_hmac::deserialize_verify_hmac_result
240    );
241
242    impl_wire_method!(
243        create_signature,
244        CreateSignature,
245        CreateSignatureArgs,
246        CreateSignatureResult,
247        create_signature::serialize_create_signature_args,
248        create_signature::deserialize_create_signature_result
249    );
250
251    impl_wire_method!(
252        verify_signature,
253        VerifySignature,
254        VerifySignatureArgs,
255        VerifySignatureResult,
256        verify_signature::serialize_verify_signature_args,
257        verify_signature::deserialize_verify_signature_result
258    );
259
260    impl_wire_method!(
261        acquire_certificate,
262        AcquireCertificate,
263        AcquireCertificateArgs,
264        Certificate,
265        acquire_certificate::serialize_acquire_certificate_args,
266        certificate_ser::deserialize_certificate
267    );
268
269    impl_wire_method!(
270        list_certificates,
271        ListCertificates,
272        ListCertificatesArgs,
273        ListCertificatesResult,
274        list_certificates::serialize_list_certificates_args,
275        list_certificates::deserialize_list_certificates_result
276    );
277
278    impl_wire_method!(
279        prove_certificate,
280        ProveCertificate,
281        ProveCertificateArgs,
282        ProveCertificateResult,
283        prove_certificate::serialize_prove_certificate_args,
284        prove_certificate::deserialize_prove_certificate_result
285    );
286
287    impl_wire_method!(
288        relinquish_certificate,
289        RelinquishCertificate,
290        RelinquishCertificateArgs,
291        RelinquishCertificateResult,
292        relinquish_certificate::serialize_relinquish_certificate_args,
293        relinquish_certificate::deserialize_relinquish_certificate_result
294    );
295
296    impl_wire_method!(
297        discover_by_identity_key,
298        DiscoverByIdentityKey,
299        DiscoverByIdentityKeyArgs,
300        DiscoverCertificatesResult,
301        discover_by_identity_key::serialize_discover_by_identity_key_args,
302        discover_certificates_result::deserialize_discover_certificates_result
303    );
304
305    impl_wire_method!(
306        discover_by_attributes,
307        DiscoverByAttributes,
308        DiscoverByAttributesArgs,
309        DiscoverCertificatesResult,
310        discover_by_attributes::serialize_discover_by_attributes_args,
311        discover_certificates_result::deserialize_discover_certificates_result
312    );
313
314    impl_wire_method!(no_args
315        is_authenticated, IsAuthenticated, AuthenticatedResult,
316        authenticated::deserialize_is_authenticated_result
317    );
318
319    impl_wire_method!(no_args
320        wait_for_authentication, WaitForAuthentication, AuthenticatedResult,
321        authenticated::deserialize_wait_authenticated_result
322    );
323
324    impl_wire_method!(no_args
325        get_height, GetHeight, GetHeightResult,
326        get_height::deserialize_get_height_result
327    );
328
329    impl_wire_method!(
330        get_header_for_height,
331        GetHeaderForHeight,
332        GetHeaderArgs,
333        GetHeaderResult,
334        get_header::serialize_get_header_args,
335        get_header::deserialize_get_header_result
336    );
337
338    impl_wire_method!(no_args
339        get_network, GetNetwork, GetNetworkResult,
340        get_network::deserialize_get_network_result
341    );
342
343    impl_wire_method!(no_args
344        get_version, GetVersion, GetVersionResult,
345        get_version::deserialize_get_version_result
346    );
347}