From 52772475c2bce105b45849bb901e5f03daa9ecc0 Mon Sep 17 00:00:00 2001 From: Carlos Alejandro Gutierrez Sandoval Date: Mon, 13 Nov 2023 17:02:02 -0600 Subject: [PATCH] wip deposit refactor + withdrawal fulfillment check --- romeo/examples/deposit_withdrawal.rs | 135 ++++++++++----------------- romeo/examples/fund.rs | 10 +- 2 files changed, 58 insertions(+), 87 deletions(-) diff --git a/romeo/examples/deposit_withdrawal.rs b/romeo/examples/deposit_withdrawal.rs index ab07a3cb..80b13757 100644 --- a/romeo/examples/deposit_withdrawal.rs +++ b/romeo/examples/deposit_withdrawal.rs @@ -1,8 +1,7 @@ -use std::{io::Cursor, str::FromStr, time::Duration}; +use std::{io::Cursor, time::Duration}; use bdk::{ - bitcoin::{psbt::serialize::Serialize, Address, PrivateKey}, - bitcoincore_rpc::{Auth, Client, RpcApi}, + bitcoin::{psbt::serialize::Serialize, PrivateKey}, blockchain::{ ConfigurableBlockchain, ElectrumBlockchain, ElectrumBlockchainConfig, }, @@ -29,6 +28,7 @@ use tokio::time::sleep; use url::Url; /// Wait until all your services are ready before running. +/// Don't forget to fund W0 (deployer) and W1 (recipient). #[tokio::main] async fn main() { let mut config = @@ -37,75 +37,41 @@ async fn main() { config.bitcoin_node_url = "http://localhost:18443".parse().unwrap(); config.electrum_node_url = "tcp://localhost:60401".parse().unwrap(); - let recipient_stacks_wif = - "cNcXK2r8bNdWJQymtAW8tGS7QHNtFFvG5CdXqhhT752u29WspXRM"; - - let client = Client::new( - config.bitcoin_node_url.as_str(), - Auth::UserPass("devnet".into(), "devnet".into()), - ) - .unwrap(); - - // fund - { - // fund w0 - client - .generate_to_address( - 10, - &Address::from_str( - "bcrt1q3tj2fr9scwmcw3rq5m6jslva65f2rqjxfrjz47", - ) - .unwrap(), - ) - .unwrap(); - - // fund w1 + pad - client - .generate_to_address( - 101, - &Address::from_str( - "bcrt1q3zl64vadtuh3vnsuhdgv6pm93n82ye8q6cr4ch", - ) - .unwrap(), - ) - .unwrap() - .into_iter() - .last() - .unwrap(); - - // wait for realized funds - { - let blockchain = - ElectrumBlockchain::from_config(&ElectrumBlockchainConfig { - url: config.electrum_node_url.clone().into(), - socks5: None, - retry: 3, - timeout: Some(10), - stop_gap: 10, - validate_domain: false, - }) - .unwrap(); + let blockchain = + ElectrumBlockchain::from_config(&ElectrumBlockchainConfig { + url: config.electrum_node_url.clone().into(), + socks5: None, + retry: 3, + timeout: Some(10), + stop_gap: 10, + validate_domain: false, + }) + .unwrap(); - // W1 - let private_key = - PrivateKey::from_wif(recipient_stacks_wif).unwrap(); + let recipient_p2wpkh_wif = + "cNcXK2r8bNdWJQymtAW8tGS7QHNtFFvG5CdXqhhT752u29WspXRM"; - let wallet = Wallet::new( - P2Wpkh(private_key), - Some(P2Wpkh(private_key)), - bdk::bitcoin::Network::Regtest, - MemoryDatabase::default(), - ) - .unwrap(); + // W1 + let wallet = { + let private_key = PrivateKey::from_wif(recipient_p2wpkh_wif).unwrap(); + + Wallet::new( + P2Wpkh(private_key), + Some(P2Wpkh(private_key)), + bdk::bitcoin::Network::Regtest, + MemoryDatabase::default(), + ) + .unwrap() + }; - while { - wallet.sync(&blockchain, SyncOptions::default()).unwrap(); - wallet.get_balance().unwrap().confirmed - } == 0 - { - sleep(Duration::from_millis(1_000)).await; - } + loop { + wallet.sync(&blockchain, SyncOptions::default()).unwrap(); + let balance = wallet.get_balance().unwrap().confirmed; + println!("recipient's btc: {balance}"); + if balance != 0 { + break; } + sleep(Duration::from_secs(1)).await; } let recipient = "ST2ST2H80NP5C9SPR4ENJ1Z9CDM9PKAJVPYWPQZ50"; @@ -118,7 +84,7 @@ async fn main() { let tx = { let args = DepositArgs { node_url: electrum_url.clone(), - wif: recipient_stacks_wif.into(), + wif: recipient_p2wpkh_wif.into(), network: bdk::bitcoin::Network::Regtest, recipient:recipient.into(), amount, @@ -142,6 +108,7 @@ async fn main() { let stacks_client = StacksClient::new(config.clone(), reqwest::Client::new()); + println!("Waiting on sBTC mint"); // request token balance from the asset contract. while { let res: serde_json::Value = stacks_client @@ -172,6 +139,7 @@ async fn main() { sleep(Duration::from_secs(2)).await; } + let fee = 2000; // withdraw let args = WithdrawalArgs { node_url: config.electrum_node_url.clone(), @@ -183,7 +151,7 @@ async fn main() { .into(), payee_address: "bcrt1q3zl64vadtuh3vnsuhdgv6pm93n82ye8q6cr4ch".into(), amount, - fulfillment_fee: 2000, + fulfillment_fee: fee, sbtc_wallet: "bcrt1pte5zmd7qzj4hdu45lh9mmdm0nwq3z35pwnxmzkwld6y0a8g83nnqhj6vc0" .into(), @@ -191,27 +159,24 @@ async fn main() { let tx = build_withdrawal_tx(&args).unwrap(); + wallet.sync(&blockchain, SyncOptions::default()).unwrap(); + let balance = wallet.get_balance().unwrap().confirmed; + broadcast_tx(&BroadcastArgs { - node_url: config.electrum_node_url, + node_url: config.electrum_node_url.clone(), tx: hex::encode(tx.serialize()), }) .unwrap(); - let txid = tx.txid(); - + println!("Waiting on fulfillment"); loop { - match client.get_transaction(&txid, None) { - Ok(tx) if tx.info.confirmations >= 1 => { - break; - } - Ok(ok) => { - println!("Waiting confirmation on {txid}:{ok:?}") - } - Err(e) => { - println!("Waiting confirmation on {txid}:{e:?}") - } + wallet.sync(&blockchain, SyncOptions::default()).unwrap(); + let current = wallet.get_balance().unwrap().confirmed; + // will fail if tx_fees is not an upper bound for real fees. + let tx_fees = 400; + if balance - fee - tx_fees < current { + break; } - - sleep(Duration::from_secs(1)).await; + sleep(Duration::from_secs(2)).await; } } diff --git a/romeo/examples/fund.rs b/romeo/examples/fund.rs index f9e34c6b..0a9fec55 100644 --- a/romeo/examples/fund.rs +++ b/romeo/examples/fund.rs @@ -19,7 +19,13 @@ fn main() { .unwrap(); // p2wpkh W0 - let address = "bcrt1q3tj2fr9scwmcw3rq5m6jslva65f2rqjxfrjz47"; - let block_hashes = mine_blocks(&client, 10, address); + let address_0 = "bcrt1q3tj2fr9scwmcw3rq5m6jslva65f2rqjxfrjz47"; + let block_hashes = mine_blocks(&client, 10, address_0); println!("blocks mined: {block_hashes:#?}"); + let address_1 = "bcrt1q3zl64vadtuh3vnsuhdgv6pm93n82ye8q6cr4ch"; + let block_hashes = mine_blocks(&client, 10, address_1); + println!("blocks mined: {block_hashes:#?}"); + let address_0 = "bcrt1q3tj2fr9scwmcw3rq5m6jslva65f2rqjxfrjz47"; + let block_hashes = mine_blocks(&client, 101, address_0); + println!("padding blocks mined: {block_hashes:#?}"); }