Skip to main content

bsv/wallet/substrates/
wallet_wire_processor.rs

1//! WalletWireProcessor: receives wire frames, dispatches to a wallet
2//! implementation, and returns wire result frames.
3//!
4//! This is the server-side half of the wire protocol. It reads the request
5//! frame, deserializes args, calls the real wallet, serializes the result,
6//! and writes a result frame.
7//!
8//! Also implements WalletWire so it can be used as an in-memory transport
9//! for testing (transceiver -> processor -> wallet).
10//!
11//! Translated from Go SDK wallet/substrates/wallet_wire_processor.go.
12
13use crate::wallet::error::WalletError;
14use crate::wallet::interfaces::WalletInterface;
15use crate::wallet::serializer::frame::{read_request_frame, write_result_frame};
16use crate::wallet::substrates::wallet_wire_calls::WalletWireCall;
17use crate::wallet::substrates::WalletWire;
18
19use crate::wallet::serializer::{
20    abort_action, acquire_certificate, authenticated, certificate_ser, create_action, create_hmac,
21    create_signature, decrypt, discover_by_attributes, discover_by_identity_key,
22    discover_certificates_result, encrypt, get_header, get_height, get_network, get_public_key,
23    get_version, internalize_action, list_actions, list_certificates, list_outputs,
24    prove_certificate, relinquish_certificate, relinquish_output, reveal_counterparty_key_linkage,
25    reveal_specific_key_linkage, sign_action, verify_hmac, verify_signature,
26};
27
28/// Receives wire protocol messages and dispatches them to a wallet implementation.
29pub struct WalletWireProcessor<W: WalletInterface> {
30    wallet: W,
31}
32
33impl<W: WalletInterface> WalletWireProcessor<W> {
34    /// Create a new processor wrapping a wallet implementation.
35    pub fn new(wallet: W) -> Self {
36        Self { wallet }
37    }
38
39    /// Process a raw wire message: parse frame, dispatch, return result frame.
40    pub async fn process(&self, message: &[u8]) -> Vec<u8> {
41        match self.process_inner(message).await {
42            Ok(result_data) => write_result_frame(Some(&result_data), None),
43            Err(err) => write_result_frame(None, Some(&err)),
44        }
45    }
46
47    async fn process_inner(&self, message: &[u8]) -> Result<Vec<u8>, WalletError> {
48        if message.is_empty() {
49            return Err(WalletError::Internal("empty message".to_string()));
50        }
51
52        let frame = read_request_frame(message)?;
53        let call = WalletWireCall::try_from(frame.call)?;
54        let originator = if frame.originator.is_empty() {
55            None
56        } else {
57            Some(frame.originator.as_str())
58        };
59
60        match call {
61            WalletWireCall::CreateAction => {
62                let args = create_action::deserialize_create_action_args(&frame.params)?;
63                let result = self.wallet.create_action(args, originator).await?;
64                create_action::serialize_create_action_result(&result)
65            }
66            WalletWireCall::SignAction => {
67                let args = sign_action::deserialize_sign_action_args(&frame.params)?;
68                let result = self.wallet.sign_action(args, originator).await?;
69                sign_action::serialize_sign_action_result(&result)
70            }
71            WalletWireCall::AbortAction => {
72                let args = abort_action::deserialize_abort_action_args(&frame.params)?;
73                let result = self.wallet.abort_action(args, originator).await?;
74                abort_action::serialize_abort_action_result(&result)
75            }
76            WalletWireCall::ListActions => {
77                let args = list_actions::deserialize_list_actions_args(&frame.params)?;
78                let result = self.wallet.list_actions(args, originator).await?;
79                list_actions::serialize_list_actions_result(&result)
80            }
81            WalletWireCall::InternalizeAction => {
82                let args = internalize_action::deserialize_internalize_action_args(&frame.params)?;
83                let result = self.wallet.internalize_action(args, originator).await?;
84                internalize_action::serialize_internalize_action_result(&result)
85            }
86            WalletWireCall::ListOutputs => {
87                let args = list_outputs::deserialize_list_outputs_args(&frame.params)?;
88                let result = self.wallet.list_outputs(args, originator).await?;
89                list_outputs::serialize_list_outputs_result(&result)
90            }
91            WalletWireCall::RelinquishOutput => {
92                let args = relinquish_output::deserialize_relinquish_output_args(&frame.params)?;
93                let result = self.wallet.relinquish_output(args, originator).await?;
94                relinquish_output::serialize_relinquish_output_result(&result)
95            }
96            WalletWireCall::GetPublicKey => {
97                let args = get_public_key::deserialize_get_public_key_args(&frame.params)?;
98                let result = self.wallet.get_public_key(args, originator).await?;
99                get_public_key::serialize_get_public_key_result(&result)
100            }
101            WalletWireCall::RevealCounterpartyKeyLinkage => {
102                let args = reveal_counterparty_key_linkage::deserialize_reveal_counterparty_key_linkage_args(&frame.params)?;
103                let result = self
104                    .wallet
105                    .reveal_counterparty_key_linkage(args, originator)
106                    .await?;
107                reveal_counterparty_key_linkage::serialize_reveal_counterparty_key_linkage_result(
108                    &result,
109                )
110            }
111            WalletWireCall::RevealSpecificKeyLinkage => {
112                let args =
113                    reveal_specific_key_linkage::deserialize_reveal_specific_key_linkage_args(
114                        &frame.params,
115                    )?;
116                let result = self
117                    .wallet
118                    .reveal_specific_key_linkage(args, originator)
119                    .await?;
120                reveal_specific_key_linkage::serialize_reveal_specific_key_linkage_result(&result)
121            }
122            WalletWireCall::Encrypt => {
123                let args = encrypt::deserialize_encrypt_args(&frame.params)?;
124                let result = self.wallet.encrypt(args, originator).await?;
125                encrypt::serialize_encrypt_result(&result)
126            }
127            WalletWireCall::Decrypt => {
128                let args = decrypt::deserialize_decrypt_args(&frame.params)?;
129                let result = self.wallet.decrypt(args, originator).await?;
130                decrypt::serialize_decrypt_result(&result)
131            }
132            WalletWireCall::CreateHmac => {
133                let args = create_hmac::deserialize_create_hmac_args(&frame.params)?;
134                let result = self.wallet.create_hmac(args, originator).await?;
135                create_hmac::serialize_create_hmac_result(&result)
136            }
137            WalletWireCall::VerifyHmac => {
138                let args = verify_hmac::deserialize_verify_hmac_args(&frame.params)?;
139                let result = self.wallet.verify_hmac(args, originator).await?;
140                verify_hmac::serialize_verify_hmac_result(&result)
141            }
142            WalletWireCall::CreateSignature => {
143                let args = create_signature::deserialize_create_signature_args(&frame.params)?;
144                let result = self.wallet.create_signature(args, originator).await?;
145                create_signature::serialize_create_signature_result(&result)
146            }
147            WalletWireCall::VerifySignature => {
148                let args = verify_signature::deserialize_verify_signature_args(&frame.params)?;
149                let result = self.wallet.verify_signature(args, originator).await?;
150                verify_signature::serialize_verify_signature_result(&result)
151            }
152            WalletWireCall::AcquireCertificate => {
153                let args =
154                    acquire_certificate::deserialize_acquire_certificate_args(&frame.params)?;
155                let result = self.wallet.acquire_certificate(args, originator).await?;
156                certificate_ser::serialize_certificate(&result)
157            }
158            WalletWireCall::ListCertificates => {
159                let args = list_certificates::deserialize_list_certificates_args(&frame.params)?;
160                let result = self.wallet.list_certificates(args, originator).await?;
161                list_certificates::serialize_list_certificates_result(&result)
162            }
163            WalletWireCall::ProveCertificate => {
164                let args = prove_certificate::deserialize_prove_certificate_args(&frame.params)?;
165                let result = self.wallet.prove_certificate(args, originator).await?;
166                prove_certificate::serialize_prove_certificate_result(&result)
167            }
168            WalletWireCall::RelinquishCertificate => {
169                let args =
170                    relinquish_certificate::deserialize_relinquish_certificate_args(&frame.params)?;
171                let result = self.wallet.relinquish_certificate(args, originator).await?;
172                relinquish_certificate::serialize_relinquish_certificate_result(&result)
173            }
174            WalletWireCall::DiscoverByIdentityKey => {
175                let args = discover_by_identity_key::deserialize_discover_by_identity_key_args(
176                    &frame.params,
177                )?;
178                let result = self
179                    .wallet
180                    .discover_by_identity_key(args, originator)
181                    .await?;
182                discover_certificates_result::serialize_discover_certificates_result(&result)
183            }
184            WalletWireCall::DiscoverByAttributes => {
185                let args =
186                    discover_by_attributes::deserialize_discover_by_attributes_args(&frame.params)?;
187                let result = self.wallet.discover_by_attributes(args, originator).await?;
188                discover_certificates_result::serialize_discover_certificates_result(&result)
189            }
190            WalletWireCall::IsAuthenticated => {
191                let result = self.wallet.is_authenticated(originator).await?;
192                authenticated::serialize_is_authenticated_result(&result)
193            }
194            WalletWireCall::WaitForAuthentication => {
195                let result = self.wallet.wait_for_authentication(originator).await?;
196                authenticated::serialize_wait_authenticated_result(&result)
197            }
198            WalletWireCall::GetHeight => {
199                let result = self.wallet.get_height(originator).await?;
200                get_height::serialize_get_height_result(&result)
201            }
202            WalletWireCall::GetHeaderForHeight => {
203                let args = get_header::deserialize_get_header_args(&frame.params)?;
204                let result = self.wallet.get_header_for_height(args, originator).await?;
205                get_header::serialize_get_header_result(&result)
206            }
207            WalletWireCall::GetNetwork => {
208                let result = self.wallet.get_network(originator).await?;
209                get_network::serialize_get_network_result(&result)
210            }
211            WalletWireCall::GetVersion => {
212                let result = self.wallet.get_version(originator).await?;
213                get_version::serialize_get_version_result(&result)
214            }
215        }
216    }
217}
218
219/// WalletWireProcessor also implements WalletWire so it can serve as an
220/// in-memory transport for testing (transceiver -> processor -> wallet).
221#[async_trait::async_trait]
222impl<W: WalletInterface + Send + Sync> WalletWire for WalletWireProcessor<W> {
223    async fn transmit_to_wallet(&self, message: &[u8]) -> Result<Vec<u8>, WalletError> {
224        Ok(self.process(message).await)
225    }
226}