# Spark Wallet SDK
[](LICENSE)

A Rust-based Bitcoin wallet SDK for the Spark protocol that provides advanced cryptographic operations, transaction management, and Lightning Network capabilities.
## Overview
Spark Wallet SDK is a comprehensive toolkit designed to manage Bitcoin transactions through a structured "tree" of UTXOs. It provides a safe, reliable interface for interacting with Bitcoin and Lightning Network functionality, with advanced features like threshold signatures.
### Key Features
- **Deposit Address Generation** - Create secure Bitcoin addresses for receiving funds
- **UTXO Tree Management** - Organize UTXOs in a hierarchical tree structure for efficient management
- **Cooperative Signing** - Coordinate transaction signing between multiple parties
- **Threshold Signatures** - Support for FROST-based threshold Schnorr signatures
- **Lightning Network Integration** - Invoice creation and payment capabilities
- **Robust Error Handling** - Comprehensive error types and recovery mechanisms
- **Configurable Backend** - Connect to mainnet or regtest networks
## Installation
Add Spark Wallet SDK to your `Cargo.toml`:
```toml
[dependencies]
spark-sdk = { git = "https://github.com/polarity/spark-rs.git", features = ["self-signing"] }
```
## Architecture
The SDK is structured around a central `SparkSdk` struct that provides access to all functionality through a set of handlers:
```
spark-sdk/
├── src/
│ ├── wallet/
│ │ ├── handlers/ # Public API for wallet operations
│ │ ├── internal_handlers/ # Lower-level implementation details
│ │ ├── leaf_manager/ # UTXO tree management
│ │ └── client.rs # Main SparkSdk implementation
│ ├── signer/ # Cryptographic signing operations
│ ├── rpc/ # Communication with Spark services
│ └── error/ # Error handling
└── examples/ # Usage examples
```
## Usage
### Initializing the SDK
```rust
use spark_sdk::{SparkSdk, SparkNetwork, signer::default_signer::DefaultSigner};
use rand::rngs::OsRng;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Generate a random master seed (or load from secure storage)
let mut rng = OsRng;
let master_seed = bitcoin::secp256k1::SecretKey::new(&mut rng);
// Create a signer with the seed
let network = SparkNetwork::Regtest;
let signer = DefaultSigner::from_master_seed(
&master_seed.secret_bytes().to_vec(),
network
).await?;
// Initialize the SDK
let sdk = SparkSdk::new(network, signer).await?;
// SDK is now ready to use
Ok(())
}
```
### Generating a Deposit Address
```rust
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize SDK (see above)
let sdk = get_initialized_sdk().await?;
// Generate a deposit address
let response = sdk.generate_deposit_address().await?;
println!("Deposit to: {}", response.deposit_address.address);
Ok(())
}
```
### Creating a UTXO Tree
```rust
use bitcoin::Transaction;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let sdk = get_initialized_sdk().await?;
// After receiving funds at a deposit address
// deposit_tx contains the transaction that sent funds to your deposit address
let deposit_tx = Transaction::default(); // Replace with actual transaction
// Create a tree with split level 2 (creating 4 leaf nodes)
let split_level = 2;
// Create the tree
let result = sdk.create_tree(
Some(deposit_tx),
None, // No parent node ID (creating from deposit)
0, // UTXO output index
split_level,
vec![] // No parent public keys
).await?;
println!("Created {} nodes in tree", result.nodes.len());
Ok(())
}
```
### Transferring Funds
```rust
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let sdk = get_initialized_sdk().await?;
// Transfer 50,000 satoshis to recipient
let recipient_pubkey = vec![/* public key bytes */];
let amount_sats = 50_000;
let transfer_id = sdk.transfer(amount_sats, recipient_pubkey).await?;
println!("Transfer initiated with ID: {}", transfer_id);
Ok(())
}
```
### Creating a Lightning Invoice
```rust
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let sdk = get_initialized_sdk().await?;
// Create an invoice for 10,000 satoshis
let amount_msat = 10_000_000; // 10,000 sats in millisats
let description = "Payment for services".to_string();
let invoice = sdk.create_lightning_invoice(amount_msat, description).await?;
println!("Lightning invoice: {}", invoice.bolt11);
Ok(())
}
```
## Feature Flags
The SDK supports several feature flags to enable different functionality:
- **`self-signing`** (default): Enable local key generation and storage
- **`integration-tests`** (default): Enable concurrency and advanced integration tests
- **`local-operator-tests`**: Run tests with local Spark operators
- **`lightning`**: Enable Lightning Network functionality
Example with specific features:
```toml
[dependencies]
spark-sdk = { git = "https://github.com/polarity/spark-rs.git", features = ["self-signing", "lightning"] }
```
## Handler Modules
The SDK is organized into handler modules, each focusing on specific functionality:
| `init` | SDK initialization | `new()`, `new_with_default_config()` |
| `deposit` | Fund reception | `generate_deposit_address()` |
| `create_tree` | UTXO structuring | `create_tree()` |
| `leaves` | UTXO management | `get_available_leaves()` |
| `transfer` | Fund movement | `transfer()`, `claim_transfer()` |
| `lightning` | LN operations | `create_lightning_invoice()`, `pay_invoice()` |
| `split` | UTXO division | `split_leaf()` |
| `swap` | Atomic exchanges | `initiate_swap()` |
## Error Handling
The SDK provides a comprehensive error type through `SparkSdkError` that covers:
- Connection issues
- Authentication failures
- Transaction validation errors
- Signing problems
- Local storage issues
Example error handling:
```rust
match sdk.generate_deposit_address().await {
Ok(response) => {
println!("Success! Address: {}", response.deposit_address.address);
},
Err(e) => match e {
SparkSdkError::AuthenticationError(_) => {
println!("Authentication failed. Please re-initialize the SDK.");
},
SparkSdkError::ConnectionError(_) => {
println!("Connection to Spark service failed. Check your internet connection.");
},
_ => {
println!("An error occurred: {}", e);
}
}
}
```
## Advanced Usage
### Custom Signers
You can implement the `SparkSigner` trait to provide your own signing mechanism:
```rust
use spark_sdk::signer::traits::SparkSigner;
struct MyCustomSigner {
// Your implementation details
}
#[async_trait::async_trait]
impl SparkSigner for MyCustomSigner {
// Implement required methods
}
// Then use it with the SDK
let sdk = SparkSdk::new(SparkNetwork::Regtest, my_custom_signer).await?;
```
### Working with FROST Threshold Signatures
```rust
// Generate threshold signing commitments (for a t-of-n scheme)
let commitments = sdk.new_frost_signing_commitments().await?;
// Distribute commitments to participants
// ...
// Later, receive signature shares and aggregate them
let signature = sdk.aggregate_frost_signature_shares(message, shares).await?;
```
## Security Considerations
- **Seed Management**: Properly secure the master seed used to initialize the signer
- **Network Traffic**: All API calls are encrypted, but be aware of the network you're connected to
- **Key Rotation**: Consider implementing key rotation for long-lived applications
- **Backup**: Implement backup functionality for critical wallet data
## For Contributors
See the [CONTRIBUTING.md](../../CONTRIBUTING.md) file for guidelines on contributing to this project.
### Development Setup
```bash
# Clone the repository
git clone https://github.com/polarity/spark-rs.git
cd spark-rs
# Build the SDK
cargo build -p spark-sdk
# Run tests
cargo test -p spark-sdk
```
### Running the Examples
```bash
# Run the new wallet example
cargo run --example new_wallet
# Run the deposit example
cargo run --example deposit
```
## License
This project is licensed under the Apache License, Version 2.0 - see the [LICENSE](LICENSE) file for details.