Skip to content

Commit

Permalink
Pass supported_versions from calling module
Browse files Browse the repository at this point in the history
This finally allows v1, v2 features to be additive. However, it does
complicate the UnknownVersion variant (used only by v1 as far as I can
tell).

I'm inclined to leave this as an open issue until we separate the
receive::{v1,v2} errors from each other.
  • Loading branch information
DanGould committed Jan 7, 2025
1 parent 86d61d3 commit d7d31c8
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 17 deletions.
5 changes: 2 additions & 3 deletions payjoin/src/receive/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,15 @@ impl fmt::Display for RequestError {
format!("Content length too large: {}.", length),
),
InternalRequestError::SenderParams(e) => match e {
super::optional_parameters::Error::UnknownVersion => {
super::optional_parameters::Error::UnknownVersion { supported_versions } => {
write!(
f,
r#"{{
"errorCode": "version-unsupported",
"supported": "{}",
"message": "This version of payjoin is not supported."
}}"#,
serde_json::to_string(&super::optional_parameters::SUPPORTED_VERSIONS)
.map_err(|_| fmt::Error)?
serde_json::to_string(supported_versions).map_err(|_| fmt::Error)?
)
}
_ => write_error(f, "sender-params-error", e),
Expand Down
19 changes: 8 additions & 11 deletions payjoin/src/receive/optional_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@ use std::fmt;
use bitcoin::FeeRate;
use log::warn;

#[cfg(feature = "v2")]
pub(crate) const SUPPORTED_VERSIONS: [usize; 2] = [1, 2];
#[cfg(not(feature = "v2"))]
pub(crate) const SUPPORTED_VERSIONS: [usize; 1] = [1];

#[derive(Debug, Clone)]
pub(crate) struct Params {
// version
Expand All @@ -33,8 +28,10 @@ impl Default for Params {
}

impl Params {
#[cfg(feature = "receive")]
pub fn from_query_pairs<K, V, I>(pairs: I) -> Result<Self, Error>
pub fn from_query_pairs<K, V, I>(
pairs: I,
supported_versions: &'static [usize],
) -> Result<Self, Error>
where
I: Iterator<Item = (K, V)>,
K: Borrow<str> + Into<String>,
Expand All @@ -49,8 +46,8 @@ impl Params {
match (key.borrow(), v.borrow()) {
("v", version) =>
params.v = match version.parse::<usize>() {
Ok(version) if SUPPORTED_VERSIONS.contains(&version) => version,
_ => return Err(Error::UnknownVersion),
Ok(version) if supported_versions.contains(&version) => version,
_ => return Err(Error::UnknownVersion { supported_versions }),
},
("additionalfeeoutputindex", index) =>
additional_fee_output_index = match index.parse::<usize>() {
Expand Down Expand Up @@ -107,14 +104,14 @@ impl Params {

#[derive(Debug)]
pub(crate) enum Error {
UnknownVersion,
UnknownVersion { supported_versions: &'static [usize] },
FeeRate,
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::UnknownVersion => write!(f, "unknown version"),
Error::UnknownVersion { .. } => write!(f, "unknown version"),
Error::FeeRate => write!(f, "could not parse feerate"),
}
}
Expand Down
5 changes: 4 additions & 1 deletion payjoin/src/receive/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ use super::{
};
use crate::psbt::PsbtExt;

const SUPPORTED_VERSIONS: &[usize] = &[1];

pub trait Headers {
fn get_header(&self, key: &str) -> Option<&str>;
}
Expand Down Expand Up @@ -104,7 +106,8 @@ impl UncheckedProposal {
log::debug!("Received original psbt: {:?}", psbt);

let pairs = url::form_urlencoded::parse(query.as_bytes());
let params = Params::from_query_pairs(pairs).map_err(InternalRequestError::SenderParams)?;
let params = Params::from_query_pairs(pairs, SUPPORTED_VERSIONS)
.map_err(InternalRequestError::SenderParams)?;
log::debug!("Received request with params: {:?}", params);

// TODO check that params are valid for the request's Original PSBT
Expand Down
9 changes: 7 additions & 2 deletions payjoin/src/receive/v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ use crate::Request;

pub(crate) mod error;

const SUPPORTED_VERSIONS: &[usize] = &[1, 2];

static TWENTY_FOUR_HOURS_DEFAULT_EXPIRY: Duration = Duration::from_secs(60 * 60 * 24);

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
Expand Down Expand Up @@ -165,8 +167,11 @@ impl Receiver {
let unchecked_psbt = Psbt::from_str(base64).map_err(InternalRequestError::ParsePsbt)?;
let psbt = unchecked_psbt.validate().map_err(InternalRequestError::InconsistentPsbt)?;
log::debug!("Received original psbt: {:?}", psbt);
let mut params = Params::from_query_pairs(url::form_urlencoded::parse(query.as_bytes()))
.map_err(InternalRequestError::SenderParams)?;
let mut params = Params::from_query_pairs(
url::form_urlencoded::parse(query.as_bytes()),
SUPPORTED_VERSIONS,
)
.map_err(InternalRequestError::SenderParams)?;

// Output substitution must be disabled for V1 sessions in V2 contexts.
//
Expand Down

0 comments on commit d7d31c8

Please sign in to comment.