Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Cargo-minimal.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1473,8 +1473,10 @@ dependencies = [
[[package]]
name = "ohttp-relay"
version = "0.0.9"
source = "git+https://github.com/payjoin/ohttp-relay.git?rev=b8153e5c290560be58e1395a8e50ea610e146f6d#b8153e5c290560be58e1395a8e50ea610e146f6d"
source = "git+https://github.com/payjoin/ohttp-relay.git?rev=c1a4bfd489a69170b4107317fd99aabc87796bab#c1a4bfd489a69170b4107317fd99aabc87796bab"
dependencies = [
"byteorder",
"bytes",
"futures",
"http",
"http-body-util",
Expand Down
4 changes: 3 additions & 1 deletion Cargo-recent.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1473,8 +1473,10 @@ dependencies = [
[[package]]
name = "ohttp-relay"
version = "0.0.9"
source = "git+https://github.com/payjoin/ohttp-relay.git?rev=b8153e5c290560be58e1395a8e50ea610e146f6d#b8153e5c290560be58e1395a8e50ea610e146f6d"
source = "git+https://github.com/payjoin/ohttp-relay.git?rev=c1a4bfd489a69170b4107317fd99aabc87796bab#c1a4bfd489a69170b4107317fd99aabc87796bab"
dependencies = [
"byteorder",
"bytes",
"futures",
"http",
"http-body-util",
Expand Down
2 changes: 1 addition & 1 deletion payjoin-test-utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ bitcoind = { version = "0.36.0", features = ["0_21_2"] }
http = "1"
log = "0.4.7"
ohttp = { package = "bitcoin-ohttp", version = "0.6.0" }
ohttp-relay = { git = "https://github.com/payjoin/ohttp-relay.git", rev = "b8153e5c290560be58e1395a8e50ea610e146f6d", version = "0.0.9", features = ["_test-util"] }
ohttp-relay = { git = "https://github.com/payjoin/ohttp-relay.git", rev = "c1a4bfd489a69170b4107317fd99aabc87796bab", version = "0.0.9", features = ["_test-util"] }
once_cell = "1"
payjoin = { path = "../payjoin", features = ["io", "_danger-local-https"] }
payjoin-directory = { path = "../payjoin-directory", features = ["_danger-local-https"] }
Expand Down
25 changes: 19 additions & 6 deletions payjoin/src/receive/v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,21 @@ pub(crate) struct SessionContext {
e: Option<HpkePublicKey>,
}

impl SessionContext {
fn full_relay_url(&self, ohttp_relay: impl IntoUrl) -> Result<Url, InternalSessionError> {
let relay_base = ohttp_relay.into_url().map_err(InternalSessionError::ParseUrl)?;

// Only reveal scheme and authority to the relay
let directory_base =
self.directory.join("/").map_err(|e| InternalSessionError::ParseUrl(e.into()))?;

// Append that information as a path to the relay URL
relay_base
.join(&format!("/{}", directory_base))
.map_err(|e| InternalSessionError::ParseUrl(e.into()))
}
}

fn deserialize_address_assume_checked<'de, D>(deserializer: D) -> Result<Address, D::Error>
where
D: Deserializer<'de>,
Expand Down Expand Up @@ -104,8 +119,7 @@ impl Receiver {
}
let (body, ohttp_ctx) =
self.fallback_req_body().map_err(InternalSessionError::OhttpEncapsulation)?;
let url = ohttp_relay.into_url().map_err(InternalSessionError::ParseUrl)?;
let req = Request::new_v2(&url, &body);
let req = Request::new_v2(&self.context.full_relay_url(ohttp_relay)?, &body);
Ok((req, ohttp_ctx))
}

Expand Down Expand Up @@ -273,8 +287,7 @@ impl UncheckedProposal {
Some(err.to_json().as_bytes()),
)
.map_err(InternalSessionError::OhttpEncapsulation)?;
let url = ohttp_relay.into_url().map_err(InternalSessionError::ParseUrl)?;
let req = Request::new_v2(&url, &body);
let req = Request::new_v2(&self.context.full_relay_url(ohttp_relay)?, &body);
Ok((req, ohttp_ctx))
}

Expand Down Expand Up @@ -533,8 +546,8 @@ impl PayjoinProposal {
target_resource.as_str(),
Some(&body),
)?;
let url = ohttp_relay.into_url().map_err(InternalSessionError::ParseUrl)?;
let req = Request::new_v2(&url, &body);

let req = Request::new_v2(&self.context.full_relay_url(ohttp_relay)?, &body);
Ok((req, ctx))
}

Expand Down
11 changes: 9 additions & 2 deletions payjoin/src/send/v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,11 @@ pub(crate) fn extract_request(
let (body, ohttp_ctx) = ohttp_encapsulate(ohttp_keys, "POST", url.as_str(), Some(&body))
.map_err(InternalCreateRequestError::OhttpEncapsulation)?;
log::debug!("ohttp_relay_url: {:?}", ohttp_relay);
let request = Request::new_v2(&ohttp_relay, &body);
let directory_base = url.join("/").map_err(|e| InternalCreateRequestError::Url(e.into()))?;
let full_ohttp_relay = ohttp_relay
.join(&format!("/{}", directory_base))
.map_err(|e| InternalCreateRequestError::Url(e.into()))?;
let request = Request::new_v2(&full_ohttp_relay, &body);
Ok((request, ohttp_ctx))
}

Expand Down Expand Up @@ -407,7 +411,10 @@ mod test {
let result = sender.extract_v2(ohttp_relay);
let (request, context) = result.expect("Result should be ok");
assert!(!request.body.is_empty(), "Request body should not be empty");
assert_eq!(request.url, EXAMPLE_URL.clone());
assert_eq!(
request.url.to_string(),
format!("{}{}", EXAMPLE_URL.clone(), sender.v1.endpoint.join("/")?)
);
assert_eq!(context.endpoint, sender.v1.endpoint);
assert_eq!(context.psbt_ctx.original_psbt, sender.v1.psbt);
Ok(())
Expand Down
15 changes: 8 additions & 7 deletions payjoin/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ mod integration {
// Test that an expired pj_url errors
let expired_req_ctx = SenderBuilder::new(psbt, expired_receiver.pj_uri())
.build_non_incentivizing(FeeRate::BROADCAST_MIN)?;
match expired_req_ctx.extract_v2(directory.to_owned()) {
match expired_req_ctx.extract_v2(ohttp_relay) {
// Internal error types are private, so check against a string
Err(err) => assert!(err.to_string().contains("expired")),
_ => panic!("Expired send session should error"),
Expand Down Expand Up @@ -727,6 +727,7 @@ mod integration {

services.wait_for_services_ready().await?;
let directory = services.directory_url();
let ohttp_relay = services.ohttp_relay_url();
let ohttp_keys = services.fetch_ohttp_keys().await?;
let agent = services.http_agent();

Expand All @@ -747,7 +748,7 @@ mod integration {
let sender_ctx = MultiPartySenderBuilder::new(psbt.clone(), pj_uri.clone())
.build_recommended(FeeRate::BROADCAST_MIN)?;
let (Request { url, body, content_type, .. }, send_post_ctx) =
sender_ctx.extract_v2(directory.to_owned())?;
sender_ctx.extract_v2(ohttp_relay.to_owned())?;
let response = agent
.post(url.clone())
.header("Content-Type", content_type)
Expand All @@ -772,7 +773,7 @@ mod integration {
payjoin::receive::multiparty::UncheckedProposalBuilder::new();
for sender_sesssion in inner_sender_test_sessions.iter() {
let mut receiver_session = sender_sesssion.receiver_session.clone();
let (req, reciever_ctx) = receiver_session.extract_req(&directory)?;
let (req, reciever_ctx) = receiver_session.extract_req(&ohttp_relay)?;
let response = agent
.post(req.url)
.header("Content-Type", req.content_type)
Expand All @@ -793,7 +794,7 @@ mod integration {

// Send the payjoin proposals to the senders
for mut proposal in multi_sender_payjoin_proposal.sender_iter() {
let (req, ctx) = proposal.extract_v2_req(&directory)?;
let (req, ctx) = proposal.extract_v2_req(&ohttp_relay)?;
let response = agent
.post(req.url)
.header("Content-Type", req.content_type)
Expand All @@ -811,7 +812,7 @@ mod integration {
for (i, sender_sesssion) in inner_sender_test_sessions.iter().enumerate() {
let sender_get_ctx = &sender_sesssion.sender_get_ctx;
let (Request { url, body, content_type, .. }, ohttp_response_ctx) =
sender_get_ctx.extract_req(directory.to_owned())?;
sender_get_ctx.extract_req(ohttp_relay.to_owned())?;
let response = agent
.post(url.clone())
.header("Content-Type", content_type)
Expand All @@ -824,7 +825,7 @@ mod integration {
|psbt| finalize_psbt(&senders[i], psbt),
)?;
let (Request { url, body, content_type, .. }, ohttp_response_ctx) =
finalize_ctx.extract_req(directory.to_owned())?;
finalize_ctx.extract_req(ohttp_relay.to_owned())?;
let response = agent
.post(url.clone())
.header("Content-Type", content_type)
Expand All @@ -846,7 +847,7 @@ mod integration {
payjoin::receive::multiparty::FinalizedProposal::new();
for sender_sesssion in inner_sender_test_sessions.iter() {
let mut receiver_session = sender_sesssion.receiver_session.clone();
let (req, reciever_ctx) = receiver_session.extract_req(&directory)?;
let (req, reciever_ctx) = receiver_session.extract_req(&ohttp_relay)?;
let response = agent
.post(req.url)
.header("Content-Type", req.content_type)
Expand Down