diff --git a/src/bitcoin.rs b/src/bitcoin.rs new file mode 100644 index 0000000..a8d46c0 --- /dev/null +++ b/src/bitcoin.rs @@ -0,0 +1,74 @@ +use std::str::FromStr; + +use payjoin::bitcoin; + +/// A reference to a transaction output. +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct OutPoint { + /// The referenced transaction's txid. + pub txid: String, + /// The index of the referenced output in its transaction's vout. + pub vout: u32, +} + +impl From for bitcoin::OutPoint { + fn from(outpoint: OutPoint) -> Self { + bitcoin::OutPoint { + txid: bitcoin::Txid::from_str(&outpoint.txid).expect("Invalid txid"), + vout: outpoint.vout, + } + } +} + +impl From for OutPoint { + fn from(outpoint: bitcoin::OutPoint) -> Self { + OutPoint { txid: outpoint.txid.to_string(), vout: outpoint.vout } + } +} + +#[derive(Debug, Clone)] +pub struct TxOut { + /// The value of the output, in satoshis. + pub value: u64, + /// The address of the output. + pub script_pubkey: Vec, +} + +impl From for bitcoin::TxOut { + fn from(tx_out: TxOut) -> Self { + bitcoin::TxOut { + value: bitcoin::amount::Amount::from_sat(tx_out.value), + script_pubkey: bitcoin::ScriptBuf::from_bytes(tx_out.script_pubkey), + } + } +} + +impl From for TxOut { + fn from(tx_out: bitcoin::TxOut) -> Self { + TxOut { value: tx_out.value.to_sat(), script_pubkey: tx_out.script_pubkey.to_bytes() } + } +} + +#[derive(Clone, Default)] +pub enum Network { + ///Bitcoin’s testnet + Testnet, + ///Bitcoin’s regtest + Regtest, + #[default] + ///Classic Bitcoin + Bitcoin, + ///Bitcoin’s signet + Signet, +} + +impl From for bitcoin::Network { + fn from(network: Network) -> Self { + match network { + Network::Signet => bitcoin::Network::Signet, + Network::Testnet => bitcoin::Network::Testnet, + Network::Regtest => bitcoin::Network::Regtest, + Network::Bitcoin => bitcoin::Network::Bitcoin, + } + } +} diff --git a/src/io.rs b/src/io.rs index 4dce7de..690160f 100644 --- a/src/io.rs +++ b/src/io.rs @@ -1,5 +1,5 @@ use crate::error::PayjoinError; -use crate::types::OhttpKeys; +use crate::ohttp::OhttpKeys; use crate::uri::Url; /// Fetch the ohttp keys from the specified payjoin directory via proxy. diff --git a/src/lib.rs b/src/lib.rs index 5fdb9dd..7c4580c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,19 +1,42 @@ #![crate_name = "payjoin_ffi"] +pub mod bitcoin; pub mod error; pub mod io; +pub mod ohttp; pub mod receive; pub mod send; -pub mod types; pub mod uri; +pub use crate::bitcoin::*; use crate::error::PayjoinError; +pub use crate::ohttp::*; pub use crate::receive::v1::*; pub use crate::receive::v2::*; pub use crate::send::v1::*; pub use crate::send::v2::*; -pub use crate::types::*; pub use crate::uri::{PjUri, PjUriBuilder, Uri, Url}; #[cfg(feature = "uniffi")] uniffi::include_scaffolding!("payjoin_ffi"); + +use std::sync::Arc; +///Represents data that needs to be transmitted to the receiver. +///You need to send this request over HTTP(S) to the receiver. +#[derive(Clone, Debug)] +pub struct Request { + ///URL to send the request to. + /// + ///This is full URL with scheme etc - you can pass it right to reqwest or a similar library. + pub url: Arc, + ///Bytes to be sent to the receiver. + /// + ///This is properly encoded PSBT, already in base64. You only need to make sure Content-Type is text/plain and Content-Length is body.len() (most libraries do the latter automatically). + pub body: Vec, +} + +impl From for Request { + fn from(value: payjoin::Request) -> Self { + Self { url: Arc::new(value.url.into()), body: value.body } + } +} diff --git a/src/ohttp.rs b/src/ohttp.rs new file mode 100644 index 0000000..cdc2d15 --- /dev/null +++ b/src/ohttp.rs @@ -0,0 +1,20 @@ +use crate::error::PayjoinError; + +impl From for OhttpKeys { + fn from(value: payjoin::OhttpKeys) -> Self { + Self(value) + } +} +impl From for payjoin::OhttpKeys { + fn from(value: OhttpKeys) -> Self { + value.0 + } +} +#[derive(Debug, Clone)] +pub struct OhttpKeys(pub payjoin::OhttpKeys); +impl OhttpKeys { + /// Decode an OHTTP KeyConfig + pub fn decode(bytes: Vec) -> Result { + payjoin::OhttpKeys::decode(bytes.as_slice()).map(|e| e.into()).map_err(|e| e.into()) + } +} diff --git a/src/receive/v1.rs b/src/receive/v1.rs index 9fbbc22..0ea19d4 100644 --- a/src/receive/v1.rs +++ b/src/receive/v1.rs @@ -6,8 +6,8 @@ use payjoin::bitcoin::psbt::Psbt; use payjoin::bitcoin::FeeRate; use payjoin::receive as pdk; +use crate::bitcoin::{OutPoint, TxOut}; use crate::error::PayjoinError; -use crate::types::{OutPoint, TxOut}; pub trait CanBroadcast { fn callback(&self, tx: Vec) -> Result; diff --git a/src/receive/v2.rs b/src/receive/v2.rs index de8ee22..156299f 100644 --- a/src/receive/v2.rs +++ b/src/receive/v2.rs @@ -8,13 +8,14 @@ use payjoin::bitcoin::psbt::Psbt; use payjoin::bitcoin::FeeRate; use payjoin::receive as pdk; +use crate::bitcoin::Network; +use crate::ohttp::OhttpKeys; #[cfg(feature = "uniffi")] use crate::receive::v1::{ CanBroadcast, GenerateScript, IsOutputKnown, IsScriptOwned, ProcessPartiallySignedTransaction, }; -use crate::types::Network; use crate::uri::PjUriBuilder; -use crate::{OhttpKeys, OutPoint, PayjoinError, Request, TxOut, Url}; +use crate::{OutPoint, PayjoinError, Request, TxOut, Url}; pub struct ClientResponse(Mutex>); diff --git a/src/request.rs b/src/request.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/send/v1.rs b/src/send/v1.rs index cc5b392..e625e77 100644 --- a/src/send/v1.rs +++ b/src/send/v1.rs @@ -6,8 +6,8 @@ pub use payjoin::send as pdk; use crate::error::PayjoinError; use crate::send::v2::ContextV2; -use crate::types::Request; use crate::uri::{PjUri, Url}; +use crate::Request; ///Builder for sender-side payjoin parameters /// diff --git a/src/types.rs b/src/types.rs deleted file mode 100644 index 54425a2..0000000 --- a/src/types.rs +++ /dev/null @@ -1,114 +0,0 @@ -use std::str::FromStr; -use std::sync::Arc; - -use crate::error::PayjoinError; -use crate::uri::Url; -///Represents data that needs to be transmitted to the receiver. -///You need to send this request over HTTP(S) to the receiver. -#[derive(Clone, Debug)] -pub struct Request { - ///URL to send the request to. - /// - ///This is full URL with scheme etc - you can pass it right to reqwest or a similar library. - pub url: Arc, - ///Bytes to be sent to the receiver. - /// - ///This is properly encoded PSBT, already in base64. You only need to make sure Content-Type is text/plain and Content-Length is body.len() (most libraries do the latter automatically). - pub body: Vec, -} - -impl From for Request { - fn from(value: payjoin::Request) -> Self { - Self { url: Arc::new(value.url.into()), body: value.body } - } -} - -/// A reference to a transaction output. -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct OutPoint { - /// The referenced transaction's txid. - pub txid: String, - /// The index of the referenced output in its transaction's vout. - pub vout: u32, -} - -impl From for payjoin::bitcoin::OutPoint { - fn from(outpoint: OutPoint) -> Self { - payjoin::bitcoin::OutPoint { - txid: payjoin::bitcoin::Txid::from_str(&outpoint.txid).expect("Invalid txid"), - vout: outpoint.vout, - } - } -} - -impl From for OutPoint { - fn from(outpoint: payjoin::bitcoin::OutPoint) -> Self { - OutPoint { txid: outpoint.txid.to_string(), vout: outpoint.vout } - } -} - -#[derive(Debug, Clone)] -pub struct TxOut { - /// The value of the output, in satoshis. - pub value: u64, - /// The address of the output. - pub script_pubkey: Vec, -} - -impl From for payjoin::bitcoin::TxOut { - fn from(tx_out: TxOut) -> Self { - payjoin::bitcoin::TxOut { - value: payjoin::bitcoin::amount::Amount::from_sat(tx_out.value), - script_pubkey: payjoin::bitcoin::ScriptBuf::from_bytes(tx_out.script_pubkey), - } - } -} - -impl From for TxOut { - fn from(tx_out: payjoin::bitcoin::TxOut) -> Self { - TxOut { value: tx_out.value.to_sat(), script_pubkey: tx_out.script_pubkey.to_bytes() } - } -} - -#[derive(Clone, Default)] -pub enum Network { - ///Bitcoin’s testnet - Testnet, - ///Bitcoin’s regtest - Regtest, - #[default] - ///Classic Bitcoin - Bitcoin, - ///Bitcoin’s signet - Signet, -} - -impl From for payjoin::bitcoin::Network { - fn from(network: Network) -> Self { - match network { - Network::Signet => payjoin::bitcoin::Network::Signet, - Network::Testnet => payjoin::bitcoin::Network::Testnet, - Network::Regtest => payjoin::bitcoin::Network::Regtest, - Network::Bitcoin => payjoin::bitcoin::Network::Bitcoin, - } - } -} - -impl From for OhttpKeys { - fn from(value: payjoin::OhttpKeys) -> Self { - Self(value) - } -} -impl From for payjoin::OhttpKeys { - fn from(value: OhttpKeys) -> Self { - value.0 - } -} -#[derive(Debug, Clone)] -pub struct OhttpKeys(pub payjoin::OhttpKeys); -impl OhttpKeys { - /// Decode an OHTTP KeyConfig - pub fn decode(bytes: Vec) -> Result { - payjoin::OhttpKeys::decode(bytes.as_slice()).map(|e| e.into()).map_err(|e| e.into()) - } -} diff --git a/src/uri.rs b/src/uri.rs index 0b83ba9..be93cd5 100644 --- a/src/uri.rs +++ b/src/uri.rs @@ -7,7 +7,7 @@ use payjoin::bitcoin::address::NetworkChecked; use payjoin::UriExt; use crate::error::PayjoinError; -use crate::types::OhttpKeys; +use crate::ohttp::OhttpKeys; #[derive(Clone)] pub struct Uri(payjoin::Uri<'static, NetworkChecked>); impl From for payjoin::Uri<'static, NetworkChecked> { diff --git a/tests/bitcoin_core_integration.rs b/tests/bitcoin_core_integration.rs index 3345c8a..7e09c36 100644 --- a/tests/bitcoin_core_integration.rs +++ b/tests/bitcoin_core_integration.rs @@ -8,10 +8,11 @@ use std::sync::Arc; use bitcoincore_rpc::bitcoincore_rpc_json::WalletProcessPsbtResult; use bitcoincore_rpc::{Auth, Client, RpcApi}; +use payjoin_ffi::bitcoin::{OutPoint, Request, TxOut}; use payjoin_ffi::receive::v1::{Headers, PayjoinProposal, UncheckedProposal}; use payjoin_ffi::send::v1::RequestBuilder; -use payjoin_ffi::types::{OutPoint, Request, TxOut}; use payjoin_ffi::uri::{PjUriBuilder, Uri, Url}; +use payjoin_ffi::Request; type BoxError = Box;