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
84 changes: 23 additions & 61 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<a href="https://github.com/payjoin/rust-payjoin/actions/workflows/rust.yml"><img alt="CI Status" src="https://github.com/payjoin/rust-payjoin/actions/workflows/rust.yml/badge.svg"></a>
<a href="https://coveralls.io/github/payjoin/rust-payjoin?branch=master"><img src="https://coveralls.io/repos/github/payjoin/rust-payjoin/badge.svg?branch=master"/></a>
<a href="https://blog.rust-lang.org/2025/02/20/Rust-1.85.0/"><img alt="Rustc Version 1.85.0+" src="https://img.shields.io/badge/rustc-1.85.0%2B-lightgrey.svg"/></a>
<a href="https://discord.gg/6rJD9R684h"><img alt="Chat on Discord" src="https://img.shields.io/discord/753336465005608961?logo=discord"></a>
</p>

<h4>
Expand All @@ -22,90 +23,51 @@

## About

### `payjoin`
`payjoin/rust-payjoin` contains multiple crates implementing Payjoin as defined in [BIP 77: Async Payjoin](https://github.com/bitcoin/bips/blob/master/bip-0077.mediawiki) and [BIP 78: Simple Payjoin](https://github.com/bitcoin/bips/blob/master/bip-0078.md), and associated OHTTP Relay and Payjoin Directory infrastructure.

The Payjoin Dev Kit `payjoin` library implements both [BIP 78 Payjoin V1](https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki) and [BIP 77 Payjoin V2](https://github.com/bitcoin/bips/blob/master/bip-0077.md).
Find the description of each crate below.

### `payjoin-cli`
### [`payjoin`](https://github.com/payjoin/rust-payjoin/tree/master/payjoin)

The [`payjoin-cli`](https://github.com/payjoin/rust-payjoin/tree/master/payjoin-cli) crate performs no-frills Payjoin as a reference implementation using Bitcoin Core wallet.
The main Payjoin Dev Kit library which provides tools for implementing both Async and Simple Payjoin. `payjoin` implements Payjoin session persistence support and IO utilities for interacting with OHTTP relays in Async Payjoin integrations.

### `payjoin-directory`
**Disclaimer: This crate has not been reviewed by independent Rust and Bitcoin security professionals (yet). Use at your own risk.**

The [`payjoin-directory`](https://github.com/payjoin/rust-payjoin/tree/master/payjoin-directory) crate implements the Payjoin Directory store-and-forward server required for Payjoin V2's asynchronous operation.
### [`payjoin-cli`](https://github.com/payjoin/rust-payjoin/tree/master/payjoin-cli)

### `payjoin-test-utils`
A CLI tool which performs no-frills Payjoin. It is a reference implementation of the Payjoin Dev Kit which uses a Bitcoin Core wallet.

The [`payjoin-test-utils`](https://github.com/payjoin/rust-payjoin/tree/master/payjoin-test-utils) crate provides commonly used testing fixtures such as a local OHTTP relay and payjoin directory, bitcoind node and wallets, and official test vectors.
### [`ohttp-relay`](https://github.com/payjoin/rust-payjoin/tree/master/ohttp-relay)

### `payjoin-ffi`
A Rust implementation of an Oblivious HTTP (OHTTP) relay resource.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's worth mentioning high-level bip77 specific changes here and definitely in the ohttp-relay readme. TODO


The [`payjoin-ffi`](https://github.com/payjoin/rust-payjoin/tree/master/payjoin-ffi) crate provides language bindings that expose the Rust-based Payjoin implementation to various programming languages.
**Disclaimer: Both this crate and the [IETF paper](https://ietf-wg-ohai.github.io/oblivious-http/draft-ietf-ohai-ohttp.html) are undergoing active revision. Use at your own risk.**

### Disclaimer ⚠️ WIP
### [`payjoin-directory`](https://github.com/payjoin/rust-payjoin/tree/master/payjoin-directory)

**Use at your own risk. This crate has not yet been reviewed by independent Rust and Bitcoin security professionals.**
A reference implementation for a Payjoin Directory which stores and forwards HTTP client messages between the sender and the receiver to allow for Async Payjoin transactions. Async Payjoin clients make requests to the directory using [Oblivious HTTP (OHTTP)](https://www.ietf.org/rfc/rfc9458.html) which prevents the directory from being able to link payjoins to specific client IP addresses.

While I don't think there is a _huge_ risk running it, be careful relying on its security for now!
### [`payjoin-test-utils`](https://github.com/payjoin/rust-payjoin/tree/master/payjoin-test-utils)

Seeking review of the code that verifies there is no overpayment. Contributions are welcome!
The test utilities library which provides commonly used testing fixtures such as a local OHTTP relay and Payjoin directory, bitcoind node and wallets, and official test vectors.

### Development status
### [`payjoin-ffi`](https://github.com/payjoin/rust-payjoin/tree/master/payjoin-ffi)

#### Sender (V1 beta, V2 alpha)
The language bindings which expose the Rust-based Payjoin implementation to various programming languages.

- [x] Basic logic
- [x] Most checks implemented
- [x] Documentation
- [x] Unit test with official test vectors passes
- [x] Many unit tests
- [x] Fee contribution support
- [x] Example client using bitcoind
- [x] Tested and works with BTCPayServer
- [x] Tested and works with JoinMarket
- [x] Minimum fee rate enforcement
- [ ] Independent review
- [x] Independent testing
Currently supported languages:

#### Receiver (V1 beta, V2 alpha)

- [x] Basic logic
- [x] Most checks implemented
- [x] Documentation
- [x] Unit test with official test vectors passes
- [x] Many unit tests
- [x] Fee contribution support
- [x] Example server using bitcoind
- [x] Tested and works with BTCPayServer
- [x] Tested and works with WasabiWallet
- [x] Tested and works with Blue Wallet
- [x] Tested and works with Sparrow
- [x] Tested and works with JoinMarket
- [x] Minimum fee rate enforcement
- [ ] Discount support
- [ ] Independent review
- [ ] Independent testing

#### Code quality

- [x] Idiomatic Rust code
- [x] Newtypes
- [x] Panic-free error handling
- [x] No `unsafe` code or well-tested/analyzed/proven/... `unsafe` code
- [x] Warning-free
- [x] CI
- [x] Integration tests
- [ ] Fuzzing
- [x] Coverage measurement
- [x] Mutation testing
- Dart
- Javascript
- Python
Comment on lines +60 to +62
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As these are published, we may link them


## Minimum Supported Rust Version (MSRV)

The `payjoin` library and `payjoin-cli` should always compile with any combination of features on Rust **1.85.0**.
All crates in this repository should always compile with any combination of features on Rust **1.85.0**.

## Contributing

See [`CONTRIBUTING.md`](.github/CONTRIBUTING.md)
See [`CONTRIBUTING.md`](.github/CONTRIBUTING.md).

## License

Expand Down
20 changes: 17 additions & 3 deletions payjoin/src/core/receive/v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,15 @@ impl ReceiverBuilder {
pub struct Initialized {}

impl Receiver<Initialized> {
/// construct an OHTTP Encapsulated HTTP GET request for the Original PSBT
/// Create an OHTTP encapsulated HTTP GET request to poll for the Original PSBT
/// from the Payjoin Directory.
///
/// After the receiver extracts the Payjoin URI with [`Receiver<Initialized>::pj_uri`] and sends it
/// to the sender, they should poll the Payjoin Directory in the PJ URI for the sender's
/// Original PSBT.
///
/// Requests created with this function are OHTTP encapsulated for the configured directory and
/// addressed to the `ohttp_relay` parameter.
pub fn create_poll_request(
&self,
ohttp_relay: impl IntoUrl,
Expand All @@ -360,8 +368,14 @@ impl Receiver<Initialized> {
Ok((req, ohttp_ctx))
}

/// The response can either be an UncheckedOriginalPayload or an ACCEPTED message
/// indicating no UncheckedOriginalPayload is available yet.
/// Process the response to the Original PSBT poll from the Payjoin Directory.
///
/// The response can either be an [`UncheckedOriginalPayload`] or an ACCEPTED message
/// indicating no [`UncheckedOriginalPayload`] is available yet.
///
/// If the response contains the Original PSBT from the sender, transition to the next
/// typestate. If the response is an ACCEPTED message from the directory which indicates that
/// no payload is available yet, continue to poll.
pub fn process_response(
self,
body: &[u8],
Expand Down
56 changes: 31 additions & 25 deletions payjoin/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,35 @@
#![cfg_attr(docsrs, feature(doc_cfg))]

//! # Payjoin implementation in Rust
//!
//! Supercharge payment batching to save you fees and preserve your privacy.
//!
//! This library implements both [BIP 78 Payjoin V1](https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki) and [BIP 77 Payjoin V2](https://github.com/bitcoin/bips/blob/master/bip-0077.md).
//!
//! Only the latest BIP 77 Payjoin V2 is enabled by default. To use BIP 78 Payjoin V1, enable the `v1` feature.
//!
//! The library API is organized by protocol version and operation type:
//! - Sending Payjoins: [`send::v1`] and [`send::v2`] modules
//! - Receiving Payjoins: [`receive::v1`] and [`receive::v2`] modules
//!
//! The library is perfectly IO-agnostic — in fact, it does no IO by default without the `io` feature.
//!
//! Types relevant to a Payjoin Directory as defined in BIP 77 are available in the [`directory`] module enabled by
//! the `directory` feature.
//!
//! ## Example Usage
//!
//! See [payjoin-cli](https://github.com/payjoin/rust-payjoin/tree/master/payjoin-cli) for a complete example of sending and receiving payjoins using both protocol versions.
//!
//! ## Disclaimer ⚠️ WIP
//!
//! **Use at your own risk. This crate has not yet been reviewed by independent Rust and Bitcoin security professionals.**
#![cfg_attr(
docsrs,
doc(
html_logo_url = "https://raw.githubusercontent.com/payjoin/rust-payjoin/master/static/monad.svg"
)
)]
Comment on lines +2 to +7
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see this render. Do you?

Image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expect the logo to be on the left Table of Contents panel (BDK reference here). I did not see it render when I generated the documentation locally, but I did not give it too much thought after reading somewhere how the local build did not have external content (image, etc.). If it does not render with the new release, I'll remember to come back to this and see what's happening.

//! # Rust Payjoin Library
//!
//! The main Payjoin Dev Kit (PDK) library which implements Async Payjoin. The library implements
//! Payjoin session persistence support and IO utilities for interacting with OHTTP relays to make
//! integration plug-and-play.
//!
//! Both sender and receiver construct design follow [The Typestate Pattern in Rust](https://cliffle.com/blog/rust-typestate/),
//! where higher-level [`Sender`] and [`Receiver`] structs are transitioned through
//! consecutive states which represent a specific step they can be on over the course of a Payjoin
//! session. See the documentation of state implementations for more information.
//!
//! ## Cargo Features
//! - `v2`: all constructs for [BIP 77: Async Payjoin](https://github.com/bitcoin/bips/blob/master/bip-0077.md)
//! send and receive operations. Note that IO for fetching OHTTP keys from the Payjoin directory is not enabled here,
//! and requires you to bring your own implementation and HTTP client unless you choose to use ours
//! with the `io` feature.
//! - `v1`: all constructs for [BIP 78: Simple Payjoin](https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki)
//! send and receive operations.
//! - `io`: helper functions for fetching and parsing OHTTP keys.
//! - `directory`: type for identifying Payjoin Directory entries as defined in BIP 77.
//!
//! Only the `v2` feature is enabled by default.
//!
//! [`Sender`]: crate::send::v2::Sender
//! [`Receiver`]: crate::receive::v2::Receiver
#[cfg(not(any(feature = "directory", feature = "v1", feature = "v2")))]
compile_error!("At least one of the features ['directory', 'v1', 'v2'] must be enabled");
Expand Down
Loading