Remove --send-btc in favor of swapping the available balance

If the current balance is 0, we wait until the user deposits money
to the given address. After that, we simply swap the full balance.

Not only does this simplify the interface by removing a parameter,
but it also integrates the `deposit` command into the `buy-xmr`
command.

Syncing a wallet that is backed by electrum includes transactions
that are part of the mempool when computing the balance.
As such, waiting for a deposit is a very quick action because it
allows us to build our lock transaction on top of the yet to be
confirmed deposit transactions.

This patch introduces another function to the `bitcoin::Wallet` that
relies on the currently statically encoded fee rate. To make sure
future developers don't forget to adjust both, we extract a function
that "selects" a fee rate and return the constant from there.

Fixes #196.
This commit is contained in:
Thomas Eizinger 2021-02-26 14:31:09 +11:00
parent 32cb0eb896
commit f472070546
No known key found for this signature in database
GPG key ID: 651AC83A6C6C8B96
3 changed files with 55 additions and 24 deletions

View file

@ -16,6 +16,7 @@ use bdk::{
miniscript::bitcoin::PrivateKey,
FeeRate,
};
use bitcoin::Script;
use reqwest::{Method, Url};
use serde::{Deserialize, Serialize};
use std::{path::Path, sync::Arc, time::Duration};
@ -120,15 +121,47 @@ impl Wallet {
let mut tx_builder = wallet.build_tx();
tx_builder.add_recipient(address.script_pubkey(), amount.as_sat());
tx_builder.fee_rate(FeeRate::from_sat_per_vb(5.0)); // todo: make dynamic
tx_builder.fee_rate(self.select_feerate());
let (psbt, _details) = tx_builder.finish()?;
Ok(psbt)
}
/// Calculates the maximum "giveable" amount of this wallet.
///
/// We define this as the maximum amount we can pay to a single output,
/// already accounting for the fees we need to spend to get the
/// transaction confirmed.
pub async fn max_giveable(&self) -> Result<Amount> {
let wallet = self.inner.lock().await;
let mut tx_builder = wallet.build_tx();
// create a dummy script to make the txbuilder pass
// we don't intend to send this transaction, we just want to know the max amount
// we can spend
let dummy_script = Script::default();
tx_builder.set_single_recipient(dummy_script);
tx_builder.drain_wallet();
tx_builder.fee_rate(self.select_feerate());
let (_, details) = tx_builder.finish()?;
let max_giveable = details.sent - details.fees;
Ok(Amount::from_sat(max_giveable))
}
pub async fn get_network(&self) -> bitcoin::Network {
self.inner.lock().await.network()
}
/// Selects an appropriate [`FeeRate`] to be used for getting transactions
/// confirmed within a reasonable amount of time.
fn select_feerate(&self) -> FeeRate {
// TODO: This should obviously not be a const :)
FeeRate::from_sat_per_vb(5.0)
}
}
#[async_trait]