bitcoinsv-rpc 2.0.1

Async Rust library for Bitcoin SV node communication
Documentation
# rust-bitcoinsv-rpc

[![Crates.io](https://img.shields.io/crates/v/bitcoinsv-rpc.svg)](https://crates.io/crates/bitcoinsv-rpc)
[![Documentation](https://docs.rs/bitcoinsv-rpc/badge.svg)](https://docs.rs/bitcoinsv-rpc)
[![License](https://img.shields.io/crates/l/bitcoinsv-rpc.svg)](./LICENSE)

An async Rust library for interfacing with Bitcoin SV nodes via their JSON-RPC API and REST interface.
See the documentation at https://docs.rs/bitcoinsv-rpc/latest/bitcoinsv_rpc/.

## Features

- 🚀 **Async/await** support with Tokio
- 🔐 **JSON-RPC** interface for node commands with authentication support
-**REST API** interface for efficient binary block retrieval
- 🔧 **Type-safe** integration with the [bitcoinsv]https://crates.io/crates/bitcoinsv crate
-**Tested** with comprehensive unit and integration tests

Only a very limited number of functions have been implemented, to meet my immediate needs. If you need additional functions, 
please submit a pull request (preferred) or a ticket (I cant guarentee a quick response).

## Installation

Add this to your `Cargo.toml`:

```toml
[dependencies]
bitcoinsv-rpc = "1.0"
tokio = { version = "1", features = ["full"] }
```

## Quick Start

```rust
use bitcoinsv_rpc::{NodeClient, SvNodeClient};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a client connection to a Bitcoin SV node
    let client = SvNodeClient::new(
        "http://localhost:8332",
        Some("your_rpc_user".to_string()),
        Some("your_rpc_password".to_string()),
    )?;

    // Get the best block hash
    let best_hash = client.get_best_block_hash().await?;
    println!("Best block hash: {}", best_hash);

    // Get the block header
    let header = client.get_block_header(&best_hash).await?;
    println!("Block version: {}", header.version());
    println!("Block timestamp: {}", header.timestamp());

    // Get the complete block (uses REST API for efficiency)
    let block = client.get_block(&best_hash).await?;
    println!("Number of transactions: {}", block.num_tx);

    Ok(())
}
```

## API Methods

### `get_best_block_hash()`

Returns the hash of the best (tip) block in the longest blockchain.

**Returns:** `Result<bitcoinsv::bitcoin::BlockHash>`

**Example:**
```rust
let hash = client.get_best_block_hash().await?;
println!("Best block: {}", hash);
```

### `get_block_header(block_hash: &BlockHash)`

Returns the block header for a specified block hash. Uses the JSON-RPC interface.

**Parameters:**
- `block_hash`: The hash of the block to retrieve

**Returns:** `Result<bitcoinsv::bitcoin::BlockHeader>`

**Example:**
```rust
let hash = client.get_best_block_hash().await?;
let header = client.get_block_header(&hash).await?;
println!("Block difficulty: {}", header.difficulty());
```

### `get_block(block_hash: &BlockHash)`

Returns the complete block data for a specified block hash. Uses the REST API in binary mode for efficient data transfer.

**Parameters:**
- `block_hash`: The hash of the block to retrieve

**Returns:** `Result<bitcoinsv::bitcoin::Block>`

**Example:**
```rust
let hash = client.get_best_block_hash().await?;
let block = client.get_block(&hash).await?;
for tx in block.tx_iter() {
    // Process transactions
}
```

## Configuration

### Node Connection

The client requires a node URL and optionally authentication credentials:

```rust
use bitcoinsv_rpc::{NodeClient, SvNodeClient};

// Without authentication (for nodes with rpcauth disabled)
let client = SvNodeClient::new("http://localhost:8332", None, None)?;

// With authentication
let client = SvNodeClient::new(
    "http://localhost:8332",
    Some("username".to_string()),
    Some("password".to_string()),
)?;

// For testnet (default port 18332)
let client = SvNodeClient::new(
    "http://localhost:18332",
    Some("username".to_string()),
    Some("password".to_string()),
)?;
```

### Bitcoin SV Node Setup

To use this library, you need a running Bitcoin SV node with:

1. **JSON-RPC enabled** (enabled by default)
2. **REST interface enabled** - Add `-rest` to your node configuration or command line
3. **Authentication configured** (if required) - Set `rpcuser` and `rpcpassword` in your bitcoin.conf

Example `bitcoin.conf`:
```ini
# Enable RPC server
server=1

# RPC credentials
rpcuser=your_username
rpcpassword=your_password

# RPC bind address (default: 127.0.0.1)
rpcbind=127.0.0.1

# RPC port (8332 for mainnet, 18332 for testnet)
rpcport=8332

# Enable REST API
rest=1
```

## Testing

### Unit Tests

Run the unit tests:

```bash
cargo test
```

### Integration Tests

Integration tests require a running Bitcoin SV node. Configure the connection using environment variables:

```bash
# Set node connection details
export BSV_NODE_URL=http://localhost:18332
export BSV_NODE_USER=your_username
export BSV_NODE_PASSWORD=your_password

# Run integration tests
cargo test --test integration -- --ignored
```

**Environment Variables:**
- `BSV_NODE_URL`: URL of the Bitcoin SV node (default: `http://localhost:18332`)
- `BSV_NODE_USER`: RPC username (optional, omit if authentication is disabled)
- `BSV_NODE_PASSWORD`: RPC password (optional, omit if authentication is disabled)

**Note:** Integration tests are marked with `#[ignore]` by default and must be explicitly run with the `--ignored` flag.

## Error Handling

The library provides detailed error types via the `Error` enum:

```rust
use bitcoinsv_rpc::{Error, NodeClient, SvNodeClient};

let hash = client.get_best_block_hash().await?;
match client.get_block(&hash).await {
    Ok(block) => println!("Got block with {} transactions", block.num_tx),
    Err(Error::Rpc { code, message }) => {
        eprintln!("RPC error {}: {}", code, message);
    }
    Err(Error::Http(e)) => {
        eprintln!("HTTP error: {}", e);
    }
    Err(e) => {
        eprintln!("Other error: {}", e);
    }
}
```

## Architecture

The library is structured into several modules:

- **`client`**: Main `SvNodeClient` struct and `NodeClient` trait
- **`rpc`**: JSON-RPC client implementation for RPC methods
- **`rest`**: REST API client for efficient binary block retrieval
- **`error`**: Error types and Result type alias

### The NodeClient Trait

The `NodeClient` trait defines a common interface for communicating with Bitcoin nodes. This abstraction allows different client implementations (e.g., SV node, Teranode) to provide the same functionality, enabling easy switching between node types without changing your application code.

**Note:** You must import the `NodeClient` trait to use its methods on `SvNodeClient`:

```rust
use bitcoinsv_rpc::{NodeClient, SvNodeClient};
```

### Why REST for Blocks?

The library uses the REST API (instead of JSON-RPC) for retrieving complete blocks because:

1. **Binary format** is more efficient than JSON for large data structures
2. **Reduced overhead** - no JSON encoding/decoding for block data
3. **Better performance** for large blocks (Bitcoin SV supports very large blocks)

## Development Status

This library is under active development. Current implementation includes:

- ✅ Connection management (JSON-RPC and REST)
-`get_best_block_hash()`
-`get_block_header()`
-`get_block()` via REST API
- 🚧 Additional RPC methods (planned)
- 🚧 Teranode support (planned)

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## Acknowledgments

- Built with the [bitcoinsv]https://crates.io/crates/bitcoinsv crate for Bitcoin SV types
- Uses [tokio]https://tokio.rs/ for async runtime
- HTTP client powered by [reqwest]https://docs.rs/reqwest/