1#![warn(
2 missing_debug_implementations,
3 missing_docs,
4 rust_2018_idioms,
5 unreachable_pub
6)]
7
8pub mod wallet;
16
17use bytes::Buf;
18use http::header::{HeaderMap, HeaderValue, ACCEPT, CONTENT_TYPE};
19use prost::{DecodeError, Message};
20use thiserror::Error;
21
22#[allow(missing_docs)]
23pub mod bip70 {
24 include!(concat!(env!("OUT_DIR"), "/bip70.rs"));
29}
30
31use bip70::Payment;
32
33#[derive(Debug, Error)]
35pub enum PreprocessingError {
36 #[error("missing accept header")]
38 MissingAcceptHeader,
39 #[error("invalid content-type")]
41 MissingContentTypeHeader,
42 #[error("payment decoding failure: {0}")]
44 PaymentDecode(DecodeError),
45}
46
47pub async fn preprocess_payment<B: Buf>(
49 headers: HeaderMap,
50 body: B,
51) -> Result<Payment, PreprocessingError> {
52 let bch_content_type_value = HeaderValue::from_static("application/bitcoincash-payment");
54 let bch_accept_value = HeaderValue::from_static("application/bitcoincash-paymentack");
55
56 if !headers
58 .get_all(CONTENT_TYPE)
59 .iter()
60 .any(|header_val| header_val == bch_content_type_value)
61 {
62 return Err(PreprocessingError::MissingContentTypeHeader);
63 }
64
65 if !headers
67 .get_all(ACCEPT)
68 .iter()
69 .any(|header_val| header_val == bch_accept_value)
70 {
71 return Err(PreprocessingError::MissingAcceptHeader);
72 }
73
74 let payment = bip70::Payment::decode(body).map_err(PreprocessingError::PaymentDecode)?;
76
77 Ok(payment)
78}