mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-12-11 17:04:31 -05:00
fixing formatting and cargo clippy warnings
This commit is contained in:
parent
925c7bc179
commit
9d1a39b2ff
@ -194,7 +194,7 @@ mod monero_serde_hex_block {
|
|||||||
{
|
{
|
||||||
let hex = String::deserialize(deserializer)?;
|
let hex = String::deserialize(deserializer)?;
|
||||||
|
|
||||||
let bytes = hex::decode(&hex).map_err(D::Error::custom)?;
|
let bytes = hex::decode(hex).map_err(D::Error::custom)?;
|
||||||
let mut cursor = Cursor::new(bytes);
|
let mut cursor = Cursor::new(bytes);
|
||||||
|
|
||||||
let block = monero::Block::consensus_decode(&mut cursor).map_err(D::Error::custom)?;
|
let block = monero::Block::consensus_decode(&mut cursor).map_err(D::Error::custom)?;
|
||||||
|
@ -79,17 +79,17 @@ zip = "0.5"
|
|||||||
bitcoin-harness = "0.2.2"
|
bitcoin-harness = "0.2.2"
|
||||||
get-port = "3"
|
get-port = "3"
|
||||||
hyper = "0.14"
|
hyper = "0.14"
|
||||||
monero-harness = { path = "../monero-harness" }
|
|
||||||
jsonrpsee = { version = "0.16.2", features = [ "ws-client" ] }
|
jsonrpsee = { version = "0.16.2", features = [ "ws-client" ] }
|
||||||
jsonrpsee-types = { version = "0.16.2" }
|
jsonrpsee-types = { version = "0.16.2" }
|
||||||
|
monero-harness = { path = "../monero-harness" }
|
||||||
port_check = "0.1"
|
port_check = "0.1"
|
||||||
proptest = "1"
|
proptest = "1"
|
||||||
|
sequential-test = "0.2.4"
|
||||||
serde_cbor = "0.11"
|
serde_cbor = "0.11"
|
||||||
serial_test = "0.10"
|
serial_test = "0.10"
|
||||||
spectral = "0.6"
|
spectral = "0.6"
|
||||||
tempfile = "3"
|
tempfile = "3"
|
||||||
testcontainers = "0.12"
|
testcontainers = "0.12"
|
||||||
sequential-test = "0.2.4"
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
|
@ -11,10 +11,9 @@ use anyhow::{Context as AnyContext, Result};
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::{Arc};
|
use std::sync::{Arc, Once};
|
||||||
use url::Url;
|
|
||||||
use std::sync::Once;
|
|
||||||
use tokio::sync::{broadcast, Mutex};
|
use tokio::sync::{broadcast, Mutex};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
static START: Once = Once::new();
|
static START: Once = Once::new();
|
||||||
|
|
||||||
@ -42,7 +41,6 @@ pub struct Context {
|
|||||||
pub shutdown: Arc<broadcast::Sender<()>>,
|
pub shutdown: Arc<broadcast::Sender<()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
pub async fn build(
|
pub async fn build(
|
||||||
bitcoin: Option<Bitcoin>,
|
bitcoin: Option<Bitcoin>,
|
||||||
@ -91,19 +89,12 @@ impl Context {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let tor_socks5_port = {
|
let tor_socks5_port = tor.map(|tor| tor.tor_socks5_port);
|
||||||
if let Some(tor) = tor {
|
|
||||||
Some(tor.tor_socks5_port)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
START.call_once(|| {
|
START.call_once(|| {
|
||||||
let _ = cli::tracing::init(debug, json, data_dir.join("logs"), None);
|
let _ = cli::tracing::init(debug, json, data_dir.join("logs"), None);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
let init = Context {
|
let init = Context {
|
||||||
db: open_db(data_dir.join("sqlite")).await?,
|
db: open_db(data_dir.join("sqlite")).await?,
|
||||||
bitcoin_wallet,
|
bitcoin_wallet,
|
||||||
@ -125,16 +116,14 @@ impl Context {
|
|||||||
|
|
||||||
Ok(init)
|
Ok(init)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Context {
|
impl fmt::Debug for Context {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "Testing {}", true)
|
write!(f, "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async fn init_bitcoin_wallet(
|
async fn init_bitcoin_wallet(
|
||||||
electrum_rpc_url: Url,
|
electrum_rpc_url: Url,
|
||||||
seed: &Seed,
|
seed: &Seed,
|
||||||
@ -159,7 +148,6 @@ async fn init_bitcoin_wallet(
|
|||||||
Ok(wallet)
|
Ok(wallet)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async fn init_monero_wallet(
|
async fn init_monero_wallet(
|
||||||
data_dir: PathBuf,
|
data_dir: PathBuf,
|
||||||
monero_daemon_address: String,
|
monero_daemon_address: String,
|
||||||
@ -213,12 +201,12 @@ fn env_config_from(testnet: bool) -> EnvConfig {
|
|||||||
}
|
}
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod api_test {
|
pub mod api_test {
|
||||||
|
use crate::api::request::{Method, Params, Request, Shutdown};
|
||||||
use crate::tor::DEFAULT_SOCKS5_PORT;
|
use crate::tor::DEFAULT_SOCKS5_PORT;
|
||||||
use std::str::FromStr;
|
|
||||||
use uuid::Uuid;
|
|
||||||
use crate::api::request::{Request, Params, Method, Shutdown};
|
|
||||||
use libp2p::Multiaddr;
|
use libp2p::Multiaddr;
|
||||||
|
use std::str::FromStr;
|
||||||
use tokio::sync::broadcast;
|
use tokio::sync::broadcast;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
pub const MULTI_ADDRESS: &str =
|
pub const MULTI_ADDRESS: &str =
|
||||||
"/ip4/127.0.0.1/tcp/9939/p2p/12D3KooWCdMKjesXMJz1SiZ7HgotrxuqhQJbP5sgBm2BwP1cqThi";
|
"/ip4/127.0.0.1/tcp/9939/p2p/12D3KooWCdMKjesXMJz1SiZ7HgotrxuqhQJbP5sgBm2BwP1cqThi";
|
||||||
@ -251,7 +239,6 @@ pub mod api_test {
|
|||||||
is_testnet,
|
is_testnet,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
impl Request {
|
impl Request {
|
||||||
pub fn buy_xmr(is_testnet: bool, tx: broadcast::Sender<()>) -> Request {
|
pub fn buy_xmr(is_testnet: bool, tx: broadcast::Sender<()>) -> Request {
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
|
use crate::api::Context;
|
||||||
use crate::bitcoin::{Amount, TxLock};
|
use crate::bitcoin::{Amount, TxLock};
|
||||||
use crate::cli::{list_sellers, EventLoop, SellerStatus};
|
use crate::cli::{list_sellers, EventLoop, SellerStatus};
|
||||||
use crate::libp2p_ext::MultiAddrExt;
|
use crate::libp2p_ext::MultiAddrExt;
|
||||||
use crate::network::quote::{BidQuote, ZeroQuoteReceived};
|
use crate::network::quote::{BidQuote, ZeroQuoteReceived};
|
||||||
use crate::network::swarm;
|
use crate::network::swarm;
|
||||||
use crate::protocol::bob::{BobState, Swap};
|
|
||||||
use crate::protocol::bob;
|
use crate::protocol::bob;
|
||||||
|
use crate::protocol::bob::{BobState, Swap};
|
||||||
use crate::{bitcoin, cli, monero, rpc};
|
use crate::{bitcoin, cli, monero, rpc};
|
||||||
use anyhow::{bail, Context as AnyContext, Result};
|
use anyhow::{bail, Context as AnyContext, Result};
|
||||||
use libp2p::core::Multiaddr;
|
use libp2p::core::Multiaddr;
|
||||||
@ -16,10 +17,8 @@ use std::convert::TryInto;
|
|||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use uuid::Uuid;
|
|
||||||
use crate::api::Context;
|
|
||||||
use tokio::sync::broadcast;
|
use tokio::sync::broadcast;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub struct Request {
|
pub struct Request {
|
||||||
@ -61,11 +60,11 @@ impl Shutdown {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Shutdown {
|
pub struct Shutdown {
|
||||||
shutdown: bool,
|
shutdown: bool,
|
||||||
notify: broadcast::Receiver<()>
|
notify: broadcast::Receiver<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Shutdown {
|
impl PartialEq for Shutdown {
|
||||||
fn eq(&self, other: &Shutdown) -> bool {
|
fn eq(&self, other: &Shutdown) -> bool {
|
||||||
self.shutdown == other.shutdown
|
self.shutdown == other.shutdown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,7 +80,6 @@ pub struct Params {
|
|||||||
pub address: Option<bitcoin::Address>,
|
pub address: Option<bitcoin::Address>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum Method {
|
pub enum Method {
|
||||||
BuyXmr,
|
BuyXmr,
|
||||||
@ -93,8 +91,7 @@ pub enum Method {
|
|||||||
GetSeller,
|
GetSeller,
|
||||||
SwapStartDate,
|
SwapStartDate,
|
||||||
Resume,
|
Resume,
|
||||||
Cancel,
|
CancelAndRefund,
|
||||||
Refund,
|
|
||||||
ListSellers,
|
ListSellers,
|
||||||
ExportBitcoinWallet,
|
ExportBitcoinWallet,
|
||||||
MoneroRecovery,
|
MoneroRecovery,
|
||||||
@ -107,19 +104,29 @@ impl Request {
|
|||||||
Method::BuyXmr => {
|
Method::BuyXmr => {
|
||||||
let swap_id = Uuid::new_v4();
|
let swap_id = Uuid::new_v4();
|
||||||
|
|
||||||
let seed = context.config.seed.as_ref().unwrap();
|
let seed = context.config.seed.as_ref().context("Could not get seed")?;
|
||||||
let env_config = context.config.env_config;
|
let env_config = context.config.env_config;
|
||||||
let btc = context.bitcoin_wallet.as_ref().unwrap();
|
let btc = context
|
||||||
let seller = self.params.seller.clone().unwrap();
|
.bitcoin_wallet
|
||||||
let monero_receive_address = self.params.monero_receive_address.unwrap();
|
.as_ref()
|
||||||
let bitcoin_change_address = self.params.bitcoin_change_address.clone().unwrap();
|
.context("Could not get Bitcoin wallet")?;
|
||||||
|
let seller = self
|
||||||
let bitcoin_wallet = btc;
|
|
||||||
let seller_peer_id = self
|
|
||||||
.params
|
.params
|
||||||
.seller
|
.seller
|
||||||
.as_ref()
|
.clone()
|
||||||
.unwrap()
|
.context("Parameter seller is missing")?;
|
||||||
|
let monero_receive_address = self
|
||||||
|
.params
|
||||||
|
.monero_receive_address
|
||||||
|
.context("Parameter monero_receive_address is missing")?;
|
||||||
|
let bitcoin_change_address = self
|
||||||
|
.params
|
||||||
|
.bitcoin_change_address
|
||||||
|
.clone()
|
||||||
|
.context("Parameter bitcoin_change_address is missing")?;
|
||||||
|
|
||||||
|
let bitcoin_wallet = btc;
|
||||||
|
let seller_peer_id = seller
|
||||||
.extract_peer_id()
|
.extract_peer_id()
|
||||||
.context("Seller address must contain peer ID")?;
|
.context("Seller address must contain peer ID")?;
|
||||||
context
|
context
|
||||||
@ -135,7 +142,10 @@ impl Request {
|
|||||||
);
|
);
|
||||||
let mut swarm = swarm::cli(
|
let mut swarm = swarm::cli(
|
||||||
seed.derive_libp2p_identity(),
|
seed.derive_libp2p_identity(),
|
||||||
context.config.tor_socks5_port.unwrap(),
|
context
|
||||||
|
.config
|
||||||
|
.tor_socks5_port
|
||||||
|
.context("Could not get Tor SOCKS5 port")?,
|
||||||
behaviour,
|
behaviour,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@ -178,13 +188,16 @@ impl Request {
|
|||||||
.db
|
.db
|
||||||
.insert_monero_address(swap_id, monero_receive_address)
|
.insert_monero_address(swap_id, monero_receive_address)
|
||||||
.await?;
|
.await?;
|
||||||
let monero_wallet = context.monero_wallet.as_ref().unwrap();
|
let monero_wallet = context
|
||||||
|
.monero_wallet
|
||||||
|
.as_ref()
|
||||||
|
.context("Could not get Monero wallet")?;
|
||||||
|
|
||||||
let swap = Swap::new(
|
let swap = Swap::new(
|
||||||
Arc::clone(&context.db),
|
Arc::clone(&context.db),
|
||||||
swap_id,
|
swap_id,
|
||||||
Arc::clone(&bitcoin_wallet),
|
Arc::clone(bitcoin_wallet),
|
||||||
Arc::clone(&monero_wallet),
|
Arc::clone(monero_wallet),
|
||||||
env_config,
|
env_config,
|
||||||
event_loop_handle,
|
event_loop_handle,
|
||||||
monero_receive_address,
|
monero_receive_address,
|
||||||
@ -217,15 +230,21 @@ impl Request {
|
|||||||
}
|
}
|
||||||
Method::RawHistory => {
|
Method::RawHistory => {
|
||||||
let raw_history = context.db.raw_all().await?;
|
let raw_history = context.db.raw_all().await?;
|
||||||
json!({
|
json!({ "raw_history": raw_history })
|
||||||
"raw_history": raw_history
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
Method::GetSeller => {
|
Method::GetSeller => {
|
||||||
let swap_id = self.params.swap_id.with_context(|| "A swap_id is needed")?;
|
let swap_id = self.params.swap_id.context("Parameter swap_id is needed")?;
|
||||||
let peerId = context.db.get_peer_id(swap_id).await.with_context(|| "Could not get PeerID")?;
|
let peerId = context
|
||||||
|
.db
|
||||||
|
.get_peer_id(swap_id)
|
||||||
|
.await
|
||||||
|
.with_context(|| "Could not get PeerID")?;
|
||||||
|
|
||||||
let addresses = context.db.get_addresses(peerId).await.with_context(|| "Could not get addressess")?;
|
let addresses = context
|
||||||
|
.db
|
||||||
|
.get_addresses(peerId)
|
||||||
|
.await
|
||||||
|
.with_context(|| "Could not get addressess")?;
|
||||||
|
|
||||||
json!({
|
json!({
|
||||||
"peerId": peerId.to_base58(),
|
"peerId": peerId.to_base58(),
|
||||||
@ -233,12 +252,12 @@ impl Request {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
Method::SwapStartDate => {
|
Method::SwapStartDate => {
|
||||||
let swap_id = self.params.swap_id.with_context(|| "A swap_id is needed")?;
|
let swap_id = self
|
||||||
|
.params
|
||||||
|
.swap_id
|
||||||
|
.context("Parameter swap_id is missing")?;
|
||||||
|
|
||||||
let start_date = context
|
let start_date = context.db.get_swap_start_date(swap_id).await?;
|
||||||
.db
|
|
||||||
.get_swap_start_date(swap_id)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
json!({
|
json!({
|
||||||
"start_date": start_date,
|
"start_date": start_date,
|
||||||
@ -262,9 +281,16 @@ impl Request {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
Method::WithdrawBtc => {
|
Method::WithdrawBtc => {
|
||||||
let bitcoin_wallet = context.bitcoin_wallet.as_ref().unwrap();
|
let bitcoin_wallet = context
|
||||||
|
.bitcoin_wallet
|
||||||
|
.as_ref()
|
||||||
|
.context("Could not get Bitcoin wallet")?;
|
||||||
|
|
||||||
let address = self.params.address.clone().unwrap();
|
let address = self
|
||||||
|
.params
|
||||||
|
.address
|
||||||
|
.clone()
|
||||||
|
.context("Parameter address is missing")?;
|
||||||
|
|
||||||
let amount = match self.params.amount {
|
let amount = match self.params.amount {
|
||||||
Some(amount) => amount,
|
Some(amount) => amount,
|
||||||
@ -306,7 +332,10 @@ impl Request {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Method::Balance => {
|
Method::Balance => {
|
||||||
let bitcoin_wallet = context.bitcoin_wallet.as_ref().unwrap();
|
let bitcoin_wallet = context
|
||||||
|
.bitcoin_wallet
|
||||||
|
.as_ref()
|
||||||
|
.context("Could not get Bitcoin wallet")?;
|
||||||
|
|
||||||
bitcoin_wallet.sync().await?;
|
bitcoin_wallet.sync().await?;
|
||||||
let bitcoin_balance = bitcoin_wallet.balance().await?;
|
let bitcoin_balance = bitcoin_wallet.balance().await?;
|
||||||
@ -320,22 +349,38 @@ impl Request {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
Method::Resume => {
|
Method::Resume => {
|
||||||
let swap_id = self.params.swap_id.unwrap();
|
let swap_id = self
|
||||||
|
.params
|
||||||
|
.swap_id
|
||||||
|
.context("Parameter swap_id is missing")?;
|
||||||
|
|
||||||
let seller_peer_id = context.db.get_peer_id(swap_id).await?;
|
let seller_peer_id = context.db.get_peer_id(swap_id).await?;
|
||||||
let seller_addresses = context.db.get_addresses(seller_peer_id).await?;
|
let seller_addresses = context.db.get_addresses(seller_peer_id).await?;
|
||||||
|
|
||||||
let seed = context.config.seed.as_ref().unwrap().derive_libp2p_identity();
|
let seed = context
|
||||||
|
.config
|
||||||
|
.seed
|
||||||
|
.as_ref()
|
||||||
|
.context("Could not get seed")?
|
||||||
|
.derive_libp2p_identity();
|
||||||
|
|
||||||
let behaviour = cli::Behaviour::new(
|
let behaviour = cli::Behaviour::new(
|
||||||
seller_peer_id,
|
seller_peer_id,
|
||||||
context.config.env_config,
|
context.config.env_config,
|
||||||
Arc::clone(context.bitcoin_wallet.as_ref().unwrap()),
|
Arc::clone(
|
||||||
|
context
|
||||||
|
.bitcoin_wallet
|
||||||
|
.as_ref()
|
||||||
|
.context("Could not get Bitcoin wallet")?,
|
||||||
|
),
|
||||||
(seed.clone(), context.config.namespace),
|
(seed.clone(), context.config.namespace),
|
||||||
);
|
);
|
||||||
let mut swarm = swarm::cli(
|
let mut swarm = swarm::cli(
|
||||||
seed.clone(),
|
seed.clone(),
|
||||||
context.config.tor_socks5_port.clone().unwrap(),
|
context
|
||||||
|
.config
|
||||||
|
.tor_socks5_port
|
||||||
|
.context("Could not get Tor SOCKS5 port")?,
|
||||||
behaviour,
|
behaviour,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@ -357,8 +402,18 @@ impl Request {
|
|||||||
let swap = Swap::from_db(
|
let swap = Swap::from_db(
|
||||||
Arc::clone(&context.db),
|
Arc::clone(&context.db),
|
||||||
swap_id,
|
swap_id,
|
||||||
Arc::clone(context.bitcoin_wallet.as_ref().unwrap()),
|
Arc::clone(
|
||||||
Arc::clone(context.monero_wallet.as_ref().unwrap()),
|
context
|
||||||
|
.bitcoin_wallet
|
||||||
|
.as_ref()
|
||||||
|
.context("Could not get Bitcoin wallet")?,
|
||||||
|
),
|
||||||
|
Arc::clone(
|
||||||
|
context
|
||||||
|
.monero_wallet
|
||||||
|
.as_ref()
|
||||||
|
.context("Could not get Monero wallet")?,
|
||||||
|
),
|
||||||
context.config.env_config,
|
context.config.env_config,
|
||||||
event_loop_handle,
|
event_loop_handle,
|
||||||
monero_receive_address,
|
monero_receive_address,
|
||||||
@ -378,39 +433,49 @@ impl Request {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
Method::CancelAndRefund => {
|
Method::CancelAndRefund => {
|
||||||
let bitcoin_wallet = context.bitcoin_wallet.as_ref().unwrap();
|
let bitcoin_wallet = context
|
||||||
|
.bitcoin_wallet
|
||||||
|
.as_ref()
|
||||||
|
.context("Could not get Bitcoin wallet")?;
|
||||||
|
|
||||||
let (txid, _) = cli::cancel_and_refund(swap_id, Arc::clone(bitcoin_wallet), Arc::clone(&context.db).await?;
|
let state = cli::cancel_and_refund(
|
||||||
|
self.params
|
||||||
json!({
|
.swap_id
|
||||||
"txid": txid,
|
.context("Parameter swap_id is missing")?,
|
||||||
})
|
|
||||||
}
|
|
||||||
Method::Refund => {
|
|
||||||
let bitcoin_wallet = context.bitcoin_wallet.as_ref().unwrap();
|
|
||||||
|
|
||||||
let state = cli::refund(
|
|
||||||
self.params.swap_id.unwrap(),
|
|
||||||
Arc::clone(bitcoin_wallet),
|
Arc::clone(bitcoin_wallet),
|
||||||
Arc::clone(&context.db),
|
Arc::clone(&context.db),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
json!({ "result": state })
|
json!({
|
||||||
|
"result": state,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
Method::ListSellers => {
|
Method::ListSellers => {
|
||||||
let rendezvous_point = self.params.rendezvous_point.clone().unwrap();
|
let rendezvous_point = self
|
||||||
|
.params
|
||||||
|
.rendezvous_point
|
||||||
|
.clone()
|
||||||
|
.context("Parameter rendezvous_point is missing")?;
|
||||||
let rendezvous_node_peer_id = rendezvous_point
|
let rendezvous_node_peer_id = rendezvous_point
|
||||||
.extract_peer_id()
|
.extract_peer_id()
|
||||||
.context("Rendezvous node address must contain peer ID")?;
|
.context("Rendezvous node address must contain peer ID")?;
|
||||||
|
|
||||||
let identity = context.config.seed.as_ref().unwrap().derive_libp2p_identity();
|
let identity = context
|
||||||
|
.config
|
||||||
|
.seed
|
||||||
|
.as_ref()
|
||||||
|
.context("Cannot extract seed")?
|
||||||
|
.derive_libp2p_identity();
|
||||||
|
|
||||||
let sellers = list_sellers(
|
let sellers = list_sellers(
|
||||||
rendezvous_node_peer_id,
|
rendezvous_node_peer_id,
|
||||||
rendezvous_point,
|
rendezvous_point,
|
||||||
context.config.namespace,
|
context.config.namespace,
|
||||||
context.config.tor_socks5_port.unwrap(),
|
context
|
||||||
|
.config
|
||||||
|
.tor_socks5_port
|
||||||
|
.context("Could not get Tor SOCKS5 port")?,
|
||||||
identity,
|
identity,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@ -440,7 +505,10 @@ impl Request {
|
|||||||
json!({ "sellers": sellers })
|
json!({ "sellers": sellers })
|
||||||
}
|
}
|
||||||
Method::ExportBitcoinWallet => {
|
Method::ExportBitcoinWallet => {
|
||||||
let bitcoin_wallet = context.bitcoin_wallet.as_ref().unwrap();
|
let bitcoin_wallet = context
|
||||||
|
.bitcoin_wallet
|
||||||
|
.as_ref()
|
||||||
|
.context("Could not get Bitcoin wallet")?;
|
||||||
|
|
||||||
let wallet_export = bitcoin_wallet.wallet_export("cli").await?;
|
let wallet_export = bitcoin_wallet.wallet_export("cli").await?;
|
||||||
tracing::info!(descriptor=%wallet_export.to_string(), "Exported bitcoin wallet");
|
tracing::info!(descriptor=%wallet_export.to_string(), "Exported bitcoin wallet");
|
||||||
@ -451,7 +519,11 @@ impl Request {
|
|||||||
Method::MoneroRecovery => {
|
Method::MoneroRecovery => {
|
||||||
let swap_state: BobState = context
|
let swap_state: BobState = context
|
||||||
.db
|
.db
|
||||||
.get_state(self.params.swap_id.clone().unwrap())
|
.get_state(
|
||||||
|
self.params
|
||||||
|
.swap_id
|
||||||
|
.context("Parameter swap_id is missing")?,
|
||||||
|
)
|
||||||
.await?
|
.await?
|
||||||
.try_into()?;
|
.try_into()?;
|
||||||
|
|
||||||
@ -495,7 +567,6 @@ impl Request {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn qr_code(value: &impl ToString) -> Result<String> {
|
fn qr_code(value: &impl ToString) -> Result<String> {
|
||||||
let code = QrCode::new(value.to_string())?;
|
let code = QrCode::new(value.to_string())?;
|
||||||
let qr_code = code
|
let qr_code = code
|
||||||
|
@ -54,7 +54,7 @@ impl Wallet {
|
|||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let data_dir = data_dir.as_ref();
|
let data_dir = data_dir.as_ref();
|
||||||
let wallet_dir = data_dir.join(WALLET);
|
let wallet_dir = data_dir.join(WALLET);
|
||||||
let database = bdk::sled::open(&wallet_dir)?.open_tree(SLED_TREE_NAME)?;
|
let database = bdk::sled::open(wallet_dir)?.open_tree(SLED_TREE_NAME)?;
|
||||||
let network = env_config.bitcoin_network;
|
let network = env_config.bitcoin_network;
|
||||||
|
|
||||||
let wallet = match bdk::Wallet::new(
|
let wallet = match bdk::Wallet::new(
|
||||||
@ -97,7 +97,7 @@ impl Wallet {
|
|||||||
std::fs::rename(from, to)?;
|
std::fs::rename(from, to)?;
|
||||||
|
|
||||||
let wallet_dir = data_dir.join(WALLET);
|
let wallet_dir = data_dir.join(WALLET);
|
||||||
let database = bdk::sled::open(&wallet_dir)?.open_tree(SLED_TREE_NAME)?;
|
let database = bdk::sled::open(wallet_dir)?.open_tree(SLED_TREE_NAME)?;
|
||||||
|
|
||||||
let wallet = bdk::Wallet::new(
|
let wallet = bdk::Wallet::new(
|
||||||
bdk::template::Bip84(xprivkey, KeychainKind::External),
|
bdk::template::Bip84(xprivkey, KeychainKind::External),
|
||||||
|
@ -28,7 +28,7 @@ pub async fn cancel_and_refund(
|
|||||||
pub async fn cancel(
|
pub async fn cancel(
|
||||||
swap_id: Uuid,
|
swap_id: Uuid,
|
||||||
bitcoin_wallet: Arc<Wallet>,
|
bitcoin_wallet: Arc<Wallet>,
|
||||||
db: Arc<dyn Database>,
|
db: Arc<dyn Database + Send + Sync>,
|
||||||
) -> Result<(Txid, Subscription, BobState)> {
|
) -> Result<(Txid, Subscription, BobState)> {
|
||||||
let state = db.get_state(swap_id).await?.try_into()?;
|
let state = db.get_state(swap_id).await?.try_into()?;
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ pub async fn cancel(
|
|||||||
pub async fn refund(
|
pub async fn refund(
|
||||||
swap_id: Uuid,
|
swap_id: Uuid,
|
||||||
bitcoin_wallet: Arc<Wallet>,
|
bitcoin_wallet: Arc<Wallet>,
|
||||||
db: Arc<dyn Database>,
|
db: Arc<dyn Database + Send + Sync>,
|
||||||
) -> Result<BobState> {
|
) -> Result<BobState> {
|
||||||
let state = db.get_state(swap_id).await?.try_into()?;
|
let state = db.get_state(swap_id).await?.try_into()?;
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
|
use crate::api::request::{Method, Params, Request, Shutdown};
|
||||||
use crate::api::Context;
|
use crate::api::Context;
|
||||||
use crate::api::request::{Request, Params, Method, Shutdown};
|
use crate::bitcoin::{bitcoin_address, Amount};
|
||||||
use crate::bitcoin::{Amount, bitcoin_address};
|
|
||||||
use crate::monero::monero_address;
|
|
||||||
use crate::monero;
|
use crate::monero;
|
||||||
|
use crate::monero::monero_address;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use libp2p::core::Multiaddr;
|
use libp2p::core::Multiaddr;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
@ -11,9 +11,9 @@ use std::path::PathBuf;
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use structopt::{clap, StructOpt};
|
use structopt::{clap, StructOpt};
|
||||||
|
use tokio::sync::broadcast;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use tokio::sync::broadcast;
|
|
||||||
|
|
||||||
// See: https://moneroworld.com/
|
// See: https://moneroworld.com/
|
||||||
pub const DEFAULT_MONERO_DAEMON_ADDRESS: &str = "node.community.rino.io:18081";
|
pub const DEFAULT_MONERO_DAEMON_ADDRESS: &str = "node.community.rino.io:18081";
|
||||||
@ -42,7 +42,10 @@ pub enum ParseResult {
|
|||||||
PrintAndExitZero { message: String },
|
PrintAndExitZero { message: String },
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn parse_args_and_apply_defaults<I, T>(raw_args: I, rx: broadcast::Sender<()>) -> Result<ParseResult>
|
pub async fn parse_args_and_apply_defaults<I, T>(
|
||||||
|
raw_args: I,
|
||||||
|
rx: broadcast::Sender<()>,
|
||||||
|
) -> Result<ParseResult>
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = T>,
|
I: IntoIterator<Item = T>,
|
||||||
T: Into<OsString> + Clone,
|
T: Into<OsString> + Clone,
|
||||||
@ -70,8 +73,10 @@ where
|
|||||||
monero_receive_address,
|
monero_receive_address,
|
||||||
tor,
|
tor,
|
||||||
} => {
|
} => {
|
||||||
let monero_receive_address = monero_address::validate(monero_receive_address, is_testnet)?;
|
let monero_receive_address =
|
||||||
let bitcoin_change_address = bitcoin_address::validate(bitcoin_change_address, is_testnet)?;
|
monero_address::validate(monero_receive_address, is_testnet)?;
|
||||||
|
let bitcoin_change_address =
|
||||||
|
bitcoin_address::validate(bitcoin_change_address, is_testnet)?;
|
||||||
|
|
||||||
let request = Request {
|
let request = Request {
|
||||||
params: Params {
|
params: Params {
|
||||||
@ -268,8 +273,18 @@ where
|
|||||||
shutdown: Shutdown::new(rx.subscribe()),
|
shutdown: Shutdown::new(rx.subscribe()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let context =
|
let context = Context::build(
|
||||||
Context::build(None, None, Some(tor), data, is_testnet, debug, json, None, rx).await?;
|
None,
|
||||||
|
None,
|
||||||
|
Some(tor),
|
||||||
|
data,
|
||||||
|
is_testnet,
|
||||||
|
debug,
|
||||||
|
json,
|
||||||
|
None,
|
||||||
|
rx,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
(context, request)
|
(context, request)
|
||||||
}
|
}
|
||||||
@ -563,10 +578,10 @@ mod tests {
|
|||||||
use crate::tor::DEFAULT_SOCKS5_PORT;
|
use crate::tor::DEFAULT_SOCKS5_PORT;
|
||||||
|
|
||||||
use crate::api::api_test::*;
|
use crate::api::api_test::*;
|
||||||
use sequential_test::sequential;
|
|
||||||
use crate::monero::monero_address::MoneroAddressNetworkMismatch;
|
|
||||||
use crate::api::Config;
|
use crate::api::Config;
|
||||||
use crate::fs::system_data_dir;
|
use crate::fs::system_data_dir;
|
||||||
|
use crate::monero::monero_address::MoneroAddressNetworkMismatch;
|
||||||
|
use sequential_test::sequential;
|
||||||
|
|
||||||
const BINARY_NAME: &str = "swap";
|
const BINARY_NAME: &str = "swap";
|
||||||
const ARGS_DATA_DIR: &str = "/tmp/dir/";
|
const ARGS_DATA_DIR: &str = "/tmp/dir/";
|
||||||
@ -586,7 +601,9 @@ mod tests {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let args = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let (is_testnet, debug, json) = (false, false, false);
|
let (is_testnet, debug, json) = (false, false, false);
|
||||||
|
|
||||||
let (expected_config, expected_request) = (
|
let (expected_config, expected_request) = (
|
||||||
@ -619,7 +636,9 @@ mod tests {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let args = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let (is_testnet, debug, json) = (true, false, false);
|
let (is_testnet, debug, json) = (true, false, false);
|
||||||
|
|
||||||
let (expected_config, expected_request) = (
|
let (expected_config, expected_request) = (
|
||||||
@ -651,7 +670,9 @@ mod tests {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let err = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap_err();
|
let err = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap_err();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
err.downcast_ref::<MoneroAddressNetworkMismatch>().unwrap(),
|
err.downcast_ref::<MoneroAddressNetworkMismatch>().unwrap(),
|
||||||
@ -678,7 +699,9 @@ mod tests {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let err = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap_err();
|
let err = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap_err();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
err.downcast_ref::<MoneroAddressNetworkMismatch>().unwrap(),
|
err.downcast_ref::<MoneroAddressNetworkMismatch>().unwrap(),
|
||||||
@ -695,7 +718,9 @@ mod tests {
|
|||||||
let raw_ars = vec![BINARY_NAME, "resume", "--swap-id", SWAP_ID];
|
let raw_ars = vec![BINARY_NAME, "resume", "--swap-id", SWAP_ID];
|
||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let args = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let (is_testnet, debug, json) = (false, false, false);
|
let (is_testnet, debug, json) = (false, false, false);
|
||||||
|
|
||||||
let (expected_config, expected_request) = (
|
let (expected_config, expected_request) = (
|
||||||
@ -718,7 +743,9 @@ mod tests {
|
|||||||
let raw_ars = vec![BINARY_NAME, "--testnet", "resume", "--swap-id", SWAP_ID];
|
let raw_ars = vec![BINARY_NAME, "--testnet", "resume", "--swap-id", SWAP_ID];
|
||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let args = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let (is_testnet, debug, json) = (true, false, false);
|
let (is_testnet, debug, json) = (true, false, false);
|
||||||
|
|
||||||
let (expected_config, expected_request) = (
|
let (expected_config, expected_request) = (
|
||||||
@ -741,7 +768,9 @@ mod tests {
|
|||||||
let raw_ars = vec![BINARY_NAME, "cancel", "--swap-id", SWAP_ID];
|
let raw_ars = vec![BINARY_NAME, "cancel", "--swap-id", SWAP_ID];
|
||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let args = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let (is_testnet, debug, json) = (false, false, false);
|
let (is_testnet, debug, json) = (false, false, false);
|
||||||
|
|
||||||
@ -765,7 +794,9 @@ mod tests {
|
|||||||
let raw_ars = vec![BINARY_NAME, "--testnet", "cancel", "--swap-id", SWAP_ID];
|
let raw_ars = vec![BINARY_NAME, "--testnet", "cancel", "--swap-id", SWAP_ID];
|
||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let args = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let (is_testnet, debug, json) = (true, false, false);
|
let (is_testnet, debug, json) = (true, false, false);
|
||||||
|
|
||||||
let (expected_config, expected_request) = (
|
let (expected_config, expected_request) = (
|
||||||
@ -788,7 +819,9 @@ mod tests {
|
|||||||
let raw_ars = vec![BINARY_NAME, "refund", "--swap-id", SWAP_ID];
|
let raw_ars = vec![BINARY_NAME, "refund", "--swap-id", SWAP_ID];
|
||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let args = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let (is_testnet, debug, json) = (false, false, false);
|
let (is_testnet, debug, json) = (false, false, false);
|
||||||
|
|
||||||
let (expected_config, expected_request) = (
|
let (expected_config, expected_request) = (
|
||||||
@ -811,7 +844,9 @@ mod tests {
|
|||||||
let raw_ars = vec![BINARY_NAME, "--testnet", "refund", "--swap-id", SWAP_ID];
|
let raw_ars = vec![BINARY_NAME, "--testnet", "refund", "--swap-id", SWAP_ID];
|
||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let args = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let (is_testnet, debug, json) = (true, false, false);
|
let (is_testnet, debug, json) = (true, false, false);
|
||||||
|
|
||||||
let (expected_config, expected_request) = (
|
let (expected_config, expected_request) = (
|
||||||
@ -845,7 +880,9 @@ mod tests {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let args = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let (is_testnet, debug, json) = (false, false, false);
|
let (is_testnet, debug, json) = (false, false, false);
|
||||||
let data_dir = PathBuf::from_str(ARGS_DATA_DIR).unwrap();
|
let data_dir = PathBuf::from_str(ARGS_DATA_DIR).unwrap();
|
||||||
|
|
||||||
@ -863,7 +900,6 @@ mod tests {
|
|||||||
assert_eq!(actual_request, Box::new(expected_request));
|
assert_eq!(actual_request, Box::new(expected_request));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[sequential]
|
#[sequential]
|
||||||
async fn given_buy_xmr_on_testnet_with_data_dir_then_data_dir_set() {
|
async fn given_buy_xmr_on_testnet_with_data_dir_then_data_dir_set() {
|
||||||
@ -883,7 +919,9 @@ mod tests {
|
|||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let data_dir = PathBuf::from_str(ARGS_DATA_DIR).unwrap();
|
let data_dir = PathBuf::from_str(ARGS_DATA_DIR).unwrap();
|
||||||
let args = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let (is_testnet, debug, json) = (true, false, false);
|
let (is_testnet, debug, json) = (true, false, false);
|
||||||
|
|
||||||
let (expected_config, expected_request) = (
|
let (expected_config, expected_request) = (
|
||||||
@ -903,7 +941,6 @@ mod tests {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[sequential]
|
#[sequential]
|
||||||
async fn given_resume_on_mainnet_with_data_dir_then_data_dir_set() {
|
async fn given_resume_on_mainnet_with_data_dir_then_data_dir_set() {
|
||||||
|
|
||||||
let raw_ars = vec![
|
let raw_ars = vec![
|
||||||
BINARY_NAME,
|
BINARY_NAME,
|
||||||
"--data-base-dir",
|
"--data-base-dir",
|
||||||
@ -915,7 +952,9 @@ mod tests {
|
|||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let data_dir = PathBuf::from_str(ARGS_DATA_DIR).unwrap();
|
let data_dir = PathBuf::from_str(ARGS_DATA_DIR).unwrap();
|
||||||
let args = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let (is_testnet, debug, json) = (false, false, false);
|
let (is_testnet, debug, json) = (false, false, false);
|
||||||
|
|
||||||
let (expected_config, expected_request) = (
|
let (expected_config, expected_request) = (
|
||||||
@ -935,7 +974,6 @@ mod tests {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[sequential]
|
#[sequential]
|
||||||
async fn given_resume_on_testnet_with_data_dir_then_data_dir_set() {
|
async fn given_resume_on_testnet_with_data_dir_then_data_dir_set() {
|
||||||
|
|
||||||
let raw_ars = vec![
|
let raw_ars = vec![
|
||||||
BINARY_NAME,
|
BINARY_NAME,
|
||||||
"--testnet",
|
"--testnet",
|
||||||
@ -948,7 +986,9 @@ mod tests {
|
|||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let data_dir = PathBuf::from_str(ARGS_DATA_DIR).unwrap();
|
let data_dir = PathBuf::from_str(ARGS_DATA_DIR).unwrap();
|
||||||
let args = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let (is_testnet, debug, json) = (true, false, false);
|
let (is_testnet, debug, json) = (true, false, false);
|
||||||
|
|
||||||
let (expected_config, expected_request) = (
|
let (expected_config, expected_request) = (
|
||||||
@ -981,7 +1021,9 @@ mod tests {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let args = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let (is_testnet, debug, json) = (false, true, false);
|
let (is_testnet, debug, json) = (false, true, false);
|
||||||
|
|
||||||
let (expected_config, expected_request) = (
|
let (expected_config, expected_request) = (
|
||||||
@ -1015,7 +1057,9 @@ mod tests {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let args = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let (is_testnet, debug, json) = (true, true, false);
|
let (is_testnet, debug, json) = (true, true, false);
|
||||||
|
|
||||||
let (expected_config, expected_request) = (
|
let (expected_config, expected_request) = (
|
||||||
@ -1035,11 +1079,12 @@ mod tests {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[sequential]
|
#[sequential]
|
||||||
async fn given_resume_on_mainnet_with_debug_then_debug_set() {
|
async fn given_resume_on_mainnet_with_debug_then_debug_set() {
|
||||||
|
|
||||||
let raw_ars = vec![BINARY_NAME, "--debug", "resume", "--swap-id", SWAP_ID];
|
let raw_ars = vec![BINARY_NAME, "--debug", "resume", "--swap-id", SWAP_ID];
|
||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let args = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let (is_testnet, debug, json) = (false, true, false);
|
let (is_testnet, debug, json) = (false, true, false);
|
||||||
|
|
||||||
let (expected_config, expected_request) = (
|
let (expected_config, expected_request) = (
|
||||||
@ -1056,7 +1101,6 @@ mod tests {
|
|||||||
assert_eq!(actual_request, Box::new(expected_request));
|
assert_eq!(actual_request, Box::new(expected_request));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[sequential]
|
#[sequential]
|
||||||
async fn given_resume_on_testnet_with_debug_then_debug_set() {
|
async fn given_resume_on_testnet_with_debug_then_debug_set() {
|
||||||
@ -1070,7 +1114,9 @@ mod tests {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let args = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let (is_testnet, debug, json) = (true, true, false);
|
let (is_testnet, debug, json) = (true, true, false);
|
||||||
|
|
||||||
let (expected_config, expected_request) = (
|
let (expected_config, expected_request) = (
|
||||||
@ -1103,7 +1149,9 @@ mod tests {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let args = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let (is_testnet, debug, json) = (false, false, true);
|
let (is_testnet, debug, json) = (false, false, true);
|
||||||
let data_dir = data_dir_path_cli(is_testnet);
|
let data_dir = data_dir_path_cli(is_testnet);
|
||||||
|
|
||||||
@ -1138,7 +1186,9 @@ mod tests {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let args = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let (is_testnet, debug, json) = (true, false, true);
|
let (is_testnet, debug, json) = (true, false, true);
|
||||||
|
|
||||||
let (expected_config, expected_request) = (
|
let (expected_config, expected_request) = (
|
||||||
@ -1158,10 +1208,11 @@ mod tests {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[sequential]
|
#[sequential]
|
||||||
async fn given_resume_on_mainnet_with_json_then_json_set() {
|
async fn given_resume_on_mainnet_with_json_then_json_set() {
|
||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let raw_ars = vec![BINARY_NAME, "--json", "resume", "--swap-id", SWAP_ID];
|
let raw_ars = vec![BINARY_NAME, "--json", "resume", "--swap-id", SWAP_ID];
|
||||||
let args = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let (is_testnet, debug, json) = (false, false, true);
|
let (is_testnet, debug, json) = (false, false, true);
|
||||||
|
|
||||||
let (expected_config, expected_request) = (
|
let (expected_config, expected_request) = (
|
||||||
@ -1181,7 +1232,6 @@ mod tests {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[sequential]
|
#[sequential]
|
||||||
async fn given_resume_on_testnet_with_json_then_json_set() {
|
async fn given_resume_on_testnet_with_json_then_json_set() {
|
||||||
|
|
||||||
let raw_ars = vec![
|
let raw_ars = vec![
|
||||||
BINARY_NAME,
|
BINARY_NAME,
|
||||||
"--testnet",
|
"--testnet",
|
||||||
@ -1192,7 +1242,9 @@ mod tests {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let args = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let (is_testnet, debug, json) = (true, false, true);
|
let (is_testnet, debug, json) = (true, false, true);
|
||||||
|
|
||||||
let (expected_config, expected_request) = (
|
let (expected_config, expected_request) = (
|
||||||
@ -1223,7 +1275,9 @@ mod tests {
|
|||||||
MULTI_ADDRESS,
|
MULTI_ADDRESS,
|
||||||
];
|
];
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
let result = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap_err();
|
let result = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap_err();
|
||||||
|
|
||||||
let raw_ars = vec![
|
let raw_ars = vec![
|
||||||
BINARY_NAME,
|
BINARY_NAME,
|
||||||
@ -1235,7 +1289,9 @@ mod tests {
|
|||||||
"--seller",
|
"--seller",
|
||||||
MULTI_ADDRESS,
|
MULTI_ADDRESS,
|
||||||
];
|
];
|
||||||
let result = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap_err();
|
let result = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap_err();
|
||||||
|
|
||||||
let raw_ars = vec![
|
let raw_ars = vec![
|
||||||
BINARY_NAME,
|
BINARY_NAME,
|
||||||
@ -1247,7 +1303,9 @@ mod tests {
|
|||||||
"--seller",
|
"--seller",
|
||||||
MULTI_ADDRESS,
|
MULTI_ADDRESS,
|
||||||
];
|
];
|
||||||
let result = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let result = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
assert!(matches!(result, ParseResult::Context(_, _)));
|
assert!(matches!(result, ParseResult::Context(_, _)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1266,7 +1324,9 @@ mod tests {
|
|||||||
"--seller",
|
"--seller",
|
||||||
MULTI_ADDRESS,
|
MULTI_ADDRESS,
|
||||||
];
|
];
|
||||||
let result = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap_err();
|
let result = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap_err();
|
||||||
|
|
||||||
let raw_ars = vec![
|
let raw_ars = vec![
|
||||||
BINARY_NAME,
|
BINARY_NAME,
|
||||||
@ -1279,7 +1339,9 @@ mod tests {
|
|||||||
"--seller",
|
"--seller",
|
||||||
MULTI_ADDRESS,
|
MULTI_ADDRESS,
|
||||||
];
|
];
|
||||||
let result = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap_err();
|
let result = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap_err();
|
||||||
|
|
||||||
let raw_ars = vec![
|
let raw_ars = vec![
|
||||||
BINARY_NAME,
|
BINARY_NAME,
|
||||||
@ -1292,7 +1354,9 @@ mod tests {
|
|||||||
"--seller",
|
"--seller",
|
||||||
MULTI_ADDRESS,
|
MULTI_ADDRESS,
|
||||||
];
|
];
|
||||||
let result = parse_args_and_apply_defaults(raw_ars, tx.clone()).await.unwrap();
|
let result = parse_args_and_apply_defaults(raw_ars, tx.clone())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
assert!(matches!(result, ParseResult::Context(_, _)));
|
assert!(matches!(result, ParseResult::Context(_, _)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::database::Swap;
|
use crate::database::Swap;
|
||||||
use crate::monero::Address;
|
use crate::monero::Address;
|
||||||
use crate::protocol::{Database, State};
|
use crate::protocol::{Database, State};
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{anyhow, Context, Result};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use libp2p::{Multiaddr, PeerId};
|
use libp2p::{Multiaddr, PeerId};
|
||||||
use sqlx::sqlite::Sqlite;
|
use sqlx::sqlite::Sqlite;
|
||||||
@ -185,7 +185,8 @@ impl Database for SqliteDatabase {
|
|||||||
.fetch_one(&mut conn)
|
.fetch_one(&mut conn)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
return Ok(row.start_date.unwrap());
|
row.start_date
|
||||||
|
.ok_or_else(|| anyhow!("Could not get swap start date"))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn insert_latest_state(&self, swap_id: Uuid, state: State) -> Result<()> {
|
async fn insert_latest_state(&self, swap_id: Uuid, state: State) -> Result<()> {
|
||||||
@ -283,13 +284,16 @@ impl Database for SqliteDatabase {
|
|||||||
let mut swaps: HashMap<Uuid, Vec<serde_json::Value>> = HashMap::new();
|
let mut swaps: HashMap<Uuid, Vec<serde_json::Value>> = HashMap::new();
|
||||||
|
|
||||||
for row in &rows {
|
for row in &rows {
|
||||||
let swap_id = Uuid::from_str(&row.swap_id).unwrap();
|
let swap_id = Uuid::from_str(&row.swap_id)?;
|
||||||
let state = serde_json::from_str(&row.state).unwrap();
|
let state = serde_json::from_str(&row.state)?;
|
||||||
|
|
||||||
if swaps.contains_key(&swap_id) {
|
if let std::collections::hash_map::Entry::Vacant(e) = swaps.entry(swap_id) {
|
||||||
swaps.get_mut(&swap_id).unwrap().push(state);
|
e.insert(vec![state]);
|
||||||
} else {
|
} else {
|
||||||
swaps.insert(swap_id, vec![state]);
|
swaps
|
||||||
|
.get_mut(&swap_id)
|
||||||
|
.ok_or_else(|| anyhow!("Error while retrieving the swap"))?
|
||||||
|
.push(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +321,7 @@ pub mod monero_amount {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub mod monero_address {
|
pub mod monero_address {
|
||||||
use anyhow::{bail, Result, Context};
|
use anyhow::{bail, Context, Result};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug, Clone, Copy, PartialEq)]
|
#[derive(thiserror::Error, Debug, Clone, Copy, PartialEq)]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::api::Context;
|
use crate::api::Context;
|
||||||
use jsonrpsee::server::{ServerBuilder, ServerHandle, RpcModule};
|
use jsonrpsee::server::{RpcModule, ServerBuilder, ServerHandle};
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
@ -21,7 +21,7 @@ pub async fn run_server(
|
|||||||
{
|
{
|
||||||
modules
|
modules
|
||||||
.merge(methods::register_modules(Arc::clone(&context)))
|
.merge(methods::register_modules(Arc::clone(&context)))
|
||||||
.unwrap()
|
.expect("Could not register RPC modules")
|
||||||
}
|
}
|
||||||
|
|
||||||
let addr = server.local_addr()?;
|
let addr = server.local_addr()?;
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use crate::api::{Context};
|
use crate::api::request::{Method, Params, Request, Shutdown};
|
||||||
use crate::api::request::{Params, Request, Method, Shutdown};
|
use crate::api::Context;
|
||||||
use anyhow::Result;
|
use crate::bitcoin::bitcoin_address;
|
||||||
|
use crate::monero::monero_address;
|
||||||
use crate::{bitcoin, monero};
|
use crate::{bitcoin, monero};
|
||||||
use crate::{bitcoin::bitcoin_address, monero::monero_address};
|
use anyhow::Result;
|
||||||
use jsonrpsee::server::RpcModule;
|
use jsonrpsee::server::RpcModule;
|
||||||
use libp2p::core::Multiaddr;
|
use libp2p::core::Multiaddr;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
@ -16,17 +17,17 @@ pub fn register_modules(context: Arc<Context>) -> RpcModule<Arc<Context>> {
|
|||||||
.register_async_method("get_bitcoin_balance", |_, context| async move {
|
.register_async_method("get_bitcoin_balance", |_, context| async move {
|
||||||
get_bitcoin_balance(&context).await
|
get_bitcoin_balance(&context).await
|
||||||
})
|
})
|
||||||
.unwrap();
|
.expect("Could not register RPC method get_bitcoin_balance");
|
||||||
module
|
module
|
||||||
.register_async_method("get_history", |_, context| async move {
|
.register_async_method("get_history", |_, context| async move {
|
||||||
get_history(&context).await
|
get_history(&context).await
|
||||||
})
|
})
|
||||||
.unwrap();
|
.expect("Could not register RPC method get_history");
|
||||||
module
|
module
|
||||||
.register_async_method("get_raw_history", |_, context| async move {
|
.register_async_method("get_raw_history", |_, context| async move {
|
||||||
get_raw_history(&context).await
|
get_raw_history(&context).await
|
||||||
})
|
})
|
||||||
.unwrap();
|
.expect("Could not register RPC method get_history");
|
||||||
module
|
module
|
||||||
.register_async_method("get_seller", |params, context| async move {
|
.register_async_method("get_seller", |params, context| async move {
|
||||||
let params: HashMap<String, Uuid> = params.parse()?;
|
let params: HashMap<String, Uuid> = params.parse()?;
|
||||||
@ -37,7 +38,7 @@ pub fn register_modules(context: Arc<Context>) -> RpcModule<Arc<Context>> {
|
|||||||
|
|
||||||
get_seller(*swap_id, &context).await
|
get_seller(*swap_id, &context).await
|
||||||
})
|
})
|
||||||
.unwrap();
|
.expect("Could not register RPC method get_seller");
|
||||||
module
|
module
|
||||||
.register_async_method("get_swap_start_date", |params, context| async move {
|
.register_async_method("get_swap_start_date", |params, context| async move {
|
||||||
let params: HashMap<String, Uuid> = params.parse()?;
|
let params: HashMap<String, Uuid> = params.parse()?;
|
||||||
@ -48,7 +49,7 @@ pub fn register_modules(context: Arc<Context>) -> RpcModule<Arc<Context>> {
|
|||||||
|
|
||||||
get_swap_start_date(*swap_id, &context).await
|
get_swap_start_date(*swap_id, &context).await
|
||||||
})
|
})
|
||||||
.unwrap();
|
.expect("Could not register RPC method get_swap_start_date");
|
||||||
module
|
module
|
||||||
.register_async_method("resume_swap", |params, context| async move {
|
.register_async_method("resume_swap", |params, context| async move {
|
||||||
let params: HashMap<String, Uuid> = params.parse()?;
|
let params: HashMap<String, Uuid> = params.parse()?;
|
||||||
@ -59,7 +60,7 @@ pub fn register_modules(context: Arc<Context>) -> RpcModule<Arc<Context>> {
|
|||||||
|
|
||||||
resume_swap(*swap_id, &context).await
|
resume_swap(*swap_id, &context).await
|
||||||
})
|
})
|
||||||
.unwrap();
|
.expect("Could not register RPC method resume_swap");
|
||||||
module
|
module
|
||||||
.register_async_method("withdraw_btc", |params, context| async move {
|
.register_async_method("withdraw_btc", |params, context| async move {
|
||||||
let params: HashMap<String, String> = params.parse()?;
|
let params: HashMap<String, String> = params.parse()?;
|
||||||
@ -80,11 +81,12 @@ pub fn register_modules(context: Arc<Context>) -> RpcModule<Arc<Context>> {
|
|||||||
jsonrpsee_core::Error::Custom("Does not contain address".to_string())
|
jsonrpsee_core::Error::Custom("Does not contain address".to_string())
|
||||||
})?)
|
})?)
|
||||||
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
||||||
let withdraw_address = bitcoin_address::validate(withdraw_address, context.config.is_testnet)?;
|
let withdraw_address =
|
||||||
|
bitcoin_address::validate(withdraw_address, context.config.is_testnet)?;
|
||||||
|
|
||||||
withdraw_btc(withdraw_address, amount, &context).await
|
withdraw_btc(withdraw_address, amount, &context).await
|
||||||
})
|
})
|
||||||
.unwrap();
|
.expect("Could not register RPC method withdraw_btc");
|
||||||
module
|
module
|
||||||
.register_async_method("buy_xmr", |params, context| async move {
|
.register_async_method("buy_xmr", |params, context| async move {
|
||||||
let params: HashMap<String, String> = params.parse()?;
|
let params: HashMap<String, String> = params.parse()?;
|
||||||
@ -98,7 +100,8 @@ pub fn register_modules(context: Arc<Context>) -> RpcModule<Arc<Context>> {
|
|||||||
)
|
)
|
||||||
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
||||||
|
|
||||||
let bitcoin_change_address = bitcoin_address::validate(bitcoin_change_address, context.config.is_testnet)?;
|
let bitcoin_change_address =
|
||||||
|
bitcoin_address::validate(bitcoin_change_address, context.config.is_testnet)?;
|
||||||
|
|
||||||
let monero_receive_address = monero::Address::from_str(
|
let monero_receive_address = monero::Address::from_str(
|
||||||
params.get("monero_receive_address").ok_or_else(|| {
|
params.get("monero_receive_address").ok_or_else(|| {
|
||||||
@ -109,7 +112,8 @@ pub fn register_modules(context: Arc<Context>) -> RpcModule<Arc<Context>> {
|
|||||||
)
|
)
|
||||||
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
||||||
|
|
||||||
let monero_receive_address = monero_address::validate(monero_receive_address, context.config.is_testnet)?;
|
let monero_receive_address =
|
||||||
|
monero_address::validate(monero_receive_address, context.config.is_testnet)?;
|
||||||
|
|
||||||
let seller = Multiaddr::from_str(params.get("seller").ok_or_else(|| {
|
let seller = Multiaddr::from_str(params.get("seller").ok_or_else(|| {
|
||||||
jsonrpsee_core::Error::Custom("Does not contain seller".to_string())
|
jsonrpsee_core::Error::Custom("Does not contain seller".to_string())
|
||||||
@ -121,29 +125,33 @@ pub fn register_modules(context: Arc<Context>) -> RpcModule<Arc<Context>> {
|
|||||||
monero_receive_address,
|
monero_receive_address,
|
||||||
seller,
|
seller,
|
||||||
&context,
|
&context,
|
||||||
).await
|
)
|
||||||
|
.await
|
||||||
})
|
})
|
||||||
.unwrap();
|
.expect("Could not register RPC method buy_xmr");
|
||||||
module
|
module
|
||||||
.register_async_method("list_sellers", |params, context| async move {
|
.register_async_method("list_sellers", |params, context| async move {
|
||||||
let params: HashMap<String, Multiaddr> = params.parse()?;
|
let params: HashMap<String, Multiaddr> = params.parse()?;
|
||||||
let rendezvous_point = params.get("rendezvous_point").ok_or_else(|| {
|
let rendezvous_point = params.get("rendezvous_point").ok_or_else(|| {
|
||||||
jsonrpsee_core::Error::Custom("Does not contain rendezvous_point".to_string())
|
jsonrpsee_core::Error::Custom("Does not contain rendezvous_point".to_string())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
list_sellers(rendezvous_point.clone(), &context).await
|
list_sellers(rendezvous_point.clone(), &context).await
|
||||||
})
|
})
|
||||||
.unwrap();
|
.expect("Could not register RPC method list_sellers");
|
||||||
module
|
module
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_bitcoin_balance(context: &Arc<Context>) -> Result<serde_json::Value, jsonrpsee_core::Error> {
|
async fn get_bitcoin_balance(
|
||||||
|
context: &Arc<Context>,
|
||||||
|
) -> Result<serde_json::Value, jsonrpsee_core::Error> {
|
||||||
let mut request = Request {
|
let mut request = Request {
|
||||||
params: Params::default(),
|
params: Params::default(),
|
||||||
cmd: Method::Balance,
|
cmd: Method::Balance,
|
||||||
shutdown: Shutdown::new(context.shutdown.subscribe()),
|
shutdown: Shutdown::new(context.shutdown.subscribe()),
|
||||||
};
|
};
|
||||||
let balance = request.call(Arc::clone(context))
|
let balance = request
|
||||||
|
.call(Arc::clone(context))
|
||||||
.await
|
.await
|
||||||
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
||||||
|
|
||||||
@ -156,19 +164,23 @@ async fn get_history(context: &Arc<Context>) -> Result<serde_json::Value, jsonrp
|
|||||||
cmd: Method::History,
|
cmd: Method::History,
|
||||||
shutdown: Shutdown::new(context.shutdown.subscribe()),
|
shutdown: Shutdown::new(context.shutdown.subscribe()),
|
||||||
};
|
};
|
||||||
let history = request.call(Arc::clone(context))
|
let history = request
|
||||||
|
.call(Arc::clone(context))
|
||||||
.await
|
.await
|
||||||
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
||||||
|
|
||||||
Ok(history)
|
Ok(history)
|
||||||
}
|
}
|
||||||
async fn get_raw_history(context: &Arc<Context>) -> Result<serde_json::Value, jsonrpsee_core::Error> {
|
async fn get_raw_history(
|
||||||
|
context: &Arc<Context>,
|
||||||
|
) -> Result<serde_json::Value, jsonrpsee_core::Error> {
|
||||||
let mut request = Request {
|
let mut request = Request {
|
||||||
params: Params::default(),
|
params: Params::default(),
|
||||||
cmd: Method::RawHistory,
|
cmd: Method::RawHistory,
|
||||||
shutdown: Shutdown::new(context.shutdown.subscribe()),
|
shutdown: Shutdown::new(context.shutdown.subscribe()),
|
||||||
};
|
};
|
||||||
let history = request.call(Arc::clone(context))
|
let history = request
|
||||||
|
.call(Arc::clone(context))
|
||||||
.await
|
.await
|
||||||
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
||||||
|
|
||||||
@ -177,7 +189,7 @@ async fn get_raw_history(context: &Arc<Context>) -> Result<serde_json::Value, js
|
|||||||
|
|
||||||
async fn get_seller(
|
async fn get_seller(
|
||||||
swap_id: Uuid,
|
swap_id: Uuid,
|
||||||
context: &Arc<Context>
|
context: &Arc<Context>,
|
||||||
) -> Result<serde_json::Value, jsonrpsee_core::Error> {
|
) -> Result<serde_json::Value, jsonrpsee_core::Error> {
|
||||||
let mut request = Request {
|
let mut request = Request {
|
||||||
params: Params {
|
params: Params {
|
||||||
@ -187,7 +199,8 @@ async fn get_seller(
|
|||||||
cmd: Method::GetSeller,
|
cmd: Method::GetSeller,
|
||||||
shutdown: Shutdown::new(context.shutdown.subscribe()),
|
shutdown: Shutdown::new(context.shutdown.subscribe()),
|
||||||
};
|
};
|
||||||
let result = request.call(Arc::clone(context))
|
let result = request
|
||||||
|
.call(Arc::clone(context))
|
||||||
.await
|
.await
|
||||||
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
||||||
|
|
||||||
@ -196,7 +209,7 @@ async fn get_seller(
|
|||||||
|
|
||||||
async fn get_swap_start_date(
|
async fn get_swap_start_date(
|
||||||
swap_id: Uuid,
|
swap_id: Uuid,
|
||||||
context: &Arc<Context>
|
context: &Arc<Context>,
|
||||||
) -> Result<serde_json::Value, jsonrpsee_core::Error> {
|
) -> Result<serde_json::Value, jsonrpsee_core::Error> {
|
||||||
let mut request = Request {
|
let mut request = Request {
|
||||||
params: Params {
|
params: Params {
|
||||||
@ -206,7 +219,8 @@ async fn get_swap_start_date(
|
|||||||
cmd: Method::SwapStartDate,
|
cmd: Method::SwapStartDate,
|
||||||
shutdown: Shutdown::new(context.shutdown.subscribe()),
|
shutdown: Shutdown::new(context.shutdown.subscribe()),
|
||||||
};
|
};
|
||||||
let result = request.call(Arc::clone(context))
|
let result = request
|
||||||
|
.call(Arc::clone(context))
|
||||||
.await
|
.await
|
||||||
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
||||||
|
|
||||||
@ -226,7 +240,8 @@ async fn resume_swap(
|
|||||||
shutdown: Shutdown::new(context.shutdown.subscribe()),
|
shutdown: Shutdown::new(context.shutdown.subscribe()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = request.call(Arc::clone(context))
|
let result = request
|
||||||
|
.call(Arc::clone(context))
|
||||||
.await
|
.await
|
||||||
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
||||||
Ok(result)
|
Ok(result)
|
||||||
@ -245,7 +260,8 @@ async fn withdraw_btc(
|
|||||||
cmd: Method::WithdrawBtc,
|
cmd: Method::WithdrawBtc,
|
||||||
shutdown: Shutdown::new(context.shutdown.subscribe()),
|
shutdown: Shutdown::new(context.shutdown.subscribe()),
|
||||||
};
|
};
|
||||||
let result = request.call(Arc::clone(context))
|
let result = request
|
||||||
|
.call(Arc::clone(context))
|
||||||
.await
|
.await
|
||||||
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
||||||
Ok(result)
|
Ok(result)
|
||||||
@ -267,7 +283,8 @@ async fn buy_xmr(
|
|||||||
cmd: Method::BuyXmr,
|
cmd: Method::BuyXmr,
|
||||||
shutdown: Shutdown::new(context.shutdown.subscribe()),
|
shutdown: Shutdown::new(context.shutdown.subscribe()),
|
||||||
};
|
};
|
||||||
let swap = request.call(Arc::clone(context))
|
let swap = request
|
||||||
|
.call(Arc::clone(context))
|
||||||
.await
|
.await
|
||||||
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
||||||
Ok(swap)
|
Ok(swap)
|
||||||
@ -285,7 +302,8 @@ async fn list_sellers(
|
|||||||
cmd: Method::ListSellers,
|
cmd: Method::ListSellers,
|
||||||
shutdown: Shutdown::new(context.shutdown.subscribe()),
|
shutdown: Shutdown::new(context.shutdown.subscribe()),
|
||||||
};
|
};
|
||||||
let result = request.call(Arc::clone(context))
|
let result = request
|
||||||
|
.call(Arc::clone(context))
|
||||||
.await
|
.await
|
||||||
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
.map_err(|err| jsonrpsee_core::Error::Custom(err.to_string()))?;
|
||||||
Ok(result)
|
Ok(result)
|
||||||
|
@ -61,7 +61,7 @@ impl Seed {
|
|||||||
let file_path = Path::new(&file_path_buf);
|
let file_path = Path::new(&file_path_buf);
|
||||||
|
|
||||||
if file_path.exists() {
|
if file_path.exists() {
|
||||||
return Self::from_file(&file_path);
|
return Self::from_file(file_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
tracing::debug!("No seed file found, creating at {}", file_path.display());
|
tracing::debug!("No seed file found, creating at {}", file_path.display());
|
||||||
|
@ -1,37 +1,39 @@
|
|||||||
use testcontainers::clients::Cli;
|
|
||||||
use testcontainers::{Container, Docker, RunArgs};
|
|
||||||
use anyhow::{bail, Context as AnyContext, Result};
|
use anyhow::{bail, Context as AnyContext, Result};
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
use swap::api::{Context, Config};
|
|
||||||
use swap::api::request::{Request, Params, Method, Shutdown};
|
|
||||||
use std::sync::Arc;
|
|
||||||
use tokio::time::{interval, timeout};
|
|
||||||
use std::time::Duration;
|
|
||||||
use jsonrpsee::ws_client::WsClientBuilder;
|
use jsonrpsee::ws_client::WsClientBuilder;
|
||||||
use jsonrpsee_core::{client::ClientT, params::ObjectParams};
|
|
||||||
use jsonrpsee::{rpc_params, RpcModule};
|
use jsonrpsee::{rpc_params, RpcModule};
|
||||||
|
use jsonrpsee_core::client::ClientT;
|
||||||
|
use jsonrpsee_core::params::ObjectParams;
|
||||||
use jsonrpsee_types::error::CallError;
|
use jsonrpsee_types::error::CallError;
|
||||||
use tokio::sync::broadcast;
|
|
||||||
use swap::cli::command::{Bitcoin, Monero};
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use uuid::Uuid;
|
|
||||||
use serde_json::{json, Value};
|
|
||||||
use sequential_test::sequential;
|
use sequential_test::sequential;
|
||||||
|
use serde_json::{json, Value};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::time::Duration;
|
||||||
|
use swap::api::request::{Method, Params, Request, Shutdown};
|
||||||
|
use swap::api::{Config, Context};
|
||||||
|
use swap::cli::command::{Bitcoin, Monero};
|
||||||
|
use testcontainers::clients::Cli;
|
||||||
|
use testcontainers::{Container, Docker, RunArgs};
|
||||||
|
use tokio::sync::broadcast;
|
||||||
|
use tokio::time::{interval, timeout};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
||||||
|
|
||||||
// to be replaced with actual "real" testing values
|
// to be replaced with actual "real" testing values
|
||||||
// need to create some kind of swap database and bitcoin environment with some funds
|
// need to create some kind of swap database and bitcoin environment with some
|
||||||
|
// funds
|
||||||
const SERVER_ADDRESS: &str = "127.0.0.1:1234";
|
const SERVER_ADDRESS: &str = "127.0.0.1:1234";
|
||||||
const BITCOIN_ADDR: &str = "tb1qr3em6k3gfnyl8r7q0v7t4tlnyxzgxma3lressv";
|
const BITCOIN_ADDR: &str = "tb1qr3em6k3gfnyl8r7q0v7t4tlnyxzgxma3lressv";
|
||||||
const MONERO_ADDR: &str = "53gEuGZUhP9JMEBZoGaFNzhwEgiG7hwQdMCqFxiyiTeFPmkbt1mAoNybEUvYBKHcnrSgxnVWgZsTvRBaHBNXPa8tHiCU51a";
|
const MONERO_ADDR: &str = "53gEuGZUhP9JMEBZoGaFNzhwEgiG7hwQdMCqFxiyiTeFPmkbt1mAoNybEUvYBKHcnrSgxnVWgZsTvRBaHBNXPa8tHiCU51a";
|
||||||
const SELLER: &str = "/ip4/127.0.0.1/tcp/9939/p2p/12D3KooWCdMKjesXMJz1SiZ7HgotrxuqhQJbP5sgBm2BwP1cqThi";
|
const SELLER: &str =
|
||||||
|
"/ip4/127.0.0.1/tcp/9939/p2p/12D3KooWCdMKjesXMJz1SiZ7HgotrxuqhQJbP5sgBm2BwP1cqThi";
|
||||||
const SWAP_ID: &str = "ea030832-3be9-454f-bb98-5ea9a788406b";
|
const SWAP_ID: &str = "ea030832-3be9-454f-bb98-5ea9a788406b";
|
||||||
|
|
||||||
pub async fn initialize_context() -> (Arc<Context>, Request) {
|
pub async fn initialize_context() -> (Arc<Context>, Request) {
|
||||||
let (is_testnet, debug, json) = (true, false, false);
|
let (is_testnet, debug, json) = (true, false, false);
|
||||||
//let data_dir = data::data_dir_from(None, is_testnet).unwrap();
|
// let data_dir = data::data_dir_from(None, is_testnet).unwrap();
|
||||||
let server_address = None;
|
let server_address = None;
|
||||||
let (tx, _) = broadcast::channel(1);
|
let (tx, _) = broadcast::channel(1);
|
||||||
|
|
||||||
@ -60,12 +62,13 @@ pub async fn initialize_context() -> (Arc<Context>, Request) {
|
|||||||
json,
|
json,
|
||||||
server_address,
|
server_address,
|
||||||
tx,
|
tx,
|
||||||
).await.unwrap();
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
(Arc::new(context), request)
|
(Arc::new(context), request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[sequential]
|
#[sequential]
|
||||||
pub async fn can_start_server() {
|
pub async fn can_start_server() {
|
||||||
@ -92,7 +95,10 @@ pub async fn get_bitcoin_balance() {
|
|||||||
tokio::time::sleep(Duration::from_secs(3)).await;
|
tokio::time::sleep(Duration::from_secs(3)).await;
|
||||||
|
|
||||||
let client = WsClientBuilder::default().build(&url).await.unwrap();
|
let client = WsClientBuilder::default().build(&url).await.unwrap();
|
||||||
let response: HashMap<String, i32> = client.request("get_bitcoin_balance", rpc_params!["id"]).await.unwrap();
|
let response: HashMap<String, i32> = client
|
||||||
|
.request("get_bitcoin_balance", rpc_params!["id"])
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(response, HashMap::from([("balance".to_string(), 0)]));
|
assert_eq!(response, HashMap::from([("balance".to_string(), 0)]));
|
||||||
ctx.shutdown.send(());
|
ctx.shutdown.send(());
|
||||||
@ -113,7 +119,8 @@ pub async fn get_history() {
|
|||||||
let client = WsClientBuilder::default().build(&url).await.unwrap();
|
let client = WsClientBuilder::default().build(&url).await.unwrap();
|
||||||
let mut params = ObjectParams::new();
|
let mut params = ObjectParams::new();
|
||||||
|
|
||||||
let response: HashMap<String, Vec<(Uuid, String)>> = client.request("get_history", params).await.unwrap();
|
let response: HashMap<String, Vec<(Uuid, String)>> =
|
||||||
|
client.request("get_history", params).await.unwrap();
|
||||||
let swaps: Vec<(Uuid, String)> = Vec::new();
|
let swaps: Vec<(Uuid, String)> = Vec::new();
|
||||||
|
|
||||||
assert_eq!(response, HashMap::from([("swaps".to_string(), swaps)]));
|
assert_eq!(response, HashMap::from([("swaps".to_string(), swaps)]));
|
||||||
@ -136,9 +143,13 @@ pub async fn get_raw_history() {
|
|||||||
let mut params = ObjectParams::new();
|
let mut params = ObjectParams::new();
|
||||||
let raw_history: HashMap<Uuid, String> = HashMap::new();
|
let raw_history: HashMap<Uuid, String> = HashMap::new();
|
||||||
|
|
||||||
let response: HashMap<String, HashMap<Uuid, String>> = client.request("get_raw_history", params).await.unwrap();
|
let response: HashMap<String, HashMap<Uuid, String>> =
|
||||||
|
client.request("get_raw_history", params).await.unwrap();
|
||||||
|
|
||||||
assert_eq!(response, HashMap::from([("raw_history".to_string(), raw_history)]));
|
assert_eq!(
|
||||||
|
response,
|
||||||
|
HashMap::from([("raw_history".to_string(), raw_history)])
|
||||||
|
);
|
||||||
ctx.shutdown.send(());
|
ctx.shutdown.send(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +170,8 @@ pub async fn get_seller() {
|
|||||||
|
|
||||||
let response: Result<HashMap<String, String>, _> = client.request("get_seller", params).await;
|
let response: Result<HashMap<String, String>, _> = client.request("get_seller", params).await;
|
||||||
|
|
||||||
// We should ideally match the expected error and panic if it's different one, but the request returns a custom error (to investigate)
|
// We should ideally match the expected error and panic if it's different one,
|
||||||
|
// but the request returns a custom error (to investigate)
|
||||||
// Err(jsonrpsee_core::Error::Call(CallError::InvalidParams(e))) => (),
|
// Err(jsonrpsee_core::Error::Call(CallError::InvalidParams(e))) => (),
|
||||||
// Err(e) => panic!("ErrorType was not ParseError but {e:?}"),
|
// Err(e) => panic!("ErrorType was not ParseError but {e:?}"),
|
||||||
|
|
||||||
@ -185,7 +197,10 @@ pub async fn get_seller() {
|
|||||||
|
|
||||||
match response {
|
match response {
|
||||||
Ok(hash) => (),
|
Ok(hash) => (),
|
||||||
Err(e) => panic!("Expected a HashMap with correct params, got an error: {}", e),
|
Err(e) => panic!(
|
||||||
|
"Expected a HashMap with correct params, got an error: {}",
|
||||||
|
e
|
||||||
|
),
|
||||||
}
|
}
|
||||||
ctx.shutdown.send(());
|
ctx.shutdown.send(());
|
||||||
}
|
}
|
||||||
@ -205,7 +220,8 @@ pub async fn get_swap_start_date() {
|
|||||||
let client = WsClientBuilder::default().build(&url).await.unwrap();
|
let client = WsClientBuilder::default().build(&url).await.unwrap();
|
||||||
let mut params = ObjectParams::new();
|
let mut params = ObjectParams::new();
|
||||||
|
|
||||||
let response: Result<HashMap<String, String>, _> = client.request("get_swap_start_date", params).await;
|
let response: Result<HashMap<String, String>, _> =
|
||||||
|
client.request("get_swap_start_date", params).await;
|
||||||
|
|
||||||
match response {
|
match response {
|
||||||
Err(e) => (),
|
Err(e) => (),
|
||||||
@ -215,7 +231,8 @@ pub async fn get_swap_start_date() {
|
|||||||
let mut params = ObjectParams::new();
|
let mut params = ObjectParams::new();
|
||||||
params.insert("swap_id", "invalid_swap");
|
params.insert("swap_id", "invalid_swap");
|
||||||
|
|
||||||
let response: Result<HashMap<String, String>, _> = client.request("get_swap_start_date", params).await;
|
let response: Result<HashMap<String, String>, _> =
|
||||||
|
client.request("get_swap_start_date", params).await;
|
||||||
|
|
||||||
match response {
|
match response {
|
||||||
Err(e) => (),
|
Err(e) => (),
|
||||||
@ -225,7 +242,8 @@ pub async fn get_swap_start_date() {
|
|||||||
let mut params = ObjectParams::new();
|
let mut params = ObjectParams::new();
|
||||||
params.insert("swap_id", SWAP_ID);
|
params.insert("swap_id", SWAP_ID);
|
||||||
|
|
||||||
let response: Result<HashMap<String, String>, _> = client.request("get_swap_start_date", params).await;
|
let response: Result<HashMap<String, String>, _> =
|
||||||
|
client.request("get_swap_start_date", params).await;
|
||||||
|
|
||||||
match response {
|
match response {
|
||||||
Ok(hash) => (),
|
Ok(hash) => (),
|
||||||
@ -249,7 +267,8 @@ pub async fn resume_swap() {
|
|||||||
let client = WsClientBuilder::default().build(&url).await.unwrap();
|
let client = WsClientBuilder::default().build(&url).await.unwrap();
|
||||||
let mut params = ObjectParams::new();
|
let mut params = ObjectParams::new();
|
||||||
|
|
||||||
let response: Result<HashMap<String, String>, _> = client.request("get_swap_start_date", params).await;
|
let response: Result<HashMap<String, String>, _> =
|
||||||
|
client.request("get_swap_start_date", params).await;
|
||||||
|
|
||||||
match response {
|
match response {
|
||||||
Err(e) => (),
|
Err(e) => (),
|
||||||
@ -259,7 +278,8 @@ pub async fn resume_swap() {
|
|||||||
let mut params = ObjectParams::new();
|
let mut params = ObjectParams::new();
|
||||||
params.insert("swap_id", "invalid_swap");
|
params.insert("swap_id", "invalid_swap");
|
||||||
|
|
||||||
let response: Result<HashMap<String, String>, _> = client.request("get_swap_start_date", params).await;
|
let response: Result<HashMap<String, String>, _> =
|
||||||
|
client.request("get_swap_start_date", params).await;
|
||||||
|
|
||||||
match response {
|
match response {
|
||||||
Err(e) => (),
|
Err(e) => (),
|
||||||
@ -269,7 +289,8 @@ pub async fn resume_swap() {
|
|||||||
let mut params = ObjectParams::new();
|
let mut params = ObjectParams::new();
|
||||||
params.insert("swap_id", SWAP_ID);
|
params.insert("swap_id", SWAP_ID);
|
||||||
|
|
||||||
let response: Result<HashMap<String, String>, _> = client.request("get_swap_start_date", params).await;
|
let response: Result<HashMap<String, String>, _> =
|
||||||
|
client.request("get_swap_start_date", params).await;
|
||||||
|
|
||||||
match response {
|
match response {
|
||||||
Ok(hash) => (),
|
Ok(hash) => (),
|
||||||
|
Loading…
Reference in New Issue
Block a user