Skip to content
This repository has been archived by the owner on Dec 4, 2024. It is now read-only.

Commit

Permalink
integration: broadcast withdrawal
Browse files Browse the repository at this point in the history
  • Loading branch information
CAGS295 committed Nov 3, 2023
1 parent 3f2948a commit 305907f
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 42 deletions.
2 changes: 1 addition & 1 deletion devenv/integration/bin/test
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ project_name() {
echo "$filter"
}

filters=("test(deposit)")
filters=("test(deposit)" "test(withdrawal)")
filter_union=""
ids=()
projects=()
Expand Down
1 change: 1 addition & 0 deletions romeo/tests/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod bitcoin_client;
pub mod deposit;
pub mod stacks_client;
pub mod withdrawal;

use std::ops::Index;

Expand Down
89 changes: 89 additions & 0 deletions romeo/tests/tests/withdrawal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use std::{thread::sleep, time::Duration};

use bdk::{
bitcoin::{psbt::serialize::Serialize, PrivateKey},
blockchain::{
ConfigurableBlockchain, ElectrumBlockchain, ElectrumBlockchainConfig,
},
database::MemoryDatabase,
template::P2Wpkh,
SyncOptions, Wallet,
};
use reqwest::blocking::Client;
use sbtc_cli::commands::{
broadcast::{broadcast_tx, BroadcastArgs},
withdraw::{build_withdrawal_tx, WithdrawalArgs},
};

use super::{
bitcoin_client::{electrs_url, generate_blocks},
KeyType::*,
WALLETS,
};

#[test]
fn broadcast_withdrawal() {
let client = Client::new();
{
generate_blocks(1, &client, WALLETS[0][P2wpkh].address);
generate_blocks(1, &client, WALLETS[1][P2wpkh].address);
// pads blocks to get rewards.
generate_blocks(100, &client, WALLETS[0][P2wpkh].address);
};

let electrum_url = electrs_url();

// suboptimal, replace once we have better events.
{
let blockchain =
ElectrumBlockchain::from_config(&ElectrumBlockchainConfig {
url: electrum_url.clone().into(),
socks5: None,
retry: 3,
timeout: Some(10),
stop_gap: 10,
validate_domain: false,
})
.unwrap();

let private_key = PrivateKey::from_wif(WALLETS[0][P2wpkh].wif).unwrap();

let wallet = Wallet::new(
P2Wpkh(private_key),
Some(P2Wpkh(private_key)),
bdk::bitcoin::Network::Regtest,
MemoryDatabase::default(),
)
.unwrap();

loop {
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
let balance = wallet.get_balance().unwrap();
if balance.confirmed != 0 {
break;
}
sleep(Duration::from_millis(1_000));
}
}

// amount random [1000,2000)
// fee random [1000,2000)
let args = WithdrawalArgs {
node_url: electrs_url(),
network: bdk::bitcoin::Network::Regtest,
wif: WALLETS[1][P2wpkh].wif.into(),
drawee_wif: WALLETS[1][Stacks].wif.into(),
payee_address: WALLETS[1][P2wpkh].address.into(),
amount: 2000,
fulfillment_fee: 2000,
sbtc_wallet: WALLETS[0][P2tr].address.into(),
};

let tx = build_withdrawal_tx(&args).unwrap();

broadcast_tx(&BroadcastArgs {
node_url: electrum_url,
tx: hex::encode(tx.serialize()),
})
.unwrap();
}
55 changes: 23 additions & 32 deletions sbtc-cli/src/commands/withdraw.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::{io::stdout, str::FromStr};
use std::str::FromStr;

use bdk::{
bitcoin::{
psbt::serialize::Serialize, Address as BitcoinAddress,
blockdata::transaction::Transaction, Address as BitcoinAddress,
Network as BitcoinNetwork, PrivateKey,
},
blockchain::{
Expand All @@ -15,45 +15,45 @@ use bdk::{
use clap::Parser;
use url::Url;

use crate::commands::utils::TransactionData;

#[derive(Parser, Debug, Clone)]
pub struct WithdrawalArgs {
/// Where to broadcast the transaction
#[clap(short('u'), long)]
node_url: Url,
pub node_url: Url,

Check warning on line 22 in sbtc-cli/src/commands/withdraw.rs

View check run for this annotation

Codecov / codecov/patch

sbtc-cli/src/commands/withdraw.rs#L22

Added line #L22 was not covered by tests

/// Bitcoin network where the deposit will be broadcasted to
#[clap(short, long)]
network: BitcoinNetwork,
pub network: BitcoinNetwork,

Check warning on line 26 in sbtc-cli/src/commands/withdraw.rs

View check run for this annotation

Codecov / codecov/patch

sbtc-cli/src/commands/withdraw.rs#L26

Added line #L26 was not covered by tests

/// WIF of the Bitcoin P2WPKH address that will broadcast and pay for the
/// withdrawal request
#[clap(short, long)]
wif: String,
pub wif: String,

Check warning on line 31 in sbtc-cli/src/commands/withdraw.rs

View check run for this annotation

Codecov / codecov/patch

sbtc-cli/src/commands/withdraw.rs#L31

Added line #L31 was not covered by tests

/// WIF of the Stacks address that owns sBTC to be withdrawn
#[clap(short, long)]
drawee_wif: String,
pub drawee_wif: String,

Check warning on line 35 in sbtc-cli/src/commands/withdraw.rs

View check run for this annotation

Codecov / codecov/patch

sbtc-cli/src/commands/withdraw.rs#L35

Added line #L35 was not covered by tests

/// Bitcoin address that will receive BTC
#[clap(short('b'), long)]
payee_address: String,
pub payee_address: String,

Check warning on line 39 in sbtc-cli/src/commands/withdraw.rs

View check run for this annotation

Codecov / codecov/patch

sbtc-cli/src/commands/withdraw.rs#L39

Added line #L39 was not covered by tests

/// The amount of sats to withdraw
#[clap(short, long)]
amount: u64,
pub amount: u64,

Check warning on line 43 in sbtc-cli/src/commands/withdraw.rs

View check run for this annotation

Codecov / codecov/patch

sbtc-cli/src/commands/withdraw.rs#L43

Added line #L43 was not covered by tests

/// The amount of sats to send for the fulfillment fee
#[clap(short, long)]
fulfillment_fee: u64,
pub fulfillment_fee: u64,

Check warning on line 47 in sbtc-cli/src/commands/withdraw.rs

View check run for this annotation

Codecov / codecov/patch

sbtc-cli/src/commands/withdraw.rs#L47

Added line #L47 was not covered by tests

/// Bitcoin address of the sbtc wallet
#[clap(short, long)]
sbtc_wallet: String,
pub sbtc_wallet: String,

Check warning on line 51 in sbtc-cli/src/commands/withdraw.rs

View check run for this annotation

Codecov / codecov/patch

sbtc-cli/src/commands/withdraw.rs#L51

Added line #L51 was not covered by tests
}

pub fn build_withdrawal_tx(withdrawal: &WithdrawalArgs) -> anyhow::Result<()> {
pub fn build_withdrawal_tx(
withdrawal: &WithdrawalArgs,
) -> anyhow::Result<Transaction> {

Check warning on line 56 in sbtc-cli/src/commands/withdraw.rs

View check run for this annotation

Codecov / codecov/patch

sbtc-cli/src/commands/withdraw.rs#L54-L56

Added lines #L54 - L56 were not covered by tests
let private_key = PrivateKey::from_wif(&withdrawal.wif)?;

let blockchain =
Expand Down Expand Up @@ -82,23 +82,14 @@ pub fn build_withdrawal_tx(withdrawal: &WithdrawalArgs) -> anyhow::Result<()> {
let sbtc_wallet_bitcoin_address =
BitcoinAddress::from_str(&withdrawal.sbtc_wallet)?;

let tx = sbtc_core::operations::op_return::withdrawal_request::build_withdrawal_tx(
&wallet,
withdrawal.network,
drawee_stacks_private_key,
payee_bitcoin_address,
sbtc_wallet_bitcoin_address,
withdrawal.amount,
withdrawal.fulfillment_fee,
)?;

serde_json::to_writer_pretty(
stdout(),
&TransactionData {
id: tx.txid().to_string(),
hex: hex::encode(tx.serialize()),
},
)?;

Ok(())
sbtc_core::operations::op_return::withdrawal_request::build_withdrawal_tx(
&wallet,
withdrawal.network,
drawee_stacks_private_key,
payee_bitcoin_address,
sbtc_wallet_bitcoin_address,
withdrawal.amount,
withdrawal.fulfillment_fee,
)
.map_err(|e| e.into())

Check warning on line 94 in sbtc-cli/src/commands/withdraw.rs

View check run for this annotation

Codecov / codecov/patch

sbtc-cli/src/commands/withdraw.rs#L85-L94

Added lines #L85 - L94 were not covered by tests
}
25 changes: 16 additions & 9 deletions sbtc-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//! and interact with the Bitcoin and Stacks networks.
use std::io::stdout;

use bdk::bitcoin::psbt::serialize::Serialize;
use bdk::bitcoin::{psbt::serialize::Serialize, Transaction};
use clap::{Parser, Subcommand};
use sbtc_cli::commands::{
broadcast::{broadcast_tx, BroadcastArgs},
Expand All @@ -31,23 +31,30 @@ enum Command {
GenerateFrom(GenerateArgs),
}

fn to_stdout_pretty(txn: Transaction) -> serde_json::Result<()> {
serde_json::to_writer_pretty(
stdout(),
&utils::TransactionData {
id: txn.txid().to_string(),
hex: hex::encode(txn.serialize()),
},
)
}

Check warning on line 42 in sbtc-cli/src/main.rs

View check run for this annotation

Codecov / codecov/patch

sbtc-cli/src/main.rs#L34-L42

Added lines #L34 - L42 were not covered by tests

fn main() -> Result<(), anyhow::Error> {
let args = Cli::parse();

match args.command {
Command::Deposit(deposit_args) => build_deposit_tx(&deposit_args)
.and_then(|t| {
serde_json::to_writer_pretty(
stdout(),
&utils::TransactionData {
id: t.txid().to_string(),
hex: hex::encode(t.serialize()),
},
)?;
to_stdout_pretty(t)?;
Ok(())
}),

Check warning on line 52 in sbtc-cli/src/main.rs

View check run for this annotation

Codecov / codecov/patch

sbtc-cli/src/main.rs#L48-L52

Added lines #L48 - L52 were not covered by tests
Command::Withdraw(withdrawal_args) => {
build_withdrawal_tx(&withdrawal_args)
build_withdrawal_tx(&withdrawal_args).and_then(|t| {
to_stdout_pretty(t)?;
Ok(())
})

Check warning on line 57 in sbtc-cli/src/main.rs

View check run for this annotation

Codecov / codecov/patch

sbtc-cli/src/main.rs#L54-L57

Added lines #L54 - L57 were not covered by tests
}
Command::Broadcast(broadcast_args) => broadcast_tx(&broadcast_args),
Command::GenerateFrom(generate_args) => generate(&generate_args),
Expand Down

0 comments on commit 305907f

Please sign in to comment.