use crate::wallet::error::WalletError;
use crate::wallet::serializer::frame::read_request_frame;
use crate::wallet::substrates::wallet_wire_calls::WalletWireCall;
use crate::wallet::substrates::WalletWire;
pub struct HttpWalletWire {
base_url: String,
client: reqwest::Client,
}
impl HttpWalletWire {
pub fn new(base_url: &str) -> Self {
let url = if base_url.is_empty() {
"http://localhost:3301".to_string()
} else {
base_url.to_string()
};
Self {
base_url: url,
client: reqwest::Client::new(),
}
}
}
#[async_trait::async_trait]
impl WalletWire for HttpWalletWire {
async fn transmit_to_wallet(&self, message: &[u8]) -> Result<Vec<u8>, WalletError> {
let frame = read_request_frame(message)?;
let call = WalletWireCall::try_from(frame.call)?;
let url = format!("{}/{}", self.base_url, call.to_call_path());
let mut request = self
.client
.post(&url)
.header("Content-Type", "application/octet-stream")
.body(frame.params.clone());
if !frame.originator.is_empty() {
request = request.header("Origin", frame.originator.clone());
}
let response = request
.send()
.await
.map_err(|e| WalletError::Internal(format!("HTTP request failed: {}", e)))?;
if !response.status().is_success() {
return Err(WalletError::Internal(format!(
"HTTP request failed with status: {}",
response.status()
)));
}
let bytes = response
.bytes()
.await
.map_err(|e| WalletError::Internal(format!("failed to read response: {}", e)))?;
Ok(bytes.to_vec())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_http_wallet_wire_construction() {
let wire = HttpWalletWire::new("http://example.com:3301");
assert_eq!(wire.base_url, "http://example.com:3301");
}
#[test]
fn test_http_wallet_wire_default_url() {
let wire = HttpWalletWire::new("");
assert_eq!(wire.base_url, "http://localhost:3301");
}
}