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<Box<dyn ::core::future::Future<Output = Result<$result_type, WalletError>> + ::core::marker::Send + 'async_trait>>
58        where
59            'life0: 'async_trait,
60            'life1: 'async_trait,
61            Self: 'async_trait,
62        {
63            Box::pin(async move {
64                let data = $serialize(&args)?;
65                let resp = self
66                    .transmit(WalletWireCall::$call, originator, data)
67                    .await?;
68                $deserialize(&resp)
69            })
70        }
71    };
72    // Methods without args (only originator)
73    (no_args $method:ident, $call:ident, $result_type:ty, $deserialize:path) => {
74        fn $method<'life0, 'life1, 'async_trait>(
75            &'life0 self,
76            originator: Option<&'life1 str>,
77        ) -> ::core::pin::Pin<Box<dyn ::core::future::Future<Output = Result<$result_type, WalletError>> + ::core::marker::Send + 'async_trait>>
78        where
79            'life0: 'async_trait,
80            'life1: 'async_trait,
81            Self: 'async_trait,
82        {
83            Box::pin(async move {
84                let resp = self
85                    .transmit(WalletWireCall::$call, originator, Vec::new())
86                    .await?;
87                $deserialize(&resp)
88            })
89        }
90    };
91}
92
93use crate::wallet::serializer::{
94    abort_action, acquire_certificate, authenticated, certificate_ser, create_action, create_hmac,
95    create_signature, decrypt, discover_by_attributes, discover_by_identity_key,
96    discover_certificates_result, encrypt, get_header, get_height, get_network, get_public_key,
97    get_version, internalize_action, list_actions, list_certificates, list_outputs,
98    prove_certificate, relinquish_certificate, relinquish_output, reveal_counterparty_key_linkage,
99    reveal_specific_key_linkage, sign_action, verify_hmac, verify_signature,
100};
101
102#[async_trait::async_trait]
103impl<W: WalletWire> WalletInterface for WalletWireTransceiver<W> {
104    impl_wire_method!(
105        create_action,
106        CreateAction,
107        CreateActionArgs,
108        CreateActionResult,
109        create_action::serialize_create_action_args,
110        create_action::deserialize_create_action_result
111    );
112
113    impl_wire_method!(
114        sign_action,
115        SignAction,
116        SignActionArgs,
117        SignActionResult,
118        sign_action::serialize_sign_action_args,
119        sign_action::deserialize_sign_action_result
120    );
121
122    impl_wire_method!(
123        abort_action,
124        AbortAction,
125        AbortActionArgs,
126        AbortActionResult,
127        abort_action::serialize_abort_action_args,
128        abort_action::deserialize_abort_action_result
129    );
130
131    impl_wire_method!(
132        list_actions,
133        ListActions,
134        ListActionsArgs,
135        ListActionsResult,
136        list_actions::serialize_list_actions_args,
137        list_actions::deserialize_list_actions_result
138    );
139
140    impl_wire_method!(
141        internalize_action,
142        InternalizeAction,
143        InternalizeActionArgs,
144        InternalizeActionResult,
145        internalize_action::serialize_internalize_action_args,
146        internalize_action::deserialize_internalize_action_result
147    );
148
149    impl_wire_method!(
150        list_outputs,
151        ListOutputs,
152        ListOutputsArgs,
153        ListOutputsResult,
154        list_outputs::serialize_list_outputs_args,
155        list_outputs::deserialize_list_outputs_result
156    );
157
158    impl_wire_method!(
159        relinquish_output,
160        RelinquishOutput,
161        RelinquishOutputArgs,
162        RelinquishOutputResult,
163        relinquish_output::serialize_relinquish_output_args,
164        relinquish_output::deserialize_relinquish_output_result
165    );
166
167    impl_wire_method!(
168        get_public_key,
169        GetPublicKey,
170        GetPublicKeyArgs,
171        GetPublicKeyResult,
172        get_public_key::serialize_get_public_key_args,
173        get_public_key::deserialize_get_public_key_result
174    );
175
176    impl_wire_method!(
177        reveal_counterparty_key_linkage,
178        RevealCounterpartyKeyLinkage,
179        RevealCounterpartyKeyLinkageArgs,
180        RevealCounterpartyKeyLinkageResult,
181        reveal_counterparty_key_linkage::serialize_reveal_counterparty_key_linkage_args,
182        reveal_counterparty_key_linkage::deserialize_reveal_counterparty_key_linkage_result
183    );
184
185    impl_wire_method!(
186        reveal_specific_key_linkage,
187        RevealSpecificKeyLinkage,
188        RevealSpecificKeyLinkageArgs,
189        RevealSpecificKeyLinkageResult,
190        reveal_specific_key_linkage::serialize_reveal_specific_key_linkage_args,
191        reveal_specific_key_linkage::deserialize_reveal_specific_key_linkage_result
192    );
193
194    impl_wire_method!(
195        encrypt,
196        Encrypt,
197        EncryptArgs,
198        EncryptResult,
199        encrypt::serialize_encrypt_args,
200        encrypt::deserialize_encrypt_result
201    );
202
203    impl_wire_method!(
204        decrypt,
205        Decrypt,
206        DecryptArgs,
207        DecryptResult,
208        decrypt::serialize_decrypt_args,
209        decrypt::deserialize_decrypt_result
210    );
211
212    impl_wire_method!(
213        create_hmac,
214        CreateHmac,
215        CreateHmacArgs,
216        CreateHmacResult,
217        create_hmac::serialize_create_hmac_args,
218        create_hmac::deserialize_create_hmac_result
219    );
220
221    impl_wire_method!(
222        verify_hmac,
223        VerifyHmac,
224        VerifyHmacArgs,
225        VerifyHmacResult,
226        verify_hmac::serialize_verify_hmac_args,
227        verify_hmac::deserialize_verify_hmac_result
228    );
229
230    impl_wire_method!(
231        create_signature,
232        CreateSignature,
233        CreateSignatureArgs,
234        CreateSignatureResult,
235        create_signature::serialize_create_signature_args,
236        create_signature::deserialize_create_signature_result
237    );
238
239    impl_wire_method!(
240        verify_signature,
241        VerifySignature,
242        VerifySignatureArgs,
243        VerifySignatureResult,
244        verify_signature::serialize_verify_signature_args,
245        verify_signature::deserialize_verify_signature_result
246    );
247
248    impl_wire_method!(
249        acquire_certificate,
250        AcquireCertificate,
251        AcquireCertificateArgs,
252        Certificate,
253        acquire_certificate::serialize_acquire_certificate_args,
254        certificate_ser::deserialize_certificate
255    );
256
257    impl_wire_method!(
258        list_certificates,
259        ListCertificates,
260        ListCertificatesArgs,
261        ListCertificatesResult,
262        list_certificates::serialize_list_certificates_args,
263        list_certificates::deserialize_list_certificates_result
264    );
265
266    impl_wire_method!(
267        prove_certificate,
268        ProveCertificate,
269        ProveCertificateArgs,
270        ProveCertificateResult,
271        prove_certificate::serialize_prove_certificate_args,
272        prove_certificate::deserialize_prove_certificate_result
273    );
274
275    impl_wire_method!(
276        relinquish_certificate,
277        RelinquishCertificate,
278        RelinquishCertificateArgs,
279        RelinquishCertificateResult,
280        relinquish_certificate::serialize_relinquish_certificate_args,
281        relinquish_certificate::deserialize_relinquish_certificate_result
282    );
283
284    impl_wire_method!(
285        discover_by_identity_key,
286        DiscoverByIdentityKey,
287        DiscoverByIdentityKeyArgs,
288        DiscoverCertificatesResult,
289        discover_by_identity_key::serialize_discover_by_identity_key_args,
290        discover_certificates_result::deserialize_discover_certificates_result
291    );
292
293    impl_wire_method!(
294        discover_by_attributes,
295        DiscoverByAttributes,
296        DiscoverByAttributesArgs,
297        DiscoverCertificatesResult,
298        discover_by_attributes::serialize_discover_by_attributes_args,
299        discover_certificates_result::deserialize_discover_certificates_result
300    );
301
302    impl_wire_method!(no_args
303        is_authenticated, IsAuthenticated, AuthenticatedResult,
304        authenticated::deserialize_is_authenticated_result
305    );
306
307    impl_wire_method!(no_args
308        wait_for_authentication, WaitForAuthentication, AuthenticatedResult,
309        authenticated::deserialize_wait_authenticated_result
310    );
311
312    impl_wire_method!(no_args
313        get_height, GetHeight, GetHeightResult,
314        get_height::deserialize_get_height_result
315    );
316
317    impl_wire_method!(
318        get_header_for_height,
319        GetHeaderForHeight,
320        GetHeaderArgs,
321        GetHeaderResult,
322        get_header::serialize_get_header_args,
323        get_header::deserialize_get_header_result
324    );
325
326    impl_wire_method!(no_args
327        get_network, GetNetwork, GetNetworkResult,
328        get_network::deserialize_get_network_result
329    );
330
331    impl_wire_method!(no_args
332        get_version, GetVersion, GetVersionResult,
333        get_version::deserialize_get_version_result
334    );
335}