mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-10-01 01:45:40 -04:00
feat: Add RPC endpoint for requesting raw cancel and refund transactions
This commit is contained in:
parent
47b0fdbdee
commit
787827e50f
20
Cargo.lock
generated
20
Cargo.lock
generated
@ -743,7 +743,7 @@ dependencies = [
|
||||
"nom",
|
||||
"pathdiff",
|
||||
"serde",
|
||||
"toml 0.8.17",
|
||||
"toml 0.8.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4580,7 +4580,7 @@ dependencies = [
|
||||
"tokio-tar",
|
||||
"tokio-tungstenite",
|
||||
"tokio-util",
|
||||
"toml 0.8.17",
|
||||
"toml 0.8.16",
|
||||
"torut",
|
||||
"tracing",
|
||||
"tracing-appender",
|
||||
@ -4920,9 +4920,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.17"
|
||||
version = "0.8.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a44eede9b727419af8095cb2d72fab15487a541f54647ad4414b34096ee4631"
|
||||
checksum = "81967dd0dd2c1ab0bc3468bd7caecc32b8a4aa47d0c8c695d8c2b2108168d62c"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
@ -4932,18 +4932,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.8"
|
||||
version = "0.6.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
|
||||
checksum = "f8fb9f64314842840f1d940ac544da178732128f1c78c21772e876579e0da1db"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.18"
|
||||
version = "0.22.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1490595c74d930da779e944f5ba2ecdf538af67df1a9848cbd156af43c1b7cf0"
|
||||
checksum = "8d9f8729f5aea9562aac1cc0441f5d6de3cff1ee0c5d67293eeca5eb36ee7c16"
|
||||
dependencies = [
|
||||
"indexmap 2.1.0",
|
||||
"serde",
|
||||
@ -5767,9 +5767,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.6.16"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b480ae9340fc261e6be3e95a1ba86d54ae3f9171132a73ce8d4bbaf68339507c"
|
||||
checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
@ -7,9 +7,12 @@ use crate::network::swarm;
|
||||
use crate::protocol::bob::{BobState, Swap};
|
||||
use crate::protocol::{bob, State};
|
||||
use crate::{bitcoin, cli, monero, rpc};
|
||||
use crate::database::SwapStateVecExt;
|
||||
use anyhow::{bail, Context as AnyContext, Result};
|
||||
use ::bitcoin::consensus::encode::serialize_hex;
|
||||
use comfy_table::Table;
|
||||
use libp2p::core::Multiaddr;
|
||||
use monero_rpc::wallet::BlockHeight;
|
||||
use qrcode::render::unicode;
|
||||
use qrcode::QrCode;
|
||||
use rust_decimal::prelude::FromPrimitive;
|
||||
@ -69,6 +72,9 @@ pub enum Method {
|
||||
swap_id: Uuid,
|
||||
},
|
||||
GetRawStates,
|
||||
GetRawTransactions {
|
||||
swap_id: Uuid,
|
||||
},
|
||||
}
|
||||
|
||||
impl Method {
|
||||
@ -164,6 +170,14 @@ impl Method {
|
||||
method_name = "WithdrawBtc",
|
||||
log_reference_id = field::Empty
|
||||
)
|
||||
},
|
||||
Method::GetRawTransactions { swap_id } => {
|
||||
debug_span!(
|
||||
"method",
|
||||
method_name = "GetRawTransactions",
|
||||
swap_id=%swap_id,
|
||||
log_reference_id = field::Empty
|
||||
)
|
||||
}
|
||||
};
|
||||
if let Some(log_reference_id) = log_reference_id {
|
||||
@ -660,15 +674,7 @@ impl Request {
|
||||
let latest_state: BobState = state.try_into()?;
|
||||
let all_states = context.db.get_states(swap_id).await?;
|
||||
let state3 = all_states
|
||||
.iter()
|
||||
.find_map(|s| {
|
||||
if let State::Bob(BobState::BtcLocked { state3, .. }) = s {
|
||||
Some(state3)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.context("Failed to get \"BtcLocked\" state")?;
|
||||
.find_state3()?;
|
||||
|
||||
let swap_start_date = context.db.get_swap_start_date(swap_id).await?;
|
||||
let peer_id = context.db.get_peer_id(swap_id).await?;
|
||||
@ -915,6 +921,19 @@ impl Request {
|
||||
Method::GetCurrentSwap => Ok(json!({
|
||||
"swap_id": context.swap_lock.get_current_swap_id().await
|
||||
})),
|
||||
Method::GetRawTransactions { swap_id } => {
|
||||
let all_states = context.db.get_states(swap_id).await?;
|
||||
let state3 = all_states.find_state3()?;
|
||||
|
||||
let cancelledState = state3.cancel(BlockHeight { height: 0 });
|
||||
let txCancel = cancelledState.construct_tx_cancel()?;
|
||||
let txRefund = cancelledState.signed_refund_transaction()?;
|
||||
|
||||
Ok(json!({
|
||||
"tx_cancel": txCancel.serialize_hex(),
|
||||
"tx_refund": serialize_hex(&txRefund),
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ use std::cmp::Ordering;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::ops::Add;
|
||||
use bdk::bitcoin::consensus::encode::{serialize_hex, serialize};
|
||||
|
||||
/// Represent a timelock, expressed in relative block height as defined in
|
||||
/// [BIP68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki).
|
||||
@ -160,6 +161,10 @@ impl TxCancel {
|
||||
pub fn txid(&self) -> Txid {
|
||||
self.inner.txid()
|
||||
}
|
||||
|
||||
pub fn serialize_hex(&self) -> String {
|
||||
serialize_hex(&self.inner)
|
||||
}
|
||||
|
||||
pub fn digest(&self) -> Sighash {
|
||||
self.digest
|
||||
|
@ -1,10 +1,12 @@
|
||||
pub use alice::Alice;
|
||||
pub use bob::Bob;
|
||||
use monero_rpc::wallet::BlockHeight;
|
||||
pub use sqlite::SqliteDatabase;
|
||||
|
||||
use crate::fs::ensure_directory_exists;
|
||||
use crate::protocol::bob::{BobState, State2, State3};
|
||||
use crate::protocol::{Database, State};
|
||||
use anyhow::{bail, Result};
|
||||
use anyhow::{bail, Result, anyhow};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Display;
|
||||
use std::path::Path;
|
||||
@ -105,3 +107,18 @@ pub async fn open_db(
|
||||
Ok(Arc::new(sqlite))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait SwapStateVecExt {
|
||||
fn find_state3(&self) -> Result<State3>;
|
||||
}
|
||||
|
||||
impl SwapStateVecExt for Vec<State> {
|
||||
fn find_state3(&self) -> Result<State3> {
|
||||
self.iter()
|
||||
.find_map(|state| match state {
|
||||
State::Bob(BobState::BtcLocked {state3, ..}) => Some(state3.clone()),
|
||||
_ => None
|
||||
})
|
||||
.ok_or_else(|| anyhow!("No BobState::BtcLocked found"))
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
use crate::database::Swap;
|
||||
use crate::monero::{Address, TransferProof};
|
||||
use crate::protocol::bob::{BobState, State3};
|
||||
use crate::protocol::{Database, State};
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use async_trait::async_trait;
|
||||
|
@ -727,11 +727,7 @@ impl State6 {
|
||||
&self,
|
||||
bitcoin_wallet: &bitcoin::Wallet,
|
||||
) -> Result<(Txid, Subscription)> {
|
||||
let transaction = self
|
||||
.construct_tx_cancel()?
|
||||
.complete_as_bob(self.A, self.b.clone(), self.tx_cancel_sig_a.clone())
|
||||
.context("Failed to complete Bitcoin cancel transaction")?;
|
||||
|
||||
let transaction = self.signed_cancel_transaction()?;
|
||||
let (tx_id, subscription) = bitcoin_wallet.broadcast(transaction, "cancel").await?;
|
||||
|
||||
Ok((tx_id, subscription))
|
||||
@ -760,6 +756,10 @@ impl State6 {
|
||||
Ok(signed_tx_refund)
|
||||
}
|
||||
|
||||
pub fn signed_cancel_transaction(&self) -> Result<Transaction> {
|
||||
self.construct_tx_cancel()?.complete_as_bob(self.A, self.b.clone(), self.tx_cancel_sig_a.clone())
|
||||
}
|
||||
|
||||
pub fn tx_lock_id(&self) -> bitcoin::Txid {
|
||||
self.tx_lock.txid()
|
||||
}
|
||||
|
@ -213,6 +213,22 @@ pub fn register_modules(context: Arc<Context>) -> Result<RpcModule<Arc<Context>>
|
||||
execute_request(params, Method::GetCurrentSwap, &context).await
|
||||
})?;
|
||||
|
||||
module.register_async_method("get_raw_transactions", |params_raw, context| async move {
|
||||
let params: HashMap<String, serde_json::Value> = params_raw.parse()?;
|
||||
|
||||
let swap_id = params.get("swap_id").ok_or_else(|| {
|
||||
jsonrpsee_core::Error::Custom("Does not contain swap_id".to_string())
|
||||
})?;
|
||||
|
||||
let swap_id = as_uuid(swap_id).ok_or_else(|| {
|
||||
jsonrpsee_core::Error::Custom("Could not parse swap_id".to_string())
|
||||
})?;
|
||||
|
||||
execute_request(params_raw, Method::GetRawTransactions {
|
||||
swap_id
|
||||
}, &context).await
|
||||
})?;
|
||||
|
||||
Ok(module)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user