Skip to content

Commit

Permalink
Merge pull request #29 from LtbLightning/upgrade-v18.0
Browse files Browse the repository at this point in the history
Upgrade v18.0
  • Loading branch information
BitcoinZavior authored Jul 19, 2024
2 parents 399046f + 6568633 commit e91e4d3
Show file tree
Hide file tree
Showing 13 changed files with 960 additions and 292 deletions.
683 changes: 595 additions & 88 deletions Cargo.lock

Large diffs are not rendered by default.

15 changes: 8 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "payjoin_ffi"
version = "0.13.0"
version = "0.18.0"
license = "MIT OR Apache-2.0"
edition = "2021"
exclude = ["tests"]
Expand All @@ -10,16 +10,17 @@ crate-type = ["lib", "staticlib", "cdylib"]
name = "payjoin_ffi"

[build-dependencies]
uniffi = { version = "0.27.1", features = ["build"] }
uniffi = { version = "0.28.0", features = ["build"] }

[dev-dependencies]
uniffi = { version = "0.27.1", features = ["bindgen-tests"] }
uniffi = { version = "0.28.0", features = ["bindgen-tests"] }
bdk = { version = "0.29.0", features = ["all-keys", "use-esplora-ureq", "keys-bip39"] }
bitcoincore-rpc = "0.18.0"
bitcoincore-rpc = "0.19.0"
[dependencies]
#https://github.com/payjoin/rust-payjoin/commit/457a0dd5cb212ddd9ea169b7fa3842bfc3d5f373
payjoin = { git= "https://github.com/payjoin/rust-payjoin", rev = "457a0dd5cb212ddd9ea169b7fa3842bfc3d5f373", features = ["send", "receive", "base64", "v2"] }
uniffi = { version = "0.27.1" }

#payjoin = {version = "=0.18.0", features = ["send", "receive", "base64", "v2", "io", "danger-local-https"] }
payjoin={ git = "https://github.com/payjoin/rust-payjoin", rev = "941a6798f52f60d72061fc0a02b5b42146321453", features = ["send", "receive", "base64", "v2", "io", "danger-local-https"]}
uniffi = { version = "0.28.0" }
thiserror = "1.0.47"
ohttp = { version = "0.5.1" }
url = "2.5.0"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ rpc_port = "18443"
```

Now, run the integration tests:
The integration tests illustrates and verify integration using bitcoin core and with bitcoin dev kit(bdk).

The integration tests illustrates and verify integration using bitcoin core and with bitcoin dev kit(bdk).

```shell

Expand Down
36 changes: 20 additions & 16 deletions python/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
# Payjoin

The Python language bindings for the [Payjoin Dev Kit](https://payjoindevkit.org/).
Welcome to the Python language bindings for the [Payjoin Dev Kit](https://payjoindevkit.org/)! Let's get you up and running with some smooth transactions and a sprinkle of fun.

## Install from PyPI

Install the latest release using
Grab the latest release with a simple:

```shell
pip install payjoin
```

## Run the unit tests
## Running Unit Tests
Follow these steps to clone the repository and run the unit tests:

```shell

Expand All @@ -27,34 +28,33 @@ python setup.py bdist_wheel --verbose
# Force reinstall payjoin
pip install ./dist/payjoin-<version>.whl --force-reinstall

#Run unit tests
# Run unit tests
python -m unittest --verbose test/payjoin_unit_test.py

```

## Run the integration test
## Running the Integration Test

Before running the integration test, we need to set up the Bitcoin core properly in the regtest network. If you don't
have Bitcoin Core locally, please refer to this [page](https://learn.saylor.org/mod/page/view.php?id=36347). Or you can
install `Nigiri Bitcoin`, which is a tool designed to simplify the process of running local instances of Bitcoin and
Liquid networks for development and testing purposes. You can refer to
this [link](https://github.com/vulpemventures/nigiri), to install it on your local machine.
Before diving into the integration test, you'll need to set up Bitcoin Core on the regtest network. If you don't have Bitcoin Core installed locally, check out [this installation guide](https://learn.saylor.org/mod/page/view.php?id=36347). Alternatively, you can use `Nigiri Bitcoin`, a tool designed to streamline the process of running local instances of Bitcoin and Liquid networks for development and testing. Follow the instructions [here](https://github.com/vulpemventures/nigiri) to install it on your machine.

Once the nigiri bitcoin starts running, please replace following snippet in `payjoin_integration_test.py`, with you
nigiri bitcoin core credentials.
Once Nigiri Bitcoin is up and running, replace the following snippet in `payjoin_integration_test.py` with your `Nigiri Bitcoin` Core credentials:

```
rpc_user = "bitcoin"
rpc_password = "bitcoin"
```

NB: The default credentials would be the following
By default, these credentials are:

```
rpc_user = "admin1"
rpc_password = "123"
rpc_host = "localhost"
rpc_port = "18443"
```
Now, proceed with the integration test:

```shell

Expand All @@ -71,11 +71,12 @@ python setup.py bdist_wheel --verbose
# Force reinstall payjoin
pip install ./dist/payjoin-<version>.whl --force-reinstall

#Run the integration test
# Run the integration test
python -m unittest --verbose test/payjoin_integration_test.py

```

## Build the package
## Building the Package

```shell
# Install dependencies
Expand All @@ -86,4 +87,7 @@ bash ./scripts/generate_macos.sh

# Build the wheel
python setup.py --verbose bdist_wheel
```

```
We hope everything worked smoothly! Now go forth test, and may your test results be as reliable as the Bitcoin blockchain itself!
₿🔒🤝
11 changes: 10 additions & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub enum PayjoinError {
PjParseError { message: String },

#[error("{message}")]
PjNotSupported { message: String },
PjNotSupported{ message: String },

#[error("Malformed response from receiver: {message}")]
ValidationError { message: String },
Expand All @@ -59,6 +59,9 @@ pub enum PayjoinError {

#[error("{message}")]
UrlError { message: String },

#[error("{message}")]
IoError { message: String },
}

macro_rules! impl_from_error {
Expand Down Expand Up @@ -99,3 +102,9 @@ impl From<payjoin::Error> for PayjoinError {
}
}
}

impl From<payjoin::io::Error> for PayjoinError {
fn from(value: payjoin::io::Error) -> Self {
PayjoinError::IoError { message: value.to_string() }
}
}
25 changes: 25 additions & 0 deletions src/io.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use crate::error::PayjoinError;
use crate::types::OhttpKeys;
use crate::uri::Url;

/// Fetch the ohttp keys from the specified payjoin directory via proxy.
///
/// * `ohttp_relay`: The http CONNNECT method proxy to request the ohttp keys from a payjoin
/// directory. Proxying requests for ohttp keys ensures a client IP address is never revealed to
/// the payjoin directory.
///
/// * `payjoin_directory`: The payjoin directory from which to fetch the ohttp keys. This
/// directory stores and forwards payjoin client payloads.
///
/// * `cert_der` (optional): The DER-encoded certificate to use for local HTTPS connections. This
/// parameter is only available when the "danger-local-https" feature is enabled.
pub async fn fetch_ohttp_keys(
ohttp_relay: Url,
payjoin_directory: Url,
cert_der: Vec<u8>,
) -> Result<OhttpKeys, PayjoinError> {
payjoin::io::fetch_ohttp_keys(ohttp_relay.into(), payjoin_directory.into(), cert_der)
.await
.map(|e| e.into())
.map_err(|e| e.into())
}
8 changes: 5 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#![crate_name = "payjoin_ffi"]

pub mod error;
pub mod io;
pub mod receive;
pub mod send;
pub mod types;
pub mod uri;

use crate::error::PayjoinError;
#[cfg(feature = "uniffi")]
use crate::receive::v1::{
Expand All @@ -17,9 +19,9 @@ use crate::receive::v1::{
};
#[allow(unused_imports)]
use crate::receive::v2::{
ClientResponse, Enrolled, Enroller, RequestResponse, V2MaybeInputsOwned, V2MaybeInputsSeen,
V2MaybeMixedInputScripts, V2OutputsUnknown, V2PayjoinProposal, V2ProvisionalProposal,
V2UncheckedProposal,
ActiveSession, ClientResponse, RequestResponse, SessionInitializer, V2MaybeInputsOwned,
V2MaybeInputsSeen, V2MaybeMixedInputScripts, V2OutputsUnknown, V2PayjoinProposal,
V2ProvisionalProposal, V2UncheckedProposal,
};
#[allow(unused_imports)]
use crate::send::v1::{
Expand Down
49 changes: 32 additions & 17 deletions src/receive/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ impl UncheckedProposal {
|transaction| {
can_broadcast
.callback(payjoin::bitcoin::consensus::encode::serialize(transaction))
.map_err(|e| payjoin::receive::Error::Server(e.into()))
.map_err(|e| payjoin::receive::Error::Server(Box::new(e)))
},
)
.map(|e| Arc::new(e.into()))
Expand All @@ -108,7 +108,7 @@ impl UncheckedProposal {
min_fee_rate.map(|x| FeeRate::from_sat_per_kwu(x)),
|transaction| {
can_broadcast(&payjoin::bitcoin::consensus::encode::serialize(transaction))
.map_err(|e| payjoin::receive::Error::Server(e.into()))
.map_err(|e| payjoin::receive::Error::Server(Box::new(e)))
},
)
.map(|e| Arc::new(e.into()))
Expand Down Expand Up @@ -151,7 +151,7 @@ impl MaybeInputsOwned {
.check_inputs_not_owned(|input| {
is_owned
.callback(input.to_bytes())
.map_err(|e| payjoin::receive::Error::Server(e.into()))
.map_err(|e| payjoin::receive::Error::Server(Box::new(e)))
})
.map_err(|e| e.into())
.map(|e| Arc::new(e.into()))
Expand All @@ -164,7 +164,8 @@ impl MaybeInputsOwned {
self.0
.clone()
.check_inputs_not_owned(|input| {
is_owned(&input.to_bytes()).map_err(|e| payjoin::receive::Error::Server(e.into()))
is_owned(&input.to_bytes())
.map_err(|e| payjoin::receive::Error::Server(Box::new(e)))
})
.map_err(|e| e.into())
.map(|e| Arc::new(e.into()))
Expand Down Expand Up @@ -222,7 +223,9 @@ impl MaybeInputsSeen {
self.0
.clone()
.check_no_inputs_seen_before(|outpoint| {
is_known.callback(outpoint.clone().into()).map_err(|e| pdk::Error::Server(e.into()))
is_known
.callback(outpoint.clone().into())
.map_err(|e| pdk::Error::Server(Box::new(e)))
})
.map_err(|e| e.into())
.map(|e| Arc::new(e.into()))
Expand All @@ -235,7 +238,7 @@ impl MaybeInputsSeen {
self.0
.clone()
.check_no_inputs_seen_before(|outpoint| {
is_known(&outpoint.clone().into()).map_err(|e| pdk::Error::Server(e.into()))
is_known(&outpoint.clone().into()).map_err(|e| pdk::Error::Server(Box::new(e)))
})
.map_err(|e| e.into())
.map(|e| Arc::new(e.into()))
Expand Down Expand Up @@ -266,7 +269,7 @@ impl OutputsUnknown {
.identify_receiver_outputs(|output_script| {
is_receiver_output
.callback(output_script.to_bytes())
.map_err(|e| payjoin::receive::Error::Server(e.into()))
.map_err(|e| payjoin::receive::Error::Server(Box::new(e)))
})
.map(|e| Arc::new(e.into()))
.map_err(|e| e.into())
Expand All @@ -275,15 +278,15 @@ impl OutputsUnknown {
pub fn identify_receiver_outputs(
&self,
is_receiver_output: impl Fn(&Vec<u8>) -> Result<bool, PayjoinError>,
) -> Result<Arc<ProvisionalProposal>, PayjoinError> {
) -> Result<ProvisionalProposal, PayjoinError> {
self.0
.clone()
.identify_receiver_outputs(|input| {
is_receiver_output(&input.to_bytes())
.map_err(|e| payjoin::receive::Error::Server(e.into()))
.map_err(|e| payjoin::receive::Error::Server(Box::new(e)))
})
.map_err(|e| e.into())
.map(|e| Arc::new(e.into()))
.map(|e| e.into())
}
}

Expand All @@ -304,13 +307,25 @@ impl ProvisionalProposal {
fn mutex_guard(&self) -> MutexGuard<'_, payjoin::receive::ProvisionalProposal> {
self.0.lock().unwrap()
}
pub fn substitute_output_address(
#[cfg(not(feature = "uniffi"))]
///If output substitution is enabled, replace the receiver’s output script with a new one.
pub fn try_substitute_receiver_output(
&self,
generate_script: impl Fn() -> Result<Vec<u8>, PayjoinError>,
) -> Result<(), PayjoinError> {
self.mutex_guard()
.try_substitute_receiver_output(|| {
generate_script()
.map(|e| payjoin::bitcoin::ScriptBuf::from_bytes(e))
.map_err(|e| payjoin::Error::Server(Box::new(e)))
})
.map_err(|e| e.into())
}
#[cfg(feature = "uniffi")]
pub fn try_substitute_receiver_output(
&self,
substitute_address: String,
generate_script: impl Fn() -> Result<Vec<u8>, PayjoinError>,
) -> Result<(), PayjoinError> {
let address =
payjoin::bitcoin::Address::from_str(substitute_address.as_str())?.assume_checked();
Ok(self.mutex_guard().substitute_output_address(address))
}
pub fn contribute_witness_input(
&self,
Expand Down Expand Up @@ -363,7 +378,7 @@ impl ProvisionalProposal {
process_psbt
.callback(psbt.to_string())
.map(|e| Psbt::from_str(e.as_str()).expect("Invalid process_psbt "))
.map_err(|e| pdk::Error::Server(e.into()))
.map_err(|e| pdk::Error::Server(Box::new(e)))
},
min_feerate_sat_per_vb.and_then(|x| FeeRate::from_sat_per_vb(x)),
)
Expand All @@ -382,7 +397,7 @@ impl ProvisionalProposal {
|psbt| {
process_psbt(psbt.to_string())
.map(|e| Psbt::from_str(e.as_str()).expect("Invalid process_psbt "))
.map_err(|e| pdk::Error::Server(e.into()))
.map_err(|e| pdk::Error::Server(Box::new(e)))
},
min_feerate_sat_per_vb.and_then(|x| FeeRate::from_sat_per_vb(x)),
)
Expand Down
Loading

0 comments on commit e91e4d3

Please sign in to comment.