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
1 change: 0 additions & 1 deletion Cargo-minimal.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2363,7 +2363,6 @@ dependencies = [
"tokio",
"tracing",
"tracing-subscriber",
"url",
]

[[package]]
Expand Down
1 change: 0 additions & 1 deletion Cargo-recent.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2363,7 +2363,6 @@ dependencies = [
"tokio",
"tracing",
"tracing-subscriber",
"url",
]

[[package]]
Expand Down
6 changes: 3 additions & 3 deletions payjoin-cli/tests/e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,8 @@ mod e2e {

let payjoin_cli = env!("CARGO_BIN_EXE_payjoin-cli");

let directory = &services.directory_url().to_string();
let ohttp_relay = &services.ohttp_relay_url().to_string();
let directory = &services.directory_url();
let ohttp_relay = &services.ohttp_relay_url();

let cli_receive_initiator = Command::new(payjoin_cli)
.arg("--root-certificate")
Expand Down Expand Up @@ -527,7 +527,7 @@ mod e2e {
.arg("--db-path")
.arg(&sender_db_path)
.arg("--ohttp-relays")
.arg(services.ohttp_relay_url().to_string())
.arg(services.ohttp_relay_url())
.arg("send")
.arg(&bip21)
.arg("--fee-rate")
Expand Down
14 changes: 7 additions & 7 deletions payjoin-ffi/dart/test/test_payjoin_integration_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,9 @@ Future<payjoin.PayjoinProposalReceiveSession> process_unchecked_proposal(
Future<payjoin.ReceiveSession?> retrieve_receiver_proposal(
payjoin.Initialized receiver,
InMemoryReceiverPersister recv_persister,
payjoin.Url ohttp_relay) async {
String ohttp_relay) async {
var agent = http.Client();
var request = receiver.createPollRequest(ohttp_relay.asString());
var request = receiver.createPollRequest(ohttp_relay);
var response = await agent.post(Uri.parse(request.request.url.asString()),
headers: {"Content-Type": request.request.contentType},
body: request.request.body);
Expand All @@ -268,7 +268,7 @@ Future<payjoin.ReceiveSession?> retrieve_receiver_proposal(
Future<payjoin.ReceiveSession?> process_receiver_proposal(
payjoin.ReceiveSession receiver,
InMemoryReceiverPersister recv_persister,
payjoin.Url ohttp_relay) async {
String ohttp_relay) async {
if (receiver is payjoin.InitializedReceiveSession) {
var res = await retrieve_receiver_proposal(
receiver.inner, recv_persister, ohttp_relay);
Expand Down Expand Up @@ -319,7 +319,7 @@ void main() {
var services = payjoin.TestServices.initialize();

services.waitForServicesReady();
var directory = services.directoryUrl().asString();
var directory = services.directoryUrl();
var ohttp_keys = services.fetchOhttpKeys();
var ohttp_relay = services.ohttpRelayUrl();
var agent = http.Client();
Expand All @@ -345,7 +345,7 @@ void main() {
.buildRecommended(1000)
.save(sender_persister);
payjoin.RequestV2PostContext request =
req_ctx.createV2PostRequest(ohttp_relay.asString());
req_ctx.createV2PostRequest(ohttp_relay);
var response = await agent.post(Uri.parse(request.request.url.asString()),
headers: {"Content-Type": request.request.contentType},
body: request.request.body);
Expand All @@ -369,7 +369,7 @@ void main() {
payjoin.PayjoinProposal proposal =
(payjoin_proposal as payjoin.PayjoinProposalReceiveSession).inner;
payjoin.RequestResponse request_response =
proposal.createPostRequest(ohttp_relay.asString());
proposal.createPostRequest(ohttp_relay);
var fallback_response = await agent.post(
Uri.parse(request_response.request.url.asString()),
headers: {"Content-Type": request_response.request.contentType},
Expand All @@ -382,7 +382,7 @@ void main() {
// Sender checks, isngs, finalizes, extracts, and broadcasts
// Replay post fallback to get the response
payjoin.RequestOhttpContext ohttp_context_request =
send_ctx.createPollRequest(ohttp_relay.asString());
send_ctx.createPollRequest(ohttp_relay);
var final_response = await agent.post(
Uri.parse(ohttp_context_request.request.url.asString()),
headers: {"Content-Type": ohttp_context_request.request.contentType},
Expand Down
16 changes: 8 additions & 8 deletions payjoin-ffi/python/test/test_payjoin_integration_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def setUpClass(cls):
cls.receiver = cls.env.get_receiver()
cls.sender = cls.env.get_sender()

async def process_receiver_proposal(self, receiver: ReceiveSession, recv_persister: InMemoryReceiverSessionEventLog, ohttp_relay: Url) -> Optional[ReceiveSession]:
async def process_receiver_proposal(self, receiver: ReceiveSession, recv_persister: InMemoryReceiverSessionEventLog, ohttp_relay: str) -> Optional[ReceiveSession]:
if receiver.is_INITIALIZED():
res = await self.retrieve_receiver_proposal(receiver.inner, recv_persister, ohttp_relay)
if res is None:
Expand Down Expand Up @@ -83,13 +83,13 @@ async def process_receiver_proposal(self, receiver: ReceiveSession, recv_persist

raise Exception(f"Unknown receiver state: {receiver}")

def create_receiver_context(self, receiver_address: bitcoinffi.Address, directory: Url, ohttp_keys: OhttpKeys, recv_persister: InMemoryReceiverSessionEventLog) -> Initialized:
receiver = ReceiverBuilder(address=receiver_address, directory=directory.as_string(), ohttp_keys=ohttp_keys).build().save(recv_persister)
def create_receiver_context(self, receiver_address: bitcoinffi.Address, directory: str, ohttp_keys: OhttpKeys, recv_persister: InMemoryReceiverSessionEventLog) -> Initialized:
receiver = ReceiverBuilder(address=receiver_address, directory=directory, ohttp_keys=ohttp_keys).build().save(recv_persister)
return receiver

async def retrieve_receiver_proposal(self, receiver: Initialized, recv_persister: InMemoryReceiverSessionEventLog, ohttp_relay: Url):
async def retrieve_receiver_proposal(self, receiver: Initialized, recv_persister: InMemoryReceiverSessionEventLog, ohttp_relay: str):
agent = httpx.AsyncClient()
request: RequestResponse = receiver.create_poll_request(ohttp_relay.as_string())
request: RequestResponse = receiver.create_poll_request(ohttp_relay)
response = await agent.post(
url=request.request.url.as_string(),
headers={"Content-Type": request.request.content_type},
Expand Down Expand Up @@ -158,7 +158,7 @@ async def test_integration_v2_to_v2(self):
pj_uri = session.pj_uri()
psbt = build_sweep_psbt(self.sender, pj_uri)
req_ctx: WithReplyKey = SenderBuilder(psbt, pj_uri).build_recommended(1000).save(sender_persister)
request: RequestV2PostContext = req_ctx.create_v2_post_request(ohttp_relay.as_string())
request: RequestV2PostContext = req_ctx.create_v2_post_request(ohttp_relay)
response = await agent.post(
url=request.request.url.as_string(),
headers={"Content-Type": request.request.content_type},
Expand All @@ -176,7 +176,7 @@ async def test_integration_v2_to_v2(self):
self.assertEqual(payjoin_proposal.is_PAYJOIN_PROPOSAL(), True)

payjoin_proposal = payjoin_proposal.inner
request: RequestResponse = payjoin_proposal.create_post_request(ohttp_relay.as_string())
request: RequestResponse = payjoin_proposal.create_post_request(ohttp_relay)
response = await agent.post(
url=request.request.url.as_string(),
headers={"Content-Type": request.request.content_type},
Expand All @@ -188,7 +188,7 @@ async def test_integration_v2_to_v2(self):
# Inside the Sender:
# Sender checks, signs, finalizes, extracts, and broadcasts
# Replay post fallback to get the response
request: RequestOhttpContext = send_ctx.create_poll_request(ohttp_relay.as_string())
request: RequestOhttpContext = send_ctx.create_poll_request(ohttp_relay)
response = await agent.post(
url=request.request.url.as_string(),
headers={"Content-Type": request.request.content_type},
Expand Down
16 changes: 7 additions & 9 deletions payjoin-ffi/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ use serde_json::Value;
use tokio::runtime::Runtime;
use tokio::sync::Mutex;

use crate::Url;

lazy_static! {
static ref RUNTIME: Arc<std::sync::Mutex<Runtime>> =
Arc::new(std::sync::Mutex::new(Runtime::new().expect("Failed to create Tokio runtime")));
Expand Down Expand Up @@ -128,9 +126,9 @@ impl TestServices {
runtime.block_on(async { self.0.lock().await.cert() })
}

pub fn directory_url(&self) -> Url {
pub fn directory_url(&self) -> String {
let runtime = RUNTIME.lock().expect("Lock should not be poisoned");
runtime.block_on(async { self.0.lock().await.directory_url().into() })
runtime.block_on(async { self.0.lock().await.directory_url() })
}

pub fn take_directory_handle(&self) -> JoinHandle {
Expand All @@ -139,14 +137,14 @@ impl TestServices {
.block_on(async { JoinHandle(Arc::new(self.0.lock().await.take_directory_handle())) })
}

pub fn ohttp_relay_url(&self) -> Url {
pub fn ohttp_relay_url(&self) -> String {
let runtime = RUNTIME.lock().expect("Lock should not be poisoned");
runtime.block_on(async { self.0.lock().await.ohttp_relay_url().into() })
runtime.block_on(async { self.0.lock().await.ohttp_relay_url() })
}

pub fn ohttp_gateway_url(&self) -> Url {
pub fn ohttp_gateway_url(&self) -> String {
let runtime = RUNTIME.lock().expect("Lock should not be poisoned");
runtime.block_on(async { self.0.lock().await.ohttp_gateway_url().into() })
runtime.block_on(async { self.0.lock().await.ohttp_gateway_url() })
}

pub fn take_ohttp_relay_handle(&self) -> JoinHandle {
Expand Down Expand Up @@ -191,7 +189,7 @@ pub fn init_bitcoind_sender_receiver() -> Result<Arc<BitcoindEnv>, FfiError> {
}

#[uniffi::export]
pub fn example_url() -> Url { EXAMPLE_URL.clone().into() }
pub fn example_url() -> String { EXAMPLE_URL.to_string() }

#[uniffi::export]
pub fn query_params() -> String { QUERY_PARAMS.to_string() }
Expand Down
1 change: 0 additions & 1 deletion payjoin-test-utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,4 @@ reqwest = { version = "0.12.23", default-features = false, features = ["rustls-t
tokio = { version = "1.47.1", features = ["full"] }
tracing = "0.1.41"
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
url = "2.5.4"
tempfile = "3.20.0"
27 changes: 10 additions & 17 deletions payjoin-test-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ use tokio::net::TcpListener;
use tokio::task::JoinHandle;
use tracing::Level;
use tracing_subscriber::{EnvFilter, FmtSubscriber};
use url::Url;

pub type BoxError = Box<dyn std::error::Error + 'static>;
pub type BoxSendSyncError = Box<dyn std::error::Error + Send + Sync>;
Expand Down Expand Up @@ -79,21 +78,16 @@ impl TestServices {

pub fn cert(&self) -> Vec<u8> { self.cert.der().to_vec() }

pub fn directory_url(&self) -> Url {
Url::parse(&format!("https://localhost:{}", self.directory.0)).expect("invalid URL")
}
pub fn directory_url(&self) -> String { format!("https://localhost:{}", self.directory.0) }

pub fn take_directory_handle(&mut self) -> JoinHandle<Result<(), BoxSendSyncError>> {
self.directory.1.take().expect("directory handle not found")
}

pub fn ohttp_relay_url(&self) -> Url {
Url::parse(&format!("http://localhost:{}", self.ohttp_relay.0)).expect("invalid URL")
}
pub fn ohttp_relay_url(&self) -> String { format!("http://localhost:{}", self.ohttp_relay.0) }

pub fn ohttp_gateway_url(&self) -> Url {
let url = self.directory_url();
url.join("/.well-known/ohttp-gateway").expect("invalid URL")
pub fn ohttp_gateway_url(&self) -> String {
format!("{}/.well-known/ohttp-gateway", self.directory_url())
}

pub fn take_ohttp_relay_handle(&mut self) -> JoinHandle<Result<(), BoxSendSyncError>> {
Expand All @@ -103,8 +97,8 @@ impl TestServices {
pub fn http_agent(&self) -> Arc<Client> { self.http_agent.clone() }

pub async fn wait_for_services_ready(&self) -> Result<(), &'static str> {
wait_for_service_ready(self.ohttp_relay_url(), self.http_agent()).await?;
wait_for_service_ready(self.directory_url(), self.http_agent()).await?;
wait_for_service_ready(&self.ohttp_relay_url(), self.http_agent()).await?;
wait_for_service_ready(&self.directory_url(), self.http_agent()).await?;
Ok(())
}

Expand Down Expand Up @@ -236,15 +230,15 @@ const TESTS_TIMEOUT: Duration = Duration::from_secs(20);
const WAIT_SERVICE_INTERVAL: Duration = Duration::from_secs(3);

pub async fn wait_for_service_ready(
service_url: Url,
service_url: &str,
agent: Arc<Client>,
) -> Result<(), &'static str> {
let health_url = service_url.join("/health").map_err(|_| "Invalid URL")?;
let health_url = format!("{}/health", service_url.trim_end_matches("/"));
let start = std::time::Instant::now();

while start.elapsed() < TESTS_TIMEOUT {
let request_result =
agent.get(health_url.as_str()).send().await.map_err(|_| "Bad request")?;
agent.get(health_url.clone()).send().await.map_err(|_| "Bad request")?;
match request_result.status() {
StatusCode::OK => return Ok(()),
StatusCode::NOT_FOUND => return Err("Endpoint not found"),
Expand All @@ -255,8 +249,7 @@ pub async fn wait_for_service_ready(
Err("Timeout waiting for service to be ready")
}

pub static EXAMPLE_URL: Lazy<Url> =
Lazy::new(|| Url::parse("https://example.com").expect("invalid URL"));
pub static EXAMPLE_URL: &str = "https://example.com";

pub const KEY_ID: KeyId = 1;
pub const KEM: Kem = Kem::K256Sha256;
Expand Down
16 changes: 6 additions & 10 deletions payjoin/src/core/receive/v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1138,7 +1138,7 @@ pub mod test {
address: Address::from_str("tb1q6d3a2w975yny0asuvd9a67ner4nks58ff0q8g4")
.expect("valid address")
.assume_checked(),
directory: EXAMPLE_URL.clone(),
directory: Url::from_str(EXAMPLE_URL).expect("Could not parse Url"),
ohttp_keys: OhttpKeys(
ohttp::KeyConfig::new(KEY_ID, KEM, Vec::from(SYMMETRIC)).expect("valid key config"),
),
Expand Down Expand Up @@ -1349,15 +1349,11 @@ pub mod test {

assert_eq!(mock_err.1.to_json(), expected_json);

let (_req, _ctx) =
extract_err_req(&mock_err.1, EXAMPLE_URL.as_str(), &receiver.session_context)?;
let (_req, _ctx) = extract_err_req(&mock_err.1, EXAMPLE_URL, &receiver.session_context)?;

let internal_error: Error = InternalPayloadError::MissingPayment.into();
let (_req, _ctx) = extract_err_req(
&(&internal_error).into(),
EXAMPLE_URL.as_str(),
&receiver.session_context,
)?;
let (_req, _ctx) =
extract_err_req(&(&internal_error).into(), EXAMPLE_URL, &receiver.session_context)?;
Ok(())
}

Expand All @@ -1384,7 +1380,7 @@ pub mod test {
let res = error.api_error().expect("check_broadcast error should propagate to api error");
let actual_json = JsonReply::from(&res);

let expiration = extract_err_req(&actual_json, EXAMPLE_URL.as_str(), &context);
let expiration = extract_err_req(&actual_json, EXAMPLE_URL, &context);

match expiration {
Err(error) => assert_eq!(
Expand Down Expand Up @@ -1466,7 +1462,7 @@ pub mod test {
fn test_v2_pj_uri() {
let uri =
Receiver { state: Initialized {}, session_context: SHARED_CONTEXT.clone() }.pj_uri();
assert_ne!(uri.extras.pj_param.endpoint(), EXAMPLE_URL.clone());
assert_ne!(uri.extras.pj_param.endpoint().as_str(), EXAMPLE_URL);
assert_eq!(uri.extras.output_substitution, OutputSubstitution::Disabled);
}

Expand Down
6 changes: 3 additions & 3 deletions payjoin/src/core/receive/v2/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,15 +619,15 @@ mod tests {

let uri = SessionHistory { events }.pj_uri();

assert_ne!(uri.extras.pj_param.endpoint(), EXAMPLE_URL.clone());
assert_ne!(uri.extras.pj_param.endpoint().as_str(), EXAMPLE_URL);
assert_eq!(uri.extras.output_substitution, OutputSubstitution::Disabled);

Ok(())
}

#[test]
fn test_skipped_session_extract_err_request() -> Result<(), BoxError> {
let ohttp_relay = EXAMPLE_URL.as_str();
let ohttp_relay = EXAMPLE_URL;
let mock_err = mock_err();

let session_history = SessionHistory { events: vec![SessionEvent::MaybeInputsOwned()] };
Expand Down Expand Up @@ -660,7 +660,7 @@ mod tests {
#[test]
fn test_session_extract_err_req_reply_key() -> Result<(), BoxError> {
let proposal = original_from_test_vector();
let ohttp_relay = EXAMPLE_URL.as_str();
let ohttp_relay = EXAMPLE_URL;
let mock_err = mock_err();

let session_history_one = SessionHistory {
Expand Down
2 changes: 1 addition & 1 deletion payjoin/src/core/send/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ mod test {
map.insert(unknown_key, value);
psbt_ctx.original_psbt.unknown = map;

let sender = Sender { endpoint: EXAMPLE_URL.clone(), psbt_ctx };
let sender = Sender { endpoint: Url::from_str(EXAMPLE_URL)?, psbt_ctx };

let body = sender.create_v1_post_request().0.body;
let res_str = std::str::from_utf8(&body)?;
Expand Down
8 changes: 4 additions & 4 deletions payjoin/src/core/send/v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -592,13 +592,13 @@ mod test {
let expiration =
Time::from_now(Duration::from_secs(60)).expect("expiration should be valid");
let sender = create_sender_context(expiration)?;
let ohttp_relay = EXAMPLE_URL.as_str();
let ohttp_relay = EXAMPLE_URL;
let result = sender.create_v2_post_request(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.to_string(),
format!("{}{}", EXAMPLE_URL.clone(), sender.pj_param.endpoint().join("/")?)
format!("{}/{}", EXAMPLE_URL, sender.pj_param.endpoint().join("/")?)
);
assert_eq!(context.psbt_ctx.original_psbt, sender.psbt_ctx.original_psbt);
Ok(())
Expand All @@ -611,7 +611,7 @@ mod test {
.expect("time in the past should be representable");

let sender = create_sender_context(expiration)?;
let ohttp_relay = EXAMPLE_URL.as_str();
let ohttp_relay = EXAMPLE_URL;
let result = sender.create_v2_post_request(ohttp_relay);
assert!(result.is_err(), "Extract v2 expected expiration error, but it succeeded");

Expand All @@ -627,7 +627,7 @@ mod test {
let address = Address::from_str("2N47mmrWXsNBvQR6k78hWJoTji57zXwNcU7")
.expect("valid address")
.assume_checked();
let directory = EXAMPLE_URL.as_str();
let directory = EXAMPLE_URL;
let ohttp_keys = OhttpKeys(
ohttp::KeyConfig::new(KEY_ID, KEM, Vec::from(SYMMETRIC)).expect("valid key config"),
);
Expand Down
Loading