mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-10-01 01:45:40 -04:00
Merge #391
391: asb Bitcoin withdraw and balance commands r=da-kami a=da-kami Fixes #368 Note: Balance prints both balances - which assumes that the Monero wallet RPC is running. I think that is fine for now. Co-authored-by: Daniel Karzel <daniel@comit.network>
This commit is contained in:
commit
4b9513b051
5
Cargo.lock
generated
5
Cargo.lock
generated
@ -279,9 +279,8 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
||||
|
||||
[[package]]
|
||||
name = "bdk"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4260e70501c2f9d6fb2915cf2be2f5b8ba57743e527834de5de6e371827f1e19"
|
||||
version = "0.5.2-dev"
|
||||
source = "git+https://github.com/bitcoindevkit/bdk.git?rev=e5ecc7f#e5ecc7f5410aea9d7a108a46d01c7a2fa0822bb7"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bdk-macros",
|
||||
|
@ -15,7 +15,7 @@ async-trait = "0.1"
|
||||
atty = "0.2"
|
||||
backoff = { version = "0.3", features = ["tokio"] }
|
||||
base64 = "0.13"
|
||||
bdk = { version = "0.5" }
|
||||
bdk = { git = "https://github.com/bitcoindevkit/bdk.git", rev = "e5ecc7f" }
|
||||
big-bytes = "1"
|
||||
bitcoin = { version = "0.26", features = ["rand", "use-serde"] }
|
||||
config = { version = "0.11", default-features = false, features = ["toml"] }
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::bitcoin::Amount;
|
||||
use bitcoin::util::amount::ParseAmountError;
|
||||
use bitcoin::Denomination;
|
||||
use bitcoin::{Address, Denomination};
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(structopt::StructOpt, Debug)]
|
||||
@ -29,6 +29,16 @@ pub enum Command {
|
||||
max_buy: Amount,
|
||||
},
|
||||
History,
|
||||
WithdrawBtc {
|
||||
#[structopt(
|
||||
long = "amount",
|
||||
help = "Optionally specify the amount of Bitcoin to be withdrawn. If not specified the wallet will be drained."
|
||||
)]
|
||||
amount: Option<Amount>,
|
||||
#[structopt(long = "address", help = "The address to receive the Bitcoin.")]
|
||||
address: Address,
|
||||
},
|
||||
Balance,
|
||||
}
|
||||
|
||||
fn parse_btc(s: &str) -> Result<Amount, ParseAmountError> {
|
||||
|
@ -13,11 +13,8 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use bdk::descriptor::Segwitv0;
|
||||
use bdk::keys::DerivableKey;
|
||||
use libp2p::Swarm;
|
||||
use prettytable::{row, Table};
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use structopt::StructOpt;
|
||||
use swap::asb::command::{Arguments, Command};
|
||||
@ -71,22 +68,29 @@ async fn main() -> Result<()> {
|
||||
let db = Database::open(config.data.dir.join(db_path).as_path())
|
||||
.context("Could not open database")?;
|
||||
|
||||
let wallet_data_dir = config.data.dir.join("wallet");
|
||||
let seed =
|
||||
Seed::from_file_or_generate(&config.data.dir).expect("Could not retrieve/initialize seed");
|
||||
|
||||
let env_config = env::Testnet::get_config();
|
||||
|
||||
match opt.cmd {
|
||||
Command::Start { max_buy } => {
|
||||
let seed = Seed::from_file_or_generate(&config.data.dir)
|
||||
.expect("Could not retrieve/initialize seed");
|
||||
let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?;
|
||||
let monero_wallet = init_monero_wallet(&config, env_config).await?;
|
||||
|
||||
let env_config = env::Testnet::get_config();
|
||||
let bitcoin_balance = bitcoin_wallet.balance().await?;
|
||||
info!("Bitcoin balance: {}", bitcoin_balance);
|
||||
|
||||
let (bitcoin_wallet, monero_wallet) = init_wallets(
|
||||
config.clone(),
|
||||
&wallet_data_dir,
|
||||
seed.derive_extended_private_key(env_config.bitcoin_network)?,
|
||||
env_config,
|
||||
)
|
||||
.await?;
|
||||
let monero_balance = monero_wallet.get_balance().await?;
|
||||
if monero_balance == Amount::ZERO {
|
||||
let deposit_address = monero_wallet.get_main_address();
|
||||
warn!(
|
||||
"The Monero balance is 0, make sure to deposit funds at: {}",
|
||||
deposit_address
|
||||
)
|
||||
} else {
|
||||
info!("Monero balance: {}", monero_balance);
|
||||
}
|
||||
|
||||
let kraken_rate_updates = kraken::connect()?;
|
||||
|
||||
@ -137,50 +141,68 @@ async fn main() -> Result<()> {
|
||||
// Print the table to stdout
|
||||
table.printstd();
|
||||
}
|
||||
Command::WithdrawBtc { amount, address } => {
|
||||
let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?;
|
||||
|
||||
let amount = match amount {
|
||||
Some(amount) => amount,
|
||||
None => {
|
||||
bitcoin_wallet
|
||||
.max_giveable(address.script_pubkey().len())
|
||||
.await?
|
||||
}
|
||||
};
|
||||
|
||||
let psbt = bitcoin_wallet.send_to_address(address, amount).await?;
|
||||
let signed_tx = bitcoin_wallet.sign_and_finalize(psbt).await?;
|
||||
|
||||
bitcoin_wallet.broadcast(signed_tx, "withdraw").await?;
|
||||
}
|
||||
Command::Balance => {
|
||||
let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?;
|
||||
let monero_wallet = init_monero_wallet(&config, env_config).await?;
|
||||
|
||||
let bitcoin_balance = bitcoin_wallet.balance().await?;
|
||||
let monero_balance = monero_wallet.get_balance().await?;
|
||||
|
||||
tracing::info!("Current balance: {}, {}", bitcoin_balance, monero_balance);
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn init_wallets(
|
||||
config: Config,
|
||||
bitcoin_wallet_data_dir: &Path,
|
||||
key: impl DerivableKey<Segwitv0> + Clone,
|
||||
env_config: env::Config,
|
||||
) -> Result<(bitcoin::Wallet, monero::Wallet)> {
|
||||
let bitcoin_wallet = bitcoin::Wallet::new(
|
||||
config.bitcoin.electrum_rpc_url,
|
||||
bitcoin_wallet_data_dir,
|
||||
key,
|
||||
async fn init_bitcoin_wallet(
|
||||
config: &Config,
|
||||
seed: &Seed,
|
||||
env_config: swap::env::Config,
|
||||
) -> Result<bitcoin::Wallet> {
|
||||
let wallet_dir = config.data.dir.join("wallet");
|
||||
|
||||
let wallet = bitcoin::Wallet::new(
|
||||
config.bitcoin.electrum_rpc_url.clone(),
|
||||
&wallet_dir,
|
||||
seed.derive_extended_private_key(env_config.bitcoin_network)?,
|
||||
env_config,
|
||||
)
|
||||
.await?;
|
||||
.await
|
||||
.context("Failed to initialize Bitcoin wallet")?;
|
||||
|
||||
bitcoin_wallet.sync().await?;
|
||||
wallet.sync().await?;
|
||||
|
||||
let bitcoin_balance = bitcoin_wallet.balance().await?;
|
||||
info!(
|
||||
"Connection to Bitcoin wallet succeeded, balance: {}",
|
||||
bitcoin_balance
|
||||
);
|
||||
Ok(wallet)
|
||||
}
|
||||
|
||||
let monero_wallet = monero::Wallet::open_or_create(
|
||||
async fn init_monero_wallet(
|
||||
config: &Config,
|
||||
env_config: swap::env::Config,
|
||||
) -> Result<monero::Wallet> {
|
||||
let wallet = monero::Wallet::open_or_create(
|
||||
config.monero.wallet_rpc_url.clone(),
|
||||
DEFAULT_WALLET_NAME.to_string(),
|
||||
env_config,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let balance = monero_wallet.get_balance().await?;
|
||||
if balance == Amount::ZERO {
|
||||
let deposit_address = monero_wallet.get_main_address();
|
||||
warn!(
|
||||
"The Monero balance is 0, make sure to deposit funds at: {}",
|
||||
deposit_address
|
||||
)
|
||||
} else {
|
||||
info!("Monero balance: {}", balance);
|
||||
}
|
||||
|
||||
Ok((bitcoin_wallet, monero_wallet))
|
||||
Ok(wallet)
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ use bdk::database::BatchDatabase;
|
||||
use bdk::descriptor::Segwitv0;
|
||||
use bdk::electrum_client::{ElectrumApi, GetHistoryRes};
|
||||
use bdk::keys::DerivableKey;
|
||||
use bdk::wallet::AddressIndex;
|
||||
use bdk::{FeeRate, KeychainKind};
|
||||
use bitcoin::{Network, Script};
|
||||
use reqwest::Url;
|
||||
@ -255,7 +256,7 @@ where
|
||||
.wallet
|
||||
.lock()
|
||||
.await
|
||||
.get_new_address()
|
||||
.get_address(AddressIndex::New)
|
||||
.context("Failed to get new Bitcoin address")?;
|
||||
|
||||
Ok(address)
|
||||
|
Loading…
Reference in New Issue
Block a user