Skip to content

Commit

Permalink
Move context to Request with borrow
Browse files Browse the repository at this point in the history
  • Loading branch information
DanGould authored and jbesraa committed Jul 31, 2023
1 parent b6a37a5 commit f0e26a1
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 19 deletions.
13 changes: 6 additions & 7 deletions payjoin-cli/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,17 @@ impl App {
.danger_accept_invalid_certs(self.config.danger_accept_invalid_certs)
.build()
.with_context(|| "Failed to build reqwest http client")?;
let ctx = req.context;
let req_url = req.url;
let req_body = req.body;
let mut response = client
.post(req_url)
.body(req_body)
.post(req.url)
.body(req.body)
.header("Content-Type", "text/plain")
.send()
.with_context(|| "HTTP request failed")?;
// TODO display well-known errors and log::debug the rest
let psbt =
ctx.process_response(&mut response).with_context(|| "Failed to process response")?;
let psbt = req
.context
.process_response(&mut response)
.with_context(|| "Failed to process response")?;
log::debug!("Proposed psbt: {:#?}", psbt);
let psbt = self
.bitcoind
Expand Down
5 changes: 2 additions & 3 deletions payjoin/src/send/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,6 @@ impl Configuration {
///
/// This type is used to process the response. It is returned from [`PjUriExt::create_pj_request()`](crate::PjUriExt::create_pj_request()) method
/// and you only need to call [`.process_response()`](crate::send::Context::process_response()) on it to continue BIP78 flow.
#[derive(Clone)]
pub struct Context {
original_psbt: Psbt,
disable_output_substitution: bool,
Expand Down Expand Up @@ -296,7 +295,7 @@ impl Context {
/// valid you will get appropriate PSBT that you should sign and broadcast.
#[inline]
pub fn process_response(
self,
&self,
response: &mut impl std::io::Read,
) -> Result<Psbt, ValidationError> {
let mut res_str = String::new();
Expand All @@ -307,7 +306,7 @@ impl Context {
self.process_proposal(proposal).map(Into::into).map_err(Into::into)
}

fn process_proposal(self, proposal: Psbt) -> InternalResult<Psbt> {
fn process_proposal(&self, proposal: Psbt) -> InternalResult<Psbt> {
self.basic_checks(&proposal)?;
let in_stats = self.check_inputs(&proposal)?;
let out_stats = self.check_outputs(&proposal)?;
Expand Down
18 changes: 9 additions & 9 deletions payjoin/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,21 +83,21 @@ mod integration {
None,
);
let req = pj_uri.create_pj_request(psbt, pj_params).unwrap();
let req_contxt = req.context.clone();
let req_body = &req.body;
let headers = HeaderMock::from_vec(req_body);
let body = req.body.as_slice();
let query = req.url.query().unwrap_or("");
let headers = HeaderMock::from_vec(&req.body);

// **********************
// Inside the Receiver:
// this data would transit from one party to another over the network in production
let response: _ = handle_pj_request(req, headers, receiver);
let response: _ = handle_pj_request(body, query, headers, receiver);
// this response would be returned as http response to the sender

// **********************
// Inside the Sender:
// Sender checks, signs, finalizes, extracts, and broadcasts
let checked_payjoin_proposal_psbt =
req_contxt.process_response(&mut response.as_bytes()).unwrap();
req.context.process_response(&mut response.as_bytes()).unwrap();
let payjoin_base64_string = base64::encode(&checked_payjoin_proposal_psbt.serialize());
let payjoin_psbt =
sender.wallet_process_psbt(&payjoin_base64_string, None, None, None).unwrap().psbt;
Expand Down Expand Up @@ -127,15 +127,15 @@ mod integration {
// Receiver receive and process original_psbt from a sender
// In production it it will come in as an HTTP request (over ssl or onion)
fn handle_pj_request(
req: Request,
body: &[u8],
query: &str,
headers: impl Headers,
receiver: bitcoincore_rpc::Client,
) -> String {
// Receiver receive payjoin proposal, IRL it will be an HTTP request (over ssl or onion)
let req_url = req.url.query().unwrap_or("");
let req_body = req.body.as_slice();

let proposal =
payjoin::receive::UncheckedProposal::from_request(req_body, req_url, headers).unwrap();
payjoin::receive::UncheckedProposal::from_request(body, query, headers).unwrap();

// in a payment processor where the sender could go offline, this is where you schedule to broadcast the original_tx
let _to_broadcast_in_failure_case = proposal.get_transaction_to_schedule_broadcast();
Expand Down

0 comments on commit f0e26a1

Please sign in to comment.