mirror of
https://github.com/RoboSats/taptrade-core.git
synced 2025-07-18 08:43:17 +00:00
beginn keyspend collaborative payout tx/psbt assembly, test for getting escrow utxo from descriptor
This commit is contained in:
@ -117,7 +117,7 @@ pub fn build_escrow_transaction_output_descriptor(
|
||||
let descriptor = Descriptor::<XOnlyPublicKey>::new_tr(internal_agg_musig_key, Some(tap_root))
|
||||
.context("Error assembling escrow output descriptor")?;
|
||||
descriptor.sanity_check()?;
|
||||
debug!("Escrow descriptor: {:#?}", descriptor);
|
||||
debug!("Escrow descriptor: {:#?}", descriptor.to_string());
|
||||
Ok(descriptor) // then spend to descriptor.address(Network::Regtest)
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
pub mod escrow_psbt;
|
||||
pub mod payout_tx;
|
||||
pub mod wallet_utils;
|
||||
// pub mod verify_tx;
|
||||
#[cfg(test)]
|
||||
|
38
taptrade-cli-demo/coordinator/src/wallet/payout_tx.rs
Normal file
38
taptrade-cli-demo/coordinator/src/wallet/payout_tx.rs
Normal file
@ -0,0 +1,38 @@
|
||||
use std::ops::Add;
|
||||
|
||||
/// construction of the transaction spending the escrow output after a successfull trade as keyspend transaction
|
||||
use super::*;
|
||||
use bdk::bitcoin::psbt::PartiallySignedTransaction;
|
||||
use bdk::bitcoin::OutPoint;
|
||||
|
||||
fn get_tx_fees_abs_sat(blockchain_backend: &RpcBlockchain) -> Result<(u64, u64)> {
|
||||
let feerate = blockchain_backend.estimate_fee(6)?;
|
||||
let keyspend_payout_tx_size_vb = 140; // ~, always 1 input, 2 outputs
|
||||
|
||||
let tx_fee_abs = feerate.fee_vb(keyspend_payout_tx_size_vb);
|
||||
|
||||
Ok((tx_fee_abs, tx_fee_abs / 2))
|
||||
}
|
||||
|
||||
impl<D: bdk::database::BatchDatabase> CoordinatorWallet<D> {
|
||||
pub async fn assemble_keyspend_payout_psbt(
|
||||
&self,
|
||||
escrow_output: OutPoint,
|
||||
payout_addresses: HashMap<Address, u64>,
|
||||
) -> Result<PartiallySignedTransaction> {
|
||||
let (payout_psbt, _) = {
|
||||
let wallet = self.wallet.lock().await;
|
||||
let mut builder = wallet.build_tx();
|
||||
let (tx_fee_abs, tx_fee_abs_sat_per_user) = get_tx_fees_abs_sat(&self.backend)?;
|
||||
|
||||
builder.add_utxo(escrow_output)?;
|
||||
for (address, amount) in payout_addresses {
|
||||
builder.add_recipient(address.script_pubkey(), amount - tx_fee_abs_sat_per_user);
|
||||
}
|
||||
builder.fee_absolute(tx_fee_abs);
|
||||
|
||||
builder.finish()?
|
||||
};
|
||||
Ok(payout_psbt)
|
||||
}
|
||||
}
|
@ -8,14 +8,9 @@ use bdk::{
|
||||
bitcoin::{psbt::Input, Network},
|
||||
blockchain::RpcBlockchain,
|
||||
database::MemoryDatabase,
|
||||
miniscript::{
|
||||
descriptor::{self},
|
||||
policy::Concrete,
|
||||
Descriptor, Tap,
|
||||
},
|
||||
miniscript::{policy::Concrete, Descriptor, Tap},
|
||||
Wallet,
|
||||
};
|
||||
use sha2::digest::XofReader;
|
||||
|
||||
async fn new_test_wallet(wallet_xprv: &str) -> CoordinatorWallet<MemoryDatabase> {
|
||||
dotenv().ok();
|
||||
@ -324,3 +319,43 @@ fn test_miniscript_compilation() {
|
||||
Descriptor::<XOnlyPublicKey>::new_tr(internal_key, Some(tap_tree_root)).unwrap();
|
||||
dbg!(descriptor.address(bdk::bitcoin::Network::Regtest).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_escrow_spending_psbt() {
|
||||
dotenv().ok();
|
||||
let test_descriptor = "tr(f00949d6dd1ce99a03f88a1a4f59117d553b0da51728bb7fd5b98fbf541337fb,{{and_v(v:pk(4987f3de20a9b1fa6f76c6758934953a8d615e415f1a656f0f6563694b53107d),pk(8f808f457423ff5e4e20a36d317ce9426f9da2fde875e74e15a04481b94bec06)),and_v(v:pk(f1f1db08126af105974cde6021096525ed390cf9b7cde5fedb17a0b16ed31151),pk(8f808f457423ff5e4e20a36d317ce9426f9da2fde875e74e15a04481b94bec06))},{and_v(v:and_v(v:pk(4987f3de20a9b1fa6f76c6758934953a8d615e415f1a656f0f6563694b53107d),pk(f1f1db08126af105974cde6021096525ed390cf9b7cde5fedb17a0b16ed31151)),after(2048)),and_v(v:pk(4987f3de20a9b1fa6f76c6758934953a8d615e415f1a656f0f6563694b53107d),after(12228))}})#0edq24m2";
|
||||
|
||||
let escrow_output_wallet = Wallet::new(
|
||||
test_descriptor,
|
||||
None,
|
||||
Network::Regtest,
|
||||
MemoryDatabase::new(),
|
||||
)
|
||||
.unwrap();
|
||||
let secp_context = secp256k1::Secp256k1::new();
|
||||
let rpc_config = RpcConfig {
|
||||
url: env::var("BITCOIN_RPC_ADDRESS_PORT").unwrap().to_string(),
|
||||
auth: Auth::UserPass {
|
||||
username: env::var("BITCOIN_RPC_USER").unwrap(),
|
||||
password: env::var("BITCOIN_RPC_PASSWORD").unwrap(),
|
||||
},
|
||||
network: Regtest,
|
||||
// wallet_name: env::var("BITCOIN_RPC_WALLET_NAME")?,
|
||||
wallet_name: bdk::wallet::wallet_name_from_descriptor(
|
||||
test_descriptor,
|
||||
None,
|
||||
Network::Regtest,
|
||||
&secp_context,
|
||||
)
|
||||
.unwrap(),
|
||||
sync_params: None,
|
||||
};
|
||||
let backend = RpcBlockchain::from_config(&rpc_config).unwrap();
|
||||
escrow_output_wallet
|
||||
.sync(&backend, SyncOptions::default())
|
||||
.unwrap();
|
||||
|
||||
let escrow_utxo = escrow_output_wallet.list_unspent().unwrap();
|
||||
dbg!(&escrow_utxo);
|
||||
assert!(escrow_utxo.len() > 0);
|
||||
}
|
||||
|
Reference in New Issue
Block a user