trader bond assemblz

This commit is contained in:
Felix
2024-06-06 15:56:29 +00:00
parent ef57aaba32
commit 672006fe63
6 changed files with 88 additions and 40 deletions

View File

@ -2,6 +2,6 @@ ELECTRUM_ENDPOINT="ssl://mempool.space:40002" # testnet 4 electrum server
COORDINATOR_ENDPOINT="http://127.0.0.1:9999"
ROBOHASH_BASE91="o!kfNkee;RF?m6FT87:1bjASE2/(1NFTnR;ILmHB<1p/vP%STz~IWolNDJa.#PmTI)sfBk+Gs!,(w8M" # "robot21"
TRADE_TYPE="buy"
PAYOUT_ADDRESS="tb1pxg64k0729s327n7u4n34vcmjxg42phvjykyt3f0xvcs3x5xfdxgqpt5sql"
PAYOUT_ADDRESS="tb1p45daj2eaza6drcd85c3wvn0zrpqxuduk3rzcmla4eu7a02cep9kqjzkc64"
BOND_RATIO=5
FUNDED_WALLET_DESCRIPTOR="tr([3ed82ea5/86h/1h/0h]tpubDCi4JkK1113yExq1Jc42fFYkWt4cfXMSnv47kz6HrU3giqpY6Cu19jc7uXgj5szMyiUnRD4tC8R9mBHLNZw1cKttySbAUEDAYo7bQGSi625/<0;1>/*)#fh3av2m4" # sparrow wallet taproot wallet descriptor
XPRV="tprv8ZgxMBicQKsPdHuCSjhQuSZP1h6ZTeiRqREYS5guGPdtL7D1uNLpnJmb2oJep99Esq1NbNZKVJBNnD2ZhuXSK7G5eFmmcx73gsoa65e2U32" # wallet xprv

View File

@ -76,7 +76,7 @@ impl CliSettings {
let trade_type: OfferType = Self::get_trade_type(None);
let payout_address = Self::get_user_input("Enter a payout address for refunded bonds or your trade payout: "); // bdk can be used for validation
let bond_ratio: u8 = Self::get_user_input("Enter bond ration in [2, 50]%: ").parse()?;
let funded_wallet_descriptor = Self::get_wallet_descriptors(Some(Self::get_user_input("Enter funded testnet wallet descriptor: ")))?;
let funded_wallet_descriptor = Self::get_wallet_descriptors(Some(Self::get_user_input("Enter funded testnet wallet xprv or leave empty to generate: ")))?;
Ok(TraderSettings {
electrum_endpoint,
coordinator_endpoint,
@ -91,13 +91,10 @@ impl CliSettings {
fn get_wallet_descriptors(cli_input: Option<String>) -> Result<WalletDescriptors> {
if let Some(user_input) = cli_input {
if !(user_input.is_empty()) {
return Ok(WalletDescriptors {
descriptor: user_input,
change_descriptor: None
});
return generate_descriptor_wallet(Some(user_input));
}
};
generate_descriptor_wallet()
generate_descriptor_wallet(None)
}
fn load_from_env() -> Result<TraderSettings> {
@ -109,7 +106,7 @@ impl CliSettings {
trade_type: Self::get_trade_type(Some(env::var("TRADE_TYPE")?)),
payout_address: env::var("PAYOUT_ADDRESS")?,
bond_ratio: env::var("BOND_RATIO")?.parse()?,
funded_wallet_descriptor: Self::get_wallet_descriptors(Some(env::var("FUNDED_WALLET_DESCRIPTOR")?))?,
funded_wallet_descriptor: Self::get_wallet_descriptors(Some(env::var("XPRV")?))?,
})
}

View File

@ -1,16 +1,18 @@
// use maker_utils;
// use taker_utils;
// use utils;
use anyhow::Result;
use crate::cli::TraderSettings;
use crate::communication::api::OfferCreationResponse;
use crate::wallet::load_wallet;
use crate::wallet::{load_wallet, bond::Bond};
pub fn run_maker(maker_config: &TraderSettings) -> Result<()> {
// let offer_conditions = OfferCreationResponse::fetch(maker_config)?;
load_wallet(maker_config)?;
// maker_utils::maker(offer_conditions, maker_config)
let offer_conditions = OfferCreationResponse::fetch(maker_config)?;
let wallet = load_wallet(maker_config)?;
let bond = Bond::assemble(&wallet, &offer_conditions, maker_config)?;
Ok(())
}

View File

@ -0,0 +1,44 @@
use anyhow::Result;
use bdk::{database::MemoryDatabase, wallet::coin_selection::BranchAndBoundCoinSelection, Wallet};
use crate::communication::api::OfferCreationResponse;
use crate::wallet::TraderSettings;
pub struct Outpoint {
pub txid_hex: String,
pub index: u32
}
pub struct Bond {
pub signed_bond_tx_hex: String,
pub used_outpoint: Outpoint
}
impl Bond {
pub fn assemble(wallet: &Wallet<MemoryDatabase>,
bond_target: &OfferCreationResponse,
trader_input: &TraderSettings) -> Result<Bond> {
// let send_to = wallet.get_address(New)?;
let (psbt, details) = {
let mut builder = wallet.build_tx();
builder
.coin_selection(BranchAndBoundCoinSelection::new(10000))
.add_recipient(send_to.script_pubkey(), 50_000)
.enable_rbf()
.do_not_spend_change()
.fee_rate(FeeRate::from_sat_per_vb(5.0));
// coin_select
// manually_selected_only
// add_unspendable
// do_not_spend_change
// builder.finish()?
};
Ok(_)
}
}
// impl BranchAndBoundCoinSelection
// pub fn new(size_of_change: u64) -> Self
// Create new instance with target size for change output

View File

@ -1,52 +1,56 @@
mod bond;
pub mod bond;
use bdk::{Wallet, KeychainKind, SyncOptions, bitcoin, template::{Bip86, DescriptorTemplate}};
use bdk::{bitcoin, keys::DescriptorPublicKey, miniscript::Descriptor, template::{Bip86, DescriptorTemplate}, KeychainKind, SyncOptions, Wallet};
use bdk::database::MemoryDatabase;
use bdk::blockchain::ElectrumBlockchain;
use bdk::bitcoin::{Network, secp256k1::rand::{self, RngCore}, bip32::ExtendedPrivKey};
use bdk::electrum_client::Client;
use anyhow::Result;
use std::str::FromStr;
use crate::cli::TraderSettings;
// https://github.com/bitcoindevkit/book-of-bdk
#[derive(Debug)]
pub struct WalletDescriptors {
pub descriptor: String,
pub change_descriptor: Option<String>
pub descriptor: Descriptor<DescriptorPublicKey>,
pub change_descriptor: Option<Descriptor<DescriptorPublicKey>>
}
pub fn generate_descriptor_wallet() -> Result<WalletDescriptors> {
let mut seed: [u8; 32] = [0u8; 32];
rand::thread_rng().fill_bytes(&mut seed); // verify this is secure randomness!
pub fn generate_descriptor_wallet(xprv_input: Option<String>) -> Result<WalletDescriptors> {
let xprv: ExtendedPrivKey;
let network: Network = Network::Testnet;
if let Some(xprv_i) = xprv_input {
xprv = ExtendedPrivKey::from_str(&xprv_i)?;
} else {
let mut seed: [u8; 32] = [0u8; 32];
rand::thread_rng().fill_bytes(&mut seed); // verify this is secure randomness!
xprv = ExtendedPrivKey::new_master(network, &seed)?;
dbg!("Generated xprv: ", xprv.to_string());
}
let network: Network = Network::Testnet;
let xprv: ExtendedPrivKey = ExtendedPrivKey::new_master(network, &seed)?;
let (descriptor, key_map, _) = Bip86(xprv, KeychainKind::External).build(network).unwrap();
let (change_descriptor, change_key_map, _) = Bip86(xprv, KeychainKind::Internal).build(network)?;
let descriptors = WalletDescriptors {
descriptor: descriptor.to_string_with_secret(&key_map),
change_descriptor: Some(change_descriptor.to_string_with_secret(&change_key_map)),
descriptor,
change_descriptor: Some(change_descriptor)
};
dbg!("Generated wallet descriptors: ", &descriptors);
Ok(descriptors)
}
pub fn load_wallet(trader_config: &TraderSettings) -> Result<()> {
// let client = Client::new(&trader_config.electrum_endpoint)?;
pub fn load_wallet(trader_config: &TraderSettings) -> Result<Wallet<MemoryDatabase>> {
let client = Client::new(&trader_config.electrum_endpoint)?;
let blockchain = ElectrumBlockchain::from(client);
let wallet = Wallet::new(
trader_config.funded_wallet_descriptor.descriptor.clone(),
trader_config.funded_wallet_descriptor.change_descriptor.clone(),
bitcoin::Network::Testnet,
MemoryDatabase::default(), // non-permanent storage
)?;
// let blockchain = ElectrumBlockchain::from(client);
// let wallet = Wallet::new(
// trader_config.funded_wallet_descriptor.as_str(),
// None,
// bitcoin::Network::Testnet,
// MemoryDatabase::default(), // non-permanent storage
// )?;
// panic!("yeet");
// wallet.sync(&blockchain, SyncOptions::default())?;
// println!("Descriptor balance: {} SAT", wallet.get_balance()?);
// panic!("yeet");
Ok(())
wallet.sync(&blockchain, SyncOptions::default())?;
println!("Descriptor balance: {} SAT", wallet.get_balance()?);
Ok(wallet)
}

View File

@ -0,0 +1 @@
tbd