pub struct SparkSdk<S: SparkSigner + Send + Sync = DefaultSigner> { /* private fields */ }
Expand description
SparkSdk is the main struct for the Spark wallet
Implementations§
Source§impl<S: SparkSigner + Send + Sync> SparkSdk<S>
impl<S: SparkSigner + Send + Sync> SparkSdk<S>
pub fn cleanup(&self) -> Result<(), SparkSdkError>
Source§impl SparkSdk
CoopExitService implementation for Rust
This is a 1-to-1 port of the TypeScript CoopExitService class
impl SparkSdk
CoopExitService implementation for Rust This is a 1-to-1 port of the TypeScript CoopExitService class
Sourcepub async fn withdraw(
&self,
onchain_address: &Address,
target_amount_sats: Option<u64>,
) -> Result<CoopExitResponse, SparkSdkError>
pub async fn withdraw( &self, onchain_address: &Address, target_amount_sats: Option<u64>, ) -> Result<CoopExitResponse, SparkSdkError>
Initiates a withdrawal to move funds from the Spark network to an on-chain Bitcoin address.
§Arguments
onchain_address
- The Bitcoin address where the funds should be senttarget_amount_sats
- The amount in satoshis to withdraw. If not specified, attempts to withdraw all available funds
§Returns
The withdrawal request details, or an error if the request cannot be completed
Sourcepub fn create_connector_refund_transaction(
&self,
sequence: u32,
node_outpoint: OutPoint,
connector_output: OutPoint,
amount_sats: u64,
receiver_pubkey: &PublicKey,
) -> Transaction
pub fn create_connector_refund_transaction( &self, sequence: u32, node_outpoint: OutPoint, connector_output: OutPoint, amount_sats: u64, receiver_pubkey: &PublicKey, ) -> Transaction
Creates a connector refund transaction.
This method is equivalent to the TypeScript createConnectorRefundTransaction
method.
It creates a refund transaction for a connector output.
§Arguments
sequence
- The sequence number for the transactionnode_outpoint
- The outpoint of the node transactionconnector_output
- The connector outputamount_sats
- The amount in satoshisreceiver_pubkey
- The receiver public key
§Returns
The created refund transaction
Source§impl<S: SparkSigner + Send + Sync + Clone + 'static> SparkSdk<S>
impl<S: SparkSigner + Send + Sync + Clone + 'static> SparkSdk<S>
Sourcepub async fn generate_deposit_address(
&self,
) -> Result<GenerateDepositAddressSdkResponse, SparkSdkError>
pub async fn generate_deposit_address( &self, ) -> Result<GenerateDepositAddressSdkResponse, SparkSdkError>
Generates a new deposit address for receiving funds into the Spark wallet.
This function handles the generation of a new deposit address by:
- Creating a new signing keypair for the deposit address
- Requesting a deposit address from the Spark network
- Validating the returned address and proof of possession
§Returns
Ok(GenerateDepositAddressSdkResponse)
- Contains the validated deposit address and signing public keyErr(SparkSdkError)
- If there was an error during address generation
§Errors
Returns SparkSdkError
if:
- Failed to generate new signing keypair
- Network errors when communicating with Spark operators
- Address validation fails (e.g. invalid proof of possession)
§Example
let deposit_address = sdk.generate_deposit_address().await?;
println!("New deposit address: {}", deposit_address.deposit_address);
Sourcepub async fn claim_deposit(
&self,
txid: String,
) -> Result<Vec<TreeNode>, SparkSdkError>
pub async fn claim_deposit( &self, txid: String, ) -> Result<Vec<TreeNode>, SparkSdkError>
Claims a pending deposit by txid
- Querying if the txid is a pending deposit
- Checking the mempool for transaction
- Finalizing the deposit by creating tree nodes
§Errors
Returns SparkSdkError
if:
- Failed to connect to Spark service
- Failed to query mempool
- Failed to finalize deposits
§Example
async fn example() {
let mnemonic = "abandon ability able about above absent absorb abstract absurd abuse access accident";
let network = SparkNetwork::Regtest;
let signer = DefaultSigner::from_mnemonic(mnemonic, network.clone()).await.unwrap();
let sdk = SparkSdk::new(network, signer).await.unwrap();
let hardcoded_txid = "edb5575e6ee96fcf175c9114e0b0d86d99d4642956edcd02e6ec7b6899e90b41";
sdk.claim_deposit(hardcoded_txid.to_string()).await.unwrap();
}
Sourcepub async fn finalize_deposit(
&self,
signing_pubkey: Vec<u8>,
verifying_pubkey: Vec<u8>,
deposit_tx: Transaction,
vout: u32,
) -> Result<Vec<TreeNode>, SparkSdkError>
pub async fn finalize_deposit( &self, signing_pubkey: Vec<u8>, verifying_pubkey: Vec<u8>, deposit_tx: Transaction, vout: u32, ) -> Result<Vec<TreeNode>, SparkSdkError>
Finalizes a deposit by creating a tree node and transferring it to self
§Arguments
signing_pubkey
- The public key used for signingdeposit_tx
- The Bitcoin transaction containing the depositvout
- The output index in the transaction
§Errors
Returns SparkSdkError
if:
- Failed to create tree node
- Failed to transfer deposits
§Returns
Returns an empty vector of TreeNode
s on success
pub async fn query_unused_deposit_addresses( &self, ) -> Result<Vec<DepositAddressQueryResult>, SparkSdkError>
Source§impl<S: SparkSigner + Send + Sync + Clone + 'static> SparkSdk<S>
impl<S: SparkSigner + Send + Sync + Clone + 'static> SparkSdk<S>
pub async fn get_lightning_receive_fee_estimate( &self, amount: u64, ) -> Result<SparkFeeEstimate, SparkSdkError>
pub async fn get_lightning_send_fee_estimate( &self, invoice: String, ) -> Result<SparkFeeEstimate, SparkSdkError>
pub async fn get_cooperative_exit_fee_estimate( &self, leaf_ids: Vec<String>, on_chain_address: String, ) -> Result<SparkFeeEstimate, SparkSdkError>
pub async fn get_leaves_swap_fee_estimate( &self, total_amount_sats: u64, ) -> Result<SparkFeeEstimate, SparkSdkError>
Source§impl<S: SparkSigner + Send + Sync + Clone + 'static> SparkSdk<S>
impl<S: SparkSigner + Send + Sync + Clone + 'static> SparkSdk<S>
Sourcepub async fn new(
network: SparkNetwork,
signer: Arc<S>,
) -> Result<Self, SparkSdkError>
pub async fn new( network: SparkNetwork, signer: Arc<S>, ) -> Result<Self, SparkSdkError>
Creates a new instance of the Spark SDK.
This is the main entry point for interacting with the Spark protocol. It initializes the SDK with the provided network configuration, signer implementation, and optional data storage path.
§Arguments
network
- The Spark network to connect to (e.g. Regtest or Mainnet)signer
- Implementation of the SparkSigner trait wrapped in Arc for thread-safe access
§Returns
Returns a Result containing either:
- The initialized SparkSdk instance
- A SparkSdkError if initialization fails
§Examples
use spark_rust::{
error::SparkSdkError,
signer::default_signer::DefaultSigner,
signer::traits::SparkSigner,
SparkNetwork, SparkSdk,
};
async fn init_sdk() {
let mnemonic = "abandon ability able about above absent absorb abstract absurd abuse access accident";
let network = SparkNetwork::Regtest;
let signer = DefaultSigner::from_mnemonic(mnemonic, network.clone()).await.unwrap();
let sdk = SparkSdk::new(
network,
signer
).await.unwrap();
}
Sourcepub fn get_spark_address(&self) -> Result<PublicKey, SparkSdkError>
pub fn get_spark_address(&self) -> Result<PublicKey, SparkSdkError>
Returns the Spark address of the wallet, which is the identity public key.
The Spark address is derived from the identity public key of the wallet. This key is generated when the wallet is first created and remains constant throughout the wallet’s lifetime.
The Spark address serves several purposes:
- Authenticates the wallet with Spark operators during API calls
- Used in deposit address generation to prove ownership
- Required for validating operator signatures
- Helps prevent unauthorized access to wallet funds
§Returns
A byte slice containing the 33-byte compressed secp256k1 public key in SEC format. The first byte is either 0x02 or 0x03 (the parity), followed by the 32-byte X coordinate.
§Examples
let network = SparkNetwork::Regtest;
let mnemonic = "abandon ability able about above absent absorb abstract absurd abuse access accident";
let signer = DefaultSigner::from_mnemonic(mnemonic, network.clone()).await.unwrap();
let sdk = SparkSdk::new(network, signer).await.unwrap();
// Spark address is the identity public key of the user. This is derived using the derivation path (TODO: add docs)
let spark_address = sdk.get_spark_address().unwrap();
// Currently, a user's Spark address is their public key.
assert_eq!(spark_address.serialize().len(), 33);
Sourcepub fn get_network(&self) -> SparkNetwork
pub fn get_network(&self) -> SparkNetwork
Returns the Bitcoin network that this wallet is connected to.
The network determines which Spark operators the wallet communicates with and which Bitcoin network (mainnet or regtest) is used for transactions.
§Network Types
SparkNetwork::Mainnet
- Production Bitcoin mainnet environmentSparkNetwork::Regtest
- Testing environment using Lightspark’s regtest network
The network is set when creating the wallet and cannot be changed after initialization. All transactions and addresses will be created for the configured network.
§Returns
Returns a SparkNetwork
enum indicating whether this is a mainnet or regtest wallet.
§Examples
let mnemonic = "abandon ability able about above absent absorb abstract absurd abuse access accident";
let network = SparkNetwork::Regtest;
// Create a DefaultSigner that implements SparkSigner
let signer = DefaultSigner::from_mnemonic(mnemonic, network.clone()).await.unwrap();
let sdk = SparkSdk::new(network, signer).await.unwrap();
assert_eq!(sdk.get_network(), SparkNetwork::Regtest);
Source§impl<S: SparkSigner + Send + Sync + Clone + 'static> SparkSdk<S>
impl<S: SparkSigner + Send + Sync + Clone + 'static> SparkSdk<S>
Sourcepub fn get_btc_balance(&self) -> u64
pub fn get_btc_balance(&self) -> u64
Returns the balance of the wallet in satoshis.
This function calculates the total value of all available leaves in the wallet.
§Returns
Ok(u64)
- The total balance in satoshisErr(SparkSdkError)
- If there was an error accessing the leaf manager
§Example
async fn example() {
let mnemonic = "abandon ability able about above absent absorb abstract absurd abuse access accident";
let network = SparkNetwork::Regtest;
let signer = DefaultSigner::from_mnemonic(mnemonic, network.clone()).await.unwrap();
let sdk = SparkSdk::new(network, signer).await.unwrap();
let balance = sdk.get_btc_balance();
println!("Balance: {}", balance);
}
pub async fn sync_wallet(&self) -> Result<(), SparkSdkError>
Source§impl<S: SparkSigner + Send + Sync + Clone + 'static> SparkSdk<S>
impl<S: SparkSigner + Send + Sync + Clone + 'static> SparkSdk<S>
pub async fn pay_lightning_invoice( &self, invoice: &String, ) -> Result<String, SparkSdkError>
Sourcepub async fn create_lightning_invoice(
&self,
amount_sats: u64,
memo: Option<String>,
expiry_seconds: Option<i32>,
) -> Result<Bolt11Invoice, SparkSdkError>
pub async fn create_lightning_invoice( &self, amount_sats: u64, memo: Option<String>, expiry_seconds: Option<i32>, ) -> Result<Bolt11Invoice, SparkSdkError>
Create a Lightning invoice with a preimage and a memo.
The invoice will be valid for 30 days by default.
Source§impl<S: SparkSigner + Send + Sync + Clone + 'static> SparkSdk<S>
impl<S: SparkSigner + Send + Sync + Clone + 'static> SparkSdk<S>
pub async fn request_leaves_swap( &self, target_amount: u64, ) -> Result<String, SparkSdkError>
Source§impl<S: SparkSigner + Send + Sync + Clone + 'static> SparkSdk<S>
impl<S: SparkSigner + Send + Sync + Clone + 'static> SparkSdk<S>
Sourcepub async fn query_pending_transfers(
&self,
) -> Result<Vec<Transfer>, SparkSdkError>
pub async fn query_pending_transfers( &self, ) -> Result<Vec<Transfer>, SparkSdkError>
Queries all pending transfers where the current user is the receiver.
This function retrieves all pending transfers that are waiting to be accepted by the current user. A pending transfer represents funds that have been sent to the user but have not yet been claimed. The transfers remain in a pending state until the receiver claims them, at which point the funds become available in their wallet.
§Returns
Ok(Vec<Transfer>)
- A vector of pendingTransfer
objects if successfulErr(SparkSdkError)
- If there was an error querying the transfers
§Example
let pending = sdk.query_pending_transfers().await?;
for transfer in pending {
println!("Pending transfer: {:?} satoshis", transfer.total_value);
}
Sourcepub async fn transfer(
&self,
amount: u64,
receiver_spark_address: &PublicKey,
) -> Result<String, SparkSdkError>
pub async fn transfer( &self, amount: u64, receiver_spark_address: &PublicKey, ) -> Result<String, SparkSdkError>
Initiates a transfer of funds to another user.
This function handles the process of transferring funds from the current user’s wallet to another user, identified by their public key. The transfer process involves several steps:
- Selecting appropriate leaves (UTXOs) that contain sufficient funds for the transfer
- Locking the selected leaves to prevent concurrent usage
- Generating new signing keys for the transfer
- Creating and signing the transfer transaction
- Removing the used leaves from the wallet
The transfer remains in a pending state until the receiver claims it. The expiry time is set to
30 days by default (see DEFAULT_TRANSFER_EXPIRY
).
§Arguments
amount
- The amount to transfer in satoshis. Must be greater than the dust limit and the wallet must have a leaf with exactly this amount.receiver_spark_address
- The Spark address identifying the receiver of the transfer. This should be the receiver’s Spark address, not a regular Bitcoin public key.
§Returns
Ok(String)
- The transfer ID if successful. This ID can be used to track the transfer status.Err(SparkSdkError)
- If the transfer fails. Common error cases include:- No leaf with exact amount available
- Failed to lock leaves
- Failed to generate new signing keys
- Network errors when communicating with Spark operators
§Example
let amount = 100_000;
// Currently, a user's Spark address is their public key.
let receiver_spark_address = PublicKey::from_str("02782d7ba8764306bd324e23082f785f7c880b7202cb10c85a2cb96496aedcaba7").unwrap();
let transfer_id_string = sdk.transfer(amount, &receiver_spark_address).await?;
let transfer_id = Uuid::parse_str(&transfer_id_string).unwrap();
println!("Transfer ID is {}", transfer_id);
§Notes
Currently, the leaf selection algorithm only supports selecting a single leaf with the exact transfer amount. Future versions will support combining multiple leaves and handling change outputs.
pub async fn transfer_leaf_ids( &self, leaf_ids: Vec<String>, receiver_identity_pubkey: &PublicKey, ) -> Result<String, SparkSdkError>
Sourcepub async fn claim_transfer(
&self,
transfer: Transfer,
) -> Result<(), SparkSdkError>
pub async fn claim_transfer( &self, transfer: Transfer, ) -> Result<(), SparkSdkError>
Claims a pending transfer that was sent to this wallet.
This function processes a pending transfer and claims the funds into the wallet. It performs the following steps:
- Verifies the transfer is in the correct state (SenderKeyTweaked)
- Verifies and decrypts the leaf private keys using the wallet’s identity key
- Generates new signing keys for the claimed leaves
- Finalizes the transfer by:
- Tweaking the leaf keys
- Signing refund transactions
- Submitting the signatures to the Spark network
- Storing the claimed leaves in the wallet’s database
§Arguments
transfer
- The pending transfer to claim, must be in SenderKeyTweaked status
§Returns
Ok(())
- If the transfer was successfully claimedErr(SparkSdkError)
- If there was an error during the claim process
§Errors
Returns [SparkSdkError::InvalidInput
] if:
- The transfer is not in SenderKeyTweaked status
May also return other SparkSdkError
variants for network, signing or storage errors.
§Example
async fn example() {
let mnemonic = "abandon ability able about above absent absorb abstract absurd abuse access accident";
let network = SparkNetwork::Regtest;
let signer = DefaultSigner::from_mnemonic(mnemonic, network.clone()).await.unwrap();
let sdk = SparkSdk::new(network, signer).await.unwrap();
let pending = sdk.query_pending_transfers().await.unwrap();
for transfer in pending {
sdk.claim_transfer(transfer).await.unwrap();
}
}
pub async fn claim_transfers(&self) -> Result<(), SparkSdkError>
pub async fn get_all_transfers( &self, limit: Option<u32>, offset: Option<u32>, ) -> Result<QueryAllTransfersResponse, SparkSdkError>
Trait Implementations§
Auto Trait Implementations§
impl<S> Freeze for SparkSdk<S>
impl<S = DefaultSigner> !RefUnwindSafe for SparkSdk<S>
impl<S> Send for SparkSdk<S>
impl<S> Sync for SparkSdk<S>
impl<S> Unpin for SparkSdk<S>
impl<S = DefaultSigner> !UnwindSafe for SparkSdk<S>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T
in a tonic::Request