Skip to content

Commit

Permalink
store public key in fragment of pj URI
Browse files Browse the repository at this point in the history
  • Loading branch information
nothingmuch committed Nov 16, 2024
1 parent 62ae400 commit 1875125
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 4 deletions.
1 change: 1 addition & 0 deletions payjoin/src/receive/v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ impl Receiver {
PjUriBuilder::new(
self.context.address.clone(),
self.pj_url(),
Some(self.context.s.public_key().clone()),
Some(self.context.ohttp_keys.clone()),
Some(self.context.expiry),
)
Expand Down
7 changes: 7 additions & 0 deletions payjoin/src/uri/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use bitcoin::{Address, Amount};
pub use error::PjParseError;
use url::Url;

#[cfg(feature = "v2")]
use crate::hpke::HpkePublicKey;
use crate::uri::error::InternalPjParseError;
#[cfg(feature = "v2")]
pub(crate) use crate::uri::url_ext::UrlExt;
Expand Down Expand Up @@ -114,12 +116,15 @@ impl PjUriBuilder {
pub fn new(
address: Address,
origin: Url,
#[cfg(feature = "v2")] receiver_pubkey: Option<HpkePublicKey>,
#[cfg(feature = "v2")] ohttp_keys: Option<OhttpKeys>,
#[cfg(feature = "v2")] expiry: Option<std::time::SystemTime>,
) -> Self {
#[allow(unused_mut)]
let mut pj = origin;
#[cfg(feature = "v2")]
pj.set_receiver_pubkey(receiver_pubkey);
#[cfg(feature = "v2")]
pj.set_ohttp(ohttp_keys);
#[cfg(feature = "v2")]
pj.set_exp(expiry);
Expand Down Expand Up @@ -361,6 +366,8 @@ mod tests {
None,
#[cfg(feature = "v2")]
None,
#[cfg(feature = "v2")]
None,
)
.amount(amount)
.message("message".to_string())
Expand Down
13 changes: 13 additions & 0 deletions payjoin/src/uri/url_ext.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
use std::str::FromStr;

use bitcoin::base64::prelude::BASE64_URL_SAFE_NO_PAD;
use bitcoin::base64::Engine;
use url::Url;

use crate::hpke::HpkePublicKey;
use crate::OhttpKeys;

/// Parse and set fragment parameters from `&pj=` URI parameter URLs
pub(crate) trait UrlExt {
fn set_receiver_pubkey(&mut self, exp: Option<HpkePublicKey>);
fn ohttp(&self) -> Option<OhttpKeys>;
fn set_ohttp(&mut self, ohttp: Option<OhttpKeys>);
fn exp(&self) -> Option<std::time::SystemTime>;
fn set_exp(&mut self, exp: Option<std::time::SystemTime>);
}

impl UrlExt for Url {
/// Set the receiver's public key in the URL fragment
fn set_receiver_pubkey(&mut self, pubkey: Option<HpkePublicKey>) {
set_param(
self,
"rk=",
pubkey.map(|k| BASE64_URL_SAFE_NO_PAD.encode(k.to_compressed_bytes())),
)
}

/// Retrieve the ohttp parameter from the URL fragment
fn ohttp(&self) -> Option<OhttpKeys> {
get_param(self, "ohttp=", |value| OhttpKeys::from_str(value).ok())
Expand Down
10 changes: 6 additions & 4 deletions payjoin/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ mod integration {
use bitcoin::Address;
use http::StatusCode;
use payjoin::receive::v2::{PayjoinProposal, Receiver, UncheckedProposal};
use payjoin::{OhttpKeys, PjUri, UriExt};
use payjoin::{HpkeKeyPair, OhttpKeys, PjUri, UriExt};
use reqwest::{Client, ClientBuilder, Error, Response};
use testcontainers_modules::redis::Redis;
use testcontainers_modules::testcontainers::clients::Cli;
Expand Down Expand Up @@ -280,6 +280,7 @@ mod integration {
let expired_pj_uri = payjoin::PjUriBuilder::new(
address,
directory.clone(),
Some(HpkeKeyPair::gen_keypair().public_key().clone()),
Some(ohttp_keys),
Some(std::time::SystemTime::now()),
)
Expand Down Expand Up @@ -601,9 +602,10 @@ mod integration {
let (_bitcoind, sender, receiver) = init_bitcoind_sender_receiver(None, None)?;
// Receiver creates the payjoin URI
let pj_receiver_address = receiver.get_new_address(None, None)?.assume_checked();
let pj_uri = PjUriBuilder::new(pj_receiver_address, EXAMPLE_URL.to_owned(), None, None)
.amount(Amount::ONE_BTC)
.build();
let pj_uri =
PjUriBuilder::new(pj_receiver_address, EXAMPLE_URL.to_owned(), None, None, None)
.amount(Amount::ONE_BTC)
.build();

// **********************
// Inside the Sender:
Expand Down

0 comments on commit 1875125

Please sign in to comment.