Skip to content

Commit ad001fc

Browse files
committed
Prepare for publish
1 parent d80a6f4 commit ad001fc

File tree

3 files changed

+75
-18
lines changed

3 files changed

+75
-18
lines changed

Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
11
[package]
22
name = "bitcoin-send-tx-p2p"
33
version = "0.1.0"
4+
authors = ["Andrew Toth"]
5+
license = "MIT"
6+
homepage = "https://github.com/andrewtoth/bitcoin-send-tx-p2p/"
7+
repository = "https://github.com/andrewtoth/bitcoin-send-tx-p2p/"
8+
documentation = "https://docs.rs/bitcoin-send-tx-p2p/"
9+
description = "Send a bitcoin tx through the peer-to-peer protocol via clearnet or tor"
10+
keywords = [ "crypto", "bitcoin", "p2p" ]
11+
readme = "README.md"
412
edition = "2021"
513

614
[features]
715
default = []
816
tor = ["dep:tokio-socks"]
917

18+
[package.metadata.docs.rs]
19+
features = [ "tor" ]
20+
rustdoc-args = ["--cfg", "docsrs"]
21+
1022
[dependencies]
1123
anyhow = "1.0"
1224
tokio = { version = "1.20.1", features = ["net", "io-util", "rt-multi-thread", "time"] }

README.md

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,29 @@ Library for sending bitcoin transactions to nodes using the bitcoin
44
peer-to-peer protocol, given only a transaction and the IP or onion address of
55
the node.
66

7+
Under the hood it creates a connection to the node and performs the version
8+
handshake. Then it sends an `inv` message with the txid or wtxid and waits
9+
for a `getdata` message. After transmitting a `tx` message with the full
10+
transaction it disconnects. Note that if the receiving node already has the
11+
transaction it will not respond with a a `getdata` message, in which case
12+
the sending function will timeout and disconnect.
13+
714
### Examples
815

9-
```
10-
use anyhow::Result;
11-
use bitcoin::consensus::encode::deserialize;
12-
use bitcoin::{Network, Transaction};
13-
use bitcoin_send_tx_p2p::{send_tx_p2p_over_clearnet, send_tx_p2p_over_tor, Config};
14-
use hex::FromHex;
1516

16-
#[tokio::main]
17-
async fn main() -> Result<()> {
18-
let tx_bytes = Vec::from_hex("000000800100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000")?;
19-
let tx: Transaction = deserialize(&tx_bytes)?;
17+
```rust
18+
use anyhow::Result;
19+
use bitcoin::Transaction;
2020

21-
send_tx_p2p_over_clearnet("127.0.0.1:8333".parse()?, tx.clone(), None).await?;
21+
use bitcoin_send_tx_p2p::{send_tx_p2p_over_clearnet, send_tx_p2p_over_tor, Config};
2222

23+
async fn send_tx(tx: Transaction) -> Result<()> {
2324
let mut config = Config::default();
24-
config.block_height = 138;
25-
config.network = Network::Regtest;
25+
config.block_height = 1000;
26+
send_tx_p2p_over_clearnet("127.0.0.1:8333".parse()?, tx, Some(config)).await
27+
}
2628

27-
send_tx_p2p_over_tor("<onion address>:8333", tx, Some(config)).await
29+
async fn send_tx_tor(tx: Transaction) -> Result<()> {
30+
send_tx_p2p_over_tor("cssusbltvosy7hhomxuhicmh5svw6e4z3eebgnyjcnslrloiy5m27pid.onion:8333", tx, None).await
2831
}
2932
```

src/lib.rs

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
//! Send a Bitcoin Transaction to a node via Peer-to-Peer protocol
2+
//!
3+
//! Supports sending via clearnet with a [SocketAddr] or via tor using a
4+
//! [SocketAddr] or onion address with the [IntoTargetAddr] trait.
5+
//!
6+
//! Under the hood it creates a connection to the node and performs the version
7+
//! handshake. Then it sends an `inv` message with the txid or wtxid and waits
8+
//! for a `getdata` message. After transmitting a `tx` message with the full
9+
//! transaction it disconnects. Note that if the receiving node already has the
10+
//! transaction it will not respond with a a `getdata` message, in which case
11+
//! the sending function will timeout and disconnect.
12+
113
mod async_encode;
214
mod message_handler;
315

@@ -20,7 +32,9 @@ use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt, BufReader};
2032
use tokio::net::TcpStream;
2133
use tokio::time::timeout;
2234
#[cfg(feature = "tor")]
23-
use tokio_socks::{tcp::Socks5Stream, IntoTargetAddr, TargetAddr};
35+
pub use tokio_socks::IntoTargetAddr;
36+
#[cfg(feature = "tor")]
37+
use tokio_socks::{tcp::Socks5Stream, TargetAddr};
2438

2539
/// Config options for sending
2640
pub struct Config {
@@ -43,9 +57,10 @@ pub struct Config {
4357
/// have the tx
4458
/// Default is 30 seconds
4559
pub send_tx_timeout: Duration,
46-
#[cfg(feature = "tor")]
4760
/// Tor SOCKS5 proxy address to send through if using tor
4861
/// Defaults to 127.0.0.1:9050
62+
#[cfg(feature = "tor")]
63+
#[cfg_attr(docsrs, doc(cfg(feature = "tor")))]
4964
pub tor_proxy: SocketAddr,
5065
}
5166

@@ -63,7 +78,21 @@ impl Default for Config {
6378
}
6479
}
6580

66-
/// Connects to a node at <address> over clearnet and attempts to send it <tx>
81+
/// Connects to a node at `address` over clearnet and attempts to send it `tx`,
82+
/// optionally taking [`config`](Config) to specify configuration options
83+
///
84+
/// # Example
85+
/// ```rust
86+
///use anyhow::Result;
87+
///use bitcoin::Transaction;
88+
///use bitcoin_send_tx_p2p::{send_tx_p2p_over_clearnet, Config};
89+
///
90+
///async fn send_tx(tx: Transaction) -> Result<()> {
91+
/// let mut config = Config::default();
92+
/// config.block_height = 1000;
93+
/// send_tx_p2p_over_clearnet("127.0.0.1:8333".parse()?, tx, Some(config)).await
94+
///}
95+
/// ```
6796
pub async fn send_tx_p2p_over_clearnet(
6897
address: SocketAddr,
6998
tx: Transaction,
@@ -85,8 +114,21 @@ pub async fn send_tx_p2p_over_clearnet(
85114
.await
86115
}
87116

117+
/// Connects to a node at `address` over tor and attempts to send it `tx`,
118+
/// optionally taking [`config`](Config) to specify configuration options
119+
///
120+
/// # Example
121+
/// ```rust
122+
///use anyhow::Result;
123+
///use bitcoin::Transaction;
124+
///use bitcoin_send_tx_p2p::send_tx_p2p_over_tor;
125+
///
126+
///async fn send_tx(tx: Transaction) -> Result<()> {
127+
/// send_tx_p2p_over_tor("cssusbltvosy7hhomxuhicmh5svw6e4z3eebgnyjcnslrloiy5m27pid.onion:8333", tx, None).await
128+
///}
129+
/// ```
88130
#[cfg(feature = "tor")]
89-
/// Connects to a node at <address> over tor and attempts to send it <tx>
131+
#[cfg_attr(docsrs, doc(cfg(feature = "tor")))]
90132
pub async fn send_tx_p2p_over_tor<'t, T>(
91133
address: T,
92134
tx: Transaction,

0 commit comments

Comments
 (0)