mirror of
https://github.com/RoboSats/taptrade-core.git
synced 2025-07-20 09:43:30 +00:00
add keyspend context struct
This commit is contained in:
@ -106,7 +106,7 @@ pub struct TradeObligationsUnsatisfied {
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct PayoutSignatureRequest {
|
||||
pub partitial_sig_hex: String,
|
||||
pub partial_sig_hex: String,
|
||||
pub offer_id_hex: String,
|
||||
pub robohash_hex: String,
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ async fn request_offer_status_maker(
|
||||
/// receives the signed escrow psbt and verifies it
|
||||
/// Supposed to be the endpoint that both maker & taker will send their part of the PSBT to (with signatures), the
|
||||
/// coordinator then has to check if their signatures are valid and everything else is according to the agreed upon contract.
|
||||
/// Once the coordinator has received both partitial signed PSBTs he can assemble them together to a transaction and publish it to the bitcoin network.
|
||||
/// Once the coordinator has received both partial signed PSBTs he can assemble them together to a transaction and publish it to the bitcoin network.
|
||||
async fn submit_escrow_psbt(
|
||||
Extension(coordinator): Extension<Arc<Coordinator>>,
|
||||
Json(payload): Json<PsbtSubmissionRequest>,
|
||||
|
@ -332,17 +332,17 @@ pub async fn handle_payout_signature(
|
||||
|
||||
check_offer_and_confirmation(&payload.offer_id_hex, &payload.robohash_hex, database).await?;
|
||||
|
||||
let (maker_partitial_sig_hex, taker_partitial_sig_hex, payout_psbt_hex) = match database
|
||||
.insert_partitial_sig_and_fetch_if_both(
|
||||
&payload.partitial_sig_hex,
|
||||
let (maker_partial_sig_hex, taker_partial_sig_hex, payout_psbt_hex) = match database
|
||||
.insert_partial_sig_and_fetch_if_both(
|
||||
&payload.partial_sig_hex,
|
||||
&payload.offer_id_hex,
|
||||
&payload.robohash_hex,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(Some((maker_partitial_sig, taker_partitial_sig, payout_transaction_psbt_hex))) => (
|
||||
maker_partitial_sig,
|
||||
taker_partitial_sig,
|
||||
Ok(Some((maker_partial_sig, taker_partial_sig, payout_transaction_psbt_hex))) => (
|
||||
maker_partial_sig,
|
||||
taker_partial_sig,
|
||||
bdk::bitcoin::psbt::PartiallySignedTransaction::deserialize(
|
||||
&hex::decode(payout_transaction_psbt_hex)
|
||||
.map_err(|e| RequestError::CoordinatorError(e.to_string()))?,
|
||||
@ -352,8 +352,13 @@ pub async fn handle_payout_signature(
|
||||
Err(e) => return Err(RequestError::Database(e.to_string())),
|
||||
};
|
||||
|
||||
let aggregated_signature = wallet
|
||||
.aggregate_partitial_signatures(&maker_partitial_sig_hex, &taker_partitial_sig_hex)?;
|
||||
warn!("Use musig2 validate partial sig to validate sigs before using to blame users providing wrong sigs");
|
||||
|
||||
let aggregated_signature = wallet::payout_tx::aggregate_partial_signatures(
|
||||
&maker_partial_sig_hex,
|
||||
&taker_partial_sig_hex,
|
||||
)
|
||||
.map_err(|e| RequestError::CoordinatorError(e.to_string()))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -137,8 +137,8 @@ impl CoordinatorDB {
|
||||
musig_pubkey_compressed_hex_maker TEXT NOT NULL,
|
||||
musig_pub_nonce_hex_taker TEXT NOT NULL,
|
||||
musig_pubkey_compressed_hex_taker TEXT NOT NULL,
|
||||
musig_partitial_sig_hex_maker TEXT,
|
||||
musig_partitial_sig_hex_taker TEXT,
|
||||
musig_partial_sig_hex_maker TEXT,
|
||||
musig_partial_sig_hex_taker TEXT,
|
||||
escrow_psbt_hex TEXT NOT NULL,
|
||||
escrow_psbt_txid TEXT NOT NULL,
|
||||
signed_escrow_psbt_hex_maker TEXT,
|
||||
@ -907,9 +907,9 @@ impl CoordinatorDB {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn insert_partitial_sig_and_fetch_if_both(
|
||||
pub async fn insert_partial_sig_and_fetch_if_both(
|
||||
&self,
|
||||
partitial_sig_hex: &str,
|
||||
partial_sig_hex: &str,
|
||||
offer_id_hex: &str,
|
||||
robohash_hex: &str,
|
||||
) -> Result<Option<(String, String, String)>> {
|
||||
@ -921,24 +921,24 @@ impl CoordinatorDB {
|
||||
let is_already_there = match is_maker {
|
||||
true => {
|
||||
let status = sqlx::query(
|
||||
"SELECT musig_partitial_sig_maker FROM taken_offers WHERE offer_id = ?",
|
||||
"SELECT musig_partial_sig_maker FROM taken_offers WHERE offer_id = ?",
|
||||
)
|
||||
.bind(offer_id_hex)
|
||||
.fetch_one(&*self.db_pool)
|
||||
.await?;
|
||||
status
|
||||
.get::<Option<String>, _>("musig_partitial_sig_maker")
|
||||
.get::<Option<String>, _>("musig_partial_sig_maker")
|
||||
.is_some()
|
||||
}
|
||||
false => {
|
||||
let status = sqlx::query(
|
||||
"SELECT musig_partitial_sig_taker FROM taken_offers WHERE offer_id = ?",
|
||||
"SELECT musig_partial_sig_taker FROM taken_offers WHERE offer_id = ?",
|
||||
)
|
||||
.bind(offer_id_hex)
|
||||
.fetch_one(&*self.db_pool)
|
||||
.await?;
|
||||
status
|
||||
.get::<Option<String>, _>("musig_partitial_sig_taker")
|
||||
.get::<Option<String>, _>("musig_partial_sig_taker")
|
||||
.is_some()
|
||||
}
|
||||
};
|
||||
@ -947,23 +947,23 @@ impl CoordinatorDB {
|
||||
return Err(anyhow!("Partial sig already submitted"));
|
||||
} else {
|
||||
let query = if is_maker {
|
||||
"UPDATE taken_offers SET musig_partitial_sig_maker = ? WHERE offer_id = ?"
|
||||
"UPDATE taken_offers SET musig_partial_sig_maker = ? WHERE offer_id = ?"
|
||||
} else {
|
||||
"UPDATE taken_offers SET musig_partitial_sig_taker = ? WHERE offer_id = ?"
|
||||
"UPDATE taken_offers SET musig_partial_sig_taker = ? WHERE offer_id = ?"
|
||||
};
|
||||
sqlx::query(query)
|
||||
.bind(partitial_sig_hex)
|
||||
.bind(partial_sig_hex)
|
||||
.bind(offer_id_hex)
|
||||
.execute(&*self.db_pool)
|
||||
.await?;
|
||||
}
|
||||
|
||||
let row = sqlx::query(
|
||||
"SELECT musig_partitial_sig_maker, musig_partitial_sig_taker, payout_transaction_psbt_hex FROM taken_offers WHERE offer_id = ?",
|
||||
"SELECT musig_partial_sig_maker, musig_partial_sig_taker, payout_transaction_psbt_hex FROM taken_offers WHERE offer_id = ?",
|
||||
).bind(offer_id_hex).fetch_one(&*self.db_pool).await?;
|
||||
|
||||
let maker_sig: Option<String> = row.try_get("musig_partitial_sig_maker")?;
|
||||
let taker_sig: Option<String> = row.try_get("musig_partitial_sig_taker")?;
|
||||
let maker_sig: Option<String> = row.try_get("musig_partial_sig_maker")?;
|
||||
let taker_sig: Option<String> = row.try_get("musig_partial_sig_taker")?;
|
||||
let payout_tx_hex: String = row.try_get("payout_transaction_psbt_hex")?;
|
||||
if let (Some(maker), Some(taker)) = (maker_sig, taker_sig) {
|
||||
Ok(Some((maker, taker, payout_tx_hex)))
|
||||
|
@ -4,6 +4,15 @@ use bdk::bitcoin::psbt::Input;
|
||||
use bdk::bitcoin::psbt::PartiallySignedTransaction;
|
||||
use bdk::bitcoin::OutPoint;
|
||||
use bdk::miniscript::Descriptor;
|
||||
use musig2::{AggNonce, KeyAggContext, PartialSignature};
|
||||
|
||||
pub struct KeyspendContext {
|
||||
pub partial_maker_sig: PartialSignature,
|
||||
pub partial_taker_sig: PartialSignature,
|
||||
pub agg_nonce: AggNonce,
|
||||
pub key_agg_context: KeyAggContext,
|
||||
pub keyspend_psbt: PartiallySignedTransaction,
|
||||
}
|
||||
|
||||
fn get_tx_fees_abs_sat(blockchain_backend: &RpcBlockchain) -> Result<(u64, u64)> {
|
||||
let feerate = blockchain_backend.estimate_fee(6)?;
|
||||
@ -14,9 +23,12 @@ fn get_tx_fees_abs_sat(blockchain_backend: &RpcBlockchain) -> Result<(u64, u64)>
|
||||
Ok((tx_fee_abs, tx_fee_abs / 2))
|
||||
}
|
||||
|
||||
pub fn aggregate_partitial_signatures() -> anyhow::Result<String> {
|
||||
Ok(())
|
||||
}
|
||||
// pub fn aggregate_partial_signatures(
|
||||
// maker_sig_hex: &str,
|
||||
// taker_sig_hex: &str,
|
||||
// ) -> anyhow::Result<String> {
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
impl<D: bdk::database::BatchDatabase> CoordinatorWallet<D> {
|
||||
fn get_escrow_utxo(
|
||||
|
@ -5,7 +5,7 @@ use super::*;
|
||||
use crate::{
|
||||
cli::{OfferType, TraderSettings},
|
||||
trading::utils::ActiveOffer,
|
||||
wallet::{bond::Bond, musig2::MuSigData},
|
||||
wallet::{bond::Bond, musig2_utils::MuSigData},
|
||||
};
|
||||
use anyhow::{anyhow, Result};
|
||||
use api::*;
|
||||
|
@ -211,7 +211,7 @@ impl TradingWallet {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// creates a partitial signature to spend the keyspend path of the escrow output
|
||||
/// creates a partial signature to spend the keyspend path of the escrow output
|
||||
/// which will be returned to the coordinator for aggregation
|
||||
pub fn sign_keyspend_payout_psbt(
|
||||
&self,
|
||||
|
Reference in New Issue
Block a user