diff --git a/.cargo/mutants.toml b/.cargo/mutants.toml
index b9c6ccd9e..a827bfd2c 100644
--- a/.cargo/mutants.toml
+++ b/.cargo/mutants.toml
@@ -7,6 +7,7 @@ exclude_re = [
"deserialize",
"Iterator",
".*Error",
+ "impl\\s+arbitrary::Arbitrary",
# ---------------------Crate-specific exclusions ---------------------
# Timeout loops
diff --git a/Cargo-minimal.lock b/Cargo-minimal.lock
index 9149118b0..bd6b60bfa 100644
--- a/Cargo-minimal.lock
+++ b/Cargo-minimal.lock
@@ -144,9 +144,9 @@ checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
[[package]]
name = "arbitrary"
-version = "1.0.0"
+version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "698b65a961a9d730fb45b6b0327e20207810c9f61ee421b082b27ba003f49e2b"
+checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
[[package]]
name = "arc-swap"
@@ -2756,6 +2756,7 @@ checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
name = "payjoin"
version = "1.0.0-rc.3"
dependencies = [
+ "arbitrary",
"bhttp",
"bitcoin 0.32.9",
"bitcoin-hpke",
@@ -2835,6 +2836,7 @@ dependencies = [
name = "payjoin-fuzz"
version = "0.0.1"
dependencies = [
+ "arbitrary",
"bitcoin_uri",
"home",
"libfuzzer-sys",
diff --git a/Cargo-recent.lock b/Cargo-recent.lock
index cc84375be..0fe1381d3 100644
--- a/Cargo-recent.lock
+++ b/Cargo-recent.lock
@@ -2800,6 +2800,7 @@ checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
name = "payjoin"
version = "1.0.0-rc.3"
dependencies = [
+ "arbitrary",
"bhttp",
"bitcoin 0.32.100",
"bitcoin-hpke",
@@ -2879,6 +2880,7 @@ dependencies = [
name = "payjoin-fuzz"
version = "0.0.1"
dependencies = [
+ "arbitrary",
"bitcoin_uri",
"home",
"libfuzzer-sys",
diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml
index 312c18a0d..06e966fb2 100644
--- a/fuzz/Cargo.toml
+++ b/fuzz/Cargo.toml
@@ -11,10 +11,12 @@ cargo-fuzz = true
default = []
[dependencies]
+arbitrary = { version = "1.4.2" }
bitcoin_uri = { version = "0.1.0" }
home = "=0.5.11"
libfuzzer-sys = { version = "0.4.10" }
payjoin = { path = "../payjoin", default-features = false, features = [
+ "arbitrary",
"_core",
"v1",
"v2",
@@ -35,3 +37,9 @@ name = "url_decode_url"
path = "fuzz_targets/url/decode_url.rs"
doc = false
bench = false
+
+[[bin]]
+name = "url_arbitrary_url"
+path = "fuzz_targets/url/arbitrary_url.rs"
+doc = false
+bench = false
diff --git a/fuzz/fuzz_targets/url/arbitrary_url.rs b/fuzz/fuzz_targets/url/arbitrary_url.rs
new file mode 100644
index 000000000..ca92b47f9
--- /dev/null
+++ b/fuzz/fuzz_targets/url/arbitrary_url.rs
@@ -0,0 +1,42 @@
+#![no_main]
+
+use arbitrary::{Arbitrary, Unstructured};
+use libfuzzer_sys::fuzz_target;
+use payjoin::Url;
+
+fn do_test(data: &[u8]) {
+ let mut u = Unstructured::new(data);
+ if let Ok(mut url) = Url::arbitrary(&mut u) {
+ if let Ok(port) = u.arbitrary::