mirror of
https://github.com/RoboSats/taptrade-core.git
synced 2025-07-20 01:33:19 +00:00
move function from wallet to escrow_psbt.rs
This commit is contained in:
@ -119,10 +119,96 @@ pub fn build_escrow_transaction_output_descriptor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// pub fn assemble_escrow_psbts(
|
// pub fn assemble_escrow_psbts(
|
||||||
// coordinator: &Coordinator,
|
impl<D: bdk::database::BatchDatabase> CoordinatorWallet<D> {
|
||||||
// escrow_data: &EscrowPsbtConstructionData,
|
pub async fn create_escrow_psbt(
|
||||||
// coordinator_pk: &XOnlyPublicKey,
|
&self,
|
||||||
// ) -> Result<()> {
|
db: &Arc<CoordinatorDB>,
|
||||||
// panic!("Implement wallet.build_escrow_psbt()");
|
taker_psbt_request: &OfferPsbtRequest,
|
||||||
// Ok(())
|
) -> Result<EscrowPsbt> {
|
||||||
// }
|
let trade_id = &taker_psbt_request.offer.offer_id_hex.clone();
|
||||||
|
let maker_psbt_input_data = db.fetch_maker_escrow_psbt_data(trade_id).await?;
|
||||||
|
let taker_psbt_input_data = EscrowPsbtConstructionData {
|
||||||
|
taproot_xonly_pubkey_hex: taker_psbt_request.trade_data.taproot_pubkey_hex.clone(),
|
||||||
|
escrow_input_utxos: csv_hex_to_bdk_input(
|
||||||
|
&taker_psbt_request.trade_data.bdk_psbt_inputs_hex_csv,
|
||||||
|
)?,
|
||||||
|
change_address: Address::from_str(
|
||||||
|
&taker_psbt_request.trade_data.client_change_address,
|
||||||
|
)?
|
||||||
|
.assume_checked(),
|
||||||
|
musig_pubkey_compressed_hex: taker_psbt_request.trade_data.musig_pubkey_hex.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let coordinator_escrow_pk = self.get_coordinator_taproot_pk().await?;
|
||||||
|
let escrow_output_descriptor = build_escrow_transaction_output_descriptor(
|
||||||
|
&maker_psbt_input_data,
|
||||||
|
&taker_psbt_input_data,
|
||||||
|
&coordinator_escrow_pk,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let escrow_coordinator_fee_address =
|
||||||
|
Address::from_str(&self.get_new_address().await?)?.assume_checked();
|
||||||
|
|
||||||
|
let (escrow_amount_maker_sat, escrow_amount_taker_sat, escrow_fee_sat_per_participant) = db
|
||||||
|
.get_escrow_tx_amounts(trade_id, self.coordinator_feerate)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let (escrow_psbt, details) = {
|
||||||
|
// maybe we can generate a address/taproot pk directly from the descriptor without a new wallet?
|
||||||
|
let temp_wallet = Wallet::new(
|
||||||
|
&escrow_output_descriptor,
|
||||||
|
None,
|
||||||
|
bitcoin::Network::Regtest,
|
||||||
|
MemoryDatabase::new(),
|
||||||
|
)?;
|
||||||
|
let escrow_address = temp_wallet
|
||||||
|
.get_address(bdk::wallet::AddressIndex::New)?
|
||||||
|
.address;
|
||||||
|
|
||||||
|
// using absolute fee for now, in production we should come up with a way to determine the tx weight
|
||||||
|
// upfront and substract the fee from the change outputs
|
||||||
|
let tx_fee_abs = 10000;
|
||||||
|
|
||||||
|
let change_amount_maker = maker_psbt_input_data.input_sum()?
|
||||||
|
- (escrow_amount_maker_sat + escrow_fee_sat_per_participant + tx_fee_abs / 2);
|
||||||
|
let change_amount_taker = taker_psbt_input_data.input_sum()?
|
||||||
|
- (escrow_amount_taker_sat + escrow_fee_sat_per_participant + tx_fee_abs / 2);
|
||||||
|
|
||||||
|
let amount_escrow = escrow_amount_maker_sat + escrow_amount_taker_sat;
|
||||||
|
let mut builder = temp_wallet.build_tx();
|
||||||
|
builder
|
||||||
|
.manually_selected_only()
|
||||||
|
.add_recipient(escrow_address.script_pubkey(), amount_escrow)
|
||||||
|
.add_recipient(
|
||||||
|
escrow_coordinator_fee_address.script_pubkey(),
|
||||||
|
escrow_fee_sat_per_participant * 2,
|
||||||
|
)
|
||||||
|
.add_recipient(
|
||||||
|
maker_psbt_input_data.change_address.script_pubkey(),
|
||||||
|
change_amount_maker,
|
||||||
|
)
|
||||||
|
.add_recipient(
|
||||||
|
taker_psbt_input_data.change_address.script_pubkey(),
|
||||||
|
change_amount_taker,
|
||||||
|
)
|
||||||
|
.fee_absolute(tx_fee_abs);
|
||||||
|
for input in maker_psbt_input_data.escrow_input_utxos.iter() {
|
||||||
|
// satisfaction weight 66 bytes for schnorr sig + opcode + sighash for keyspend. This is a hack?
|
||||||
|
builder.add_foreign_utxo(input.utxo, input.psbt_input.clone(), 264)?;
|
||||||
|
}
|
||||||
|
for input in taker_psbt_input_data.escrow_input_utxos.iter() {
|
||||||
|
builder.add_foreign_utxo(input.utxo, input.psbt_input.clone(), 264)?;
|
||||||
|
}
|
||||||
|
builder.finish()?
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(EscrowPsbt {
|
||||||
|
escrow_psbt_hex: escrow_psbt.to_string(),
|
||||||
|
escrow_output_descriptor,
|
||||||
|
coordinator_xonly_escrow_pk: coordinator_escrow_pk.to_string(),
|
||||||
|
escrow_amount_maker_sat,
|
||||||
|
escrow_amount_taker_sat,
|
||||||
|
escrow_fee_sat_per_participant,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -244,98 +244,6 @@ impl<D: bdk::database::BatchDatabase> CoordinatorWallet<D> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_escrow_psbt(
|
|
||||||
&self,
|
|
||||||
db: &Arc<CoordinatorDB>,
|
|
||||||
taker_psbt_request: &OfferPsbtRequest,
|
|
||||||
) -> Result<EscrowPsbt> {
|
|
||||||
let trade_id = &taker_psbt_request.offer.offer_id_hex.clone();
|
|
||||||
let maker_psbt_input_data = db.fetch_maker_escrow_psbt_data(trade_id).await?;
|
|
||||||
let taker_psbt_input_data = EscrowPsbtConstructionData {
|
|
||||||
taproot_xonly_pubkey_hex: taker_psbt_request.trade_data.taproot_pubkey_hex.clone(),
|
|
||||||
escrow_input_utxos: csv_hex_to_bdk_input(
|
|
||||||
&taker_psbt_request.trade_data.bdk_psbt_inputs_hex_csv,
|
|
||||||
)?,
|
|
||||||
change_address: Address::from_str(
|
|
||||||
&taker_psbt_request.trade_data.client_change_address,
|
|
||||||
)?
|
|
||||||
.assume_checked(),
|
|
||||||
musig_pubkey_compressed_hex: taker_psbt_request.trade_data.musig_pubkey_hex.clone(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let coordinator_escrow_pk = self.get_coordinator_taproot_pk().await?;
|
|
||||||
let escrow_output_descriptor = build_escrow_transaction_output_descriptor(
|
|
||||||
&maker_psbt_input_data,
|
|
||||||
&taker_psbt_input_data,
|
|
||||||
&coordinator_escrow_pk,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let escrow_coordinator_fee_address =
|
|
||||||
Address::from_str(&self.get_new_address().await?)?.assume_checked();
|
|
||||||
|
|
||||||
let (escrow_amount_maker_sat, escrow_amount_taker_sat, escrow_fee_sat_per_participant) = db
|
|
||||||
.get_escrow_tx_amounts(trade_id, self.coordinator_feerate)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let (escrow_psbt, details) = {
|
|
||||||
// maybe we can generate a address/taproot pk directly from the descriptor without a new wallet?
|
|
||||||
let temp_wallet = Wallet::new(
|
|
||||||
&escrow_output_descriptor,
|
|
||||||
None,
|
|
||||||
bitcoin::Network::Regtest,
|
|
||||||
MemoryDatabase::new(),
|
|
||||||
)?;
|
|
||||||
let escrow_address = temp_wallet
|
|
||||||
.get_address(bdk::wallet::AddressIndex::New)?
|
|
||||||
.address;
|
|
||||||
|
|
||||||
// using absolute fee for now, in production we should come up with a way to determine the tx weight
|
|
||||||
// upfront and substract the fee from the change outputs
|
|
||||||
let tx_fee_abs = 10000;
|
|
||||||
|
|
||||||
let change_amount_maker = maker_psbt_input_data.input_sum()?
|
|
||||||
- (escrow_amount_maker_sat + escrow_fee_sat_per_participant + tx_fee_abs / 2);
|
|
||||||
let change_amount_taker = taker_psbt_input_data.input_sum()?
|
|
||||||
- (escrow_amount_taker_sat + escrow_fee_sat_per_participant + tx_fee_abs / 2);
|
|
||||||
|
|
||||||
let amount_escrow = escrow_amount_maker_sat + escrow_amount_taker_sat;
|
|
||||||
let mut builder = temp_wallet.build_tx();
|
|
||||||
builder
|
|
||||||
.manually_selected_only()
|
|
||||||
.add_recipient(escrow_address.script_pubkey(), amount_escrow)
|
|
||||||
.add_recipient(
|
|
||||||
escrow_coordinator_fee_address.script_pubkey(),
|
|
||||||
escrow_fee_sat_per_participant * 2,
|
|
||||||
)
|
|
||||||
.add_recipient(
|
|
||||||
maker_psbt_input_data.change_address.script_pubkey(),
|
|
||||||
change_amount_maker,
|
|
||||||
)
|
|
||||||
.add_recipient(
|
|
||||||
taker_psbt_input_data.change_address.script_pubkey(),
|
|
||||||
change_amount_taker,
|
|
||||||
)
|
|
||||||
.fee_absolute(tx_fee_abs);
|
|
||||||
for input in maker_psbt_input_data.escrow_input_utxos.iter() {
|
|
||||||
// satisfaction weight 66 bytes for schnorr sig + opcode + sighash for keyspend. This is a hack?
|
|
||||||
builder.add_foreign_utxo(input.utxo, input.psbt_input.clone(), 264)?;
|
|
||||||
}
|
|
||||||
for input in taker_psbt_input_data.escrow_input_utxos.iter() {
|
|
||||||
builder.add_foreign_utxo(input.utxo, input.psbt_input.clone(), 264)?;
|
|
||||||
}
|
|
||||||
builder.finish()?
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(EscrowPsbt {
|
|
||||||
escrow_psbt_hex: escrow_psbt.to_string(),
|
|
||||||
escrow_output_descriptor,
|
|
||||||
coordinator_xonly_escrow_pk: coordinator_escrow_pk.to_string(),
|
|
||||||
escrow_amount_maker_sat,
|
|
||||||
escrow_amount_taker_sat,
|
|
||||||
escrow_fee_sat_per_participant,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_coordinator_taproot_pk(&self) -> Result<XOnlyPublicKey> {
|
pub async fn get_coordinator_taproot_pk(&self) -> Result<XOnlyPublicKey> {
|
||||||
let wallet = self.wallet.lock().await;
|
let wallet = self.wallet.lock().await;
|
||||||
let address = wallet.get_address(bdk::wallet::AddressIndex::New)?;
|
let address = wallet.get_address(bdk::wallet::AddressIndex::New)?;
|
||||||
|
Reference in New Issue
Block a user