You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
payjoin::send::v2::SenderBuilder::new panics with unimplemented!("V2 SenderBuilder only supports v2 URLs") when given a URI
whose pj= endpoint is v1-only (a plain HTTPS URL with no BIP 77 fragment,
as produced by any BIP 78 receiver such as BTCPay Server).
The panic is reachable with untrusted input. A v1 payjoin URI parses
successfully and passes check_pj_supported(), so nothing upstream of the
builder rejects it. Payjoin URIs are routinely scanned from QR codes, which
means any v2-only sender integration can be made to panic by paying a
BIP 78 receiver.
payjoin-ffi forwards URIs to this constructor unchecked, so the panic
crosses the FFI boundary. Through uniffi it surfaces as an opaque internal
panic exception in the host language (or a process abort in panic=abort
builds), with no way for bindings users to handle it as a typed error.
Since the FFI also exposes no v1 sender flow, bindings users currently have
no way to pay a v1-only receiver at all: the FFI V1Context and RequestV1Context types exist but nothing can produce them.
Reproduction
Confirmed in the wild: Bull Bitcoin Mobile 6.13.0 fails at payjoin sender creation when payjoin
is enabled and the destination is a v1 payjoin URI. The panic is caught
by uniffi and rethrown as a generic internal error, so the send attempt
fails with an unactionable message.
History
e59c1031 (2024-08-05, released in 0.20.0): extract_v2 gained a v1
fallback, "Make backwards-compatible v2 to v1 sends possible."
0.21.0: the unified sender exposed both extract_v1() and extract_v2(). The payjoin-ffi 0.21.0 changelog documented this as
"v1 support is now only available through the V2 backwards-compatible
APIs," which was accurate at the time.
659740d6 (2025-08-05, Refactor sender to validate PjParam by version #901, released in 0.25.0): the v1 request path
(create_v1_post_request) was removed from the v2 sender and from the
FFI in the same commit, and the v1 match arm became unimplemented!.
The changelog recorded this only as "Refactor sender to validate PjParam
by version," so the loss of v2-to-v1 sending and the new panic path went
unannounced. The receiver-side backwards compatibility (v2 receiver
serving v1 senders) is unaffected and still works.
Summary
payjoin::send::v2::SenderBuilder::newpanics withunimplemented!("V2 SenderBuilder only supports v2 URLs")when given a URIwhose
pj=endpoint is v1-only (a plain HTTPS URL with no BIP 77 fragment,as produced by any BIP 78 receiver such as BTCPay Server).
The panic is reachable with untrusted input. A v1 payjoin URI parses
successfully and passes
check_pj_supported(), so nothing upstream of thebuilder rejects it. Payjoin URIs are routinely scanned from QR codes, which
means any v2-only sender integration can be made to panic by paying a
BIP 78 receiver.
payjoin-ffiforwards URIs to this constructor unchecked, so the paniccrosses the FFI boundary. Through uniffi it surfaces as an opaque internal
panic exception in the host language (or a process abort in
panic=abortbuilds), with no way for bindings users to handle it as a typed error.
Since the FFI also exposes no v1 sender flow, bindings users currently have
no way to pay a v1-only receiver at all: the FFI
V1ContextandRequestV1Contexttypes exist but nothing can produce them.Reproduction
Confirmed in the wild: Bull Bitcoin Mobile 6.13.0 fails at payjoin sender creation when payjoin
is enabled and the destination is a v1 payjoin URI. The panic is caught
by uniffi and rethrown as a generic internal error, so the send attempt
fails with an unactionable message.
History
e59c1031(2024-08-05, released in 0.20.0):extract_v2gained a v1fallback, "Make backwards-compatible v2 to v1 sends possible."
extract_v1()andextract_v2(). The payjoin-ffi 0.21.0 changelog documented this as"v1 support is now only available through the V2 backwards-compatible
APIs," which was accurate at the time.
659740d6(2025-08-05, Refactor sender to validate PjParam by version #901, released in 0.25.0): the v1 request path(
create_v1_post_request) was removed from the v2 sender and from theFFI in the same commit, and the v1 match arm became
unimplemented!.The changelog recorded this only as "Refactor sender to validate PjParam
by version," so the loss of v2-to-v1 sending and the new panic path went
unannounced. The receiver-side backwards compatibility (v2 receiver
serving v1 senders) is unaffected and still works.