use std::sync::Arc;
use bsv::wallet::interfaces::WalletInterface;
use crate::error::PaymentError;
use crate::types::CalculateRequestPrice;
pub struct PaymentMiddlewareConfig<W: WalletInterface> {
pub wallet: W,
pub calculate_request_price: Option<Arc<CalculateRequestPrice>>,
}
pub struct PaymentMiddlewareConfigBuilder<W: WalletInterface> {
wallet: Option<W>,
calculate_request_price: Option<Arc<CalculateRequestPrice>>,
}
impl<W: WalletInterface> Default for PaymentMiddlewareConfigBuilder<W> {
fn default() -> Self {
Self::new()
}
}
impl<W: WalletInterface> PaymentMiddlewareConfigBuilder<W> {
pub fn new() -> Self {
Self {
wallet: None,
calculate_request_price: None,
}
}
pub fn wallet(mut self, wallet: W) -> Self {
self.wallet = Some(wallet);
self
}
pub fn calculate_request_price(mut self, cb: CalculateRequestPrice) -> Self {
self.calculate_request_price = Some(Arc::new(cb));
self
}
pub fn build(self) -> Result<PaymentMiddlewareConfig<W>, PaymentError> {
let wallet = self.wallet.ok_or(PaymentError::ServerMisconfigured)?;
Ok(PaymentMiddlewareConfig {
wallet,
calculate_request_price: self.calculate_request_price,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use async_trait::async_trait;
use bsv::wallet::error::WalletError;
use bsv::wallet::interfaces::*;
#[derive(Clone)]
struct MockWallet;
#[async_trait]
impl WalletInterface for MockWallet {
async fn create_action(
&self,
_args: CreateActionArgs,
_originator: Option<&str>,
) -> Result<CreateActionResult, WalletError> {
unimplemented!()
}
async fn sign_action(
&self,
_args: SignActionArgs,
_originator: Option<&str>,
) -> Result<SignActionResult, WalletError> {
unimplemented!()
}
async fn abort_action(
&self,
_args: AbortActionArgs,
_originator: Option<&str>,
) -> Result<AbortActionResult, WalletError> {
unimplemented!()
}
async fn list_actions(
&self,
_args: ListActionsArgs,
_originator: Option<&str>,
) -> Result<ListActionsResult, WalletError> {
unimplemented!()
}
async fn internalize_action(
&self,
_args: InternalizeActionArgs,
_originator: Option<&str>,
) -> Result<InternalizeActionResult, WalletError> {
unimplemented!()
}
async fn list_outputs(
&self,
_args: ListOutputsArgs,
_originator: Option<&str>,
) -> Result<ListOutputsResult, WalletError> {
unimplemented!()
}
async fn relinquish_output(
&self,
_args: RelinquishOutputArgs,
_originator: Option<&str>,
) -> Result<RelinquishOutputResult, WalletError> {
unimplemented!()
}
async fn get_public_key(
&self,
_args: GetPublicKeyArgs,
_originator: Option<&str>,
) -> Result<GetPublicKeyResult, WalletError> {
unimplemented!()
}
async fn reveal_counterparty_key_linkage(
&self,
_args: RevealCounterpartyKeyLinkageArgs,
_originator: Option<&str>,
) -> Result<RevealCounterpartyKeyLinkageResult, WalletError> {
unimplemented!()
}
async fn reveal_specific_key_linkage(
&self,
_args: RevealSpecificKeyLinkageArgs,
_originator: Option<&str>,
) -> Result<RevealSpecificKeyLinkageResult, WalletError> {
unimplemented!()
}
async fn encrypt(
&self,
_args: EncryptArgs,
_originator: Option<&str>,
) -> Result<EncryptResult, WalletError> {
unimplemented!()
}
async fn decrypt(
&self,
_args: DecryptArgs,
_originator: Option<&str>,
) -> Result<DecryptResult, WalletError> {
unimplemented!()
}
async fn create_hmac(
&self,
_args: CreateHmacArgs,
_originator: Option<&str>,
) -> Result<CreateHmacResult, WalletError> {
unimplemented!()
}
async fn verify_hmac(
&self,
_args: VerifyHmacArgs,
_originator: Option<&str>,
) -> Result<VerifyHmacResult, WalletError> {
unimplemented!()
}
async fn create_signature(
&self,
_args: CreateSignatureArgs,
_originator: Option<&str>,
) -> Result<CreateSignatureResult, WalletError> {
unimplemented!()
}
async fn verify_signature(
&self,
_args: VerifySignatureArgs,
_originator: Option<&str>,
) -> Result<VerifySignatureResult, WalletError> {
unimplemented!()
}
async fn acquire_certificate(
&self,
_args: AcquireCertificateArgs,
_originator: Option<&str>,
) -> Result<Certificate, WalletError> {
unimplemented!()
}
async fn list_certificates(
&self,
_args: ListCertificatesArgs,
_originator: Option<&str>,
) -> Result<ListCertificatesResult, WalletError> {
unimplemented!()
}
async fn prove_certificate(
&self,
_args: ProveCertificateArgs,
_originator: Option<&str>,
) -> Result<ProveCertificateResult, WalletError> {
unimplemented!()
}
async fn relinquish_certificate(
&self,
_args: RelinquishCertificateArgs,
_originator: Option<&str>,
) -> Result<RelinquishCertificateResult, WalletError> {
unimplemented!()
}
async fn discover_by_identity_key(
&self,
_args: DiscoverByIdentityKeyArgs,
_originator: Option<&str>,
) -> Result<DiscoverCertificatesResult, WalletError> {
unimplemented!()
}
async fn discover_by_attributes(
&self,
_args: DiscoverByAttributesArgs,
_originator: Option<&str>,
) -> Result<DiscoverCertificatesResult, WalletError> {
unimplemented!()
}
async fn is_authenticated(
&self,
_originator: Option<&str>,
) -> Result<AuthenticatedResult, WalletError> {
unimplemented!()
}
async fn wait_for_authentication(
&self,
_originator: Option<&str>,
) -> Result<AuthenticatedResult, WalletError> {
unimplemented!()
}
async fn get_height(
&self,
_originator: Option<&str>,
) -> Result<GetHeightResult, WalletError> {
unimplemented!()
}
async fn get_header_for_height(
&self,
_args: GetHeaderArgs,
_originator: Option<&str>,
) -> Result<GetHeaderResult, WalletError> {
unimplemented!()
}
async fn get_network(
&self,
_originator: Option<&str>,
) -> Result<GetNetworkResult, WalletError> {
unimplemented!()
}
async fn get_version(
&self,
_originator: Option<&str>,
) -> Result<GetVersionResult, WalletError> {
unimplemented!()
}
}
#[test]
fn builder_with_wallet_succeeds() {
let config = PaymentMiddlewareConfigBuilder::new()
.wallet(MockWallet)
.build();
assert!(config.is_ok());
let config = config.unwrap();
assert!(config.calculate_request_price.is_none());
}
#[test]
fn builder_without_wallet_fails() {
let result = PaymentMiddlewareConfigBuilder::<MockWallet>::new().build();
assert!(result.is_err());
}
#[test]
fn builder_with_wallet_and_callback_succeeds() {
let cb: CalculateRequestPrice = Box::new(|_req| Box::pin(async { Ok(500u64) }));
let config = PaymentMiddlewareConfigBuilder::new()
.wallet(MockWallet)
.calculate_request_price(cb)
.build();
assert!(config.is_ok());
assert!(config.unwrap().calculate_request_price.is_some());
}
}