wowario 3 years ago
parent 4212504941
commit af0c7c5df8
No known key found for this signature in database
GPG Key ID: 24DCBE762DE9C111

@ -3,7 +3,7 @@ name = "swap"
version = "0.8.1" version = "0.8.1"
authors = [ "The COMIT guys <hello@comit.network>" ] authors = [ "The COMIT guys <hello@comit.network>" ]
edition = "2018" edition = "2018"
description = "XMR/BTC trustless atomic swaps." description = "WOW/BTC trustless atomic swaps."
[lib] [lib]
name = "swap" name = "swap"
@ -32,8 +32,8 @@ futures = { version = "0.3", default-features = false }
itertools = "0.10" itertools = "0.10"
libp2p = { git = "https://github.com/comit-network/rust-libp2p", branch = "rendezvous", default-features = false, features = [ "tcp-tokio", "yamux", "mplex", "dns-tokio", "noise", "request-response", "websocket", "ping", "rendezvous" ] } libp2p = { git = "https://github.com/comit-network/rust-libp2p", branch = "rendezvous", default-features = false, features = [ "tcp-tokio", "yamux", "mplex", "dns-tokio", "noise", "request-response", "websocket", "ping", "rendezvous" ] }
miniscript = { version = "5", features = [ "serde" ] } miniscript = { version = "5", features = [ "serde" ] }
monero = { version = "0.12", features = [ "serde_support" ] } wownero = { version = "0.12", features = [ "serde_support" ] }
monero-rpc = { path = "../monero-rpc" } wownero-rpc = { path = "../wownero-rpc" }
pem = "0.8" pem = "0.8"
proptest = "1" proptest = "1"
qrcode = "0.12" qrcode = "0.12"
@ -78,7 +78,7 @@ bdk-testutils = { version = "0.4" }
bitcoin-harness = { git = "https://github.com/coblox/bitcoin-harness-rs" } bitcoin-harness = { git = "https://github.com/coblox/bitcoin-harness-rs" }
get-port = "3" get-port = "3"
hyper = "0.14" hyper = "0.14"
monero-harness = { path = "../monero-harness" } wownero-harness = { path = "../wownero-harness" }
port_check = "0.1" port_check = "0.1"
proptest = "1" proptest = "1"
serde_cbor = "0.11" serde_cbor = "0.11"

@ -199,7 +199,7 @@ pub enum Command {
#[derive(structopt::StructOpt, Debug)] #[derive(structopt::StructOpt, Debug)]
#[structopt( #[structopt(
name = "asb", name = "asb",
about = "Automated Swap Backend for swapping XMR for BTC", about = "Automated Swap Backend for swapping WOW for BTC",
author, author,
version = env!("VERGEN_GIT_SEMVER_LIGHTWEIGHT") version = env!("VERGEN_GIT_SEMVER_LIGHTWEIGHT")
)] )]
@ -226,7 +226,7 @@ pub struct RawArguments {
} }
#[derive(structopt::StructOpt, Debug)] #[derive(structopt::StructOpt, Debug)]
#[structopt(name = "xmr_btc-swap", about = "XMR BTC atomic swap")] #[structopt(name = "wow_btc-swap", about = "WOW BTC atomic swap")]
pub enum RawCommand { pub enum RawCommand {
#[structopt(about = "Main command to run the ASB.")] #[structopt(about = "Main command to run the ASB.")]
Start { Start {
@ -249,7 +249,7 @@ pub enum RawCommand {
address: Address, address: Address,
}, },
#[structopt( #[structopt(
about = "Prints the Bitcoin and Monero balance. Requires the monero-wallet-rpc to be running." about = "Prints the Bitcoin and Wownero balance. Requires the wownero-wallet-rpc to be running."
)] )]
Balance, Balance,
#[structopt(about = "Contains sub-commands for recovering a swap manually.")] #[structopt(about = "Contains sub-commands for recovering a swap manually.")]
@ -279,7 +279,7 @@ pub enum ManualRecovery {
cancel_params: RecoverCommandParams, cancel_params: RecoverCommandParams,
}, },
#[structopt( #[structopt(
about = "Publishes the Monero refund transaction. By default, a swap-state where the cancel transaction was already published will be enforced. This command requires the counterparty Bitcoin refund transaction and will error if it was not published yet. " about = "Publishes the Wownero refund transaction. By default, a swap-state where the cancel transaction was already published will be enforced. This command requires the counterparty Bitcoin refund transaction and will error if it was not published yet. "
)] )]
Refund { Refund {
#[structopt(flatten)] #[structopt(flatten)]
@ -292,7 +292,7 @@ pub enum ManualRecovery {
#[structopt(flatten)] #[structopt(flatten)]
punish_params: RecoverCommandParams, punish_params: RecoverCommandParams,
}, },
#[structopt(about = "Safely Abort requires the swap to be in a state prior to locking XMR.")] #[structopt(about = "Safely Abort requires the swap to be in a state prior to locking WOW.")]
SafelyAbort { SafelyAbort {
#[structopt( #[structopt(
long = "swap-id", long = "swap-id",

@ -25,7 +25,7 @@ pub struct Defaults {
listen_address_tcp: Multiaddr, listen_address_tcp: Multiaddr,
listen_address_ws: Multiaddr, listen_address_ws: Multiaddr,
electrum_rpc_url: Url, electrum_rpc_url: Url,
monero_wallet_rpc_url: Url, wownero_wallet_rpc_url: Url,
price_ticker_ws_url: Url, price_ticker_ws_url: Url,
bitcoin_confirmation_target: usize, bitcoin_confirmation_target: usize,
} }
@ -40,7 +40,7 @@ impl GetDefaults for Testnet {
listen_address_tcp: Multiaddr::from_str("/ip4/0.0.0.0/tcp/9939")?, listen_address_tcp: Multiaddr::from_str("/ip4/0.0.0.0/tcp/9939")?,
listen_address_ws: Multiaddr::from_str("/ip4/0.0.0.0/tcp/9940/ws")?, listen_address_ws: Multiaddr::from_str("/ip4/0.0.0.0/tcp/9940/ws")?,
electrum_rpc_url: Url::parse("ssl://electrum.blockstream.info:60002")?, electrum_rpc_url: Url::parse("ssl://electrum.blockstream.info:60002")?,
monero_wallet_rpc_url: Url::parse("http://127.0.0.1:38083/json_rpc")?, wownero_wallet_rpc_url: Url::parse("http://127.0.0.1:38083/json_rpc")?,
price_ticker_ws_url: Url::parse("wss://ws.kraken.com")?, price_ticker_ws_url: Url::parse("wss://ws.kraken.com")?,
bitcoin_confirmation_target: 1, bitcoin_confirmation_target: 1,
}; };
@ -59,7 +59,7 @@ impl GetDefaults for Mainnet {
listen_address_tcp: Multiaddr::from_str("/ip4/0.0.0.0/tcp/9939")?, listen_address_tcp: Multiaddr::from_str("/ip4/0.0.0.0/tcp/9939")?,
listen_address_ws: Multiaddr::from_str("/ip4/0.0.0.0/tcp/9940/ws")?, listen_address_ws: Multiaddr::from_str("/ip4/0.0.0.0/tcp/9940/ws")?,
electrum_rpc_url: Url::parse("ssl://electrum.blockstream.info:50002")?, electrum_rpc_url: Url::parse("ssl://electrum.blockstream.info:50002")?,
monero_wallet_rpc_url: Url::parse("http://127.0.0.1:18083/json_rpc")?, wownero_wallet_rpc_url: Url::parse("http://127.0.0.1:18083/json_rpc")?,
price_ticker_ws_url: Url::parse("wss://ws.kraken.com")?, price_ticker_ws_url: Url::parse("wss://ws.kraken.com")?,
bitcoin_confirmation_target: 3, bitcoin_confirmation_target: 3,
}; };
@ -90,7 +90,7 @@ pub struct Config {
pub data: Data, pub data: Data,
pub network: Network, pub network: Network,
pub bitcoin: Bitcoin, pub bitcoin: Bitcoin,
pub monero: Monero, pub wownero: Wownero,
pub tor: TorConf, pub tor: TorConf,
pub maker: Maker, pub maker: Maker,
} }
@ -136,11 +136,11 @@ pub struct Bitcoin {
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
pub struct Monero { pub struct Wownero {
pub wallet_rpc_url: Url, pub wallet_rpc_url: Url,
pub finality_confirmations: Option<u64>, pub finality_confirmations: Option<u64>,
#[serde(with = "crate::monero::network")] #[serde(with = "crate::wownero::network")]
pub network: monero::Network, pub network: wownero::Network,
} }
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
@ -204,21 +204,21 @@ pub fn initial_setup(config_path: PathBuf, config: Config) -> Result<()> {
} }
pub fn query_user_for_initial_config(testnet: bool) -> Result<Config> { pub fn query_user_for_initial_config(testnet: bool) -> Result<Config> {
let (bitcoin_network, monero_network, defaults) = if testnet { let (bitcoin_network, wownero_network, defaults) = if testnet {
tracing::info!("Running initial setup for testnet"); tracing::info!("Running initial setup for testnet");
let bitcoin_network = bitcoin::Network::Testnet; let bitcoin_network = bitcoin::Network::Testnet;
let monero_network = monero::Network::Stagenet; let wownero_network = wownero::Network::Stagenet;
let defaults = Testnet::getConfigFileDefaults()?; let defaults = Testnet::getConfigFileDefaults()?;
(bitcoin_network, monero_network, defaults) (bitcoin_network, wownero_network, defaults)
} else { } else {
tracing::info!("Running initial setup for mainnet"); tracing::info!("Running initial setup for mainnet");
let bitcoin_network = bitcoin::Network::Bitcoin; let bitcoin_network = bitcoin::Network::Bitcoin;
let monero_network = monero::Network::Mainnet; let wownero_network = wownero::Network::Mainnet;
let defaults = Mainnet::getConfigFileDefaults()?; let defaults = Mainnet::getConfigFileDefaults()?;
(bitcoin_network, monero_network, defaults) (bitcoin_network, wownero_network, defaults)
}; };
println!(); println!();
@ -253,9 +253,9 @@ pub fn query_user_for_initial_config(testnet: bool) -> Result<Config> {
.default(defaults.electrum_rpc_url) .default(defaults.electrum_rpc_url)
.interact_text()?; .interact_text()?;
let monero_wallet_rpc_url = Input::with_theme(&ColorfulTheme::default()) let wownero_wallet_rpc_url = Input::with_theme(&ColorfulTheme::default())
.with_prompt("Enter Monero Wallet RPC URL or hit enter to use default") .with_prompt("Enter Wownero Wallet RPC URL or hit enter to use default")
.default(defaults.monero_wallet_rpc_url) .default(defaults.wownero_wallet_rpc_url)
.interact_text()?; .interact_text()?;
let tor_control_port = Input::with_theme(&ColorfulTheme::default()) let tor_control_port = Input::with_theme(&ColorfulTheme::default())
@ -313,10 +313,10 @@ pub fn query_user_for_initial_config(testnet: bool) -> Result<Config> {
finality_confirmations: None, finality_confirmations: None,
network: bitcoin_network, network: bitcoin_network,
}, },
monero: Monero { wownero: Wownero {
wallet_rpc_url: monero_wallet_rpc_url, wallet_rpc_url: wownero_wallet_rpc_url,
finality_confirmations: None, finality_confirmations: None,
network: monero_network, network: wownero_network,
}, },
tor: TorConf { tor: TorConf {
control_port: tor_control_port, control_port: tor_control_port,
@ -359,10 +359,10 @@ mod tests {
external_addresses: vec![], external_addresses: vec![],
}, },
monero: Monero { wownero: Wownero {
wallet_rpc_url: defaults.monero_wallet_rpc_url, wallet_rpc_url: defaults.wownero_wallet_rpc_url,
finality_confirmations: None, finality_confirmations: None,
network: monero::Network::Stagenet, network: wownero::Network::Stagenet,
}, },
tor: Default::default(), tor: Default::default(),
maker: Maker { maker: Maker {
@ -402,10 +402,10 @@ mod tests {
external_addresses: vec![], external_addresses: vec![],
}, },
monero: Monero { wownero: Wownero {
wallet_rpc_url: defaults.monero_wallet_rpc_url, wallet_rpc_url: defaults.wownero_wallet_rpc_url,
finality_confirmations: None, finality_confirmations: None,
network: monero::Network::Mainnet, network: wownero::Network::Mainnet,
}, },
tor: Default::default(), tor: Default::default(),
maker: Maker { maker: Maker {

@ -4,7 +4,7 @@ use crate::network::quote::BidQuote;
use crate::network::swap_setup::alice::WalletSnapshot; use crate::network::swap_setup::alice::WalletSnapshot;
use crate::network::transfer_proof; use crate::network::transfer_proof;
use crate::protocol::alice::{AliceState, State3, Swap}; use crate::protocol::alice::{AliceState, State3, Swap};
use crate::{bitcoin, env, kraken, monero}; use crate::{bitcoin, env, kraken, wownero};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use futures::future; use futures::future;
use futures::future::{BoxFuture, FutureExt}; use futures::future::{BoxFuture, FutureExt};
@ -38,7 +38,7 @@ where
swarm: libp2p::Swarm<Behaviour<LR>>, swarm: libp2p::Swarm<Behaviour<LR>>,
env_config: env::Config, env_config: env::Config,
bitcoin_wallet: Arc<bitcoin::Wallet>, bitcoin_wallet: Arc<bitcoin::Wallet>,
monero_wallet: Arc<monero::Wallet>, wownero_wallet: Arc<wownero::Wallet>,
db: Arc<Database>, db: Arc<Database>,
latest_rate: LR, latest_rate: LR,
min_buy: bitcoin::Amount, min_buy: bitcoin::Amount,
@ -70,7 +70,7 @@ where
swarm: Swarm<Behaviour<LR>>, swarm: Swarm<Behaviour<LR>>,
env_config: env::Config, env_config: env::Config,
bitcoin_wallet: Arc<bitcoin::Wallet>, bitcoin_wallet: Arc<bitcoin::Wallet>,
monero_wallet: Arc<monero::Wallet>, wownero_wallet: Arc<wownero::Wallet>,
db: Arc<Database>, db: Arc<Database>,
latest_rate: LR, latest_rate: LR,
min_buy: bitcoin::Amount, min_buy: bitcoin::Amount,
@ -82,7 +82,7 @@ where
swarm, swarm,
env_config, env_config,
bitcoin_wallet, bitcoin_wallet,
monero_wallet, wownero_wallet,
db, db,
latest_rate, latest_rate,
swap_sender: swap_channel.sender, swap_sender: swap_channel.sender,
@ -130,7 +130,7 @@ where
let swap = Swap { let swap = Swap {
event_loop_handle: handle, event_loop_handle: handle,
bitcoin_wallet: self.bitcoin_wallet.clone(), bitcoin_wallet: self.bitcoin_wallet.clone(),
monero_wallet: self.monero_wallet.clone(), wownero_wallet: self.wownero_wallet.clone(),
env_config: self.env_config, env_config: self.env_config,
db: self.db.clone(), db: self.db.clone(),
state: state.into(), state: state.into(),
@ -159,7 +159,7 @@ where
} }
}; };
let wallet_snapshot = match WalletSnapshot::capture(&self.bitcoin_wallet, &self.monero_wallet, btc).await { let wallet_snapshot = match WalletSnapshot::capture(&self.bitcoin_wallet, &self.wownero_wallet, btc).await {
Ok(wallet_snapshot) => wallet_snapshot, Ok(wallet_snapshot) => wallet_snapshot,
Err(error) => { Err(error) => {
tracing::error!("Swap request will be ignored because we were unable to create wallet snapshot for swap: {:#}", error); tracing::error!("Swap request will be ignored because we were unable to create wallet snapshot for swap: {:#}", error);
@ -341,7 +341,7 @@ where
let swap = Swap { let swap = Swap {
event_loop_handle: handle, event_loop_handle: handle,
bitcoin_wallet: self.bitcoin_wallet.clone(), bitcoin_wallet: self.bitcoin_wallet.clone(),
monero_wallet: self.monero_wallet.clone(), wownero_wallet: self.wownero_wallet.clone(),
env_config: self.env_config, env_config: self.env_config,
db: self.db.clone(), db: self.db.clone(),
state: initial_state, state: initial_state,
@ -461,7 +461,7 @@ impl LatestRate for KrakenRate {
#[derive(Debug)] #[derive(Debug)]
pub struct EventLoopHandle { pub struct EventLoopHandle {
recv_encrypted_signature: Option<bmrng::RequestReceiver<bitcoin::EncryptedSignature, ()>>, recv_encrypted_signature: Option<bmrng::RequestReceiver<bitcoin::EncryptedSignature, ()>>,
send_transfer_proof: Option<bmrng::RequestSender<monero::TransferProof, ()>>, send_transfer_proof: Option<bmrng::RequestSender<wownero::TransferProof, ()>>,
} }
impl EventLoopHandle { impl EventLoopHandle {
@ -480,7 +480,7 @@ impl EventLoopHandle {
Ok(tx_redeem_encsig) Ok(tx_redeem_encsig)
} }
pub async fn send_transfer_proof(&mut self, msg: monero::TransferProof) -> Result<()> { pub async fn send_transfer_proof(&mut self, msg: wownero::TransferProof) -> Result<()> {
self.send_transfer_proof self.send_transfer_proof
.take() .take()
.context("Transfer proof was already sent")? .context("Transfer proof was already sent")?

@ -1,7 +1,7 @@
use crate::asb::event_loop::LatestRate; use crate::asb::event_loop::LatestRate;
use crate::env; use crate::env;
use crate::network::quote::BidQuote; use crate::network::quote::BidQuote;
use crate::network::rendezvous::XmrBtcNamespace; use crate::network::rendezvous::WowBtcNamespace;
use crate::network::swap_setup::alice; use crate::network::swap_setup::alice;
use crate::network::swap_setup::alice::WalletSnapshot; use crate::network::swap_setup::alice::WalletSnapshot;
use crate::network::transport::authenticate_and_multiplex; use crate::network::transport::authenticate_and_multiplex;
@ -98,7 +98,7 @@ pub mod behaviour {
} }
} }
/// A `NetworkBehaviour` that represents an XMR/BTC swap node as Alice. /// A `NetworkBehaviour` that represents an WOW/BTC swap node as Alice.
#[derive(NetworkBehaviour)] #[derive(NetworkBehaviour)]
#[behaviour(out_event = "OutEvent", event_process = false)] #[behaviour(out_event = "OutEvent", event_process = false)]
#[allow(missing_debug_implementations)] #[allow(missing_debug_implementations)]
@ -128,7 +128,7 @@ pub mod behaviour {
latest_rate: LR, latest_rate: LR,
resume_only: bool, resume_only: bool,
env_config: env::Config, env_config: env::Config,
rendezvous_params: Option<(identity::Keypair, PeerId, Multiaddr, XmrBtcNamespace)>, rendezvous_params: Option<(identity::Keypair, PeerId, Multiaddr, WowBtcNamespace)>,
) -> Self { ) -> Self {
Self { Self {
rendezvous: libp2p::swarm::toggle::Toggle::from(rendezvous_params.map( rendezvous: libp2p::swarm::toggle::Toggle::from(rendezvous_params.map(
@ -193,7 +193,7 @@ pub mod rendezous {
inner: libp2p::rendezvous::Rendezvous, inner: libp2p::rendezvous::Rendezvous,
rendezvous_point: Multiaddr, rendezvous_point: Multiaddr,
rendezvous_peer_id: PeerId, rendezvous_peer_id: PeerId,
namespace: XmrBtcNamespace, namespace: WowBtcNamespace,
registration_status: RegistrationStatus, registration_status: RegistrationStatus,
connection_status: ConnectionStatus, connection_status: ConnectionStatus,
registration_ttl: Option<u64>, registration_ttl: Option<u64>,
@ -204,7 +204,7 @@ pub mod rendezous {
identity: identity::Keypair, identity: identity::Keypair,
rendezvous_peer_id: PeerId, rendezvous_peer_id: PeerId,
rendezvous_address: Multiaddr, rendezvous_address: Multiaddr,
namespace: XmrBtcNamespace, namespace: WowBtcNamespace,
registration_ttl: Option<u64>, registration_ttl: Option<u64>,
) -> Self { ) -> Self {
Self { Self {
@ -362,7 +362,7 @@ pub mod rendezous {
identity, identity,
*rendezvous_node.local_peer_id(), *rendezvous_node.local_peer_id(),
rendezvous_address, rendezvous_address,
XmrBtcNamespace::Testnet, WowBtcNamespace::Testnet,
None, None,
) )
}); });
@ -405,7 +405,7 @@ pub mod rendezous {
identity, identity,
*rendezvous_node.local_peer_id(), *rendezvous_node.local_peer_id(),
rendezvous_address, rendezvous_address,
XmrBtcNamespace::Testnet, WowBtcNamespace::Testnet,
Some(5), Some(5),
) )
}); });

@ -1,10 +1,10 @@
use crate::{bitcoin, monero}; use crate::{bitcoin, wownero};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use rust_decimal::prelude::ToPrimitive; use rust_decimal::prelude::ToPrimitive;
use rust_decimal::Decimal; use rust_decimal::Decimal;
use std::fmt::{Debug, Display, Formatter}; use std::fmt::{Debug, Display, Formatter};
/// Represents the rate at which we are willing to trade 1 XMR. /// Represents the rate at which we are willing to trade 1 WOW.
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct Rate { pub struct Rate {
/// Represents the asking price from the market. /// Represents the asking price from the market.
@ -25,7 +25,7 @@ impl Rate {
Self { ask, ask_spread } Self { ask, ask_spread }
} }
/// Computes the asking price at which we are willing to sell 1 XMR. /// Computes the asking price at which we are willing to sell 1 WOW.
/// ///
/// This applies the spread to the market asking price. /// This applies the spread to the market asking price.
pub fn ask(&self) -> Result<bitcoin::Amount> { pub fn ask(&self) -> Result<bitcoin::Amount> {
@ -43,12 +43,12 @@ impl Rate {
} }
/// Calculate a sell quote for a given BTC amount. /// Calculate a sell quote for a given BTC amount.
pub fn sell_quote(&self, quote: bitcoin::Amount) -> Result<monero::Amount> { pub fn sell_quote(&self, quote: bitcoin::Amount) -> Result<wownero::Amount> {
Self::quote(self.ask()?, quote) Self::quote(self.ask()?, quote)
} }
fn quote(rate: bitcoin::Amount, quote: bitcoin::Amount) -> Result<monero::Amount> { fn quote(rate: bitcoin::Amount, quote: bitcoin::Amount) -> Result<wownero::Amount> {
// quote (btc) = rate * base (xmr) // quote (btc) = rate * base (wow)
// base = quote / rate // base = quote / rate
let quote_in_sats = quote.as_sat(); let quote_in_sats = quote.as_sat();
@ -60,16 +60,16 @@ impl Rate {
.checked_div(Decimal::from(bitcoin::Amount::ONE_BTC.as_sat())) .checked_div(Decimal::from(bitcoin::Amount::ONE_BTC.as_sat()))
.context("Division overflow")?; .context("Division overflow")?;
let base_in_xmr = quote_in_btc let base_in_wow = quote_in_btc
.checked_div(rate_in_btc) .checked_div(rate_in_btc)
.context("Division overflow")?; .context("Division overflow")?;
let base_in_piconero = base_in_xmr * Decimal::from(monero::Amount::ONE_XMR.as_piconero()); let base_in_piconero = base_in_wow * Decimal::from(wownero::Amount::ONE_WOW.as_piconero());
let base_in_piconero = base_in_piconero let base_in_piconero = base_in_piconero
.to_u64() .to_u64()
.context("Failed to fit piconero amount into a u64")?; .context("Failed to fit piconero amount into a u64")?;
Ok(monero::Amount::from_piconero(base_in_piconero)) Ok(wownero::Amount::from_piconero(base_in_piconero))
} }
} }
@ -93,9 +93,9 @@ mod tests {
let btc_amount = bitcoin::Amount::from_btc(2.5).unwrap(); let btc_amount = bitcoin::Amount::from_btc(2.5).unwrap();
let xmr_amount = rate.sell_quote(btc_amount).unwrap(); let wow_amount = rate.sell_quote(btc_amount).unwrap();
assert_eq!(xmr_amount, monero::Amount::from_monero(1000.0).unwrap()) assert_eq!(wow_amount, wownero::Amount::from_wownero(1000.0).unwrap())
} }
#[test] #[test]
@ -116,16 +116,16 @@ mod tests {
let rate_no_spread = Rate::new(asking_price, ZERO_SPREAD); let rate_no_spread = Rate::new(asking_price, ZERO_SPREAD);
let rate_with_spread = Rate::new(asking_price, TWO_PERCENT); let rate_with_spread = Rate::new(asking_price, TWO_PERCENT);
let xmr_no_spread = rate_no_spread.sell_quote(bitcoin::Amount::ONE_BTC).unwrap(); let wow_no_spread = rate_no_spread.sell_quote(bitcoin::Amount::ONE_BTC).unwrap();
let xmr_with_spread = rate_with_spread let wow_with_spread = rate_with_spread
.sell_quote(bitcoin::Amount::ONE_BTC) .sell_quote(bitcoin::Amount::ONE_BTC)
.unwrap(); .unwrap();
let xmr_factor = let wow_factor =
xmr_no_spread.as_piconero_decimal() / xmr_with_spread.as_piconero_decimal() - ONE; wow_no_spread.as_piconero_decimal() / wow_with_spread.as_piconero_decimal() - ONE;
assert!(xmr_with_spread < xmr_no_spread); assert!(wow_with_spread < wow_no_spread);
assert_eq!(xmr_factor.round_dp(8), TWO_PERCENT); // round to 8 decimal assert_eq!(wow_factor.round_dp(8), TWO_PERCENT); // round to 8 decimal
// places to show that // places to show that
// it is really close // it is really close
// to two percent // to two percent

@ -19,20 +19,20 @@ pub async fn cancel(
) -> Result<Result<(Txid, AliceState), Error>> { ) -> Result<Result<(Txid, AliceState), Error>> {
let state = db.get_state(swap_id)?.try_into_alice()?.into(); let state = db.get_state(swap_id)?.try_into_alice()?.into();
let (monero_wallet_restore_blockheight, transfer_proof, state3) = match state { let (wownero_wallet_restore_blockheight, transfer_proof, state3) = match state {
// In case no XMR has been locked, move to Safely Aborted // In case no WOW has been locked, move to Safely Aborted
AliceState::Started { .. } AliceState::Started { .. }
| AliceState::BtcLockTransactionSeen { .. } | AliceState::BtcLockTransactionSeen { .. }
| AliceState::BtcLocked { .. } => bail!("Cannot cancel swap {} because it is in state {} where no XMR was locked.", swap_id, state), | AliceState::BtcLocked { .. } => bail!("Cannot cancel swap {} because it is in state {} where no WOW was locked.", swap_id, state),
AliceState::XmrLockTransactionSent { monero_wallet_restore_blockheight, transfer_proof, state3, } AliceState::WowLockTransactionSent { wownero_wallet_restore_blockheight, transfer_proof, state3, }
| AliceState::XmrLocked { monero_wallet_restore_blockheight, transfer_proof, state3 } | AliceState::WowLocked { wownero_wallet_restore_blockheight, transfer_proof, state3 }
| AliceState::XmrLockTransferProofSent { monero_wallet_restore_blockheight, transfer_proof, state3 } | AliceState::WowLockTransferProofSent { wownero_wallet_restore_blockheight, transfer_proof, state3 }
// in cancel mode we do not care about the fact that we could redeem, but always wait for cancellation (leading either refund or punish) // in cancel mode we do not care about the fact that we could redeem, but always wait for cancellation (leading either refund or punish)
| AliceState::EncSigLearned { monero_wallet_restore_blockheight, transfer_proof, state3, .. } | AliceState::EncSigLearned { wownero_wallet_restore_blockheight, transfer_proof, state3, .. }
| AliceState::CancelTimelockExpired { monero_wallet_restore_blockheight, transfer_proof, state3} => { | AliceState::CancelTimelockExpired { wownero_wallet_restore_blockheight, transfer_proof, state3} => {
(monero_wallet_restore_blockheight, transfer_proof, state3) (wownero_wallet_restore_blockheight, transfer_proof, state3)
} }
// The redeem transaction was already published, it is not safe to cancel anymore // The redeem transaction was already published, it is not safe to cancel anymore
@ -45,7 +45,7 @@ pub async fn cancel(
// Alice already in final state // Alice already in final state
| AliceState::BtcRedeemed | AliceState::BtcRedeemed
| AliceState::XmrRefunded | AliceState::WowRefunded
| AliceState::BtcPunished | AliceState::BtcPunished
| AliceState::SafelyAborted => bail!("Swap is is in state {} which is not cancelable", state), | AliceState::SafelyAborted => bail!("Swap is is in state {} which is not cancelable", state),
}; };
@ -69,7 +69,7 @@ pub async fn cancel(
}; };
let state = AliceState::BtcCancelled { let state = AliceState::BtcCancelled {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
}; };

@ -32,15 +32,15 @@ pub async fn punish(
let state3 = if force { let state3 = if force {
match state { match state {
// In case no XMR has been locked, move to Safely Aborted // In case no WOW has been locked, move to Safely Aborted
AliceState::Started { .. } => bail!(Error::NoBtcLocked(state)), AliceState::Started { .. } => bail!(Error::NoBtcLocked(state)),
// Punish potentially possible (no knowledge of cancel transaction) // Punish potentially possible (no knowledge of cancel transaction)
AliceState::BtcLockTransactionSeen { state3 } AliceState::BtcLockTransactionSeen { state3 }
| AliceState::BtcLocked { state3, .. } | AliceState::BtcLocked { state3, .. }
| AliceState::XmrLockTransactionSent {state3, ..} | AliceState::WowLockTransactionSent {state3, ..}
| AliceState::XmrLocked {state3, ..} | AliceState::WowLocked {state3, ..}
| AliceState::XmrLockTransferProofSent {state3, ..} | AliceState::WowLockTransferProofSent {state3, ..}
| AliceState::EncSigLearned {state3, ..} | AliceState::EncSigLearned {state3, ..}
| AliceState::CancelTimelockExpired {state3, ..} | AliceState::CancelTimelockExpired {state3, ..}
@ -55,7 +55,7 @@ pub async fn punish(
| AliceState::BtcRefunded {..} | AliceState::BtcRefunded {..}
// Alice already in final state // Alice already in final state
| AliceState::BtcRedeemed | AliceState::BtcRedeemed
| AliceState::XmrRefunded | AliceState::WowRefunded
| AliceState::BtcPunished | AliceState::BtcPunished
| AliceState::SafelyAborted => bail!(Error::SwapNotPunishable(state)), | AliceState::SafelyAborted => bail!(Error::SwapNotPunishable(state)),
} }
@ -71,7 +71,7 @@ pub async fn punish(
AliceState::BtcRefunded { .. } AliceState::BtcRefunded { .. }
| AliceState::BtcRedeemed | AliceState::BtcRedeemed
| AliceState::XmrRefunded | AliceState::WowRefunded
| AliceState::BtcPunished | AliceState::BtcPunished
| AliceState::SafelyAborted => bail!(Error::SwapNotPunishable(state)), | AliceState::SafelyAborted => bail!(Error::SwapNotPunishable(state)),

@ -86,15 +86,15 @@ pub async fn redeem(
AliceState::Started { .. } AliceState::Started { .. }
| AliceState::BtcLockTransactionSeen { .. } | AliceState::BtcLockTransactionSeen { .. }
| AliceState::BtcLocked { .. } | AliceState::BtcLocked { .. }
| AliceState::XmrLockTransactionSent { .. } | AliceState::WowLockTransactionSent { .. }
| AliceState::XmrLocked { .. } | AliceState::WowLocked { .. }
| AliceState::XmrLockTransferProofSent { .. } | AliceState::WowLockTransferProofSent { .. }
| AliceState::CancelTimelockExpired { .. } | AliceState::CancelTimelockExpired { .. }
| AliceState::BtcCancelled { .. } | AliceState::BtcCancelled { .. }
| AliceState::BtcRefunded { .. } | AliceState::BtcRefunded { .. }
| AliceState::BtcPunishable { .. } | AliceState::BtcPunishable { .. }
| AliceState::BtcRedeemed | AliceState::BtcRedeemed
| AliceState::XmrRefunded | AliceState::WowRefunded
| AliceState::BtcPunished | AliceState::BtcPunished
| AliceState::SafelyAborted => bail!( | AliceState::SafelyAborted => bail!(
"Cannot redeem swap {} because it is in state {} which cannot be manually redeemed", "Cannot redeem swap {} because it is in state {} which cannot be manually redeemed",

@ -1,6 +1,6 @@
use crate::bitcoin::{self}; use crate::bitcoin::{self};
use crate::database::{Database, Swap}; use crate::database::{Database, Swap};
use crate::monero; use crate::wownero;
use crate::protocol::alice::AliceState; use crate::protocol::alice::AliceState;
use anyhow::{bail, Result}; use anyhow::{bail, Result};
use libp2p::PeerId; use libp2p::PeerId;
@ -19,8 +19,8 @@ pub enum Error {
// Errors indicating that the swap cannot be refunded because because it is in a abort/final // Errors indicating that the swap cannot be refunded because because it is in a abort/final
// state // state
#[error("Swap is in state {0} where no XMR was locked. Try aborting instead.")] #[error("Swap is in state {0} where no WOW was locked. Try aborting instead.")]
NoXmrLocked(AliceState), NoWowLocked(AliceState),
#[error("Swap is in state {0} which is not refundable")] #[error("Swap is in state {0} which is not refundable")]
SwapNotRefundable(AliceState), SwapNotRefundable(AliceState),
} }
@ -28,67 +28,67 @@ pub enum Error {
pub async fn refund( pub async fn refund(
swap_id: Uuid, swap_id: Uuid,
bitcoin_wallet: Arc<bitcoin::Wallet>, bitcoin_wallet: Arc<bitcoin::Wallet>,
monero_wallet: Arc<monero::Wallet>, wownero_wallet: Arc<wownero::Wallet>,
db: Arc<Database>, db: Arc<Database>,
force: bool, force: bool,
) -> Result<Result<AliceState, Error>> { ) -> Result<Result<AliceState, Error>> {
let state = db.get_state(swap_id)?.try_into_alice()?.into(); let state = db.get_state(swap_id)?.try_into_alice()?.into();
let (monero_wallet_restore_blockheight, transfer_proof, state3) = if force { let (wownero_wallet_restore_blockheight, transfer_proof, state3) = if force {
match state { match state {
// In case no XMR has been locked, move to Safely Aborted // In case no WOW has been locked, move to Safely Aborted
AliceState::Started { .. } AliceState::Started { .. }
| AliceState::BtcLockTransactionSeen { .. } | AliceState::BtcLockTransactionSeen { .. }
| AliceState::BtcLocked { .. } => bail!(Error::NoXmrLocked(state)), | AliceState::BtcLocked { .. } => bail!(Error::NoWowLocked(state)),
// Refund potentially possible (no knowledge of cancel transaction) // Refund potentially possible (no knowledge of cancel transaction)
AliceState::XmrLockTransactionSent { monero_wallet_restore_blockheight, transfer_proof, state3, } AliceState::WowLockTransactionSent { wownero_wallet_restore_blockheight, transfer_proof, state3, }
| AliceState::XmrLocked { monero_wallet_restore_blockheight, transfer_proof, state3 } | AliceState::WowLocked { wownero_wallet_restore_blockheight, transfer_proof, state3 }
| AliceState::XmrLockTransferProofSent { monero_wallet_restore_blockheight, transfer_proof, state3 } | AliceState::WowLockTransferProofSent { wownero_wallet_restore_blockheight, transfer_proof, state3 }
| AliceState::EncSigLearned { monero_wallet_restore_blockheight, transfer_proof, state3, .. } | AliceState::EncSigLearned { wownero_wallet_restore_blockheight, transfer_proof, state3, .. }
| AliceState::CancelTimelockExpired { monero_wallet_restore_blockheight, transfer_proof, state3 } | AliceState::CancelTimelockExpired { wownero_wallet_restore_blockheight, transfer_proof, state3 }
// Refund possible due to cancel transaction already being published // Refund possible due to cancel transaction already being published
| AliceState::BtcCancelled { monero_wallet_restore_blockheight, transfer_proof, state3 } | AliceState::BtcCancelled { wownero_wallet_restore_blockheight, transfer_proof, state3 }
| AliceState::BtcRefunded { monero_wallet_restore_blockheight, transfer_proof, state3, .. } | AliceState::BtcRefunded { wownero_wallet_restore_blockheight, transfer_proof, state3, .. }
| AliceState::BtcPunishable { monero_wallet_restore_blockheight, transfer_proof, state3, .. } => { | AliceState::BtcPunishable { wownero_wallet_restore_blockheight, transfer_proof, state3, .. } => {
(monero_wallet_restore_blockheight, transfer_proof, state3) (wownero_wallet_restore_blockheight, transfer_proof, state3)
} }
// Alice already in final state // Alice already in final state
AliceState::BtcRedeemTransactionPublished { .. } AliceState::BtcRedeemTransactionPublished { .. }
| AliceState::BtcRedeemed | AliceState::BtcRedeemed
| AliceState::XmrRefunded | AliceState::WowRefunded
| AliceState::BtcPunished | AliceState::BtcPunished
| AliceState::SafelyAborted => bail!(Error::SwapNotRefundable(state)), | AliceState::SafelyAborted => bail!(Error::SwapNotRefundable(state)),
} }
} else { } else {
match state { match state {
AliceState::Started { .. } | AliceState::BtcLocked { .. } => { AliceState::Started { .. } | AliceState::BtcLocked { .. } => {
bail!(Error::NoXmrLocked(state)) bail!(Error::NoWowLocked(state))
} }
AliceState::BtcCancelled { AliceState::BtcCancelled {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} }
| AliceState::BtcRefunded { | AliceState::BtcRefunded {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
.. ..
} }
| AliceState::BtcPunishable { | AliceState::BtcPunishable {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
.. ..
} => (monero_wallet_restore_blockheight, transfer_proof, state3), } => (wownero_wallet_restore_blockheight, transfer_proof, state3),
AliceState::BtcRedeemed AliceState::BtcRedeemed
| AliceState::XmrRefunded | AliceState::WowRefunded
| AliceState::BtcPunished | AliceState::BtcPunished
| AliceState::SafelyAborted => bail!(Error::SwapNotRefundable(state)), | AliceState::SafelyAborted => bail!(Error::SwapNotRefundable(state)),
@ -101,24 +101,24 @@ pub async fn refund(
let spend_key = if let Ok(published_refund_tx) = let spend_key = if let Ok(published_refund_tx) =
state3.fetch_tx_refund(bitcoin_wallet.as_ref()).await state3.fetch_tx_refund(bitcoin_wallet.as_ref()).await
{ {
tracing::debug!(%swap_id, "Bitcoin refund transaction found, extracting key to refund Monero"); tracing::debug!(%swap_id, "Bitcoin refund transaction found, extracting key to refund Wownero");
state3.extract_monero_private_key(published_refund_tx)? state3.extract_wownero_private_key(published_refund_tx)?
} else { } else {
let bob_peer_id = db.get_peer_id(swap_id)?; let bob_peer_id = db.get_peer_id(swap_id)?;
return Ok(Err(Error::RefundTransactionNotPublishedYet(bob_peer_id))); return Ok(Err(Error::RefundTransactionNotPublishedYet(bob_peer_id)));
}; };
state3 state3
.refund_xmr( .refund_wow(
&monero_wallet, &wownero_wallet,
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
swap_id.to_string(), swap_id.to_string(),
spend_key, spend_key,
transfer_proof, transfer_proof,
) )
.await?; .await?;
let state = AliceState::XmrRefunded; let state = AliceState::WowRefunded;
let db_state = (&state).into(); let db_state = (&state).into();
db.insert_latest_state(swap_id, Swap::Alice(db_state)) db.insert_latest_state(swap_id, Swap::Alice(db_state))
.await?; .await?;

@ -20,9 +20,9 @@ pub async fn safely_abort(swap_id: Uuid, db: Arc<Database>) -> Result<AliceState
Ok(state) Ok(state)
} }
AliceState::XmrLockTransactionSent { .. } AliceState::WowLockTransactionSent { .. }
| AliceState::XmrLocked { .. } | AliceState::WowLocked { .. }
| AliceState::XmrLockTransferProofSent { .. } | AliceState::WowLockTransferProofSent { .. }
| AliceState::EncSigLearned { .. } | AliceState::EncSigLearned { .. }
| AliceState::BtcRedeemTransactionPublished { .. } | AliceState::BtcRedeemTransactionPublished { .. }
| AliceState::CancelTimelockExpired { .. } | AliceState::CancelTimelockExpired { .. }
@ -30,7 +30,7 @@ pub async fn safely_abort(swap_id: Uuid, db: Arc<Database>) -> Result<AliceState
| AliceState::BtcRefunded { .. } | AliceState::BtcRefunded { .. }
| AliceState::BtcPunishable { .. } | AliceState::BtcPunishable { .. }
| AliceState::BtcRedeemed | AliceState::BtcRedeemed
| AliceState::XmrRefunded | AliceState::WowRefunded
| AliceState::BtcPunished | AliceState::BtcPunished
| AliceState::SafelyAborted => bail!( | AliceState::SafelyAborted => bail!(
"Cannot safely abort swap {} because it is in state {} which cannot be safely aborted", "Cannot safely abort swap {} because it is in state {} which cannot be safely aborted",

@ -29,13 +29,13 @@ use swap::asb::config::{
}; };
use swap::asb::{cancel, punish, redeem, refund, safely_abort, EventLoop, Finality, KrakenRate}; use swap::asb::{cancel, punish, redeem, refund, safely_abort, EventLoop, Finality, KrakenRate};
use swap::database::Database; use swap::database::Database;
use swap::monero::Amount; use swap::wownero::Amount;
use swap::network::rendezvous::XmrBtcNamespace; use swap::network::rendezvous::WowBtcNamespace;
use swap::network::swarm; use swap::network::swarm;
use swap::protocol::alice::run; use swap::protocol::alice::run;
use swap::seed::Seed; use swap::seed::Seed;
use swap::tor::AuthenticatedClient; use swap::tor::AuthenticatedClient;
use swap::{asb, bitcoin, kraken, monero, tor}; use swap::{asb, bitcoin, kraken, wownero, tor};
use tracing_subscriber::filter::LevelFilter; use tracing_subscriber::filter::LevelFilter;
const DEFAULT_WALLET_NAME: &str = "asb-wallet"; const DEFAULT_WALLET_NAME: &str = "asb-wallet";
@ -76,10 +76,10 @@ async fn main() -> Result<()> {
} }
}; };
if config.monero.network != env_config.monero_network { if config.wownero.network != env_config.wownero_network {
bail!(format!( bail!(format!(
"Expected monero network in config file to be {:?} but was {:?}", "Expected wownero network in config file to be {:?} but was {:?}",
env_config.monero_network, config.monero.network env_config.wownero_network, config.wownero.network
)); ));
} }
if config.bitcoin.network != env_config.bitcoin_network { if config.bitcoin.network != env_config.bitcoin_network {
@ -101,20 +101,20 @@ async fn main() -> Result<()> {
Command::Start { resume_only } => { Command::Start { resume_only } => {
let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?; let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?;
let monero_wallet = init_monero_wallet(&config, env_config).await?; let wownero_wallet = init_wownero_wallet(&config, env_config).await?;
let bitcoin_balance = bitcoin_wallet.balance().await?; let bitcoin_balance = bitcoin_wallet.balance().await?;
tracing::info!(%bitcoin_balance, "Initialized Bitcoin wallet"); tracing::info!(%bitcoin_balance, "Initialized Bitcoin wallet");
let monero_balance = monero_wallet.get_balance().await?; let wownero_balance = wownero_wallet.get_balance().await?;
if monero_balance == Amount::ZERO { if wownero_balance == Amount::ZERO {
let monero_address = monero_wallet.get_main_address(); let wownero_address = wownero_wallet.get_main_address();
tracing::warn!( tracing::warn!(
%monero_address, %wownero_address,
"The Monero balance is 0, make sure to deposit funds at", "The Wownero balance is 0, make sure to deposit funds at",
) )
} else { } else {
tracing::info!(%monero_balance, "Initialized Monero wallet"); tracing::info!(%wownero_balance, "Initialized Wownero wallet");
} }
let kraken_price_updates = kraken::connect(config.maker.price_ticker_ws_url.clone())?; let kraken_price_updates = kraken::connect(config.maker.price_ticker_ws_url.clone())?;
@ -148,9 +148,9 @@ async fn main() -> Result<()> {
( (
rendezvous_point, rendezvous_point,
if testnet { if testnet {
XmrBtcNamespace::Testnet WowBtcNamespace::Testnet
} else { } else {
XmrBtcNamespace::Mainnet WowBtcNamespace::Mainnet
}, },
) )
}), }),
@ -175,7 +175,7 @@ async fn main() -> Result<()> {
swarm, swarm,
env_config, env_config,
Arc::new(bitcoin_wallet), Arc::new(bitcoin_wallet),
Arc::new(monero_wallet), Arc::new(wownero_wallet),
Arc::new(db), Arc::new(db),
kraken_rate.clone(), kraken_rate.clone(),
config.maker.min_buy_btc, config.maker.min_buy_btc,
@ -234,14 +234,14 @@ async fn main() -> Result<()> {
} }
Command::Balance => { Command::Balance => {
let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?; let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?;
let monero_wallet = init_monero_wallet(&config, env_config).await?; let wownero_wallet = init_wownero_wallet(&config, env_config).await?;
let bitcoin_balance = bitcoin_wallet.balance().await?; let bitcoin_balance = bitcoin_wallet.balance().await?;
let monero_balance = monero_wallet.get_balance().await?; let wownero_balance = wownero_wallet.get_balance().await?;
tracing::info!( tracing::info!(
%bitcoin_balance, %bitcoin_balance,
%monero_balance, %wownero_balance,
"Current balance"); "Current balance");
} }
Command::Cancel { swap_id, force } => { Command::Cancel { swap_id, force } => {
@ -254,18 +254,18 @@ async fn main() -> Result<()> {
} }
Command::Refund { swap_id, force } => { Command::Refund { swap_id, force } => {
let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?; let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?;
let monero_wallet = init_monero_wallet(&config, env_config).await?; let wownero_wallet = init_wownero_wallet(&config, env_config).await?;
refund( refund(
swap_id, swap_id,
Arc::new(bitcoin_wallet), Arc::new(bitcoin_wallet),
Arc::new(monero_wallet), Arc::new(wownero_wallet),
Arc::new(db), Arc::new(db),
force, force,
) )
.await??; .await??;
tracing::info!("Monero successfully refunded"); tracing::info!("Wownero successfully refunded");
} }
Command::Punish { swap_id, force } => { Command::Punish { swap_id, force } => {
let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?; let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?;
@ -326,13 +326,13 @@ async fn init_bitcoin_wallet(
Ok(wallet) Ok(wallet)
} }
async fn init_monero_wallet( async fn init_wownero_wallet(
config: &Config, config: &Config,
env_config: swap::env::Config, env_config: swap::env::Config,
) -> Result<monero::Wallet> { ) -> Result<wownero::Wallet> {
tracing::debug!("Opening Monero wallet"); tracing::debug!("Opening Wownero wallet");
let wallet = monero::Wallet::open_or_create( let wallet = wownero::Wallet::open_or_create(
config.monero.wallet_rpc_url.clone(), config.wownero.wallet_rpc_url.clone(),
DEFAULT_WALLET_NAME.to_string(), DEFAULT_WALLET_NAME.to_string(),
env_config, env_config,
) )

@ -33,7 +33,7 @@ use swap::network::swarm;
use swap::protocol::bob; use swap::protocol::bob;
use swap::protocol::bob::Swap; use swap::protocol::bob::Swap;
use swap::seed::Seed; use swap::seed::Seed;
use swap::{bitcoin, cli, monero}; use swap::{bitcoin, cli, wownero};
use url::Url; use url::Url;
use uuid::Uuid; use uuid::Uuid;
@ -54,13 +54,13 @@ async fn main() -> Result<()> {
}; };
match cmd { match cmd {
Command::BuyXmr { Command::BuyWow {
seller, seller,
bitcoin_electrum_rpc_url, bitcoin_electrum_rpc_url,
bitcoin_target_block, bitcoin_target_block,
bitcoin_change_address, bitcoin_change_address,
monero_receive_address, wownero_receive_address,
monero_daemon_address, wownero_daemon_address,
tor_socks5_port, tor_socks5_port,
} => { } => {
let swap_id = Uuid::new_v4(); let swap_id = Uuid::new_v4();
@ -79,8 +79,8 @@ async fn main() -> Result<()> {
bitcoin_target_block, bitcoin_target_block,
) )
.await?; .await?;
let (monero_wallet, _process) = let (wownero_wallet, _process) =
init_monero_wallet(data_dir, monero_daemon_address, env_config).await?; init_wownero_wallet(data_dir, wownero_daemon_address, env_config).await?;
let bitcoin_wallet = Arc::new(bitcoin_wallet); let bitcoin_wallet = Arc::new(bitcoin_wallet);
let seller_peer_id = seller let seller_peer_id = seller
@ -113,17 +113,17 @@ async fn main() -> Result<()> {
tracing::info!(%amount, %fees, %swap_id, "Starting new swap"); tracing::info!(%amount, %fees, %swap_id, "Starting new swap");
db.insert_peer_id(swap_id, seller_peer_id).await?; db.insert_peer_id(swap_id, seller_peer_id).await?;
db.insert_monero_address(swap_id, monero_receive_address) db.insert_wownero_address(swap_id, wownero_receive_address)
.await?; .await?;
let swap = Swap::new( let swap = Swap::new(
db, db,
swap_id, swap_id,
bitcoin_wallet, bitcoin_wallet,
Arc::new(monero_wallet), Arc::new(wownero_wallet),
env_config, env_config,
event_loop_handle, event_loop_handle,
monero_receive_address, wownero_receive_address,
bitcoin_change_address, bitcoin_change_address,
amount, amount,
); );
@ -156,7 +156,7 @@ async fn main() -> Result<()> {
swap_id, swap_id,
bitcoin_electrum_rpc_url, bitcoin_electrum_rpc_url,
bitcoin_target_block, bitcoin_target_block,
monero_daemon_address, wownero_daemon_address,
tor_socks5_port, tor_socks5_port,
} => { } => {
cli::tracing::init(debug, json, data_dir.join("logs"), Some(swap_id))?; cli::tracing::init(debug, json, data_dir.join("logs"), Some(swap_id))?;
@ -173,8 +173,8 @@ async fn main() -> Result<()> {
bitcoin_target_block, bitcoin_target_block,
) )
.await?; .await?;
let (monero_wallet, _process) = let (wownero_wallet, _process) =
init_monero_wallet(data_dir, monero_daemon_address, env_config).await?; init_wownero_wallet(data_dir, wownero_daemon_address, env_config).await?;
let bitcoin_wallet = Arc::new(bitcoin_wallet); let bitcoin_wallet = Arc::new(bitcoin_wallet);
let seller_peer_id = db.get_peer_id(swap_id)?; let seller_peer_id = db.get_peer_id(swap_id)?;
@ -196,15 +196,15 @@ async fn main() -> Result<()> {
EventLoop::new(swap_id, swarm, seller_peer_id, env_config)?; EventLoop::new(swap_id, swarm, seller_peer_id, env_config)?;
let handle = tokio::spawn(event_loop.run()); let handle = tokio::spawn(event_loop.run());
let monero_receive_address = db.get_monero_address(swap_id)?; let wownero_receive_address = db.get_wownero_address(swap_id)?;
let swap = Swap::from_db( let swap = Swap::from_db(
db, db,
swap_id, swap_id,
bitcoin_wallet, bitcoin_wallet,
Arc::new(monero_wallet), Arc::new(wownero_wallet),
env_config, env_config,
event_loop_handle, event_loop_handle,
monero_receive_address, wownero_receive_address,
)?; )?;
tokio::select! { tokio::select! {
@ -365,29 +365,29 @@ async fn init_bitcoin_wallet(
Ok(wallet) Ok(wallet)
} }
async fn init_monero_wallet( async fn init_wownero_wallet(
data_dir: PathBuf, data_dir: PathBuf,
monero_daemon_address: String, wownero_daemon_address: String,
env_config: Config, env_config: Config,
) -> Result<(monero::Wallet, monero::WalletRpcProcess)> { ) -> Result<(wownero::Wallet, wownero::WalletRpcProcess)> {
let network = env_config.monero_network; let network = env_config.wownero_network;
const MONERO_BLOCKCHAIN_MONITORING_WALLET_NAME: &str = "swap-tool-blockchain-monitoring-wallet"; const WOWNERO_BLOCKCHAIN_MONITORING_WALLET_NAME: &str = "swap-tool-blockchain-monitoring-wallet";
let monero_wallet_rpc = monero::WalletRpc::new(data_dir.join("monero")).await?; let wownero_wallet_rpc = wownero::WalletRpc::new(data_dir.join("wownero")).await?;
let monero_wallet_rpc_process = monero_wallet_rpc let wownero_wallet_rpc_process = wownero_wallet_rpc
.run(network, monero_daemon_address.as_str()) .run(network, wownero_daemon_address.as_str())
.await?; .await?;
let monero_wallet = monero::Wallet::open_or_create( let wownero_wallet = wownero::Wallet::open_or_create(
monero_wallet_rpc_process.endpoint(), wownero_wallet_rpc_process.endpoint(),
MONERO_BLOCKCHAIN_MONITORING_WALLET_NAME.to_string(), WOWNERO_BLOCKCHAIN_MONITORING_WALLET_NAME.to_string(),
env_config, env_config,
) )
.await?; .await?;
Ok((monero_wallet, monero_wallet_rpc_process)) Ok((wownero_wallet, wownero_wallet_rpc_process))
} }
fn qr_code(value: &impl ToString) -> Result<String> { fn qr_code(value: &impl ToString) -> Result<String> {

@ -87,15 +87,15 @@ impl SecretKey {
// TxRefund encsigning explanation: // TxRefund encsigning explanation:
// //
// A and B, are the Bitcoin Public Keys which go on the joint output for // A and B, are the Bitcoin Public Keys which go on the joint output for
// TxLock_Bitcoin. S_a and S_b, are the Monero Public Keys which go on the // TxLock_Bitcoin. S_a and S_b, are the Wownero Public Keys which go on the
// joint output for TxLock_Monero // joint output for TxLock_Wownero
// tx_refund: multisig(A, B), published by bob // tx_refund: multisig(A, B), published by bob
// bob can produce sig on B using b // bob can produce sig on B using b
// alice sends over an encrypted signature on A encrypted with S_b // alice sends over an encrypted signature on A encrypted with S_b
// s_b is leaked to alice when bob publishes signed tx_refund allowing her to // s_b is leaked to alice when bob publishes signed tx_refund allowing her to
// recover s_b: recover(encsig, S_b, sig_tx_refund) = s_b // recover s_b: recover(encsig, S_b, sig_tx_refund) = s_b
// alice now has s_a and s_b and can refund monero // alice now has s_a and s_b and can refund wownero
// self = a, Y = S_b, digest = tx_refund // self = a, Y = S_b, digest = tx_refund
pub fn encsign(&self, Y: PublicKey, digest: SigHash) -> EncryptedSignature { pub fn encsign(&self, Y: PublicKey, digest: SigHash) -> EncryptedSignature {
@ -324,7 +324,7 @@ mod tests {
let bob_wallet = WalletBuilder::new(Amount::ONE_BTC.as_sat()).build(); let bob_wallet = WalletBuilder::new(Amount::ONE_BTC.as_sat()).build();
let spending_fee = Amount::from_sat(1_000); let spending_fee = Amount::from_sat(1_000);
let btc_amount = Amount::from_sat(500_000); let btc_amount = Amount::from_sat(500_000);
let xmr_amount = crate::monero::Amount::from_piconero(10000); let wow_amount = crate::wownero::Amount::from_piconero(10000);
let tx_redeem_fee = alice_wallet let tx_redeem_fee = alice_wallet
.estimate_fee(TxRedeem::weight(), btc_amount) .estimate_fee(TxRedeem::weight(), btc_amount)
@ -340,7 +340,7 @@ mod tests {
let config = Regtest::get_config(); let config = Regtest::get_config();
let alice_state0 = alice::State0::new( let alice_state0 = alice::State0::new(
btc_amount, btc_amount,
xmr_amount, wow_amount,
config, config,
redeem_address, redeem_address,
punish_address, punish_address,
@ -353,11 +353,11 @@ mod tests {
Uuid::new_v4(), Uuid::new_v4(),
&mut OsRng, &mut OsRng,
btc_amount, btc_amount,
xmr_amount, wow_amount,
config.bitcoin_cancel_timelock, config.bitcoin_cancel_timelock,
config.bitcoin_punish_timelock, config.bitcoin_punish_timelock,
bob_wallet.new_address().await.unwrap(), bob_wallet.new_address().await.unwrap(),
config.monero_finality_confirmations, config.wownero_finality_confirmations,
spending_fee, spending_fee,
spending_fee, spending_fee,
); );
@ -382,7 +382,7 @@ mod tests {
let alice_state3 = alice_state2.receive(bob_message4).unwrap(); let alice_state3 = alice_state2.receive(bob_message4).unwrap();
let (bob_state3, _tx_lock) = bob_state2.lock_btc().await.unwrap(); let (bob_state3, _tx_lock) = bob_state2.lock_btc().await.unwrap();
let bob_state4 = bob_state3.xmr_locked(monero_rpc::wallet::BlockHeight { height: 0 }); let bob_state4 = bob_state3.wow_locked(wownero_rpc::wallet::BlockHeight { height: 0 });
let encrypted_signature = bob_state4.tx_redeem_encsig(); let encrypted_signature = bob_state4.tx_redeem_encsig();
let bob_state6 = bob_state4.cancel(); let bob_state6 = bob_state4.cancel();

@ -3,7 +3,7 @@ use crate::bitcoin::{
verify_sig, Address, Amount, EmptyWitnessStack, NoInputs, NotThreeWitnesses, PublicKey, verify_sig, Address, Amount, EmptyWitnessStack, NoInputs, NotThreeWitnesses, PublicKey,
TooManyInputs, Transaction, TxCancel, TooManyInputs, Transaction, TxCancel,
}; };
use crate::{bitcoin, monero}; use crate::{bitcoin, wownero};
use ::bitcoin::util::bip143::SigHashCache; use ::bitcoin::util::bip143::SigHashCache;
use ::bitcoin::{Script, SigHash, SigHashType, Txid}; use ::bitcoin::{Script, SigHash, SigHashType, Txid};
use anyhow::{bail, Context, Result}; use anyhow::{bail, Context, Result};
@ -77,14 +77,14 @@ impl TxRefund {
Ok(tx_refund) Ok(tx_refund)
} }
pub fn extract_monero_private_key( pub fn extract_wownero_private_key(
&self, &self,
published_refund_tx: bitcoin::Transaction, published_refund_tx: bitcoin::Transaction,
s_a: monero::Scalar, s_a: wownero::Scalar,
a: bitcoin::SecretKey, a: bitcoin::SecretKey,
S_b_bitcoin: bitcoin::PublicKey, S_b_bitcoin: bitcoin::PublicKey,
) -> Result<monero::PrivateKey> { ) -> Result<wownero::PrivateKey> {
let s_a = monero::PrivateKey { scalar: s_a }; let s_a = wownero::PrivateKey { scalar: s_a };
let tx_refund_sig = self let tx_refund_sig = self
.extract_signature_by_key(published_refund_tx, a.public()) .extract_signature_by_key(published_refund_tx, a.public())
@ -92,9 +92,9 @@ impl TxRefund {
let tx_refund_encsig = a.encsign(S_b_bitcoin, self.digest()); let tx_refund_encsig = a.encsign(S_b_bitcoin, self.digest());
let s_b = bitcoin::recover(S_b_bitcoin, tx_refund_sig, tx_refund_encsig) let s_b = bitcoin::recover(S_b_bitcoin, tx_refund_sig, tx_refund_encsig)
.context("Failed to recover Monero secret key from Bitcoin signature")?; .context("Failed to recover Wownero secret key from Bitcoin signature")?;
let s_b = monero::private_key_from_secp256k1_scalar(s_b.into()); let s_b = wownero::private_key_from_secp256k1_scalar(s_b.into());
let spend_key = s_a + s_b; let spend_key = s_a + s_b;

@ -20,7 +20,7 @@ mod tests {
use crate::cli::list_sellers::{Seller, Status}; use crate::cli::list_sellers::{Seller, Status};
use crate::network::quote; use crate::network::quote;
use crate::network::quote::BidQuote; use crate::network::quote::BidQuote;
use crate::network::rendezvous::XmrBtcNamespace; use crate::network::rendezvous::WowBtcNamespace;
use crate::network::test::{new_swarm, SwarmExt}; use crate::network::test::{new_swarm, SwarmExt};
use futures::StreamExt; use futures::StreamExt;
use libp2p::multiaddr::Protocol; use libp2p::multiaddr::Protocol;
@ -33,7 +33,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn list_sellers_should_report_all_registered_asbs_with_a_quote() { async fn list_sellers_should_report_all_registered_asbs_with_a_quote() {
let namespace = XmrBtcNamespace::Mainnet; let namespace = WowBtcNamespace::Mainnet;
let (rendezvous_address, rendezvous_peer_id) = setup_rendezvous_point().await; let (rendezvous_address, rendezvous_peer_id) = setup_rendezvous_point().await;
let expected_seller_1 = let expected_seller_1 =
setup_asb(rendezvous_peer_id, rendezvous_address.clone(), namespace).await; setup_asb(rendezvous_peer_id, rendezvous_address.clone(), namespace).await;
@ -81,7 +81,7 @@ mod tests {
async fn setup_asb( async fn setup_asb(
rendezvous_peer_id: PeerId, rendezvous_peer_id: PeerId,
rendezvous_address: Multiaddr, rendezvous_address: Multiaddr,
namespace: XmrBtcNamespace, namespace: WowBtcNamespace,
) -> Seller { ) -> Seller {
let static_quote = BidQuote { let static_quote = BidQuote {
price: bitcoin::Amount::from_sat(1337), price: bitcoin::Amount::from_sat(1337),

@ -54,7 +54,7 @@ impl OutEvent {
} }
} }
/// A `NetworkBehaviour` that represents an XMR/BTC swap node as Bob. /// A `NetworkBehaviour` that represents an WOW/BTC swap node as Bob.
#[derive(NetworkBehaviour)] #[derive(NetworkBehaviour)]
#[behaviour(out_event = "OutEvent", event_process = false)] #[behaviour(out_event = "OutEvent", event_process = false)]
#[allow(missing_debug_implementations)] #[allow(missing_debug_implementations)]

@ -21,8 +21,8 @@ pub async fn cancel(
let state6 = match state { let state6 = match state {
BobState::BtcLocked(state3) => state3.cancel(), BobState::BtcLocked(state3) => state3.cancel(),
BobState::XmrLockProofReceived { state, .. } => state.cancel(), BobState::WowLockProofReceived { state, .. } => state.cancel(),
BobState::XmrLocked(state4) => state4.cancel(), BobState::WowLocked(state4) => state4.cancel(),
BobState::EncSigSent(state4) => state4.cancel(), BobState::EncSigSent(state4) => state4.cancel(),
BobState::CancelTimelockExpired(state6) => state6, BobState::CancelTimelockExpired(state6) => state6,
BobState::Started { .. } BobState::Started { .. }
@ -30,7 +30,7 @@ pub async fn cancel(
| BobState::BtcRedeemed(_) | BobState::BtcRedeemed(_)
| BobState::BtcCancelled(_) | BobState::BtcCancelled(_)
| BobState::BtcRefunded(_) | BobState::BtcRefunded(_)
| BobState::XmrRedeemed { .. } | BobState::WowRedeemed { .. }
| BobState::BtcPunished { .. } | BobState::BtcPunished { .. }
| BobState::SafelyAborted => bail!( | BobState::SafelyAborted => bail!(
"Cannot cancel swap {} because it is in state {} which is not refundable.", "Cannot cancel swap {} because it is in state {} which is not refundable.",

@ -1,7 +1,7 @@
use crate::env::GetConfig; use crate::env::GetConfig;
use crate::fs::system_data_dir; use crate::fs::system_data_dir;
use crate::network::rendezvous::XmrBtcNamespace; use crate::network::rendezvous::WowBtcNamespace;
use crate::{env, monero}; use crate::{env, wownero};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use bitcoin::AddressType; use bitcoin::AddressType;
use libp2p::core::Multiaddr; use libp2p::core::Multiaddr;
@ -12,9 +12,9 @@ use structopt::{clap, StructOpt};
use url::Url; use url::Url;
use uuid::Uuid; use uuid::Uuid;
// See: https://moneroworld.com/ // See: https://wowneroworld.com/
pub const DEFAULT_MONERO_DAEMON_ADDRESS: &str = "node.melo.tools:18081"; pub const DEFAULT_WOWNERO_DAEMON_ADDRESS: &str = "wownero.mooo.com:34568";
pub const DEFAULT_MONERO_DAEMON_ADDRESS_STAGENET: &str = "stagenet.melo.tools:38081"; pub const DEFAULT_WOWNERO_DAEMON_ADDRESS_STAGENET: &str = "stagenet.melo.tools:38081";
// See: https://1209k.com/bitcoin-eye/ele.php?chain=btc // See: https://1209k.com/bitcoin-eye/ele.php?chain=btc
const DEFAULT_ELECTRUM_RPC_URL: &str = "ssl://electrum.blockstream.info:50002"; const DEFAULT_ELECTRUM_RPC_URL: &str = "ssl://electrum.blockstream.info:50002";
@ -68,19 +68,19 @@ where
let data = args.data; let data = args.data;
let arguments = match args.cmd { let arguments = match args.cmd {
RawCommand::BuyXmr { RawCommand::BuyWow {
seller: Seller { seller }, seller: Seller { seller },
bitcoin, bitcoin,
bitcoin_change_address, bitcoin_change_address,
monero, wownero,
monero_receive_address, wownero_receive_address,
tor: Tor { tor_socks5_port }, tor: Tor { tor_socks5_port },
} => { } => {
let (bitcoin_electrum_rpc_url, bitcoin_target_block) = let (bitcoin_electrum_rpc_url, bitcoin_target_block) =
bitcoin.apply_defaults(is_testnet)?; bitcoin.apply_defaults(is_testnet)?;
let monero_daemon_address = monero.apply_defaults(is_testnet); let wownero_daemon_address = wownero.apply_defaults(is_testnet);
let monero_receive_address = let wownero_receive_address =
validate_monero_address(monero_receive_address, is_testnet)?; validate_wownero_address(wownero_receive_address, is_testnet)?;
let bitcoin_change_address = let bitcoin_change_address =
validate_bitcoin_address(bitcoin_change_address, is_testnet)?; validate_bitcoin_address(bitcoin_change_address, is_testnet)?;
@ -89,13 +89,13 @@ where
debug, debug,
json, json,
data_dir: data::data_dir_from(data, is_testnet)?, data_dir: data::data_dir_from(data, is_testnet)?,
cmd: Command::BuyXmr { cmd: Command::BuyWow {
seller, seller,
bitcoin_electrum_rpc_url, bitcoin_electrum_rpc_url,
bitcoin_target_block, bitcoin_target_block,
bitcoin_change_address, bitcoin_change_address,
monero_receive_address, wownero_receive_address,
monero_daemon_address, wownero_daemon_address,
tor_socks5_port, tor_socks5_port,
}, },
} }
@ -110,12 +110,12 @@ where
RawCommand::Resume { RawCommand::Resume {
swap_id: SwapId { swap_id }, swap_id: SwapId { swap_id },
bitcoin, bitcoin,
monero, wownero,
tor: Tor { tor_socks5_port }, tor: Tor { tor_socks5_port },
} => { } => {
let (bitcoin_electrum_rpc_url, bitcoin_target_block) = let (bitcoin_electrum_rpc_url, bitcoin_target_block) =
bitcoin.apply_defaults(is_testnet)?; bitcoin.apply_defaults(is_testnet)?;
let monero_daemon_address = monero.apply_defaults(is_testnet); let wownero_daemon_address = wownero.apply_defaults(is_testnet);
Arguments { Arguments {
env_config: env_config_from(is_testnet), env_config: env_config_from(is_testnet),
@ -126,7 +126,7 @@ where
swap_id, swap_id,
bitcoin_electrum_rpc_url, bitcoin_electrum_rpc_url,
bitcoin_target_block, bitcoin_target_block,
monero_daemon_address, wownero_daemon_address,
tor_socks5_port, tor_socks5_port,
}, },
} }
@ -194,13 +194,13 @@ where
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum Command { pub enum Command {
BuyXmr { BuyWow {
seller: Multiaddr, seller: Multiaddr,
bitcoin_electrum_rpc_url: Url, bitcoin_electrum_rpc_url: Url,
bitcoin_target_block: usize, bitcoin_target_block: usize,
bitcoin_change_address: bitcoin::Address, bitcoin_change_address: bitcoin::Address,
monero_receive_address: monero::Address, wownero_receive_address: wownero::Address,
monero_daemon_address: String, wownero_daemon_address: String,
tor_socks5_port: u16, tor_socks5_port: u16,
}, },
History, History,
@ -208,7 +208,7 @@ pub enum Command {
swap_id: Uuid, swap_id: Uuid,
bitcoin_electrum_rpc_url: Url, bitcoin_electrum_rpc_url: Url,
bitcoin_target_block: usize, bitcoin_target_block: usize,
monero_daemon_address: String, wownero_daemon_address: String,
tor_socks5_port: u16, tor_socks5_port: u16,
}, },
Cancel { Cancel {
@ -225,7 +225,7 @@ pub enum Command {
}, },
ListSellers { ListSellers {
rendezvous_point: Multiaddr, rendezvous_point: Multiaddr,
namespace: XmrBtcNamespace, namespace: WowBtcNamespace,
tor_socks5_port: u16, tor_socks5_port: u16,
}, },
} }
@ -233,7 +233,7 @@ pub enum Command {
#[derive(structopt::StructOpt, Debug)] #[derive(structopt::StructOpt, Debug)]
#[structopt( #[structopt(
name = "swap", name = "swap",
about = "CLI for swapping BTC for XMR", about = "CLI for swapping BTC for WOW",
author, author,
version = env!("VERGEN_GIT_SEMVER_LIGHTWEIGHT") version = env!("VERGEN_GIT_SEMVER_LIGHTWEIGHT")
)] )]
@ -268,8 +268,8 @@ struct RawArguments {
#[derive(structopt::StructOpt, Debug)] #[derive(structopt::StructOpt, Debug)]
enum RawCommand { enum RawCommand {
/// Start a BTC for XMR swap /// Start a BTC for WOW swap
BuyXmr { BuyWow {
#[structopt(flatten)] #[structopt(flatten)]
seller: Seller, seller: Seller,
@ -283,13 +283,13 @@ enum RawCommand {
bitcoin_change_address: bitcoin::Address, bitcoin_change_address: bitcoin::Address,
#[structopt(flatten)] #[structopt(flatten)]
monero: Monero, wownero: Wownero,
#[structopt(long = "receive-address", #[structopt(long = "receive-address",
help = "The monero address where you would like to receive monero", help = "The wownero address where you would like to receive wownero",
parse(try_from_str = parse_monero_address) parse(try_from_str = parse_wownero_address)
)] )]
monero_receive_address: monero::Address, wownero_receive_address: wownero::Address,
#[structopt(flatten)] #[structopt(flatten)]
tor: Tor, tor: Tor,
@ -305,7 +305,7 @@ enum RawCommand {
bitcoin: Bitcoin, bitcoin: Bitcoin,
#[structopt(flatten)] #[structopt(flatten)]
monero: Monero, wownero: Wownero,
#[structopt(flatten)] #[structopt(flatten)]
tor: Tor, tor: Tor,
@ -346,22 +346,22 @@ enum RawCommand {
} }
#[derive(structopt::StructOpt, Debug)] #[derive(structopt::StructOpt, Debug)]
struct Monero { struct Wownero {
#[structopt( #[structopt(
long = "monero-daemon-address", long = "wownero-daemon-address",
help = "Specify to connect to a monero daemon of your choice: <host>:<port>" help = "Specify to connect to a wownero daemon of your choice: <host>:<port>"
)] )]
monero_daemon_address: Option<String>, wownero_daemon_address: Option<String>,
} }
impl Monero { impl Wownero {
fn apply_defaults(self, testnet: bool) -> String { fn apply_defaults(self, testnet: bool) -> String {
if let Some(address) = self.monero_daemon_address { if let Some(address) = self.wownero_daemon_address {
address address
} else if testnet { } else if testnet {
DEFAULT_MONERO_DAEMON_ADDRESS_STAGENET.to_string() DEFAULT_WOWNERO_DAEMON_ADDRESS_STAGENET.to_string()
} else { } else {
DEFAULT_MONERO_DAEMON_ADDRESS.to_string() DEFAULT_WOWNERO_DAEMON_ADDRESS.to_string()
} }
} }
} }
@ -447,11 +447,11 @@ mod data {
} }
} }
fn rendezvous_namespace_from(is_testnet: bool) -> XmrBtcNamespace { fn rendezvous_namespace_from(is_testnet: bool) -> WowBtcNamespace {
if is_testnet { if is_testnet {
XmrBtcNamespace::Testnet WowBtcNamespace::Testnet
} else { } else {
XmrBtcNamespace::Mainnet WowBtcNamespace::Mainnet
} }
} }
@ -463,18 +463,18 @@ fn env_config_from(testnet: bool) -> env::Config {
} }
} }
fn validate_monero_address( fn validate_wownero_address(
address: monero::Address, address: wownero::Address,
testnet: bool, testnet: bool,
) -> Result<monero::Address, MoneroAddressNetworkMismatch> { ) -> Result<wownero::Address, WowneroAddressNetworkMismatch> {
let expected_network = if testnet { let expected_network = if testnet {
monero::Network::Stagenet wownero::Network::Stagenet
} else { } else {
monero::Network::Mainnet wownero::Network::Mainnet
}; };
if address.network != expected_network { if address.network != expected_network {
return Err(MoneroAddressNetworkMismatch { return Err(WowneroAddressNetworkMismatch {
expected: expected_network, expected: expected_network,
actual: address.network, actual: address.network,
}); });
@ -505,20 +505,20 @@ fn validate_bitcoin_address(address: bitcoin::Address, testnet: bool) -> Result<
Ok(address) Ok(address)
} }
fn parse_monero_address(s: &str) -> Result<monero::Address> { fn parse_wownero_address(s: &str) -> Result<wownero::Address> {
monero::Address::from_str(s).with_context(|| { wownero::Address::from_str(s).with_context(|| {
format!( format!(
"Failed to parse {} as a monero address, please make sure it is a valid address", "Failed to parse {} as a wownero address, please make sure it is a valid address",
s s
) )
}) })
} }
#[derive(thiserror::Error, Debug, Clone, Copy, PartialEq)] #[derive(thiserror::Error, Debug, Clone, Copy, PartialEq)]
#[error("Invalid monero address provided, expected address on network {expected:?} but address provided is on {actual:?}")] #[error("Invalid wownero address provided, expected address on network {expected:?} but address provided is on {actual:?}")]
pub struct MoneroAddressNetworkMismatch { pub struct WowneroAddressNetworkMismatch {
expected: monero::Network, expected: wownero::Network,
actual: monero::Network, actual: wownero::Network,
} }
#[cfg(test)] #[cfg(test)]
@ -531,41 +531,41 @@ mod tests {
const TESTNET: &str = "testnet"; const TESTNET: &str = "testnet";
const MAINNET: &str = "mainnet"; const MAINNET: &str = "mainnet";
const MONERO_STAGENET_ADDRESS: &str = "53gEuGZUhP9JMEBZoGaFNzhwEgiG7hwQdMCqFxiyiTeFPmkbt1mAoNybEUvYBKHcnrSgxnVWgZsTvRBaHBNXPa8tHiCU51a"; const WOWNERO_STAGENET_ADDRESS: &str = "53gEuGZUhP9JMEBZoGaFNzhwEgiG7hwQdMCqFxiyiTeFPmkbt1mAoNybEUvYBKHcnrSgxnVWgZsTvRBaHBNXPa8tHiCU51a";
const BITCOIN_TESTNET_ADDRESS: &str = "tb1qr3em6k3gfnyl8r7q0v7t4tlnyxzgxma3lressv"; const BITCOIN_TESTNET_ADDRESS: &str = "tb1qr3em6k3gfnyl8r7q0v7t4tlnyxzgxma3lressv";
const MONERO_MAINNET_ADDRESS: &str = "44Ato7HveWidJYUAVw5QffEcEtSH1DwzSP3FPPkHxNAS4LX9CqgucphTisH978FLHE34YNEx7FcbBfQLQUU8m3NUC4VqsRa"; const WOWNERO_MAINNET_ADDRESS: &str = "44Ato7HveWidJYUAVw5QffEcEtSH1DwzSP3FPPkHxNAS4LX9CqgucphTisH978FLHE34YNEx7FcbBfQLQUU8m3NUC4VqsRa";
const BITCOIN_MAINNET_ADDRESS: &str = "bc1qe4epnfklcaa0mun26yz5g8k24em5u9f92hy325"; const BITCOIN_MAINNET_ADDRESS: &str = "bc1qe4epnfklcaa0mun26yz5g8k24em5u9f92hy325";
const MULTI_ADDRESS: &str = const MULTI_ADDRESS: &str =
"/ip4/127.0.0.1/tcp/9939/p2p/12D3KooWCdMKjesXMJz1SiZ7HgotrxuqhQJbP5sgBm2BwP1cqThi"; "/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";
#[test] #[test]
fn given_buy_xmr_on_mainnet_then_defaults_to_mainnet() { fn given_buy_wow_on_mainnet_then_defaults_to_mainnet() {
let raw_ars = vec![ let raw_ars = vec![
BINARY_NAME, BINARY_NAME,
"buy-xmr", "buy-wow",
"--receive-address", "--receive-address",
MONERO_MAINNET_ADDRESS, WOWNERO_MAINNET_ADDRESS,
"--change-address", "--change-address",
BITCOIN_MAINNET_ADDRESS, BITCOIN_MAINNET_ADDRESS,
"--seller", "--seller",
MULTI_ADDRESS, MULTI_ADDRESS,
]; ];
let expected_args = ParseResult::Arguments(Arguments::buy_xmr_mainnet_defaults()); let expected_args = ParseResult::Arguments(Arguments::buy_wow_mainnet_defaults());
let args = parse_args_and_apply_defaults(raw_ars).unwrap(); let args = parse_args_and_apply_defaults(raw_ars).unwrap();
assert_eq!(expected_args, args); assert_eq!(expected_args, args);
} }
#[test] #[test]
fn given_buy_xmr_on_testnet_then_defaults_to_testnet() { fn given_buy_wow_on_testnet_then_defaults_to_testnet() {
let raw_ars = vec![ let raw_ars = vec![
BINARY_NAME, BINARY_NAME,
"--testnet", "--testnet",
"buy-xmr", "buy-wow",
"--receive-address", "--receive-address",
MONERO_STAGENET_ADDRESS, WOWNERO_STAGENET_ADDRESS,
"--change-address", "--change-address",
BITCOIN_TESTNET_ADDRESS, BITCOIN_TESTNET_ADDRESS,
"--seller", "--seller",
@ -576,17 +576,17 @@ mod tests {
assert_eq!( assert_eq!(
args, args,
ParseResult::Arguments(Arguments::buy_xmr_testnet_defaults()) ParseResult::Arguments(Arguments::buy_wow_testnet_defaults())
); );
} }
#[test] #[test]
fn given_buy_xmr_on_mainnet_with_testnet_address_then_fails() { fn given_buy_wow_on_mainnet_with_testnet_address_then_fails() {
let raw_ars = vec![ let raw_ars = vec![
BINARY_NAME, BINARY_NAME,
"buy-xmr", "buy-wow",
"--receive-address", "--receive-address",
MONERO_STAGENET_ADDRESS, WOWNERO_STAGENET_ADDRESS,
"--change-address", "--change-address",
BITCOIN_TESTNET_ADDRESS, BITCOIN_TESTNET_ADDRESS,
"--seller", "--seller",
@ -596,22 +596,22 @@ mod tests {
let err = parse_args_and_apply_defaults(raw_ars).unwrap_err(); let err = parse_args_and_apply_defaults(raw_ars).unwrap_err();
assert_eq!( assert_eq!(
err.downcast_ref::<MoneroAddressNetworkMismatch>().unwrap(), err.downcast_ref::<WowneroAddressNetworkMismatch>().unwrap(),
&MoneroAddressNetworkMismatch { &WowneroAddressNetworkMismatch {
expected: monero::Network::Mainnet, expected: wownero::Network::Mainnet,
actual: monero::Network::Stagenet actual: wownero::Network::Stagenet
} }
); );
} }
#[test] #[test]
fn given_buy_xmr_on_testnet_with_mainnet_address_then_fails() { fn given_buy_wow_on_testnet_with_mainnet_address_then_fails() {
let raw_ars = vec![ let raw_ars = vec![
BINARY_NAME, BINARY_NAME,
"--testnet", "--testnet",
"buy-xmr", "buy-wow",
"--receive-address", "--receive-address",
MONERO_MAINNET_ADDRESS, WOWNERO_MAINNET_ADDRESS,
"--change-address", "--change-address",
BITCOIN_MAINNET_ADDRESS, BITCOIN_MAINNET_ADDRESS,
"--seller", "--seller",
@ -621,10 +621,10 @@ mod tests {
let err = parse_args_and_apply_defaults(raw_ars).unwrap_err(); let err = parse_args_and_apply_defaults(raw_ars).unwrap_err();
assert_eq!( assert_eq!(
err.downcast_ref::<MoneroAddressNetworkMismatch>().unwrap(), err.downcast_ref::<WowneroAddressNetworkMismatch>().unwrap(),
&MoneroAddressNetworkMismatch { &WowneroAddressNetworkMismatch {
expected: monero::Network::Stagenet, expected: wownero::Network::Stagenet,
actual: monero::Network::Mainnet actual: wownero::Network::Mainnet
} }
); );
} }
@ -709,11 +709,11 @@ mod tests {
BINARY_NAME, BINARY_NAME,
"--data-base-dir", "--data-base-dir",
data_dir, data_dir,
"buy-xmr", "buy-wow",
"--change-address", "--change-address",
BITCOIN_MAINNET_ADDRESS, BITCOIN_MAINNET_ADDRESS,
"--receive-address", "--receive-address",
MONERO_MAINNET_ADDRESS, WOWNERO_MAINNET_ADDRESS,
"--seller", "--seller",
MULTI_ADDRESS, MULTI_ADDRESS,
]; ];
@ -723,7 +723,7 @@ mod tests {
assert_eq!( assert_eq!(
args, args,
ParseResult::Arguments( ParseResult::Arguments(
Arguments::buy_xmr_mainnet_defaults() Arguments::buy_wow_mainnet_defaults()
.with_data_dir(PathBuf::from_str(data_dir).unwrap().join("mainnet")) .with_data_dir(PathBuf::from_str(data_dir).unwrap().join("mainnet"))
) )
); );
@ -733,11 +733,11 @@ mod tests {
"--testnet", "--testnet",
"--data-base-dir", "--data-base-dir",
data_dir, data_dir,
"buy-xmr", "buy-wow",
"--change-address", "--change-address",
BITCOIN_TESTNET_ADDRESS, BITCOIN_TESTNET_ADDRESS,
"--receive-address", "--receive-address",
MONERO_STAGENET_ADDRESS, WOWNERO_STAGENET_ADDRESS,
"--seller", "--seller",
MULTI_ADDRESS, MULTI_ADDRESS,
]; ];
@ -747,7 +747,7 @@ mod tests {
assert_eq!( assert_eq!(
args, args,
ParseResult::Arguments( ParseResult::Arguments(
Arguments::buy_xmr_testnet_defaults() Arguments::buy_wow_testnet_defaults()
.with_data_dir(PathBuf::from_str(data_dir).unwrap().join("testnet")) .with_data_dir(PathBuf::from_str(data_dir).unwrap().join("testnet"))
) )
); );
@ -797,11 +797,11 @@ mod tests {
let raw_ars = vec![ let raw_ars = vec![
BINARY_NAME, BINARY_NAME,
"--debug", "--debug",
"buy-xmr", "buy-wow",
"--change-address", "--change-address",
BITCOIN_MAINNET_ADDRESS, BITCOIN_MAINNET_ADDRESS,
"--receive-address", "--receive-address",
MONERO_MAINNET_ADDRESS, WOWNERO_MAINNET_ADDRESS,
"--seller", "--seller",
MULTI_ADDRESS, MULTI_ADDRESS,
]; ];
@ -809,18 +809,18 @@ mod tests {
let args = parse_args_and_apply_defaults(raw_ars).unwrap(); let args = parse_args_and_apply_defaults(raw_ars).unwrap();
assert_eq!( assert_eq!(
args, args,
ParseResult::Arguments(Arguments::buy_xmr_mainnet_defaults().with_debug()) ParseResult::Arguments(Arguments::buy_wow_mainnet_defaults().with_debug())
); );
let raw_ars = vec![ let raw_ars = vec![
BINARY_NAME, BINARY_NAME,
"--testnet", "--testnet",
"--debug", "--debug",
"buy-xmr", "buy-wow",
"--change-address", "--change-address",
BITCOIN_TESTNET_ADDRESS, BITCOIN_TESTNET_ADDRESS,
"--receive-address", "--receive-address",
MONERO_STAGENET_ADDRESS, WOWNERO_STAGENET_ADDRESS,
"--seller", "--seller",
MULTI_ADDRESS, MULTI_ADDRESS,
]; ];
@ -828,7 +828,7 @@ mod tests {
let args = parse_args_and_apply_defaults(raw_ars).unwrap(); let args = parse_args_and_apply_defaults(raw_ars).unwrap();
assert_eq!( assert_eq!(
args, args,
ParseResult::Arguments(Arguments::buy_xmr_testnet_defaults().with_debug()) ParseResult::Arguments(Arguments::buy_wow_testnet_defaults().with_debug())
); );
let raw_ars = vec![BINARY_NAME, "--debug", "resume", "--swap-id", SWAP_ID]; let raw_ars = vec![BINARY_NAME, "--debug", "resume", "--swap-id", SWAP_ID];
@ -860,11 +860,11 @@ mod tests {
let raw_ars = vec![ let raw_ars = vec![
BINARY_NAME, BINARY_NAME,
"--json", "--json",
"buy-xmr", "buy-wow",
"--change-address", "--change-address",
BITCOIN_MAINNET_ADDRESS, BITCOIN_MAINNET_ADDRESS,
"--receive-address", "--receive-address",
MONERO_MAINNET_ADDRESS, WOWNERO_MAINNET_ADDRESS,
"--seller", "--seller",
MULTI_ADDRESS, MULTI_ADDRESS,
]; ];
@ -872,18 +872,18 @@ mod tests {
let args = parse_args_and_apply_defaults(raw_ars).unwrap(); let args = parse_args_and_apply_defaults(raw_ars).unwrap();
assert_eq!( assert_eq!(
args, args,
ParseResult::Arguments(Arguments::buy_xmr_mainnet_defaults().with_json()) ParseResult::Arguments(Arguments::buy_wow_mainnet_defaults().with_json())
); );
let raw_ars = vec![ let raw_ars = vec![
BINARY_NAME, BINARY_NAME,
"--testnet", "--testnet",
"--json", "--json",
"buy-xmr", "buy-wow",
"--change-address", "--change-address",
BITCOIN_TESTNET_ADDRESS, BITCOIN_TESTNET_ADDRESS,
"--receive-address", "--receive-address",
MONERO_STAGENET_ADDRESS, WOWNERO_STAGENET_ADDRESS,
"--seller", "--seller",
MULTI_ADDRESS, MULTI_ADDRESS,
]; ];
@ -891,7 +891,7 @@ mod tests {
let args = parse_args_and_apply_defaults(raw_ars).unwrap(); let args = parse_args_and_apply_defaults(raw_ars).unwrap();
assert_eq!( assert_eq!(
args, args,
ParseResult::Arguments(Arguments::buy_xmr_testnet_defaults().with_json()) ParseResult::Arguments(Arguments::buy_wow_testnet_defaults().with_json())
); );
let raw_ars = vec![BINARY_NAME, "--json", "resume", "--swap-id", SWAP_ID]; let raw_ars = vec![BINARY_NAME, "--json", "resume", "--swap-id", SWAP_ID];
@ -922,11 +922,11 @@ mod tests {
fn only_bech32_addresses_mainnet_are_allowed() { fn only_bech32_addresses_mainnet_are_allowed() {
let raw_ars = vec![ let raw_ars = vec![
BINARY_NAME, BINARY_NAME,
"buy-xmr", "buy-wow",
"--change-address", "--change-address",
"1A5btpLKZjgYm8R22rJAhdbTFVXgSRA2Mp", "1A5btpLKZjgYm8R22rJAhdbTFVXgSRA2Mp",
"--receive-address", "--receive-address",
MONERO_MAINNET_ADDRESS, WOWNERO_MAINNET_ADDRESS,
"--seller", "--seller",
MULTI_ADDRESS, MULTI_ADDRESS,
]; ];
@ -938,11 +938,11 @@ mod tests {
let raw_ars = vec![ let raw_ars = vec![
BINARY_NAME, BINARY_NAME,
"buy-xmr", "buy-wow",
"--change-address", "--change-address",
"36vn4mFhmTXn7YcNwELFPxTXhjorw2ppu2", "36vn4mFhmTXn7YcNwELFPxTXhjorw2ppu2",
"--receive-address", "--receive-address",
MONERO_MAINNET_ADDRESS, WOWNERO_MAINNET_ADDRESS,
"--seller", "--seller",
MULTI_ADDRESS, MULTI_ADDRESS,
]; ];
@ -954,11 +954,11 @@ mod tests {
let raw_ars = vec![ let raw_ars = vec![
BINARY_NAME, BINARY_NAME,
"buy-xmr", "buy-wow",
"--change-address", "--change-address",
"bc1qh4zjxrqe3trzg7s6m7y67q2jzrw3ru5mx3z7j3", "bc1qh4zjxrqe3trzg7s6m7y67q2jzrw3ru5mx3z7j3",
"--receive-address", "--receive-address",
MONERO_MAINNET_ADDRESS, WOWNERO_MAINNET_ADDRESS,
"--seller", "--seller",
MULTI_ADDRESS, MULTI_ADDRESS,
]; ];
@ -971,11 +971,11 @@ mod tests {
let raw_ars = vec![ let raw_ars = vec![
BINARY_NAME, BINARY_NAME,
"--testnet", "--testnet",
"buy-xmr", "buy-wow",
"--change-address", "--change-address",
"n2czxyeFCQp9e8WRyGpy4oL4YfQAeKkkUH", "n2czxyeFCQp9e8WRyGpy4oL4YfQAeKkkUH",
"--receive-address", "--receive-address",
MONERO_STAGENET_ADDRESS, WOWNERO_STAGENET_ADDRESS,
"--seller", "--seller",
MULTI_ADDRESS, MULTI_ADDRESS,
]; ];
@ -988,11 +988,11 @@ mod tests {
let raw_ars = vec![ let raw_ars = vec![
BINARY_NAME, BINARY_NAME,
"--testnet", "--testnet",
"buy-xmr", "buy-wow",
"--change-address", "--change-address",
"2ND9a4xmQG89qEWG3ETRuytjKpLmGrW7Jvf", "2ND9a4xmQG89qEWG3ETRuytjKpLmGrW7Jvf",
"--receive-address", "--receive-address",
MONERO_STAGENET_ADDRESS, WOWNERO_STAGENET_ADDRESS,
"--seller", "--seller",
MULTI_ADDRESS, MULTI_ADDRESS,
]; ];
@ -1005,11 +1005,11 @@ mod tests {
let raw_ars = vec![ let raw_ars = vec![
BINARY_NAME, BINARY_NAME,
"--testnet", "--testnet",
"buy-xmr", "buy-wow",
"--change-address", "--change-address",
"tb1q958vfh3wkdp232pktq8zzvmttyxeqnj80zkz3v", "tb1q958vfh3wkdp232pktq8zzvmttyxeqnj80zkz3v",
"--receive-address", "--receive-address",
MONERO_STAGENET_ADDRESS, WOWNERO_STAGENET_ADDRESS,
"--seller", "--seller",
MULTI_ADDRESS, MULTI_ADDRESS,
]; ];
@ -1018,40 +1018,40 @@ mod tests {
} }
impl Arguments { impl Arguments {
pub fn buy_xmr_testnet_defaults() -> Self { pub fn buy_wow_testnet_defaults() -> Self {
Self { Self {
env_config: env::Testnet::get_config(), env_config: env::Testnet::get_config(),
debug: false, debug: false,
json: false, json: false,
data_dir: data_dir_path_cli().join(TESTNET), data_dir: data_dir_path_cli().join(TESTNET),
cmd: Command::BuyXmr { cmd: Command::BuyWow {
seller: Multiaddr::from_str(MULTI_ADDRESS).unwrap(), seller: Multiaddr::from_str(MULTI_ADDRESS).unwrap(),
bitcoin_electrum_rpc_url: Url::from_str(DEFAULT_ELECTRUM_RPC_URL_TESTNET) bitcoin_electrum_rpc_url: Url::from_str(DEFAULT_ELECTRUM_RPC_URL_TESTNET)
.unwrap(), .unwrap(),
bitcoin_target_block: DEFAULT_BITCOIN_CONFIRMATION_TARGET_TESTNET, bitcoin_target_block: DEFAULT_BITCOIN_CONFIRMATION_TARGET_TESTNET,
bitcoin_change_address: BITCOIN_TESTNET_ADDRESS.parse().unwrap(), bitcoin_change_address: BITCOIN_TESTNET_ADDRESS.parse().unwrap(),
monero_receive_address: monero::Address::from_str(MONERO_STAGENET_ADDRESS) wownero_receive_address: wownero::Address::from_str(WOWNERO_STAGENET_ADDRESS)
.unwrap(), .unwrap(),
monero_daemon_address: DEFAULT_MONERO_DAEMON_ADDRESS_STAGENET.to_string(), wownero_daemon_address: DEFAULT_WOWNERO_DAEMON_ADDRESS_STAGENET.to_string(),
tor_socks5_port: DEFAULT_SOCKS5_PORT, tor_socks5_port: DEFAULT_SOCKS5_PORT,
}, },
} }
} }
pub fn buy_xmr_mainnet_defaults() -> Self { pub fn buy_wow_mainnet_defaults() -> Self {
Self { Self {
env_config: env::Mainnet::get_config(), env_config: env::Mainnet::get_config(),
debug: false, debug: false,
json: false, json: false,
data_dir: data_dir_path_cli().join(MAINNET), data_dir: data_dir_path_cli().join(MAINNET),
cmd: Command::BuyXmr { cmd: Command::BuyWow {
seller: Multiaddr::from_str(MULTI_ADDRESS).unwrap(), seller: Multiaddr::from_str(MULTI_ADDRESS).unwrap(),
bitcoin_electrum_rpc_url: Url::from_str(DEFAULT_ELECTRUM_RPC_URL).unwrap(), bitcoin_electrum_rpc_url: Url::from_str(DEFAULT_ELECTRUM_RPC_URL).unwrap(),
bitcoin_target_block: DEFAULT_BITCOIN_CONFIRMATION_TARGET, bitcoin_target_block: DEFAULT_BITCOIN_CONFIRMATION_TARGET,
bitcoin_change_address: BITCOIN_MAINNET_ADDRESS.parse().unwrap(), bitcoin_change_address: BITCOIN_MAINNET_ADDRESS.parse().unwrap(),
monero_receive_address: monero::Address::from_str(MONERO_MAINNET_ADDRESS) wownero_receive_address: wownero::Address::from_str(WOWNERO_MAINNET_ADDRESS)
.unwrap(), .unwrap(),
monero_daemon_address: DEFAULT_MONERO_DAEMON_ADDRESS.to_string(), wownero_daemon_address: DEFAULT_WOWNERO_DAEMON_ADDRESS.to_string(),
tor_socks5_port: DEFAULT_SOCKS5_PORT, tor_socks5_port: DEFAULT_SOCKS5_PORT,
}, },
} }
@ -1068,7 +1068,7 @@ mod tests {
bitcoin_electrum_rpc_url: Url::from_str(DEFAULT_ELECTRUM_RPC_URL_TESTNET) bitcoin_electrum_rpc_url: Url::from_str(DEFAULT_ELECTRUM_RPC_URL_TESTNET)
.unwrap(), .unwrap(),
bitcoin_target_block: DEFAULT_BITCOIN_CONFIRMATION_TARGET_TESTNET, bitcoin_target_block: DEFAULT_BITCOIN_CONFIRMATION_TARGET_TESTNET,
monero_daemon_address: DEFAULT_MONERO_DAEMON_ADDRESS_STAGENET.to_string(), wownero_daemon_address: DEFAULT_WOWNERO_DAEMON_ADDRESS_STAGENET.to_string(),
tor_socks5_port: DEFAULT_SOCKS5_PORT, tor_socks5_port: DEFAULT_SOCKS5_PORT,
}, },
} }
@ -1084,7 +1084,7 @@ mod tests {
swap_id: Uuid::from_str(SWAP_ID).unwrap(), swap_id: Uuid::from_str(SWAP_ID).unwrap(),
bitcoin_electrum_rpc_url: Url::from_str(DEFAULT_ELECTRUM_RPC_URL).unwrap(), bitcoin_electrum_rpc_url: Url::from_str(DEFAULT_ELECTRUM_RPC_URL).unwrap(),
bitcoin_target_block: DEFAULT_BITCOIN_CONFIRMATION_TARGET, bitcoin_target_block: DEFAULT_BITCOIN_CONFIRMATION_TARGET,
monero_daemon_address: DEFAULT_MONERO_DAEMON_ADDRESS.to_string(), wownero_daemon_address: DEFAULT_WOWNERO_DAEMON_ADDRESS.to_string(),
tor_socks5_port: DEFAULT_SOCKS5_PORT, tor_socks5_port: DEFAULT_SOCKS5_PORT,
}, },
} }

@ -4,7 +4,7 @@ use crate::network::encrypted_signature;
use crate::network::quote::BidQuote; use crate::network::quote::BidQuote;
use crate::network::swap_setup::bob::NewSwap; use crate::network::swap_setup::bob::NewSwap;
use crate::protocol::bob::State2; use crate::protocol::bob::State2;
use crate::{env, monero}; use crate::{env, wownero};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use futures::future::{BoxFuture, OptionFuture}; use futures::future::{BoxFuture, OptionFuture};
use futures::{FutureExt, StreamExt}; use futures::{FutureExt, StreamExt};
@ -34,7 +34,7 @@ pub struct EventLoop {
inflight_swap_setup: Option<bmrng::Responder<Result<State2>>>, inflight_swap_setup: Option<bmrng::Responder<Result<State2>>>,
/// The sender we will use to relay incoming transfer proofs. /// The sender we will use to relay incoming transfer proofs.
transfer_proof: bmrng::RequestSender<monero::TransferProof, ()>, transfer_proof: bmrng::RequestSender<wownero::TransferProof, ()>,
/// The future representing the successful handling of an incoming transfer /// The future representing the successful handling of an incoming transfer
/// proof. /// proof.
/// ///
@ -217,7 +217,7 @@ impl EventLoop {
#[derive(Debug)] #[derive(Debug)]
pub struct EventLoopHandle { pub struct EventLoopHandle {
swap_setup: bmrng::RequestSender<NewSwap, Result<State2>>, swap_setup: bmrng::RequestSender<NewSwap, Result<State2>>,
transfer_proof: bmrng::RequestReceiver<monero::TransferProof, ()>, transfer_proof: bmrng::RequestReceiver<wownero::TransferProof, ()>,
encrypted_signature: bmrng::RequestSender<EncryptedSignature, ()>, encrypted_signature: bmrng::RequestSender<EncryptedSignature, ()>,
quote: bmrng::RequestSender<(), BidQuote>, quote: bmrng::RequestSender<(), BidQuote>,
env_config: env::Config, env_config: env::Config,
@ -228,7 +228,7 @@ impl EventLoopHandle {
self.swap_setup.send_receive(swap).await? self.swap_setup.send_receive(swap).await?
} }
pub async fn recv_transfer_proof(&mut self) -> Result<monero::TransferProof> { pub async fn recv_transfer_proof(&mut self) -> Result<wownero::TransferProof> {
let (transfer_proof, responder) = self let (transfer_proof, responder) = self
.transfer_proof .transfer_proof
.recv() .recv()

@ -1,5 +1,5 @@
use crate::network::quote::BidQuote; use crate::network::quote::BidQuote;
use crate::network::rendezvous::XmrBtcNamespace; use crate::network::rendezvous::WowBtcNamespace;
use crate::network::{quote, swarm}; use crate::network::{quote, swarm};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use futures::StreamExt; use futures::StreamExt;
@ -24,7 +24,7 @@ use std::time::Duration;
pub async fn list_sellers( pub async fn list_sellers(
rendezvous_node_peer_id: PeerId, rendezvous_node_peer_id: PeerId,
rendezvous_node_addr: Multiaddr, rendezvous_node_addr: Multiaddr,
namespace: XmrBtcNamespace, namespace: WowBtcNamespace,
tor_socks5_port: u16, tor_socks5_port: u16,
identity: identity::Keypair, identity: identity::Keypair,
) -> Result<Vec<Seller>> { ) -> Result<Vec<Seller>> {
@ -116,7 +116,7 @@ struct EventLoop {
swarm: Swarm<Behaviour>, swarm: Swarm<Behaviour>,
rendezvous_peer_id: PeerId, rendezvous_peer_id: PeerId,
rendezvous_addr: Multiaddr, rendezvous_addr: Multiaddr,
namespace: XmrBtcNamespace, namespace: WowBtcNamespace,
reachable_asb_address: HashMap<PeerId, Multiaddr>, reachable_asb_address: HashMap<PeerId, Multiaddr>,
unreachable_asb_address: HashMap<PeerId, Multiaddr>, unreachable_asb_address: HashMap<PeerId, Multiaddr>,
asb_quote_status: HashMap<PeerId, QuoteStatus>, asb_quote_status: HashMap<PeerId, QuoteStatus>,
@ -128,7 +128,7 @@ impl EventLoop {
swarm: Swarm<Behaviour>, swarm: Swarm<Behaviour>,
rendezvous_peer_id: PeerId, rendezvous_peer_id: PeerId,
rendezvous_addr: Multiaddr, rendezvous_addr: Multiaddr,
namespace: XmrBtcNamespace, namespace: WowBtcNamespace,
) -> Self { ) -> Self {
Self { Self {
swarm, swarm,

@ -20,8 +20,8 @@ pub async fn refund(
let state6 = if force { let state6 = if force {
match state { match state {
BobState::BtcLocked(state3) => state3.cancel(), BobState::BtcLocked(state3) => state3.cancel(),
BobState::XmrLockProofReceived { state, .. } => state.cancel(), BobState::WowLockProofReceived { state, .. } => state.cancel(),
BobState::XmrLocked(state4) => state4.cancel(), BobState::WowLocked(state4) => state4.cancel(),
BobState::EncSigSent(state4) => state4.cancel(), BobState::EncSigSent(state4) => state4.cancel(),
BobState::CancelTimelockExpired(state6) => state6, BobState::CancelTimelockExpired(state6) => state6,
BobState::BtcCancelled(state6) => state6, BobState::BtcCancelled(state6) => state6,
@ -29,7 +29,7 @@ pub async fn refund(
| BobState::SwapSetupCompleted(_) | BobState::SwapSetupCompleted(_)
| BobState::BtcRedeemed(_) | BobState::BtcRedeemed(_)
| BobState::BtcRefunded(_) | BobState::BtcRefunded(_)
| BobState::XmrRedeemed { .. } | BobState::WowRedeemed { .. }
| BobState::BtcPunished { .. } | BobState::BtcPunished { .. }
| BobState::SafelyAborted => bail!( | BobState::SafelyAborted => bail!(
"Cannot refund swap {} because it is in state {} which is not refundable.", "Cannot refund swap {} because it is in state {} which is not refundable.",

@ -69,7 +69,7 @@ pub struct Database {
swaps: sled::Tree, swaps: sled::Tree,
peers: sled::Tree, peers: sled::Tree,
addresses: sled::Tree, addresses: sled::Tree,
monero_addresses: sled::Tree, wownero_addresses: sled::Tree,
} }
impl Database { impl Database {
@ -82,13 +82,13 @@ impl Database {
let swaps = db.open_tree("swaps")?; let swaps = db.open_tree("swaps")?;
let peers = db.open_tree("peers")?; let peers = db.open_tree("peers")?;
let addresses = db.open_tree("addresses")?; let addresses = db.open_tree("addresses")?;
let monero_addresses = db.open_tree("monero_addresses")?; let wownero_addresses = db.open_tree("wownero_addresses")?;
Ok(Database { Ok(Database {
swaps, swaps,
peers, peers,
addresses, addresses,
monero_addresses, wownero_addresses,
}) })
} }
@ -119,37 +119,37 @@ impl Database {
Ok(PeerId::from_str(peer_id.as_str())?) Ok(PeerId::from_str(peer_id.as_str())?)
} }
pub async fn insert_monero_address( pub async fn insert_wownero_address(
&self, &self,
swap_id: Uuid, swap_id: Uuid,
address: monero::Address, address: wownero::Address,
) -> Result<()> { ) -> Result<()> {
let key = swap_id.as_bytes(); let key = swap_id.as_bytes();
let value = serialize(&address)?; let value = serialize(&address)?;
self.monero_addresses.insert(key, value)?; self.wownero_addresses.insert(key, value)?;
self.monero_addresses self.wownero_addresses
.flush_async() .flush_async()
.await .await
.map(|_| ()) .map(|_| ())
.context("Could not flush db") .context("Could not flush db")
} }
pub fn get_monero_address(&self, swap_id: Uuid) -> Result<monero::Address> { pub fn get_wownero_address(&self, swap_id: Uuid) -> Result<wownero::Address> {
let encoded = self let encoded = self
.monero_addresses .wownero_addresses
.get(swap_id.as_bytes())? .get(swap_id.as_bytes())?
.ok_or_else(|| { .ok_or_else(|| {
anyhow!( anyhow!(
"No Monero address found for swap id {} in database", "No Wownero address found for swap id {} in database",
swap_id swap_id
) )
})?; })?;
let monero_address = deserialize(&encoded)?; let wownero_address = deserialize(&encoded)?;
Ok(monero_address) Ok(wownero_address)
} }
pub async fn insert_address(&self, peer_id: PeerId, address: Multiaddr) -> Result<()> { pub async fn insert_address(&self, peer_id: PeerId, address: Multiaddr) -> Result<()> {
@ -463,14 +463,14 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
async fn save_and_load_monero_address() -> Result<()> { async fn save_and_load_wownero_address() -> Result<()> {
let db_dir = tempfile::tempdir()?; let db_dir = tempfile::tempdir()?;
let swap_id = Uuid::new_v4(); let swap_id = Uuid::new_v4();
Database::open(db_dir.path())?.insert_monero_address(swap_id, "53gEuGZUhP9JMEBZoGaFNzhwEgiG7hwQdMCqFxiyiTeFPmkbt1mAoNybEUvYBKHcnrSgxnVWgZsTvRBaHBNXPa8tHiCU51a".parse()?).await?; Database::open(db_dir.path())?.insert_wownero_address(swap_id, "53gEuGZUhP9JMEBZoGaFNzhwEgiG7hwQdMCqFxiyiTeFPmkbt1mAoNybEUvYBKHcnrSgxnVWgZsTvRBaHBNXPa8tHiCU51a".parse()?).await?;
let loaded_monero_address = Database::open(db_dir.path())?.get_monero_address(swap_id)?; let loaded_wownero_address = Database::open(db_dir.path())?.get_wownero_address(swap_id)?;
assert_eq!(loaded_monero_address.to_string(), "53gEuGZUhP9JMEBZoGaFNzhwEgiG7hwQdMCqFxiyiTeFPmkbt1mAoNybEUvYBKHcnrSgxnVWgZsTvRBaHBNXPa8tHiCU51a"); assert_eq!(loaded_wownero_address.to_string(), "53gEuGZUhP9JMEBZoGaFNzhwEgiG7hwQdMCqFxiyiTeFPmkbt1mAoNybEUvYBKHcnrSgxnVWgZsTvRBaHBNXPa8tHiCU51a");
Ok(()) Ok(())
} }

@ -1,9 +1,9 @@
use crate::bitcoin::EncryptedSignature; use crate::bitcoin::EncryptedSignature;
use crate::monero; use crate::wownero;
use crate::monero::{monero_private_key, TransferProof}; use crate::wownero::{wownero_private_key, TransferProof};
use crate::protocol::alice; use crate::protocol::alice;
use crate::protocol::alice::AliceState; use crate::protocol::alice::AliceState;
use monero_rpc::wallet::BlockHeight; use wownero_rpc::wallet::BlockHeight;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt; use std::fmt;
@ -21,23 +21,23 @@ pub enum Alice {
BtcLocked { BtcLocked {
state3: alice::State3, state3: alice::State3,
}, },
XmrLockTransactionSent { WowLockTransactionSent {
monero_wallet_restore_blockheight: BlockHeight, wownero_wallet_restore_blockheight: BlockHeight,
transfer_proof: TransferProof, transfer_proof: TransferProof,
state3: alice::State3, state3: alice::State3,
}, },
XmrLocked { WowLocked {
monero_wallet_restore_blockheight: BlockHeight, wownero_wallet_restore_blockheight: BlockHeight,
transfer_proof: TransferProof, transfer_proof: TransferProof,
state3: alice::State3, state3: alice::State3,
}, },
XmrLockTransferProofSent { WowLockTransferProofSent {
monero_wallet_restore_blockheight: BlockHeight, wownero_wallet_restore_blockheight: BlockHeight,
transfer_proof: TransferProof, transfer_proof: TransferProof,
state3: alice::State3, state3: alice::State3,
}, },
EncSigLearned { EncSigLearned {
monero_wallet_restore_blockheight: BlockHeight, wownero_wallet_restore_blockheight: BlockHeight,
transfer_proof: TransferProof, transfer_proof: TransferProof,
encrypted_signature: EncryptedSignature, encrypted_signature: EncryptedSignature,
state3: alice::State3, state3: alice::State3,
@ -46,26 +46,26 @@ pub enum Alice {
state3: alice::State3, state3: alice::State3,
}, },
CancelTimelockExpired { CancelTimelockExpired {
monero_wallet_restore_blockheight: BlockHeight, wownero_wallet_restore_blockheight: BlockHeight,
transfer_proof: TransferProof, transfer_proof: TransferProof,
state3: alice::State3, state3: alice::State3,
}, },
BtcCancelled { BtcCancelled {
monero_wallet_restore_blockheight: BlockHeight, wownero_wallet_restore_blockheight: BlockHeight,
transfer_proof: TransferProof, transfer_proof: TransferProof,
state3: alice::State3, state3: alice::State3,
}, },
BtcPunishable { BtcPunishable {
monero_wallet_restore_blockheight: BlockHeight, wownero_wallet_restore_blockheight: BlockHeight,
transfer_proof: TransferProof, transfer_proof: TransferProof,
state3: alice::State3, state3: alice::State3,
}, },
BtcRefunded { BtcRefunded {
monero_wallet_restore_blockheight: BlockHeight, wownero_wallet_restore_blockheight: BlockHeight,
transfer_proof: TransferProof, transfer_proof: TransferProof,
state3: alice::State3, state3: alice::State3,
#[serde(with = "monero_private_key")] #[serde(with = "wownero_private_key")]
spend_key: monero::PrivateKey, spend_key: wownero::PrivateKey,
}, },
Done(AliceEndState), Done(AliceEndState),
} }
@ -74,7 +74,7 @@ pub enum Alice {
pub enum AliceEndState { pub enum AliceEndState {
SafelyAborted, SafelyAborted,
BtcRedeemed, BtcRedeemed,
XmrRefunded, WowRefunded,
BtcPunished, BtcPunished,
} }
@ -90,40 +90,40 @@ impl From<&AliceState> for Alice {
AliceState::BtcLocked { state3 } => Alice::BtcLocked { AliceState::BtcLocked { state3 } => Alice::BtcLocked {
state3: state3.as_ref().clone(), state3: state3.as_ref().clone(),
}, },
AliceState::XmrLockTransactionSent { AliceState::WowLockTransactionSent {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} => Alice::XmrLockTransactionSent { } => Alice::WowLockTransactionSent {
monero_wallet_restore_blockheight: *monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight: *wownero_wallet_restore_blockheight,
transfer_proof: transfer_proof.clone(), transfer_proof: transfer_proof.clone(),
state3: state3.as_ref().clone(), state3: state3.as_ref().clone(),
}, },
AliceState::XmrLocked { AliceState::WowLocked {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} => Alice::XmrLocked { } => Alice::WowLocked {
monero_wallet_restore_blockheight: *monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight: *wownero_wallet_restore_blockheight,
transfer_proof: transfer_proof.clone(), transfer_proof: transfer_proof.clone(),
state3: state3.as_ref().clone(), state3: state3.as_ref().clone(),
}, },
AliceState::XmrLockTransferProofSent { AliceState::WowLockTransferProofSent {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} => Alice::XmrLockTransferProofSent { } => Alice::WowLockTransferProofSent {
monero_wallet_restore_blockheight: *monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight: *wownero_wallet_restore_blockheight,
transfer_proof: transfer_proof.clone(), transfer_proof: transfer_proof.clone(),
state3: state3.as_ref().clone(), state3: state3.as_ref().clone(),
}, },
AliceState::EncSigLearned { AliceState::EncSigLearned {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
encrypted_signature, encrypted_signature,
} => Alice::EncSigLearned { } => Alice::EncSigLearned {
monero_wallet_restore_blockheight: *monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight: *wownero_wallet_restore_blockheight,
transfer_proof: transfer_proof.clone(), transfer_proof: transfer_proof.clone(),
state3: state3.as_ref().clone(), state3: state3.as_ref().clone(),
encrypted_signature: *encrypted_signature.clone(), encrypted_signature: *encrypted_signature.clone(),
@ -135,41 +135,41 @@ impl From<&AliceState> for Alice {
} }
AliceState::BtcRedeemed => Alice::Done(AliceEndState::BtcRedeemed), AliceState::BtcRedeemed => Alice::Done(AliceEndState::BtcRedeemed),
AliceState::BtcCancelled { AliceState::BtcCancelled {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} => Alice::BtcCancelled { } => Alice::BtcCancelled {
monero_wallet_restore_blockheight: *monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight: *wownero_wallet_restore_blockheight,
transfer_proof: transfer_proof.clone(), transfer_proof: transfer_proof.clone(),
state3: state3.as_ref().clone(), state3: state3.as_ref().clone(),
}, },
AliceState::BtcRefunded { AliceState::BtcRefunded {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
spend_key, spend_key,
state3, state3,
} => Alice::BtcRefunded { } => Alice::BtcRefunded {
monero_wallet_restore_blockheight: *monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight: *wownero_wallet_restore_blockheight,
transfer_proof: transfer_proof.clone(), transfer_proof: transfer_proof.clone(),
spend_key: *spend_key, spend_key: *spend_key,
state3: state3.as_ref().clone(), state3: state3.as_ref().clone(),
}, },
AliceState::BtcPunishable { AliceState::BtcPunishable {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} => Alice::BtcPunishable { } => Alice::BtcPunishable {
monero_wallet_restore_blockheight: *monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight: *wownero_wallet_restore_blockheight,
transfer_proof: transfer_proof.clone(), transfer_proof: transfer_proof.clone(),
state3: state3.as_ref().clone(), state3: state3.as_ref().clone(),
}, },
AliceState::XmrRefunded => Alice::Done(AliceEndState::XmrRefunded), AliceState::WowRefunded => Alice::Done(AliceEndState::WowRefunded),
AliceState::CancelTimelockExpired { AliceState::CancelTimelockExpired {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} => Alice::CancelTimelockExpired { } => Alice::CancelTimelockExpired {
monero_wallet_restore_blockheight: *monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight: *wownero_wallet_restore_blockheight,
transfer_proof: transfer_proof.clone(), transfer_proof: transfer_proof.clone(),
state3: state3.as_ref().clone(), state3: state3.as_ref().clone(),
}, },
@ -191,40 +191,40 @@ impl From<Alice> for AliceState {
Alice::BtcLocked { state3 } => AliceState::BtcLocked { Alice::BtcLocked { state3 } => AliceState::BtcLocked {
state3: Box::new(state3), state3: Box::new(state3),
}, },
Alice::XmrLockTransactionSent { Alice::WowLockTransactionSent {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} => AliceState::XmrLockTransactionSent { } => AliceState::WowLockTransactionSent {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3: Box::new(state3), state3: Box::new(state3),
}, },
Alice::XmrLocked { Alice::WowLocked {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} => AliceState::XmrLocked { } => AliceState::WowLocked {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3: Box::new(state3), state3: Box::new(state3),
}, },
Alice::XmrLockTransferProofSent { Alice::WowLockTransferProofSent {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} => AliceState::XmrLockTransferProofSent { } => AliceState::WowLockTransferProofSent {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3: Box::new(state3), state3: Box::new(state3),
}, },
Alice::EncSigLearned { Alice::EncSigLearned {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3: state, state3: state,
encrypted_signature, encrypted_signature,
} => AliceState::EncSigLearned { } => AliceState::EncSigLearned {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3: Box::new(state), state3: Box::new(state),
encrypted_signature: Box::new(encrypted_signature), encrypted_signature: Box::new(encrypted_signature),
@ -235,40 +235,40 @@ impl From<Alice> for AliceState {
} }
} }
Alice::CancelTimelockExpired { Alice::CancelTimelockExpired {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} => AliceState::CancelTimelockExpired { } => AliceState::CancelTimelockExpired {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3: Box::new(state3), state3: Box::new(state3),
}, },
Alice::BtcCancelled { Alice::BtcCancelled {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} => AliceState::BtcCancelled { } => AliceState::BtcCancelled {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3: Box::new(state3), state3: Box::new(state3),
}, },
Alice::BtcPunishable { Alice::BtcPunishable {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} => AliceState::BtcPunishable { } => AliceState::BtcPunishable {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3: Box::new(state3), state3: Box::new(state3),
}, },
Alice::BtcRefunded { Alice::BtcRefunded {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
spend_key, spend_key,
state3, state3,
} => AliceState::BtcRefunded { } => AliceState::BtcRefunded {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
spend_key, spend_key,
state3: Box::new(state3), state3: Box::new(state3),
@ -276,7 +276,7 @@ impl From<Alice> for AliceState {
Alice::Done(end_state) => match end_state { Alice::Done(end_state) => match end_state {
AliceEndState::SafelyAborted => AliceState::SafelyAborted, AliceEndState::SafelyAborted => AliceState::SafelyAborted,
AliceEndState::BtcRedeemed => AliceState::BtcRedeemed, AliceEndState::BtcRedeemed => AliceState::BtcRedeemed,
AliceEndState::XmrRefunded => AliceState::XmrRefunded, AliceEndState::WowRefunded => AliceState::WowRefunded,
AliceEndState::BtcPunished => AliceState::BtcPunished, AliceEndState::BtcPunished => AliceState::BtcPunished,
}, },
} }
@ -291,10 +291,10 @@ impl fmt::Display for Alice {
write!(f, "Bitcoin lock transaction in mempool") write!(f, "Bitcoin lock transaction in mempool")
} }
Alice::BtcLocked { .. } => f.write_str("Bitcoin locked"), Alice::BtcLocked { .. } => f.write_str("Bitcoin locked"),
Alice::XmrLockTransactionSent { .. } => f.write_str("Monero lock transaction sent"), Alice::WowLockTransactionSent { .. } => f.write_str("Wownero lock transaction sent"),
Alice::XmrLocked { .. } => f.write_str("Monero locked"), Alice::WowLocked { .. } => f.write_str("Wownero locked"),
Alice::XmrLockTransferProofSent { .. } => { Alice::WowLockTransferProofSent { .. } => {
f.write_str("Monero lock transfer proof sent") f.write_str("Wownero lock transfer proof sent")
} }
Alice::EncSigLearned { .. } => f.write_str("Encrypted signature learned"), Alice::EncSigLearned { .. } => f.write_str("Encrypted signature learned"),
Alice::BtcRedeemTransactionPublished { .. } => { Alice::BtcRedeemTransactionPublished { .. } => {
@ -303,7 +303,7 @@ impl fmt::Display for Alice {
Alice::CancelTimelockExpired { .. } => f.write_str("Cancel timelock is expired"), Alice::CancelTimelockExpired { .. } => f.write_str("Cancel timelock is expired"),
Alice::BtcCancelled { .. } => f.write_str("Bitcoin cancel transaction published"), Alice::BtcCancelled { .. } => f.write_str("Bitcoin cancel transaction published"),
Alice::BtcPunishable { .. } => f.write_str("Bitcoin punishable"), Alice::BtcPunishable { .. } => f.write_str("Bitcoin punishable"),
Alice::BtcRefunded { .. } => f.write_str("Monero refundable"), Alice::BtcRefunded { .. } => f.write_str("Wownero refundable"),
Alice::Done(end_state) => write!(f, "Done: {}", end_state), Alice::Done(end_state) => write!(f, "Done: {}", end_state),
} }
} }

@ -1,7 +1,7 @@
use crate::monero::TransferProof; use crate::wownero::TransferProof;
use crate::protocol::bob; use crate::protocol::bob;
use crate::protocol::bob::BobState; use crate::protocol::bob::BobState;
use monero_rpc::wallet::BlockHeight; use wownero_rpc::wallet::BlockHeight;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_with::{serde_as, DisplayFromStr}; use serde_with::{serde_as, DisplayFromStr};
use std::fmt; use std::fmt;
@ -21,12 +21,12 @@ pub enum Bob {
BtcLocked { BtcLocked {
state3: bob::State3, state3: bob::State3,
}, },
XmrLockProofReceived { WowLockProofReceived {
state: bob::State3, state: bob::State3,
lock_transfer_proof: TransferProof, lock_transfer_proof: TransferProof,
monero_wallet_restore_blockheight: BlockHeight, wownero_wallet_restore_blockheight: BlockHeight,
}, },
XmrLocked { WowLocked {
state4: bob::State4, state4: bob::State4,
}, },
EncSigSent { EncSigSent {
@ -41,7 +41,7 @@ pub enum Bob {
#[derive(Clone, strum::Display, Debug, Deserialize, Serialize, PartialEq)] #[derive(Clone, strum::Display, Debug, Deserialize, Serialize, PartialEq)]
pub enum BobEndState { pub enum BobEndState {
SafelyAborted, SafelyAborted,
XmrRedeemed { tx_lock_id: bitcoin::Txid }, WowRedeemed { tx_lock_id: bitcoin::Txid },
BtcRefunded(Box<bob::State6>), BtcRefunded(Box<bob::State6>),
BtcPunished { tx_lock_id: bitcoin::Txid }, BtcPunished { tx_lock_id: bitcoin::Txid },
} }
@ -58,23 +58,23 @@ impl From<BobState> for Bob {
}, },
BobState::SwapSetupCompleted(state2) => Bob::ExecutionSetupDone { state2 }, BobState::SwapSetupCompleted(state2) => Bob::ExecutionSetupDone { state2 },
BobState::BtcLocked(state3) => Bob::BtcLocked { state3 }, BobState::BtcLocked(state3) => Bob::BtcLocked { state3 },
BobState::XmrLockProofReceived { BobState::WowLockProofReceived {
state, state,
lock_transfer_proof, lock_transfer_proof,
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
} => Bob::XmrLockProofReceived { } => Bob::WowLockProofReceived {
state, state,
lock_transfer_proof, lock_transfer_proof,
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
}, },
BobState::XmrLocked(state4) => Bob::XmrLocked { state4 }, BobState::WowLocked(state4) => Bob::WowLocked { state4 },
BobState::EncSigSent(state4) => Bob::EncSigSent { state4 }, BobState::EncSigSent(state4) => Bob::EncSigSent { state4 },
BobState::BtcRedeemed(state5) => Bob::BtcRedeemed(state5), BobState::BtcRedeemed(state5) => Bob::BtcRedeemed(state5),
BobState::CancelTimelockExpired(state6) => Bob::CancelTimelockExpired(state6), BobState::CancelTimelockExpired(state6) => Bob::CancelTimelockExpired(state6),
BobState::BtcCancelled(state6) => Bob::BtcCancelled(state6), BobState::BtcCancelled(state6) => Bob::BtcCancelled(state6),
BobState::BtcRefunded(state6) => Bob::Done(BobEndState::BtcRefunded(Box::new(state6))), BobState::BtcRefunded(state6) => Bob::Done(BobEndState::BtcRefunded(Box::new(state6))),
BobState::XmrRedeemed { tx_lock_id } => { BobState::WowRedeemed { tx_lock_id } => {
Bob::Done(BobEndState::XmrRedeemed { tx_lock_id }) Bob::Done(BobEndState::WowRedeemed { tx_lock_id })
} }
BobState::BtcPunished { tx_lock_id } => { BobState::BtcPunished { tx_lock_id } => {
Bob::Done(BobEndState::BtcPunished { tx_lock_id }) Bob::Done(BobEndState::BtcPunished { tx_lock_id })
@ -96,23 +96,23 @@ impl From<Bob> for BobState {
}, },
Bob::ExecutionSetupDone { state2 } => BobState::SwapSetupCompleted(state2), Bob::ExecutionSetupDone { state2 } => BobState::SwapSetupCompleted(state2),
Bob::BtcLocked { state3 } => BobState::BtcLocked(state3), Bob::BtcLocked { state3 } => BobState::BtcLocked(state3),
Bob::XmrLockProofReceived { Bob::WowLockProofReceived {
state, state,
lock_transfer_proof, lock_transfer_proof,
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
} => BobState::XmrLockProofReceived { } => BobState::WowLockProofReceived {
state, state,
lock_transfer_proof, lock_transfer_proof,
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
}, },
Bob::XmrLocked { state4 } => BobState::XmrLocked(state4), Bob::WowLocked { state4 } => BobState::WowLocked(state4),
Bob::EncSigSent { state4 } => BobState::EncSigSent(state4), Bob::EncSigSent { state4 } => BobState::EncSigSent(state4),
Bob::BtcRedeemed(state5) => BobState::BtcRedeemed(state5), Bob::BtcRedeemed(state5) => BobState::BtcRedeemed(state5),
Bob::CancelTimelockExpired(state6) => BobState::CancelTimelockExpired(state6), Bob::CancelTimelockExpired(state6) => BobState::CancelTimelockExpired(state6),
Bob::BtcCancelled(state6) => BobState::BtcCancelled(state6), Bob::BtcCancelled(state6) => BobState::BtcCancelled(state6),
Bob::Done(end_state) => match end_state { Bob::Done(end_state) => match end_state {
BobEndState::SafelyAborted => BobState::SafelyAborted, BobEndState::SafelyAborted => BobState::SafelyAborted,
BobEndState::XmrRedeemed { tx_lock_id } => BobState::XmrRedeemed { tx_lock_id }, BobEndState::WowRedeemed { tx_lock_id } => BobState::WowRedeemed { tx_lock_id },
BobEndState::BtcRefunded(state6) => BobState::BtcRefunded(*state6), BobEndState::BtcRefunded(state6) => BobState::BtcRefunded(*state6),
BobEndState::BtcPunished { tx_lock_id } => BobState::BtcPunished { tx_lock_id }, BobEndState::BtcPunished { tx_lock_id } => BobState::BtcPunished { tx_lock_id },
}, },
@ -126,13 +126,13 @@ impl fmt::Display for Bob {
Bob::Started { .. } => write!(f, "Started"), Bob::Started { .. } => write!(f, "Started"),
Bob::ExecutionSetupDone { .. } => f.write_str("Execution setup done"), Bob::ExecutionSetupDone { .. } => f.write_str("Execution setup done"),
Bob::BtcLocked { .. } => f.write_str("Bitcoin locked"), Bob::BtcLocked { .. } => f.write_str("Bitcoin locked"),
Bob::XmrLockProofReceived { .. } => { Bob::WowLockProofReceived { .. } => {
f.write_str("XMR lock transaction transfer proof received") f.write_str("WOW lock transaction transfer proof received")
} }
Bob::XmrLocked { .. } => f.write_str("Monero locked"), Bob::WowLocked { .. } => f.write_str("Wownero locked"),
Bob::CancelTimelockExpired(_) => f.write_str("Cancel timelock is expired"), Bob::CancelTimelockExpired(_) => f.write_str("Cancel timelock is expired"),
Bob::BtcCancelled(_) => f.write_str("Bitcoin refundable"), Bob::BtcCancelled(_) => f.write_str("Bitcoin refundable"),
Bob::BtcRedeemed(_) => f.write_str("Monero redeemable"), Bob::BtcRedeemed(_) => f.write_str("Wownero redeemable"),
Bob::Done(end_state) => write!(f, "Done: {}", end_state), Bob::Done(end_state) => write!(f, "Done: {}", end_state),
Bob::EncSigSent { .. } => f.write_str("Encrypted signature sent"), Bob::EncSigSent { .. } => f.write_str("Encrypted signature sent"),
} }

@ -13,9 +13,9 @@ pub struct Config {
pub bitcoin_cancel_timelock: CancelTimelock, pub bitcoin_cancel_timelock: CancelTimelock,
pub bitcoin_punish_timelock: PunishTimelock, pub bitcoin_punish_timelock: PunishTimelock,
pub bitcoin_network: bitcoin::Network, pub bitcoin_network: bitcoin::Network,
pub monero_avg_block_time: Duration, pub wownero_avg_block_time: Duration,
pub monero_finality_confirmations: u64, pub wownero_finality_confirmations: u64,
pub monero_network: monero::Network, pub wownero_network: wownero::Network,
} }
impl Config { impl Config {
@ -23,8 +23,8 @@ impl Config {
sync_interval(self.bitcoin_avg_block_time) sync_interval(self.bitcoin_avg_block_time)
} }
pub fn monero_sync_interval(&self) -> Duration { pub fn wownero_sync_interval(&self) -> Duration {
sync_interval(self.monero_avg_block_time) sync_interval(self.wownero_avg_block_time)
} }
} }
@ -51,9 +51,9 @@ impl GetConfig for Mainnet {
bitcoin_cancel_timelock: CancelTimelock::new(72), bitcoin_cancel_timelock: CancelTimelock::new(72),
bitcoin_punish_timelock: PunishTimelock::new(72), bitcoin_punish_timelock: PunishTimelock::new(72),
bitcoin_network: bitcoin::Network::Bitcoin, bitcoin_network: bitcoin::Network::Bitcoin,
monero_avg_block_time: 2.minutes(), wownero_avg_block_time: 5.minutes(),
monero_finality_confirmations: 10, wownero_finality_confirmations: 4,
monero_network: monero::Network::Mainnet, wownero_network: wownero::Network::Mainnet,
} }
} }
} }
@ -68,9 +68,9 @@ impl GetConfig for Testnet {
bitcoin_cancel_timelock: CancelTimelock::new(12), bitcoin_cancel_timelock: CancelTimelock::new(12),
bitcoin_punish_timelock: PunishTimelock::new(6), bitcoin_punish_timelock: PunishTimelock::new(6),
bitcoin_network: bitcoin::Network::Testnet, bitcoin_network: bitcoin::Network::Testnet,
monero_avg_block_time: 2.minutes(), wownero_avg_block_time: 5.minutes(),
monero_finality_confirmations: 10, wownero_finality_confirmations: 4,
monero_network: monero::Network::Stagenet, wownero_network: wownero::Network::Stagenet,
} }
} }
} }
@ -85,9 +85,9 @@ impl GetConfig for Regtest {
bitcoin_cancel_timelock: CancelTimelock::new(100), bitcoin_cancel_timelock: CancelTimelock::new(100),
bitcoin_punish_timelock: PunishTimelock::new(50), bitcoin_punish_timelock: PunishTimelock::new(50),
bitcoin_network: bitcoin::Network::Regtest, bitcoin_network: bitcoin::Network::Regtest,
monero_avg_block_time: 1.seconds(), wownero_avg_block_time: 1.seconds(),
monero_finality_confirmations: 10, wownero_finality_confirmations: 4,
monero_network: monero::Network::Mainnet, // yes this is strange wownero_network: wownero::Network::Mainnet, // yes this is strange
} }
} }
} }
@ -113,9 +113,9 @@ pub fn new(is_testnet: bool, asb_config: &asb::config::Config) -> Config {
env_config env_config
}; };
if let Some(monero_finality_confirmations) = asb_config.monero.finality_confirmations { if let Some(wownero_finality_confirmations) = asb_config.wownero.finality_confirmations {
Config { Config {
monero_finality_confirmations, wownero_finality_confirmations,
..env_config ..env_config
} }
} else { } else {

@ -3,19 +3,19 @@ use directories_next::ProjectDirs;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
/// This is the default location for the overall config-dir specific by system /// This is the default location for the overall config-dir specific by system
// Linux: /home/<user>/.config/xmr-btc-swap/ // Linux: /home/<user>/.config/wow-btc-swap/
// OSX: /Users/<user>/Library/Preferences/xmr-btc-swap/ // OSX: /Users/<user>/Library/Preferences/wow-btc-swap/
pub fn system_config_dir() -> Result<PathBuf> { pub fn system_config_dir() -> Result<PathBuf> {
ProjectDirs::from("", "", "xmr-btc-swap") ProjectDirs::from("", "", "wow-btc-swap")
.map(|proj_dirs| proj_dirs.config_dir().to_path_buf()) .map(|proj_dirs| proj_dirs.config_dir().to_path_buf())
.context("Could not generate default system configuration dir path") .context("Could not generate default system configuration dir path")
} }
/// This is the default location for the overall data-dir specific by system /// This is the default location for the overall data-dir specific by system
// Linux: /home/<user>/.local/share/xmr-btc-swap/ // Linux: /home/<user>/.local/share/wow-btc-swap/
// OSX: /Users/<user>/Library/ApplicationSupport/xmr-btc-swap/ // OSX: /Users/<user>/Library/ApplicationSupport/wow-btc-swap/
pub fn system_data_dir() -> Result<PathBuf> { pub fn system_data_dir() -> Result<PathBuf> {
ProjectDirs::from("", "", "xmr-btc-swap") ProjectDirs::from("", "", "wow-btc-swap")
.map(|proj_dirs| proj_dirs.data_dir().to_path_buf()) .map(|proj_dirs| proj_dirs.data_dir().to_path_buf())
.context("Could not generate default system data-dir dir path") .context("Could not generate default system data-dir dir path")
} }

@ -135,7 +135,7 @@ mod connection {
.context("Failed to connect to Kraken websocket API")?; .context("Failed to connect to Kraken websocket API")?;
rate_stream rate_stream
.send(SUBSCRIBE_XMR_BTC_TICKER_PAYLOAD.into()) .send(SUBSCRIBE_WOW_BTC_TICKER_PAYLOAD.into())
.await?; .await?;
let stream = rate_stream.err_into().try_filter_map(parse_message).boxed(); let stream = rate_stream.err_into().try_filter_map(parse_message).boxed();
@ -213,9 +213,9 @@ mod connection {
Parse(#[from] wire::Error), Parse(#[from] wire::Error),
} }
const SUBSCRIBE_XMR_BTC_TICKER_PAYLOAD: &str = r#" const SUBSCRIBE_WOW_BTC_TICKER_PAYLOAD: &str = r#"
{ "event": "subscribe", { "event": "subscribe",
"pair": [ "XMR/XBT" ], "pair": [ "WOW/XBT" ],
"subscription": { "subscription": {
"name": "ticker" "name": "ticker"
} }
@ -325,7 +325,7 @@ mod wire {
#[test] #[test]
fn can_deserialize_subscription_status_event() { fn can_deserialize_subscription_status_event() {
let event = r#"{"channelID":980,"channelName":"ticker","event":"subscriptionStatus","pair":"XMR/XBT","status":"subscribed","subscription":{"name":"ticker"}}"#; let event = r#"{"channelID":980,"channelName":"ticker","event":"subscriptionStatus","pair":"WOW/XBT","status":"subscribed","subscription":{"name":"ticker"}}"#;
let event = serde_json::from_str::<Event>(event).unwrap(); let event = serde_json::from_str::<Event>(event).unwrap();
@ -334,7 +334,7 @@ mod wire {
#[test] #[test]
fn deserialize_ticker_update() { fn deserialize_ticker_update() {
let message = r#"[980,{"a":["0.00440700",7,"7.35318535"],"b":["0.00440200",7,"7.57416678"],"c":["0.00440700","0.22579000"],"v":["273.75489000","4049.91233351"],"p":["0.00446205","0.00441699"],"t":[123,1310],"l":["0.00439400","0.00429900"],"h":["0.00450000","0.00450000"],"o":["0.00449100","0.00433700"]},"ticker","XMR/XBT"]"#; let message = r#"[980,{"a":["0.00440700",7,"7.35318535"],"b":["0.00440200",7,"7.57416678"],"c":["0.00440700","0.22579000"],"v":["273.75489000","4049.91233351"],"p":["0.00446205","0.00441699"],"t":[123,1310],"l":["0.00439400","0.00429900"],"h":["0.00450000","0.00450000"],"o":["0.00449100","0.00433700"]},"ticker","WOW/XBT"]"#;
let _ = serde_json::from_str::<TickerUpdate>(message).unwrap(); let _ = serde_json::from_str::<TickerUpdate>(message).unwrap();
} }

@ -24,14 +24,14 @@ pub mod env;
pub mod fs; pub mod fs;
pub mod kraken; pub mod kraken;
pub mod libp2p_ext; pub mod libp2p_ext;
pub mod monero; pub mod wownero;
pub mod network; pub mod network;
pub mod protocol; pub mod protocol;
pub mod seed; pub mod seed;
pub mod tor; pub mod tor;
pub mod tracing_ext; pub mod tracing_ext;
mod monero_ext; mod wownero_ext;
#[cfg(test)] #[cfg(test)]
mod proptest; mod proptest;

@ -9,7 +9,7 @@ use libp2p::PeerId;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use uuid::Uuid; use uuid::Uuid;
const PROTOCOL: &str = "/comit/xmr/btc/encrypted_signature/1.0.0"; const PROTOCOL: &str = "/comit/wow/btc/encrypted_signature/1.0.0";
type OutEvent = RequestResponseEvent<Request, ()>; type OutEvent = RequestResponseEvent<Request, ()>;
type Message = RequestResponseMessage<Request, ()>; type Message = RequestResponseMessage<Request, ()>;

@ -8,7 +8,7 @@ use libp2p::request_response::{
use libp2p::PeerId; use libp2p::PeerId;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
const PROTOCOL: &str = "/comit/xmr/btc/bid-quote/1.0.0"; const PROTOCOL: &str = "/comit/wow/btc/bid-quote/1.0.0";
pub type OutEvent = RequestResponseEvent<(), BidQuote>; pub type OutEvent = RequestResponseEvent<(), BidQuote>;
pub type Message = RequestResponseMessage<(), BidQuote>; pub type Message = RequestResponseMessage<(), BidQuote>;
@ -23,7 +23,7 @@ impl ProtocolName for BidQuoteProtocol {
} }
} }
/// Represents a quote for buying XMR. /// Represents a quote for buying WOW.
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] #[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub struct BidQuote { pub struct BidQuote {
/// The price at which the maker is willing to buy at. /// The price at which the maker is willing to buy at.

@ -2,28 +2,28 @@ use libp2p::rendezvous::Namespace;
use std::fmt; use std::fmt;
#[derive(Debug, PartialEq, Clone, Copy)] #[derive(Debug, PartialEq, Clone, Copy)]
pub enum XmrBtcNamespace { pub enum WowBtcNamespace {
Mainnet, Mainnet,
Testnet, Testnet,
} }
const MAINNET: &str = "xmr-btc-swap-mainnet"; const MAINNET: &str = "wow-btc-swap-mainnet";
const TESTNET: &str = "xmr-btc-swap-testnet"; const TESTNET: &str = "wow-btc-swap-testnet";
impl fmt::Display for XmrBtcNamespace { impl fmt::Display for WowBtcNamespace {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
XmrBtcNamespace::Mainnet => write!(f, "{}", MAINNET), WowBtcNamespace::Mainnet => write!(f, "{}", MAINNET),
XmrBtcNamespace::Testnet => write!(f, "{}", TESTNET), WowBtcNamespace::Testnet => write!(f, "{}", TESTNET),
} }
} }
} }
impl From<XmrBtcNamespace> for Namespace { impl From<WowBtcNamespace> for Namespace {
fn from(namespace: XmrBtcNamespace) -> Self { fn from(namespace: WowBtcNamespace) -> Self {
match namespace { match namespace {
XmrBtcNamespace::Mainnet => Namespace::from_static(MAINNET), WowBtcNamespace::Mainnet => Namespace::from_static(MAINNET),
XmrBtcNamespace::Testnet => Namespace::from_static(TESTNET), WowBtcNamespace::Testnet => Namespace::from_static(TESTNET),
} }
} }
} }

@ -1,4 +1,4 @@
use crate::monero; use crate::wownero;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use libp2p::core::upgrade; use libp2p::core::upgrade;
use libp2p::swarm::NegotiatedSubstream; use libp2p::swarm::NegotiatedSubstream;
@ -19,7 +19,7 @@ pub mod protocol {
pub fn new() -> SwapSetup { pub fn new() -> SwapSetup {
from_fn( from_fn(
b"/comit/xmr/btc/swap_setup/1.0.0", b"/comit/wow/btc/swap_setup/1.0.0",
Box::new(|socket, _| future::ready(Ok(socket))), Box::new(|socket, _| future::ready(Ok(socket))),
) )
} }
@ -41,8 +41,8 @@ pub mod protocol {
pub struct BlockchainNetwork { pub struct BlockchainNetwork {
#[serde(with = "crate::bitcoin::network")] #[serde(with = "crate::bitcoin::network")]
pub bitcoin: bitcoin::Network, pub bitcoin: bitcoin::Network,
#[serde(with = "crate::monero::network")] #[serde(with = "crate::wownero::network")]
pub monero: monero::Network, pub wownero: wownero::Network,
} }
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
@ -54,7 +54,7 @@ pub struct SpotPriceRequest {
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub enum SpotPriceResponse { pub enum SpotPriceResponse {
Xmr(monero::Amount), Wow(wownero::Amount),
Error(SpotPriceError), Error(SpotPriceError),
} }

@ -5,7 +5,7 @@ use crate::network::swap_setup::{
}; };
use crate::protocol::alice::{State0, State3}; use crate::protocol::alice::{State0, State3};
use crate::protocol::{Message0, Message2, Message4}; use crate::protocol::{Message0, Message2, Message4};
use crate::{asb, bitcoin, env, monero}; use crate::{asb, bitcoin, env, wownero};
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use futures::future::{BoxFuture, OptionFuture}; use futures::future::{BoxFuture, OptionFuture};
use futures::{AsyncWriteExt, FutureExt}; use futures::{AsyncWriteExt, FutureExt};
@ -42,8 +42,8 @@ pub enum OutEvent {
#[derive(Debug)] #[derive(Debug)]
pub struct WalletSnapshot { pub struct WalletSnapshot {
balance: monero::Amount, balance: wownero::Amount,
lock_fee: monero::Amount, lock_fee: wownero::Amount,
// TODO: Consider using the same address for punish and redeem (they are mutually exclusive, so // TODO: Consider using the same address for punish and redeem (they are mutually exclusive, so
// effectively the address will only be used once) // effectively the address will only be used once)
@ -57,10 +57,10 @@ pub struct WalletSnapshot {
impl WalletSnapshot { impl WalletSnapshot {
pub async fn capture( pub async fn capture(
bitcoin_wallet: &bitcoin::Wallet, bitcoin_wallet: &bitcoin::Wallet,
monero_wallet: &monero::Wallet, wownero_wallet: &wownero::Wallet,
transfer_amount: bitcoin::Amount, transfer_amount: bitcoin::Amount,
) -> Result<Self> { ) -> Result<Self> {
let balance = monero_wallet.get_balance().await?; let balance = wownero_wallet.get_balance().await?;
let redeem_address = bitcoin_wallet.new_address().await?; let redeem_address = bitcoin_wallet.new_address().await?;
let punish_address = bitcoin_wallet.new_address().await?; let punish_address = bitcoin_wallet.new_address().await?;
let redeem_fee = bitcoin_wallet let redeem_fee = bitcoin_wallet
@ -72,7 +72,7 @@ impl WalletSnapshot {
Ok(Self { Ok(Self {
balance, balance,
lock_fee: monero::MONERO_FEE, lock_fee: wownero::WOWNERO_FEE,
redeem_address, redeem_address,
punish_address, punish_address,
redeem_fee, redeem_fee,
@ -291,7 +291,7 @@ where
let blockchain_network = BlockchainNetwork { let blockchain_network = BlockchainNetwork {
bitcoin: env_config.bitcoin_network, bitcoin: env_config.bitcoin_network,
monero: env_config.monero_network, wownero: env_config.wownero_network,
}; };
if request.blockchain_network != blockchain_network { if request.blockchain_network != blockchain_network {
@ -318,18 +318,18 @@ where
} }
let rate = latest_rate.map_err(|e| Error::LatestRateFetchFailed(Box::new(e)))?; let rate = latest_rate.map_err(|e| Error::LatestRateFetchFailed(Box::new(e)))?;
let xmr = rate let wow = rate
.sell_quote(btc) .sell_quote(btc)
.map_err(Error::SellQuoteCalculationFailed)?; .map_err(Error::SellQuoteCalculationFailed)?;
if wallet_snapshot.balance < xmr + wallet_snapshot.lock_fee { if wallet_snapshot.balance < wow + wallet_snapshot.lock_fee {
return Err(Error::BalanceTooLow { return Err(Error::BalanceTooLow {
balance: wallet_snapshot.balance, balance: wallet_snapshot.balance,
buy: btc, buy: btc,
}); });
} }
Ok(xmr) Ok(wow)
}; };
let result = validate.await; let result = validate.await;
@ -341,11 +341,11 @@ where
.await .await
.context("Failed to write spot price response")?; .context("Failed to write spot price response")?;
let xmr = result?; let wow = result?;
let state0 = State0::new( let state0 = State0::new(
request.btc, request.btc,
xmr, wow,
env_config, env_config,
wallet_snapshot.redeem_address, wallet_snapshot.redeem_address,
wallet_snapshot.punish_address, wallet_snapshot.punish_address,
@ -456,9 +456,9 @@ where
} }
impl SpotPriceResponse { impl SpotPriceResponse {
pub fn from_result_ref(result: &Result<monero::Amount, Error>) -> Self { pub fn from_result_ref(result: &Result<wownero::Amount, Error>) -> Self {
match result { match result {
Ok(amount) => SpotPriceResponse::Xmr(*amount), Ok(amount) => SpotPriceResponse::Wow(*amount),
Err(error) => SpotPriceResponse::Error(error.to_error_response()), Err(error) => SpotPriceResponse::Error(error.to_error_response()),
} }
} }
@ -480,7 +480,7 @@ pub enum Error {
}, },
#[error("Balance {balance} too low to fulfill swapping {buy}")] #[error("Balance {balance} too low to fulfill swapping {buy}")]
BalanceTooLow { BalanceTooLow {
balance: monero::Amount, balance: wownero::Amount,
buy: bitcoin::Amount, buy: bitcoin::Amount,
}, },
#[error("Failed to fetch latest rate")] #[error("Failed to fetch latest rate")]

@ -4,7 +4,7 @@ use crate::network::swap_setup::{
}; };
use crate::protocol::bob::{State0, State2}; use crate::protocol::bob::{State0, State2};
use crate::protocol::{Message1, Message3}; use crate::protocol::{Message1, Message3};
use crate::{bitcoin, cli, env, monero}; use crate::{bitcoin, cli, env, wownero};
use anyhow::Result; use anyhow::Result;
use futures::future::{BoxFuture, OptionFuture}; use futures::future::{BoxFuture, OptionFuture};
use futures::{AsyncWriteExt, FutureExt}; use futures::{AsyncWriteExt, FutureExt};
@ -158,22 +158,22 @@ impl ProtocolsHandler for Handler {
btc: info.btc, btc: info.btc,
blockchain_network: BlockchainNetwork { blockchain_network: BlockchainNetwork {
bitcoin: env_config.bitcoin_network, bitcoin: env_config.bitcoin_network,
monero: env_config.monero_network, wownero: env_config.wownero_network,
}, },
}) })
.await?; .await?;
let xmr = Result::from(read_cbor_message::<SpotPriceResponse>(&mut substream).await?)?; let WOW = Result::from(read_cbor_message::<SpotPriceResponse>(&mut substream).await?)?;
let state0 = State0::new( let state0 = State0::new(
info.swap_id, info.swap_id,
&mut rand::thread_rng(), &mut rand::thread_rng(),
info.btc, info.btc,
xmr, wow,
env_config.bitcoin_cancel_timelock, env_config.bitcoin_cancel_timelock,
env_config.bitcoin_punish_timelock, env_config.bitcoin_punish_timelock,
info.bitcoin_refund_address, info.bitcoin_refund_address,
env_config.monero_finality_confirmations, env_config.wownero_finality_confirmations,
info.tx_refund_fee, info.tx_refund_fee,
info.tx_cancel_fee, info.tx_cancel_fee,
); );
@ -248,10 +248,10 @@ impl ProtocolsHandler for Handler {
} }
} }
impl From<SpotPriceResponse> for Result<monero::Amount, Error> { impl From<SpotPriceResponse> for Result<wownero::Amount, Error> {
fn from(response: SpotPriceResponse) -> Self { fn from(response: SpotPriceResponse) -> Self {
match response { match response {
SpotPriceResponse::Xmr(amount) => Ok(amount), SpotPriceResponse::Wow(amount) => Ok(amount),
SpotPriceResponse::Error(e) => Err(e.into()), SpotPriceResponse::Error(e) => Err(e.into()),
} }
} }
@ -271,7 +271,7 @@ pub enum Error {
max: bitcoin::Amount, max: bitcoin::Amount,
buy: bitcoin::Amount, buy: bitcoin::Amount,
}, },
#[error("Seller's XMR balance is currently too low to fulfill the swap request to buy {buy}, please try again later")] #[error("Seller's WOW balance is currently too low to fulfill the swap request to buy {buy}, please try again later")]
BalanceTooLow { buy: bitcoin::Amount }, BalanceTooLow { buy: bitcoin::Amount },
#[error("Seller blockchain network {asb:?} setup did not match your blockchain network setup {cli:?}")] #[error("Seller blockchain network {asb:?} setup did not match your blockchain network setup {cli:?}")]

@ -1,6 +1,6 @@
use crate::asb::LatestRate; use crate::asb::LatestRate;
use crate::libp2p_ext::MultiAddrExt; use crate::libp2p_ext::MultiAddrExt;
use crate::network::rendezvous::XmrBtcNamespace; use crate::network::rendezvous::WowBtcNamespace;
use crate::seed::Seed; use crate::seed::Seed;
use crate::{asb, bitcoin, cli, env, tor}; use crate::{asb, bitcoin, cli, env, tor};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
@ -16,7 +16,7 @@ pub fn asb<LR>(
latest_rate: LR, latest_rate: LR,
resume_only: bool, resume_only: bool,
env_config: env::Config, env_config: env::Config,
rendezvous_params: Option<(Multiaddr, XmrBtcNamespace)>, rendezvous_params: Option<(Multiaddr, WowBtcNamespace)>,
) -> Result<Swarm<asb::Behaviour<LR>>> ) -> Result<Swarm<asb::Behaviour<LR>>>
where where
LR: LatestRate + Send + 'static + Debug + Clone, LR: LatestRate + Send + 'static + Debug + Clone,

@ -1,5 +1,5 @@
use crate::network::cbor_request_response::CborCodec; use crate::network::cbor_request_response::CborCodec;
use crate::{asb, cli, monero}; use crate::{asb, cli, wownero};
use libp2p::core::ProtocolName; use libp2p::core::ProtocolName;
use libp2p::request_response::{ use libp2p::request_response::{
ProtocolSupport, RequestResponse, RequestResponseConfig, RequestResponseEvent, ProtocolSupport, RequestResponse, RequestResponseConfig, RequestResponseEvent,
@ -9,7 +9,7 @@ use libp2p::PeerId;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use uuid::Uuid; use uuid::Uuid;
const PROTOCOL: &str = "/comit/xmr/btc/transfer_proof/1.0.0"; const PROTOCOL: &str = "/comit/wow/btc/transfer_proof/1.0.0";
type OutEvent = RequestResponseEvent<Request, ()>; type OutEvent = RequestResponseEvent<Request, ()>;
type Message = RequestResponseMessage<Request, ()>; type Message = RequestResponseMessage<Request, ()>;
@ -27,7 +27,7 @@ impl ProtocolName for TransferProofProtocol {
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Request { pub struct Request {
pub swap_id: Uuid, pub swap_id: Uuid,
pub tx_lock_proof: monero::TransferProof, pub tx_lock_proof: wownero::TransferProof,
} }
pub fn alice() -> Behaviour { pub fn alice() -> Behaviour {

@ -1,4 +1,4 @@
use crate::{bitcoin, monero}; use crate::{bitcoin, wownero};
use conquer_once::Lazy; use conquer_once::Lazy;
use ecdsa_fun::fun::marker::Mark; use ecdsa_fun::fun::marker::Mark;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -23,10 +23,10 @@ pub static CROSS_CURVE_PROOF_SYSTEM: Lazy<
pub struct Message0 { pub struct Message0 {
swap_id: Uuid, swap_id: Uuid,
B: bitcoin::PublicKey, B: bitcoin::PublicKey,
S_b_monero: monero::PublicKey, S_b_wownero: wownero::PublicKey,
S_b_bitcoin: bitcoin::PublicKey, S_b_bitcoin: bitcoin::PublicKey,
dleq_proof_s_b: CrossCurveDLEQProof, dleq_proof_s_b: CrossCurveDLEQProof,
v_b: monero::PrivateViewKey, v_b: wownero::PrivateViewKey,
refund_address: bitcoin::Address, refund_address: bitcoin::Address,
#[serde(with = "::bitcoin::util::amount::serde::as_sat")] #[serde(with = "::bitcoin::util::amount::serde::as_sat")]
tx_refund_fee: bitcoin::Amount, tx_refund_fee: bitcoin::Amount,
@ -37,10 +37,10 @@ pub struct Message0 {
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Message1 { pub struct Message1 {
A: bitcoin::PublicKey, A: bitcoin::PublicKey,
S_a_monero: monero::PublicKey, S_a_wownero: wownero::PublicKey,
S_a_bitcoin: bitcoin::PublicKey, S_a_bitcoin: bitcoin::PublicKey,
dleq_proof_s_a: CrossCurveDLEQProof, dleq_proof_s_a: CrossCurveDLEQProof,
v_a: monero::PrivateViewKey, v_a: wownero::PrivateViewKey,
redeem_address: bitcoin::Address, redeem_address: bitcoin::Address,
punish_address: bitcoin::Address, punish_address: bitcoin::Address,
#[serde(with = "::bitcoin::util::amount::serde::as_sat")] #[serde(with = "::bitcoin::util::amount::serde::as_sat")]

@ -1,8 +1,8 @@
//! Run an XMR/BTC swap in the role of Alice. //! Run an WOW/BTC swap in the role of Alice.
//! Alice holds XMR and wishes receive BTC. //! Alice holds WOW and wishes receive BTC.
use crate::database::Database; use crate::database::Database;
use crate::env::Config; use crate::env::Config;
use crate::{asb, bitcoin, monero}; use crate::{asb, bitcoin, wownero};
use std::sync::Arc; use std::sync::Arc;
use uuid::Uuid; use uuid::Uuid;
@ -16,7 +16,7 @@ pub struct Swap {
pub state: AliceState, pub state: AliceState,
pub event_loop_handle: asb::EventLoopHandle, pub event_loop_handle: asb::EventLoopHandle,
pub bitcoin_wallet: Arc<bitcoin::Wallet>, pub bitcoin_wallet: Arc<bitcoin::Wallet>,
pub monero_wallet: Arc<monero::Wallet>, pub wownero_wallet: Arc<wownero::Wallet>,
pub env_config: Config, pub env_config: Config,
pub swap_id: Uuid, pub swap_id: Uuid,
pub db: Arc<Database>, pub db: Arc<Database>,

@ -3,13 +3,13 @@ use crate::bitcoin::{
TxPunish, TxRedeem, TxRefund, Txid, TxPunish, TxRedeem, TxRefund, Txid,
}; };
use crate::env::Config; use crate::env::Config;
use crate::monero::wallet::{TransferRequest, WatchRequest}; use crate::wownero::wallet::{TransferRequest, WatchRequest};
use crate::monero::TransferProof; use crate::wownero::TransferProof;
use crate::monero_ext::ScalarExt; use crate::wownero_ext::ScalarExt;
use crate::protocol::{Message0, Message1, Message2, Message3, Message4, CROSS_CURVE_PROOF_SYSTEM}; use crate::protocol::{Message0, Message1, Message2, Message3, Message4, CROSS_CURVE_PROOF_SYSTEM};
use crate::{bitcoin, monero}; use crate::{bitcoin, wownero};
use anyhow::{anyhow, bail, Context, Result}; use anyhow::{anyhow, bail, Context, Result};
use monero_rpc::wallet::BlockHeight; use wownero_rpc::wallet::BlockHeight;
use rand::{CryptoRng, RngCore}; use rand::{CryptoRng, RngCore};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sigma_fun::ext::dl_secp256k1_ed25519_eq::CrossCurveDLEQProof; use sigma_fun::ext::dl_secp256k1_ed25519_eq::CrossCurveDLEQProof;
@ -27,23 +27,23 @@ pub enum AliceState {
BtcLocked { BtcLocked {
state3: Box<State3>, state3: Box<State3>,
}, },
XmrLockTransactionSent { WowLockTransactionSent {
monero_wallet_restore_blockheight: BlockHeight, wownero_wallet_restore_blockheight: BlockHeight,
transfer_proof: TransferProof, transfer_proof: TransferProof,
state3: Box<State3>, state3: Box<State3>,
}, },
XmrLocked { WowLocked {
monero_wallet_restore_blockheight: BlockHeight, wownero_wallet_restore_blockheight: BlockHeight,
transfer_proof: TransferProof, transfer_proof: TransferProof,
state3: Box<State3>, state3: Box<State3>,
}, },
XmrLockTransferProofSent { WowLockTransferProofSent {
monero_wallet_restore_blockheight: BlockHeight, wownero_wallet_restore_blockheight: BlockHeight,
transfer_proof: TransferProof, transfer_proof: TransferProof,
state3: Box<State3>, state3: Box<State3>,
}, },
EncSigLearned { EncSigLearned {
monero_wallet_restore_blockheight: BlockHeight, wownero_wallet_restore_blockheight: BlockHeight,
transfer_proof: TransferProof, transfer_proof: TransferProof,
encrypted_signature: Box<bitcoin::EncryptedSignature>, encrypted_signature: Box<bitcoin::EncryptedSignature>,
state3: Box<State3>, state3: Box<State3>,
@ -53,24 +53,24 @@ pub enum AliceState {
}, },
BtcRedeemed, BtcRedeemed,
BtcCancelled { BtcCancelled {
monero_wallet_restore_blockheight: BlockHeight, wownero_wallet_restore_blockheight: BlockHeight,
transfer_proof: TransferProof, transfer_proof: TransferProof,
state3: Box<State3>, state3: Box<State3>,
}, },
BtcRefunded { BtcRefunded {
monero_wallet_restore_blockheight: BlockHeight, wownero_wallet_restore_blockheight: BlockHeight,
transfer_proof: TransferProof, transfer_proof: TransferProof,
spend_key: monero::PrivateKey, spend_key: wownero::PrivateKey,
state3: Box<State3>, state3: Box<State3>,
}, },
BtcPunishable { BtcPunishable {
monero_wallet_restore_blockheight: BlockHeight, wownero_wallet_restore_blockheight: BlockHeight,
transfer_proof: TransferProof, transfer_proof: TransferProof,
state3: Box<State3>, state3: Box<State3>,
}, },
XmrRefunded, WowRefunded,
CancelTimelockExpired { CancelTimelockExpired {
monero_wallet_restore_blockheight: BlockHeight, wownero_wallet_restore_blockheight: BlockHeight,
transfer_proof: TransferProof, transfer_proof: TransferProof,
state3: Box<State3>, state3: Box<State3>,
}, },
@ -86,10 +86,10 @@ impl fmt::Display for AliceState {
write!(f, "bitcoin lock transaction in mempool") write!(f, "bitcoin lock transaction in mempool")
} }
AliceState::BtcLocked { .. } => write!(f, "btc is locked"), AliceState::BtcLocked { .. } => write!(f, "btc is locked"),
AliceState::XmrLockTransactionSent { .. } => write!(f, "xmr lock transaction sent"), AliceState::WowLockTransactionSent { .. } => write!(f, "wow lock transaction sent"),
AliceState::XmrLocked { .. } => write!(f, "xmr is locked"), AliceState::WowLocked { .. } => write!(f, "wow is locked"),
AliceState::XmrLockTransferProofSent { .. } => { AliceState::WowLockTransferProofSent { .. } => {
write!(f, "xmr lock transfer proof sent") write!(f, "wow lock transfer proof sent")
} }
AliceState::EncSigLearned { .. } => write!(f, "encrypted signature is learned"), AliceState::EncSigLearned { .. } => write!(f, "encrypted signature is learned"),
AliceState::BtcRedeemTransactionPublished { .. } => { AliceState::BtcRedeemTransactionPublished { .. } => {
@ -101,7 +101,7 @@ impl fmt::Display for AliceState {
AliceState::BtcPunished => write!(f, "btc is punished"), AliceState::BtcPunished => write!(f, "btc is punished"),
AliceState::SafelyAborted => write!(f, "safely aborted"), AliceState::SafelyAborted => write!(f, "safely aborted"),
AliceState::BtcPunishable { .. } => write!(f, "btc is punishable"), AliceState::BtcPunishable { .. } => write!(f, "btc is punishable"),
AliceState::XmrRefunded => write!(f, "xmr is refunded"), AliceState::WowRefunded => write!(f, "wow is refunded"),
AliceState::CancelTimelockExpired { .. } => write!(f, "cancel timelock is expired"), AliceState::CancelTimelockExpired { .. } => write!(f, "cancel timelock is expired"),
} }
} }
@ -110,13 +110,13 @@ impl fmt::Display for AliceState {
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct State0 { pub struct State0 {
a: bitcoin::SecretKey, a: bitcoin::SecretKey,
s_a: monero::Scalar, s_a: wownero::Scalar,
v_a: monero::PrivateViewKey, v_a: wownero::PrivateViewKey,
S_a_monero: monero::PublicKey, S_a_wownero: wownero::PublicKey,
S_a_bitcoin: bitcoin::PublicKey, S_a_bitcoin: bitcoin::PublicKey,
dleq_proof_s_a: CrossCurveDLEQProof, dleq_proof_s_a: CrossCurveDLEQProof,
btc: bitcoin::Amount, btc: bitcoin::Amount,
xmr: monero::Amount, wow: wownero::Amount,
cancel_timelock: CancelTimelock, cancel_timelock: CancelTimelock,
punish_timelock: PunishTimelock, punish_timelock: PunishTimelock,
redeem_address: bitcoin::Address, redeem_address: bitcoin::Address,
@ -129,7 +129,7 @@ impl State0 {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn new<R>( pub fn new<R>(
btc: bitcoin::Amount, btc: bitcoin::Amount,
xmr: monero::Amount, wow: wownero::Amount,
env_config: Config, env_config: Config,
redeem_address: bitcoin::Address, redeem_address: bitcoin::Address,
punish_address: bitcoin::Address, punish_address: bitcoin::Address,
@ -141,24 +141,24 @@ impl State0 {
R: RngCore + CryptoRng, R: RngCore + CryptoRng,
{ {
let a = bitcoin::SecretKey::new_random(rng); let a = bitcoin::SecretKey::new_random(rng);
let v_a = monero::PrivateViewKey::new_random(rng); let v_a = wownero::PrivateViewKey::new_random(rng);
let s_a = monero::Scalar::random(rng); let s_a = wownero::Scalar::random(rng);
let (dleq_proof_s_a, (S_a_bitcoin, S_a_monero)) = CROSS_CURVE_PROOF_SYSTEM.prove(&s_a, rng); let (dleq_proof_s_a, (S_a_bitcoin, S_a_wownero)) = CROSS_CURVE_PROOF_SYSTEM.prove(&s_a, rng);
Self { Self {
a, a,
s_a, s_a,
v_a, v_a,
S_a_bitcoin: S_a_bitcoin.into(), S_a_bitcoin: S_a_bitcoin.into(),
S_a_monero: monero::PublicKey { S_a_wownero: wownero::PublicKey {
point: S_a_monero.compress(), point: S_a_wownero.compress(),
}, },
dleq_proof_s_a, dleq_proof_s_a,
redeem_address, redeem_address,
punish_address, punish_address,
btc, btc,
xmr, wow,
cancel_timelock: env_config.bitcoin_cancel_timelock, cancel_timelock: env_config.bitcoin_cancel_timelock,
punish_timelock: env_config.bitcoin_punish_timelock, punish_timelock: env_config.bitcoin_punish_timelock,
tx_redeem_fee, tx_redeem_fee,
@ -171,10 +171,10 @@ impl State0 {
&msg.dleq_proof_s_b, &msg.dleq_proof_s_b,
( (
msg.S_b_bitcoin.into(), msg.S_b_bitcoin.into(),
msg.S_b_monero msg.S_b_wownero
.point .point
.decompress() .decompress()
.ok_or_else(|| anyhow!("S_b is not a monero curve point"))?, .ok_or_else(|| anyhow!("S_b is not a wownero curve point"))?,
), ),
); );
@ -188,15 +188,15 @@ impl State0 {
a: self.a, a: self.a,
B: msg.B, B: msg.B,
s_a: self.s_a, s_a: self.s_a,
S_a_monero: self.S_a_monero, S_a_wownero: self.S_a_wownero,
S_a_bitcoin: self.S_a_bitcoin, S_a_bitcoin: self.S_a_bitcoin,
S_b_monero: msg.S_b_monero, S_b_wownero: msg.S_b_wownero,
S_b_bitcoin: msg.S_b_bitcoin, S_b_bitcoin: msg.S_b_bitcoin,
v, v,
v_a: self.v_a, v_a: self.v_a,
dleq_proof_s_a: self.dleq_proof_s_a, dleq_proof_s_a: self.dleq_proof_s_a,
btc: self.btc, btc: self.btc,
xmr: self.xmr, wow: self.wow,
cancel_timelock: self.cancel_timelock, cancel_timelock: self.cancel_timelock,
punish_timelock: self.punish_timelock, punish_timelock: self.punish_timelock,
refund_address: msg.refund_address, refund_address: msg.refund_address,
@ -214,16 +214,16 @@ impl State0 {
pub struct State1 { pub struct State1 {
a: bitcoin::SecretKey, a: bitcoin::SecretKey,
B: bitcoin::PublicKey, B: bitcoin::PublicKey,
s_a: monero::Scalar, s_a: wownero::Scalar,
S_a_monero: monero::PublicKey, S_a_wownero: wownero::PublicKey,
S_a_bitcoin: bitcoin::PublicKey, S_a_bitcoin: bitcoin::PublicKey,
S_b_monero: monero::PublicKey, S_b_wownero: wownero::PublicKey,
S_b_bitcoin: bitcoin::PublicKey, S_b_bitcoin: bitcoin::PublicKey,
v: monero::PrivateViewKey, v: wownero::PrivateViewKey,
v_a: monero::PrivateViewKey, v_a: wownero::PrivateViewKey,
dleq_proof_s_a: CrossCurveDLEQProof, dleq_proof_s_a: CrossCurveDLEQProof,
btc: bitcoin::Amount, btc: bitcoin::Amount,
xmr: monero::Amount, wow: wownero::Amount,
cancel_timelock: CancelTimelock, cancel_timelock: CancelTimelock,
punish_timelock: PunishTimelock, punish_timelock: PunishTimelock,
refund_address: bitcoin::Address, refund_address: bitcoin::Address,
@ -239,7 +239,7 @@ impl State1 {
pub fn next_message(&self) -> Message1 { pub fn next_message(&self) -> Message1 {
Message1 { Message1 {
A: self.a.public(), A: self.a.public(),
S_a_monero: self.S_a_monero, S_a_wownero: self.S_a_wownero,
S_a_bitcoin: self.S_a_bitcoin, S_a_bitcoin: self.S_a_bitcoin,
dleq_proof_s_a: self.dleq_proof_s_a.clone(), dleq_proof_s_a: self.dleq_proof_s_a.clone(),
v_a: self.v_a, v_a: self.v_a,
@ -258,11 +258,11 @@ impl State1 {
a: self.a, a: self.a,
B: self.B, B: self.B,
s_a: self.s_a, s_a: self.s_a,
S_b_monero: self.S_b_monero, S_b_wownero: self.S_b_wownero,
S_b_bitcoin: self.S_b_bitcoin, S_b_bitcoin: self.S_b_bitcoin,
v: self.v, v: self.v,
btc: self.btc, btc: self.btc,
xmr: self.xmr, wow: self.wow,
cancel_timelock: self.cancel_timelock, cancel_timelock: self.cancel_timelock,
punish_timelock: self.punish_timelock, punish_timelock: self.punish_timelock,
refund_address: self.refund_address, refund_address: self.refund_address,
@ -281,12 +281,12 @@ impl State1 {
pub struct State2 { pub struct State2 {
a: bitcoin::SecretKey, a: bitcoin::SecretKey,
B: bitcoin::PublicKey, B: bitcoin::PublicKey,
s_a: monero::Scalar, s_a: wownero::Scalar,
S_b_monero: monero::PublicKey, S_b_wownero: wownero::PublicKey,
S_b_bitcoin: bitcoin::PublicKey, S_b_bitcoin: bitcoin::PublicKey,
v: monero::PrivateViewKey, v: wownero::PrivateViewKey,
btc: bitcoin::Amount, btc: bitcoin::Amount,
xmr: monero::Amount, wow: wownero::Amount,
cancel_timelock: CancelTimelock, cancel_timelock: CancelTimelock,
punish_timelock: PunishTimelock, punish_timelock: PunishTimelock,
refund_address: bitcoin::Address, refund_address: bitcoin::Address,
@ -311,7 +311,7 @@ impl State2 {
let tx_refund = let tx_refund =
bitcoin::TxRefund::new(&tx_cancel, &self.refund_address, self.tx_refund_fee); bitcoin::TxRefund::new(&tx_cancel, &self.refund_address, self.tx_refund_fee);
// Alice encsigns the refund transaction(bitcoin) digest with Bob's monero // Alice encsigns the refund transaction(bitcoin) digest with Bob's wownero
// pubkey(S_b). The refund transaction spends the output of // pubkey(S_b). The refund transaction spends the output of
// tx_lock_bitcoin to Bob's refund address. // tx_lock_bitcoin to Bob's refund address.
// recover(encsign(a, S_b, d), sign(a, d), S_b) = s_b where d is a digest, (a, // recover(encsign(a, S_b, d), sign(a, d), S_b) = s_b where d is a digest, (a,
@ -348,11 +348,11 @@ impl State2 {
a: self.a, a: self.a,
B: self.B, B: self.B,
s_a: self.s_a, s_a: self.s_a,
S_b_monero: self.S_b_monero, S_b_wownero: self.S_b_wownero,
S_b_bitcoin: self.S_b_bitcoin, S_b_bitcoin: self.S_b_bitcoin,
v: self.v, v: self.v,
btc: self.btc, btc: self.btc,
xmr: self.xmr, wow: self.wow,
cancel_timelock: self.cancel_timelock, cancel_timelock: self.cancel_timelock,
punish_timelock: self.punish_timelock, punish_timelock: self.punish_timelock,
refund_address: self.refund_address, refund_address: self.refund_address,
@ -373,13 +373,13 @@ impl State2 {
pub struct State3 { pub struct State3 {
a: bitcoin::SecretKey, a: bitcoin::SecretKey,
B: bitcoin::PublicKey, B: bitcoin::PublicKey,
s_a: monero::Scalar, s_a: wownero::Scalar,
S_b_monero: monero::PublicKey, S_b_wownero: wownero::PublicKey,
S_b_bitcoin: bitcoin::PublicKey, S_b_bitcoin: bitcoin::PublicKey,
pub v: monero::PrivateViewKey, pub v: wownero::PrivateViewKey,
#[serde(with = "::bitcoin::util::amount::serde::as_sat")] #[serde(with = "::bitcoin::util::amount::serde::as_sat")]
btc: bitcoin::Amount, btc: bitcoin::Amount,
xmr: monero::Amount, wow: wownero::Amount,
pub cancel_timelock: CancelTimelock, pub cancel_timelock: CancelTimelock,
pub punish_timelock: PunishTimelock, pub punish_timelock: PunishTimelock,
refund_address: bitcoin::Address, refund_address: bitcoin::Address,
@ -416,34 +416,34 @@ impl State3 {
)) ))
} }
pub fn lock_xmr_transfer_request(&self) -> TransferRequest { pub fn lock_wow_transfer_request(&self) -> TransferRequest {
let S_a = monero::PublicKey::from_private_key(&monero::PrivateKey { scalar: self.s_a }); let S_a = wownero::PublicKey::from_private_key(&wownero::PrivateKey { scalar: self.s_a });
let public_spend_key = S_a + self.S_b_monero; let public_spend_key = S_a + self.S_b_wownero;
let public_view_key = self.v.public(); let public_view_key = self.v.public();
TransferRequest { TransferRequest {
public_spend_key, public_spend_key,
public_view_key, public_view_key,
amount: self.xmr, amount: self.wow,
} }
} }
pub fn lock_xmr_watch_request( pub fn lock_wow_watch_request(
&self, &self,
transfer_proof: TransferProof, transfer_proof: TransferProof,
conf_target: u64, conf_target: u64,
) -> WatchRequest { ) -> WatchRequest {
let S_a = monero::PublicKey::from_private_key(&monero::PrivateKey { scalar: self.s_a }); let S_a = wownero::PublicKey::from_private_key(&wownero::PrivateKey { scalar: self.s_a });
let public_spend_key = S_a + self.S_b_monero; let public_spend_key = S_a + self.S_b_wownero;
let public_view_key = self.v.public(); let public_view_key = self.v.public();
WatchRequest { WatchRequest {
public_spend_key, public_spend_key,
public_view_key, public_view_key,
transfer_proof, transfer_proof,
conf_target, conf_target,
expected: self.xmr, expected: self.wow,
} }
} }
@ -465,11 +465,11 @@ impl State3 {
TxRedeem::new(&self.tx_lock, &self.redeem_address, self.tx_redeem_fee) TxRedeem::new(&self.tx_lock, &self.redeem_address, self.tx_redeem_fee)
} }
pub fn extract_monero_private_key( pub fn extract_wownero_private_key(
&self, &self,
published_refund_tx: bitcoin::Transaction, published_refund_tx: bitcoin::Transaction,
) -> Result<monero::PrivateKey> { ) -> Result<wownero::PrivateKey> {
self.tx_refund().extract_monero_private_key( self.tx_refund().extract_wownero_private_key(
published_refund_tx, published_refund_tx,
self.s_a, self.s_a,
self.a.clone(), self.a.clone(),
@ -498,28 +498,28 @@ impl State3 {
Ok(tx_id) Ok(tx_id)
} }
pub async fn refund_xmr( pub async fn refund_wow(
&self, &self,
monero_wallet: &monero::Wallet, wownero_wallet: &wownero::Wallet,
monero_wallet_restore_blockheight: BlockHeight, wownero_wallet_restore_blockheight: BlockHeight,
file_name: String, file_name: String,
spend_key: monero::PrivateKey, spend_key: wownero::PrivateKey,
transfer_proof: TransferProof, transfer_proof: TransferProof,
) -> Result<()> { ) -> Result<()> {
let view_key = self.v; let view_key = self.v;
// Ensure that the XMR to be refunded are spendable by awaiting 10 confirmations // Ensure that the WOW to be refunded are spendable by awaiting 10 confirmations
// on the lock transaction // on the lock transaction
monero_wallet wownero_wallet
.watch_for_transfer(self.lock_xmr_watch_request(transfer_proof, 10)) .watch_for_transfer(self.lock_wow_watch_request(transfer_proof, 10))
.await?; .await?;
monero_wallet wownero_wallet
.create_from( .create_from(
file_name, file_name,
spend_key, spend_key,
view_key, view_key,
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
) )
.await?; .await?;

@ -1,10 +1,10 @@
//! Run an XMR/BTC swap in the role of Alice. //! Run an WOW/BTC swap in the role of Alice.
//! Alice holds XMR and wishes receive BTC. //! Alice holds WOW and wishes receive BTC.
use crate::asb::{EventLoopHandle, LatestRate}; use crate::asb::{EventLoopHandle, LatestRate};
use crate::bitcoin::ExpiredTimelocks; use crate::bitcoin::ExpiredTimelocks;
use crate::env::Config; use crate::env::Config;
use crate::protocol::alice::{AliceState, Swap}; use crate::protocol::alice::{AliceState, Swap};
use crate::{bitcoin, database, monero}; use crate::{bitcoin, database, wownero};
use anyhow::{bail, Context, Result}; use anyhow::{bail, Context, Result};
use tokio::select; use tokio::select;
use tokio::time::timeout; use tokio::time::timeout;
@ -34,7 +34,7 @@ where
current_state, current_state,
&mut swap.event_loop_handle, &mut swap.event_loop_handle,
swap.bitcoin_wallet.as_ref(), swap.bitcoin_wallet.as_ref(),
swap.monero_wallet.as_ref(), swap.wownero_wallet.as_ref(),
&swap.env_config, &swap.env_config,
rate_service.clone(), rate_service.clone(),
) )
@ -54,7 +54,7 @@ async fn next_state<LR>(
state: AliceState, state: AliceState,
event_loop_handle: &mut EventLoopHandle, event_loop_handle: &mut EventLoopHandle,
bitcoin_wallet: &bitcoin::Wallet, bitcoin_wallet: &bitcoin::Wallet,
monero_wallet: &monero::Wallet, wownero_wallet: &wownero::Wallet,
env_config: &Config, env_config: &Config,
mut rate_service: LR, mut rate_service: LR,
) -> Result<AliceState> ) -> Result<AliceState>
@ -114,16 +114,16 @@ where
AliceState::BtcLocked { state3 } => { AliceState::BtcLocked { state3 } => {
match state3.expired_timelocks(bitcoin_wallet).await? { match state3.expired_timelocks(bitcoin_wallet).await? {
ExpiredTimelocks::None => { ExpiredTimelocks::None => {
// Record the current monero wallet block height so we don't have to scan from // Record the current wownero wallet block height so we don't have to scan from
// block 0 for scenarios where we create a refund wallet. // block 0 for scenarios where we create a refund wallet.
let monero_wallet_restore_blockheight = monero_wallet.block_height().await?; let wownero_wallet_restore_blockheight = wownero_wallet.block_height().await?;
let transfer_proof = monero_wallet let transfer_proof = wownero_wallet
.transfer(state3.lock_xmr_transfer_request()) .transfer(state3.lock_wow_transfer_request())
.await?; .await?;
AliceState::XmrLockTransactionSent { AliceState::WowLockTransactionSent {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} }
@ -131,36 +131,36 @@ where
_ => AliceState::SafelyAborted, _ => AliceState::SafelyAborted,
} }
} }
AliceState::XmrLockTransactionSent { AliceState::WowLockTransactionSent {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} => match state3.expired_timelocks(bitcoin_wallet).await? { } => match state3.expired_timelocks(bitcoin_wallet).await? {
ExpiredTimelocks::None => { ExpiredTimelocks::None => {
monero_wallet wownero_wallet
.watch_for_transfer(state3.lock_xmr_watch_request(transfer_proof.clone(), 1)) .watch_for_transfer(state3.lock_wow_watch_request(transfer_proof.clone(), 1))
.await .await
.with_context(|| { .with_context(|| {
format!( format!(
"Failed to watch for transfer of XMR in transaction {}", "Failed to watch for transfer of WOW in transaction {}",
transfer_proof.tx_hash() transfer_proof.tx_hash()
) )
})?; })?;
AliceState::XmrLocked { AliceState::WowLocked {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} }
} }
_ => AliceState::CancelTimelockExpired { _ => AliceState::CancelTimelockExpired {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
}, },
}, },
AliceState::XmrLocked { AliceState::WowLocked {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} => { } => {
@ -170,23 +170,23 @@ where
result = event_loop_handle.send_transfer_proof(transfer_proof.clone()) => { result = event_loop_handle.send_transfer_proof(transfer_proof.clone()) => {
result?; result?;
AliceState::XmrLockTransferProofSent { AliceState::WowLockTransferProofSent {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} }
}, },
_ = tx_lock_status.wait_until_confirmed_with(state3.cancel_timelock) => { _ = tx_lock_status.wait_until_confirmed_with(state3.cancel_timelock) => {
AliceState::CancelTimelockExpired { AliceState::CancelTimelockExpired {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} }
} }
} }
} }
AliceState::XmrLockTransferProofSent { AliceState::WowLockTransferProofSent {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} => { } => {
@ -197,7 +197,7 @@ where
_ = tx_lock_status.wait_until_confirmed_with(state3.cancel_timelock) => { _ = tx_lock_status.wait_until_confirmed_with(state3.cancel_timelock) => {
AliceState::CancelTimelockExpired { AliceState::CancelTimelockExpired {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} }
@ -206,7 +206,7 @@ where
tracing::info!("Received encrypted signature"); tracing::info!("Received encrypted signature");
AliceState::EncSigLearned { AliceState::EncSigLearned {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
encrypted_signature: Box::new(enc_sig?), encrypted_signature: Box::new(enc_sig?),
state3, state3,
@ -215,7 +215,7 @@ where
} }
} }
AliceState::EncSigLearned { AliceState::EncSigLearned {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
encrypted_signature, encrypted_signature,
state3, state3,
@ -237,7 +237,7 @@ where
.await?; .await?;
AliceState::CancelTimelockExpired { AliceState::CancelTimelockExpired {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} }
@ -255,7 +255,7 @@ where
.await?; .await?;
AliceState::CancelTimelockExpired { AliceState::CancelTimelockExpired {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} }
@ -263,7 +263,7 @@ where
} }
} }
_ => AliceState::CancelTimelockExpired { _ => AliceState::CancelTimelockExpired {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
}, },
@ -279,7 +279,7 @@ where
} }
} }
AliceState::CancelTimelockExpired { AliceState::CancelTimelockExpired {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} => { } => {
@ -297,13 +297,13 @@ where
} }
AliceState::BtcCancelled { AliceState::BtcCancelled {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} }
} }
AliceState::BtcCancelled { AliceState::BtcCancelled {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} => { } => {
@ -315,10 +315,10 @@ where
seen_refund.context("Failed to monitor refund transaction")?; seen_refund.context("Failed to monitor refund transaction")?;
let published_refund_tx = bitcoin_wallet.get_raw_transaction(state3.tx_refund().txid()).await?; let published_refund_tx = bitcoin_wallet.get_raw_transaction(state3.tx_refund().txid()).await?;
let spend_key = state3.extract_monero_private_key(published_refund_tx)?; let spend_key = state3.extract_wownero_private_key(published_refund_tx)?;
AliceState::BtcRefunded { AliceState::BtcRefunded {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
spend_key, spend_key,
state3, state3,
@ -326,7 +326,7 @@ where
} }
_ = tx_cancel_status.wait_until_confirmed_with(state3.punish_timelock) => { _ = tx_cancel_status.wait_until_confirmed_with(state3.punish_timelock) => {
AliceState::BtcPunishable { AliceState::BtcPunishable {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} }
@ -334,25 +334,25 @@ where
} }
} }
AliceState::BtcRefunded { AliceState::BtcRefunded {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
spend_key, spend_key,
state3, state3,
} => { } => {
state3 state3
.refund_xmr( .refund_wow(
monero_wallet, wownero_wallet,
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
swap_id.to_string(), swap_id.to_string(),
spend_key, spend_key,
transfer_proof, transfer_proof,
) )
.await?; .await?;
AliceState::XmrRefunded AliceState::WowRefunded
} }
AliceState::BtcPunishable { AliceState::BtcPunishable {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
state3, state3,
} => { } => {
@ -376,10 +376,10 @@ where
.get_raw_transaction(state3.tx_refund().txid()) .get_raw_transaction(state3.tx_refund().txid())
.await?; .await?;
let spend_key = state3.extract_monero_private_key(published_refund_tx)?; let spend_key = state3.extract_wownero_private_key(published_refund_tx)?;
AliceState::BtcRefunded { AliceState::BtcRefunded {
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
transfer_proof, transfer_proof,
spend_key, spend_key,
state3, state3,
@ -387,7 +387,7 @@ where
} }
} }
} }
AliceState::XmrRefunded => AliceState::XmrRefunded, AliceState::WowRefunded => AliceState::WowRefunded,
AliceState::BtcRedeemed => AliceState::BtcRedeemed, AliceState::BtcRedeemed => AliceState::BtcRedeemed,
AliceState::BtcPunished => AliceState::BtcPunished, AliceState::BtcPunished => AliceState::BtcPunished,
AliceState::SafelyAborted => AliceState::SafelyAborted, AliceState::SafelyAborted => AliceState::SafelyAborted,
@ -397,7 +397,7 @@ where
fn is_complete(state: &AliceState) -> bool { fn is_complete(state: &AliceState) -> bool {
matches!( matches!(
state, state,
AliceState::XmrRefunded AliceState::WowRefunded
| AliceState::BtcRedeemed | AliceState::BtcRedeemed
| AliceState::BtcPunished | AliceState::BtcPunished
| AliceState::SafelyAborted | AliceState::SafelyAborted

@ -4,7 +4,7 @@ use anyhow::Result;
use uuid::Uuid; use uuid::Uuid;
use crate::database::Database; use crate::database::Database;
use crate::{bitcoin, cli, env, monero}; use crate::{bitcoin, cli, env, wownero};
pub use self::state::*; pub use self::state::*;
pub use self::swap::{run, run_until}; pub use self::swap::{run, run_until};
@ -17,10 +17,10 @@ pub struct Swap {
pub event_loop_handle: cli::EventLoopHandle, pub event_loop_handle: cli::EventLoopHandle,
pub db: Database, pub db: Database,
pub bitcoin_wallet: Arc<bitcoin::Wallet>, pub bitcoin_wallet: Arc<bitcoin::Wallet>,
pub monero_wallet: Arc<monero::Wallet>, pub wownero_wallet: Arc<wownero::Wallet>,
pub env_config: env::Config, pub env_config: env::Config,
pub id: Uuid, pub id: Uuid,
pub monero_receive_address: monero::Address, pub wownero_receive_address: wownero::Address,
} }
impl Swap { impl Swap {
@ -29,10 +29,10 @@ impl Swap {
db: Database, db: Database,
id: Uuid, id: Uuid,
bitcoin_wallet: Arc<bitcoin::Wallet>, bitcoin_wallet: Arc<bitcoin::Wallet>,
monero_wallet: Arc<monero::Wallet>, wownero_wallet: Arc<wownero::Wallet>,
env_config: env::Config, env_config: env::Config,
event_loop_handle: cli::EventLoopHandle, event_loop_handle: cli::EventLoopHandle,
monero_receive_address: monero::Address, wownero_receive_address: wownero::Address,
bitcoin_change_address: bitcoin::Address, bitcoin_change_address: bitcoin::Address,
btc_amount: bitcoin::Amount, btc_amount: bitcoin::Amount,
) -> Self { ) -> Self {
@ -44,10 +44,10 @@ impl Swap {
event_loop_handle, event_loop_handle,
db, db,
bitcoin_wallet, bitcoin_wallet,
monero_wallet, wownero_wallet,
env_config, env_config,
id, id,
monero_receive_address, wownero_receive_address,
} }
} }
@ -56,10 +56,10 @@ impl Swap {
db: Database, db: Database,
id: Uuid, id: Uuid,
bitcoin_wallet: Arc<bitcoin::Wallet>, bitcoin_wallet: Arc<bitcoin::Wallet>,
monero_wallet: Arc<monero::Wallet>, wownero_wallet: Arc<wownero::Wallet>,
env_config: env::Config, env_config: env::Config,
event_loop_handle: cli::EventLoopHandle, event_loop_handle: cli::EventLoopHandle,
monero_receive_address: monero::Address, wownero_receive_address: wownero::Address,
) -> Result<Self> { ) -> Result<Self> {
let state = db.get_state(id)?.try_into_bob()?.into(); let state = db.get_state(id)?.try_into_bob()?.into();
@ -68,10 +68,10 @@ impl Swap {
event_loop_handle, event_loop_handle,
db, db,
bitcoin_wallet, bitcoin_wallet,
monero_wallet, wownero_wallet,
env_config, env_config,
id, id,
monero_receive_address, wownero_receive_address,
}) })
} }
} }

@ -3,17 +3,17 @@ use crate::bitcoin::{
self, current_epoch, CancelTimelock, ExpiredTimelocks, PunishTimelock, Transaction, TxCancel, self, current_epoch, CancelTimelock, ExpiredTimelocks, PunishTimelock, Transaction, TxCancel,
TxLock, Txid, TxLock, Txid,
}; };
use crate::monero; use crate::wownero;
use crate::monero::wallet::WatchRequest; use crate::wownero::wallet::WatchRequest;
use crate::monero::{monero_private_key, TransferProof}; use crate::wownero::{wownero_private_key, TransferProof};
use crate::monero_ext::ScalarExt; use crate::wownero_ext::ScalarExt;
use crate::protocol::{Message0, Message1, Message2, Message3, Message4, CROSS_CURVE_PROOF_SYSTEM}; use crate::protocol::{Message0, Message1, Message2, Message3, Message4, CROSS_CURVE_PROOF_SYSTEM};
use anyhow::{anyhow, bail, Context, Result}; use anyhow::{anyhow, bail, Context, Result};
use bdk::database::BatchDatabase; use bdk::database::BatchDatabase;
use ecdsa_fun::adaptor::{Adaptor, HashTranscript}; use ecdsa_fun::adaptor::{Adaptor, HashTranscript};
use ecdsa_fun::nonce::Deterministic; use ecdsa_fun::nonce::Deterministic;
use ecdsa_fun::Signature; use ecdsa_fun::Signature;
use monero_rpc::wallet::BlockHeight; use wownero_rpc::wallet::BlockHeight;
use rand::{CryptoRng, RngCore}; use rand::{CryptoRng, RngCore};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sha2::Sha256; use sha2::Sha256;
@ -29,18 +29,18 @@ pub enum BobState {
}, },
SwapSetupCompleted(State2), SwapSetupCompleted(State2),
BtcLocked(State3), BtcLocked(State3),
XmrLockProofReceived { WowLockProofReceived {
state: State3, state: State3,
lock_transfer_proof: TransferProof, lock_transfer_proof: TransferProof,
monero_wallet_restore_blockheight: BlockHeight, wownero_wallet_restore_blockheight: BlockHeight,
}, },
XmrLocked(State4), WowLocked(State4),
EncSigSent(State4), EncSigSent(State4),
BtcRedeemed(State5), BtcRedeemed(State5),
CancelTimelockExpired(State6), CancelTimelockExpired(State6),
BtcCancelled(State6), BtcCancelled(State6),
BtcRefunded(State6), BtcRefunded(State6),
XmrRedeemed { WowRedeemed {
tx_lock_id: bitcoin::Txid, tx_lock_id: bitcoin::Txid,
}, },
BtcPunished { BtcPunished {
@ -55,16 +55,16 @@ impl fmt::Display for BobState {
BobState::Started { .. } => write!(f, "quote has been requested"), BobState::Started { .. } => write!(f, "quote has been requested"),
BobState::SwapSetupCompleted(..) => write!(f, "execution setup done"), BobState::SwapSetupCompleted(..) => write!(f, "execution setup done"),
BobState::BtcLocked(..) => write!(f, "btc is locked"), BobState::BtcLocked(..) => write!(f, "btc is locked"),
BobState::XmrLockProofReceived { .. } => { BobState::WowLockProofReceived { .. } => {
write!(f, "XMR lock transaction transfer proof received") write!(f, "WOW lock transaction transfer proof received")
} }
BobState::XmrLocked(..) => write!(f, "xmr is locked"), BobState::WowLocked(..) => write!(f, "wow is locked"),
BobState::EncSigSent(..) => write!(f, "encrypted signature is sent"), BobState::EncSigSent(..) => write!(f, "encrypted signature is sent"),
BobState::BtcRedeemed(..) => write!(f, "btc is redeemed"), BobState::BtcRedeemed(..) => write!(f, "btc is redeemed"),
BobState::CancelTimelockExpired(..) => write!(f, "cancel timelock is expired"), BobState::CancelTimelockExpired(..) => write!(f, "cancel timelock is expired"),
BobState::BtcCancelled(..) => write!(f, "btc is cancelled"), BobState::BtcCancelled(..) => write!(f, "btc is cancelled"),
BobState::BtcRefunded(..) => write!(f, "btc is refunded"), BobState::BtcRefunded(..) => write!(f, "btc is refunded"),
BobState::XmrRedeemed { .. } => write!(f, "xmr is redeemed"), BobState::WowRedeemed { .. } => write!(f, "wow is redeemed"),
BobState::BtcPunished { .. } => write!(f, "btc is punished"), BobState::BtcPunished { .. } => write!(f, "btc is punished"),
BobState::SafelyAborted => write!(f, "safely aborted"), BobState::SafelyAborted => write!(f, "safely aborted"),
} }
@ -75,17 +75,17 @@ impl fmt::Display for BobState {
pub struct State0 { pub struct State0 {
swap_id: Uuid, swap_id: Uuid,
b: bitcoin::SecretKey, b: bitcoin::SecretKey,
s_b: monero::Scalar, s_b: wownero::Scalar,
S_b_monero: monero::PublicKey, S_b_wownero: wownero::PublicKey,
S_b_bitcoin: bitcoin::PublicKey, S_b_bitcoin: bitcoin::PublicKey,
v_b: monero::PrivateViewKey, v_b: wownero::PrivateViewKey,
dleq_proof_s_b: CrossCurveDLEQProof, dleq_proof_s_b: CrossCurveDLEQProof,
btc: bitcoin::Amount, btc: bitcoin::Amount,
xmr: monero::Amount, wow: wownero::Amount,
cancel_timelock: CancelTimelock, cancel_timelock: CancelTimelock,
punish_timelock: PunishTimelock, punish_timelock: PunishTimelock,
refund_address: bitcoin::Address, refund_address: bitcoin::Address,
min_monero_confirmations: u64, min_wownero_confirmations: u64,
tx_refund_fee: bitcoin::Amount, tx_refund_fee: bitcoin::Amount,
tx_cancel_fee: bitcoin::Amount, tx_cancel_fee: bitcoin::Amount,
} }
@ -96,20 +96,20 @@ impl State0 {
swap_id: Uuid, swap_id: Uuid,
rng: &mut R, rng: &mut R,
btc: bitcoin::Amount, btc: bitcoin::Amount,
xmr: monero::Amount, wow: wownero::Amount,
cancel_timelock: CancelTimelock, cancel_timelock: CancelTimelock,
punish_timelock: PunishTimelock, punish_timelock: PunishTimelock,
refund_address: bitcoin::Address, refund_address: bitcoin::Address,
min_monero_confirmations: u64, min_wownero_confirmations: u64,
tx_refund_fee: bitcoin::Amount, tx_refund_fee: bitcoin::Amount,
tx_cancel_fee: bitcoin::Amount, tx_cancel_fee: bitcoin::Amount,
) -> Self { ) -> Self {
let b = bitcoin::SecretKey::new_random(rng); let b = bitcoin::SecretKey::new_random(rng);
let s_b = monero::Scalar::random(rng); let s_b = wownero::Scalar::random(rng);
let v_b = monero::PrivateViewKey::new_random(rng); let v_b = wownero::PrivateViewKey::new_random(rng);
let (dleq_proof_s_b, (S_b_bitcoin, S_b_monero)) = CROSS_CURVE_PROOF_SYSTEM.prove(&s_b, rng); let (dleq_proof_s_b, (S_b_bitcoin, S_b_wownero)) = CROSS_CURVE_PROOF_SYSTEM.prove(&s_b, rng);
Self { Self {
swap_id, swap_id,
@ -117,16 +117,16 @@ impl State0 {
s_b, s_b,
v_b, v_b,
S_b_bitcoin: bitcoin::PublicKey::from(S_b_bitcoin), S_b_bitcoin: bitcoin::PublicKey::from(S_b_bitcoin),
S_b_monero: monero::PublicKey { S_b_wownero: wownero::PublicKey {
point: S_b_monero.compress(), point: S_b_wownero.compress(),
}, },
btc, btc,
xmr, wow,
dleq_proof_s_b, dleq_proof_s_b,
cancel_timelock, cancel_timelock,
punish_timelock, punish_timelock,
refund_address, refund_address,
min_monero_confirmations, min_wownero_confirmations,
tx_refund_fee, tx_refund_fee,
tx_cancel_fee, tx_cancel_fee,
} }
@ -136,7 +136,7 @@ impl State0 {
Message0 { Message0 {
swap_id: self.swap_id, swap_id: self.swap_id,
B: self.b.public(), B: self.b.public(),
S_b_monero: self.S_b_monero, S_b_wownero: self.S_b_wownero,
S_b_bitcoin: self.S_b_bitcoin, S_b_bitcoin: self.S_b_bitcoin,
dleq_proof_s_b: self.dleq_proof_s_b.clone(), dleq_proof_s_b: self.dleq_proof_s_b.clone(),
v_b: self.v_b, v_b: self.v_b,
@ -159,10 +159,10 @@ impl State0 {
&msg.dleq_proof_s_a, &msg.dleq_proof_s_a,
( (
msg.S_a_bitcoin.into(), msg.S_a_bitcoin.into(),
msg.S_a_monero msg.S_a_wownero
.point .point
.decompress() .decompress()
.ok_or_else(|| anyhow!("S_a is not a monero curve point"))?, .ok_or_else(|| anyhow!("S_a is not a wownero curve point"))?,
), ),
); );
@ -184,17 +184,17 @@ impl State0 {
A: msg.A, A: msg.A,
b: self.b, b: self.b,
s_b: self.s_b, s_b: self.s_b,
S_a_monero: msg.S_a_monero, S_a_wownero: msg.S_a_wownero,
S_a_bitcoin: msg.S_a_bitcoin, S_a_bitcoin: msg.S_a_bitcoin,
v, v,
xmr: self.xmr, wow: self.wow,
cancel_timelock: self.cancel_timelock, cancel_timelock: self.cancel_timelock,
punish_timelock: self.punish_timelock, punish_timelock: self.punish_timelock,
refund_address: self.refund_address, refund_address: self.refund_address,
redeem_address: msg.redeem_address, redeem_address: msg.redeem_address,
punish_address: msg.punish_address, punish_address: msg.punish_address,
tx_lock, tx_lock,
min_monero_confirmations: self.min_monero_confirmations, min_wownero_confirmations: self.min_wownero_confirmations,
tx_redeem_fee: msg.tx_redeem_fee, tx_redeem_fee: msg.tx_redeem_fee,
tx_refund_fee: self.tx_refund_fee, tx_refund_fee: self.tx_refund_fee,
tx_punish_fee: msg.tx_punish_fee, tx_punish_fee: msg.tx_punish_fee,
@ -207,18 +207,18 @@ impl State0 {
pub struct State1 { pub struct State1 {
A: bitcoin::PublicKey, A: bitcoin::PublicKey,
b: bitcoin::SecretKey, b: bitcoin::SecretKey,
s_b: monero::Scalar, s_b: wownero::Scalar,
S_a_monero: monero::PublicKey, S_a_wownero: wownero::PublicKey,
S_a_bitcoin: bitcoin::PublicKey, S_a_bitcoin: bitcoin::PublicKey,
v: monero::PrivateViewKey, v: wownero::PrivateViewKey,
xmr: monero::Amount, wow: wownero::Amount,
cancel_timelock: CancelTimelock, cancel_timelock: CancelTimelock,
punish_timelock: PunishTimelock, punish_timelock: PunishTimelock,
refund_address: bitcoin::Address, refund_address: bitcoin::Address,
redeem_address: bitcoin::Address, redeem_address: bitcoin::Address,
punish_address: bitcoin::Address, punish_address: bitcoin::Address,
tx_lock: bitcoin::TxLock, tx_lock: bitcoin::TxLock,
min_monero_confirmations: u64, min_wownero_confirmations: u64,
tx_redeem_fee: bitcoin::Amount, tx_redeem_fee: bitcoin::Amount,
tx_refund_fee: bitcoin::Amount, tx_refund_fee: bitcoin::Amount,
tx_punish_fee: bitcoin::Amount, tx_punish_fee: bitcoin::Amount,
@ -255,10 +255,10 @@ impl State1 {
A: self.A, A: self.A,
b: self.b, b: self.b,
s_b: self.s_b, s_b: self.s_b,
S_a_monero: self.S_a_monero, S_a_wownero: self.S_a_wownero,
S_a_bitcoin: self.S_a_bitcoin, S_a_bitcoin: self.S_a_bitcoin,
v: self.v, v: self.v,
xmr: self.xmr, wow: self.wow,
cancel_timelock: self.cancel_timelock, cancel_timelock: self.cancel_timelock,
punish_timelock: self.punish_timelock, punish_timelock: self.punish_timelock,
refund_address: self.refund_address, refund_address: self.refund_address,
@ -267,7 +267,7 @@ impl State1 {
tx_lock: self.tx_lock, tx_lock: self.tx_lock,
tx_cancel_sig_a: msg.tx_cancel_sig, tx_cancel_sig_a: msg.tx_cancel_sig,
tx_refund_encsig: msg.tx_refund_encsig, tx_refund_encsig: msg.tx_refund_encsig,
min_monero_confirmations: self.min_monero_confirmations, min_wownero_confirmations: self.min_wownero_confirmations,
tx_redeem_fee: self.tx_redeem_fee, tx_redeem_fee: self.tx_redeem_fee,
tx_refund_fee: self.tx_refund_fee, tx_refund_fee: self.tx_refund_fee,
tx_punish_fee: self.tx_punish_fee, tx_punish_fee: self.tx_punish_fee,
@ -280,11 +280,11 @@ impl State1 {
pub struct State2 { pub struct State2 {
A: bitcoin::PublicKey, A: bitcoin::PublicKey,
b: bitcoin::SecretKey, b: bitcoin::SecretKey,
s_b: monero::Scalar, s_b: wownero::Scalar,
S_a_monero: monero::PublicKey, S_a_wownero: wownero::PublicKey,
S_a_bitcoin: bitcoin::PublicKey, S_a_bitcoin: bitcoin::PublicKey,
v: monero::PrivateViewKey, v: wownero::PrivateViewKey,
xmr: monero::Amount, wow: wownero::Amount,
cancel_timelock: CancelTimelock, cancel_timelock: CancelTimelock,
punish_timelock: PunishTimelock, punish_timelock: PunishTimelock,
refund_address: bitcoin::Address, refund_address: bitcoin::Address,
@ -293,7 +293,7 @@ pub struct State2 {
tx_lock: bitcoin::TxLock, tx_lock: bitcoin::TxLock,
tx_cancel_sig_a: Signature, tx_cancel_sig_a: Signature,
tx_refund_encsig: bitcoin::EncryptedSignature, tx_refund_encsig: bitcoin::EncryptedSignature,
min_monero_confirmations: u64, min_wownero_confirmations: u64,
#[serde(with = "::bitcoin::util::amount::serde::as_sat")] #[serde(with = "::bitcoin::util::amount::serde::as_sat")]
tx_redeem_fee: bitcoin::Amount, tx_redeem_fee: bitcoin::Amount,
#[serde(with = "::bitcoin::util::amount::serde::as_sat")] #[serde(with = "::bitcoin::util::amount::serde::as_sat")]
@ -334,10 +334,10 @@ impl State2 {
A: self.A, A: self.A,
b: self.b, b: self.b,
s_b: self.s_b, s_b: self.s_b,
S_a_monero: self.S_a_monero, S_a_wownero: self.S_a_wownero,
S_a_bitcoin: self.S_a_bitcoin, S_a_bitcoin: self.S_a_bitcoin,
v: self.v, v: self.v,
xmr: self.xmr, wow: self.wow,
cancel_timelock: self.cancel_timelock, cancel_timelock: self.cancel_timelock,
punish_timelock: self.punish_timelock, punish_timelock: self.punish_timelock,
refund_address: self.refund_address, refund_address: self.refund_address,
@ -345,7 +345,7 @@ impl State2 {
tx_lock: self.tx_lock.clone(), tx_lock: self.tx_lock.clone(),
tx_cancel_sig_a: self.tx_cancel_sig_a, tx_cancel_sig_a: self.tx_cancel_sig_a,
tx_refund_encsig: self.tx_refund_encsig, tx_refund_encsig: self.tx_refund_encsig,
min_monero_confirmations: self.min_monero_confirmations, min_wownero_confirmations: self.min_wownero_confirmations,
tx_redeem_fee: self.tx_redeem_fee, tx_redeem_fee: self.tx_redeem_fee,
tx_refund_fee: self.tx_refund_fee, tx_refund_fee: self.tx_refund_fee,
tx_cancel_fee: self.tx_cancel_fee, tx_cancel_fee: self.tx_cancel_fee,
@ -359,11 +359,11 @@ impl State2 {
pub struct State3 { pub struct State3 {
A: bitcoin::PublicKey, A: bitcoin::PublicKey,
b: bitcoin::SecretKey, b: bitcoin::SecretKey,
s_b: monero::Scalar, s_b: wownero::Scalar,
S_a_monero: monero::PublicKey, S_a_wownero: wownero::PublicKey,
S_a_bitcoin: bitcoin::PublicKey, S_a_bitcoin: bitcoin::PublicKey,
v: monero::PrivateViewKey, v: wownero::PrivateViewKey,
xmr: monero::Amount, wow: wownero::Amount,
pub cancel_timelock: CancelTimelock, pub cancel_timelock: CancelTimelock,
punish_timelock: PunishTimelock, punish_timelock: PunishTimelock,
refund_address: bitcoin::Address, refund_address: bitcoin::Address,
@ -371,7 +371,7 @@ pub struct State3 {
pub tx_lock: bitcoin::TxLock, pub tx_lock: bitcoin::TxLock,
tx_cancel_sig_a: Signature, tx_cancel_sig_a: Signature,
tx_refund_encsig: bitcoin::EncryptedSignature, tx_refund_encsig: bitcoin::EncryptedSignature,
min_monero_confirmations: u64, min_wownero_confirmations: u64,
#[serde(with = "::bitcoin::util::amount::serde::as_sat")] #[serde(with = "::bitcoin::util::amount::serde::as_sat")]
tx_redeem_fee: bitcoin::Amount, tx_redeem_fee: bitcoin::Amount,
#[serde(with = "::bitcoin::util::amount::serde::as_sat")] #[serde(with = "::bitcoin::util::amount::serde::as_sat")]
@ -381,21 +381,21 @@ pub struct State3 {
} }
impl State3 { impl State3 {
pub fn lock_xmr_watch_request(&self, transfer_proof: TransferProof) -> WatchRequest { pub fn lock_wow_watch_request(&self, transfer_proof: TransferProof) -> WatchRequest {
let S_b_monero = let S_b_wownero =
monero::PublicKey::from_private_key(&monero::PrivateKey::from_scalar(self.s_b)); wownero::PublicKey::from_private_key(&wownero::PrivateKey::from_scalar(self.s_b));
let S = self.S_a_monero + S_b_monero; let S = self.S_a_wownero + S_b_wownero;
WatchRequest { WatchRequest {
public_spend_key: S, public_spend_key: S,
public_view_key: self.v.public(), public_view_key: self.v.public(),
transfer_proof, transfer_proof,
conf_target: self.min_monero_confirmations, conf_target: self.min_wownero_confirmations,
expected: self.xmr, expected: self.wow,
} }
} }
pub fn xmr_locked(self, monero_wallet_restore_blockheight: BlockHeight) -> State4 { pub fn wow_locked(self, wownero_wallet_restore_blockheight: BlockHeight) -> State4 {
State4 { State4 {
A: self.A, A: self.A,
b: self.b, b: self.b,
@ -409,7 +409,7 @@ impl State3 {
tx_lock: self.tx_lock, tx_lock: self.tx_lock,
tx_cancel_sig_a: self.tx_cancel_sig_a, tx_cancel_sig_a: self.tx_cancel_sig_a,
tx_refund_encsig: self.tx_refund_encsig, tx_refund_encsig: self.tx_refund_encsig,
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
tx_redeem_fee: self.tx_redeem_fee, tx_redeem_fee: self.tx_redeem_fee,
tx_refund_fee: self.tx_refund_fee, tx_refund_fee: self.tx_refund_fee,
tx_cancel_fee: self.tx_cancel_fee, tx_cancel_fee: self.tx_cancel_fee,
@ -464,9 +464,9 @@ impl State3 {
pub struct State4 { pub struct State4 {
A: bitcoin::PublicKey, A: bitcoin::PublicKey,
b: bitcoin::SecretKey, b: bitcoin::SecretKey,
s_b: monero::Scalar, s_b: wownero::Scalar,
S_a_bitcoin: bitcoin::PublicKey, S_a_bitcoin: bitcoin::PublicKey,
v: monero::PrivateViewKey, v: wownero::PrivateViewKey,
pub cancel_timelock: CancelTimelock, pub cancel_timelock: CancelTimelock,
punish_timelock: PunishTimelock, punish_timelock: PunishTimelock,
refund_address: bitcoin::Address, refund_address: bitcoin::Address,
@ -474,7 +474,7 @@ pub struct State4 {
pub tx_lock: bitcoin::TxLock, pub tx_lock: bitcoin::TxLock,
tx_cancel_sig_a: Signature, tx_cancel_sig_a: Signature,
tx_refund_encsig: bitcoin::EncryptedSignature, tx_refund_encsig: bitcoin::EncryptedSignature,
monero_wallet_restore_blockheight: BlockHeight, wownero_wallet_restore_blockheight: BlockHeight,
#[serde(with = "::bitcoin::util::amount::serde::as_sat")] #[serde(with = "::bitcoin::util::amount::serde::as_sat")]
tx_redeem_fee: bitcoin::Amount, tx_redeem_fee: bitcoin::Amount,
#[serde(with = "::bitcoin::util::amount::serde::as_sat")] #[serde(with = "::bitcoin::util::amount::serde::as_sat")]
@ -506,14 +506,14 @@ impl State4 {
let tx_redeem_sig = let tx_redeem_sig =
tx_redeem.extract_signature_by_key(tx_redeem_candidate, self.b.public())?; tx_redeem.extract_signature_by_key(tx_redeem_candidate, self.b.public())?;
let s_a = bitcoin::recover(self.S_a_bitcoin, tx_redeem_sig, tx_redeem_encsig)?; let s_a = bitcoin::recover(self.S_a_bitcoin, tx_redeem_sig, tx_redeem_encsig)?;
let s_a = monero::private_key_from_secp256k1_scalar(s_a.into()); let s_a = wownero::private_key_from_secp256k1_scalar(s_a.into());
Ok(State5 { Ok(State5 {
s_a, s_a,
s_b: self.s_b, s_b: self.s_b,
v: self.v, v: self.v,
tx_lock: self.tx_lock.clone(), tx_lock: self.tx_lock.clone(),
monero_wallet_restore_blockheight: self.monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight: self.wownero_wallet_restore_blockheight,
}) })
} }
@ -559,17 +559,17 @@ impl State4 {
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)] #[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct State5 { pub struct State5 {
#[serde(with = "monero_private_key")] #[serde(with = "wownero_private_key")]
s_a: monero::PrivateKey, s_a: wownero::PrivateKey,
s_b: monero::Scalar, s_b: wownero::Scalar,
v: monero::PrivateViewKey, v: wownero::PrivateViewKey,
tx_lock: bitcoin::TxLock, tx_lock: bitcoin::TxLock,
pub monero_wallet_restore_blockheight: BlockHeight, pub wownero_wallet_restore_blockheight: BlockHeight,
} }
impl State5 { impl State5 {
pub fn xmr_keys(&self) -> (monero::PrivateKey, monero::PrivateViewKey) { pub fn wow_keys(&self) -> (wownero::PrivateKey, wownero::PrivateViewKey) {
let s_b = monero::PrivateKey { scalar: self.s_b }; let s_b = wownero::PrivateKey { scalar: self.s_b };
let s = self.s_a + s_b; let s = self.s_a + s_b;
(s, self.v) (s, self.v)
@ -584,7 +584,7 @@ impl State5 {
pub struct State6 { pub struct State6 {
A: bitcoin::PublicKey, A: bitcoin::PublicKey,
b: bitcoin::SecretKey, b: bitcoin::SecretKey,
s_b: monero::Scalar, s_b: wownero::Scalar,
cancel_timelock: CancelTimelock, cancel_timelock: CancelTimelock,
punish_timelock: PunishTimelock, punish_timelock: PunishTimelock,
refund_address: bitcoin::Address, refund_address: bitcoin::Address,

@ -4,7 +4,7 @@ use crate::database::Swap;
use crate::network::swap_setup::bob::NewSwap; use crate::network::swap_setup::bob::NewSwap;
use crate::protocol::bob; use crate::protocol::bob;
use crate::protocol::bob::state::*; use crate::protocol::bob::state::*;
use crate::{bitcoin, monero}; use crate::{bitcoin, wownero};
use anyhow::{bail, Context, Result}; use anyhow::{bail, Context, Result};
use tokio::select; use tokio::select;
use uuid::Uuid; use uuid::Uuid;
@ -13,7 +13,7 @@ pub fn is_complete(state: &BobState) -> bool {
matches!( matches!(
state, state,
BobState::BtcRefunded(..) BobState::BtcRefunded(..)
| BobState::XmrRedeemed { .. } | BobState::WowRedeemed { .. }
| BobState::BtcPunished { .. } | BobState::BtcPunished { .. }
| BobState::SafelyAborted | BobState::SafelyAborted
) )
@ -36,8 +36,8 @@ pub async fn run_until(
current_state, current_state,
&mut swap.event_loop_handle, &mut swap.event_loop_handle,
swap.bitcoin_wallet.as_ref(), swap.bitcoin_wallet.as_ref(),
swap.monero_wallet.as_ref(), swap.wownero_wallet.as_ref(),
swap.monero_receive_address, swap.wownero_receive_address,
) )
.await?; .await?;
@ -55,8 +55,8 @@ async fn next_state(
state: BobState, state: BobState,
event_loop_handle: &mut EventLoopHandle, event_loop_handle: &mut EventLoopHandle,
bitcoin_wallet: &bitcoin::Wallet, bitcoin_wallet: &bitcoin::Wallet,
monero_wallet: &monero::Wallet, wownero_wallet: &wownero::Wallet,
monero_receive_address: monero::Address, wownero_receive_address: wownero::Address,
) -> Result<BobState> { ) -> Result<BobState> {
tracing::trace!(%state, "Advancing state"); tracing::trace!(%state, "Advancing state");
@ -96,7 +96,7 @@ async fn next_state(
BobState::BtcLocked(state3) BobState::BtcLocked(state3)
} }
// Bob has locked Btc // Bob has locked Btc
// Watch for Alice to Lock Xmr or for cancel timelock to elapse // Watch for Alice to Lock Wow or for cancel timelock to elapse
BobState::BtcLocked(state3) => { BobState::BtcLocked(state3) => {
let tx_lock_status = bitcoin_wallet.subscribe_to(state3.tx_lock.clone()).await; let tx_lock_status = bitcoin_wallet.subscribe_to(state3.tx_lock.clone()).await;
@ -105,26 +105,26 @@ async fn next_state(
let cancel_timelock_expires = let cancel_timelock_expires =
tx_lock_status.wait_until_confirmed_with(state3.cancel_timelock); tx_lock_status.wait_until_confirmed_with(state3.cancel_timelock);
// Record the current monero wallet block height so we don't have to scan from // Record the current wownero wallet block height so we don't have to scan from
// block 0 once we create the redeem wallet. // block 0 once we create the redeem wallet.
let monero_wallet_restore_blockheight = monero_wallet.block_height().await?; let wownero_wallet_restore_blockheight = wownero_wallet.block_height().await?;
tracing::info!("Waiting for Alice to lock Monero"); tracing::info!("Waiting for Alice to lock Wownero");
select! { select! {
transfer_proof = transfer_proof_watcher => { transfer_proof = transfer_proof_watcher => {
let transfer_proof = transfer_proof?; let transfer_proof = transfer_proof?;
tracing::info!(txid = %transfer_proof.tx_hash(), "Alice locked Monero"); tracing::info!(txid = %transfer_proof.tx_hash(), "Alice locked Wownero");
BobState::XmrLockProofReceived { BobState::WowLockProofReceived {
state: state3, state: state3,
lock_transfer_proof: transfer_proof, lock_transfer_proof: transfer_proof,
monero_wallet_restore_blockheight wownero_wallet_restore_blockheight
} }
}, },
_ = cancel_timelock_expires => { _ = cancel_timelock_expires => {
tracing::info!("Alice took too long to lock Monero, cancelling the swap"); tracing::info!("Alice took too long to lock Wownero, cancelling the swap");
let state4 = state3.cancel(); let state4 = state3.cancel();
BobState::CancelTimelockExpired(state4) BobState::CancelTimelockExpired(state4)
@ -135,22 +135,22 @@ async fn next_state(
BobState::CancelTimelockExpired(state4) BobState::CancelTimelockExpired(state4)
} }
} }
BobState::XmrLockProofReceived { BobState::WowLockProofReceived {
state, state,
lock_transfer_proof, lock_transfer_proof,
monero_wallet_restore_blockheight, wownero_wallet_restore_blockheight,
} => { } => {
let tx_lock_status = bitcoin_wallet.subscribe_to(state.tx_lock.clone()).await; let tx_lock_status = bitcoin_wallet.subscribe_to(state.tx_lock.clone()).await;
if let ExpiredTimelocks::None = state.current_epoch(bitcoin_wallet).await? { if let ExpiredTimelocks::None = state.current_epoch(bitcoin_wallet).await? {
let watch_request = state.lock_xmr_watch_request(lock_transfer_proof); let watch_request = state.lock_wow_watch_request(lock_transfer_proof);
select! { select! {
received_xmr = monero_wallet.watch_for_transfer(watch_request) => { received_wow = wownero_wallet.watch_for_transfer(watch_request) => {
match received_xmr { match received_wow {
Ok(()) => BobState::XmrLocked(state.xmr_locked(monero_wallet_restore_blockheight)), Ok(()) => BobState::WowLocked(state.wow_locked(wownero_wallet_restore_blockheight)),
Err(monero::InsufficientFunds { expected, actual }) => { Err(wownero::InsufficientFunds { expected, actual }) => {
tracing::warn!(%expected, %actual, "Insufficient Monero have been locked!"); tracing::warn!(%expected, %actual, "Insufficient Wownero have been locked!");
tracing::info!(timelock = %state.cancel_timelock, "Waiting for cancel timelock to expire"); tracing::info!(timelock = %state.cancel_timelock, "Waiting for cancel timelock to expire");
tx_lock_status.wait_until_confirmed_with(state.cancel_timelock).await?; tx_lock_status.wait_until_confirmed_with(state.cancel_timelock).await?;
@ -167,11 +167,11 @@ async fn next_state(
BobState::CancelTimelockExpired(state.cancel()) BobState::CancelTimelockExpired(state.cancel())
} }
} }
BobState::XmrLocked(state) => { BobState::WowLocked(state) => {
let tx_lock_status = bitcoin_wallet.subscribe_to(state.tx_lock.clone()).await; let tx_lock_status = bitcoin_wallet.subscribe_to(state.tx_lock.clone()).await;
if let ExpiredTimelocks::None = state.expired_timelock(bitcoin_wallet).await? { if let ExpiredTimelocks::None = state.expired_timelock(bitcoin_wallet).await? {
// Alice has locked Xmr // Alice has locked Wow
// Bob sends Alice his key // Bob sends Alice his key
select! { select! {
@ -203,38 +203,38 @@ async fn next_state(
} }
} }
BobState::BtcRedeemed(state) => { BobState::BtcRedeemed(state) => {
let (spend_key, view_key) = state.xmr_keys(); let (spend_key, view_key) = state.wow_keys();
let wallet_file_name = swap_id.to_string(); let wallet_file_name = swap_id.to_string();
if let Err(e) = monero_wallet if let Err(e) = wownero_wallet
.create_from_and_load( .create_from_and_load(
wallet_file_name.clone(), wallet_file_name.clone(),
spend_key, spend_key,
view_key, view_key,
state.monero_wallet_restore_blockheight, state.wownero_wallet_restore_blockheight,
) )
.await .await
{ {
// In case we failed to refresh/sweep, when resuming the wallet might already // In case we failed to refresh/sweep, when resuming the wallet might already
// exist! This is a very unlikely scenario, but if we don't take care of it we // exist! This is a very unlikely scenario, but if we don't take care of it we
// might not be able to ever transfer the Monero. // might not be able to ever transfer the Wownero.
tracing::warn!("Failed to generate monero wallet from keys: {:#}", e); tracing::warn!("Failed to generate wownero wallet from keys: {:#}", e);
tracing::info!(%wallet_file_name, tracing::info!(%wallet_file_name,
"Falling back to trying to open the the wallet if it already exists", "Falling back to trying to open the the wallet if it already exists",
); );
monero_wallet.open(wallet_file_name).await?; wownero_wallet.open(wallet_file_name).await?;
} }
// Ensure that the generated wallet is synced so we have a proper balance // Ensure that the generated wallet is synced so we have a proper balance
monero_wallet.refresh().await?; wownero_wallet.refresh().await?;
// Sweep (transfer all funds) to the given address // Sweep (transfer all funds) to the given address
let tx_hashes = monero_wallet.sweep_all(monero_receive_address).await?; let tx_hashes = wownero_wallet.sweep_all(wownero_receive_address).await?;
for tx_hash in tx_hashes { for tx_hash in tx_hashes {
tracing::info!(%monero_receive_address, txid=%tx_hash.0, "Successfully transferred XMR to wallet"); tracing::info!(%wownero_receive_address, txid=%tx_hash.0, "Successfully transferred WOW to wallet");
} }
BobState::XmrRedeemed { BobState::WowRedeemed {
tx_lock_id: state.tx_lock_id(), tx_lock_id: state.tx_lock_id(),
} }
} }
@ -265,6 +265,6 @@ async fn next_state(
BobState::BtcRefunded(state4) => BobState::BtcRefunded(state4), BobState::BtcRefunded(state4) => BobState::BtcRefunded(state4),
BobState::BtcPunished { tx_lock_id } => BobState::BtcPunished { tx_lock_id }, BobState::BtcPunished { tx_lock_id } => BobState::BtcPunished { tx_lock_id },
BobState::SafelyAborted => BobState::SafelyAborted, BobState::SafelyAborted => BobState::SafelyAborted,
BobState::XmrRedeemed { tx_lock_id } => BobState::XmrRedeemed { tx_lock_id }, BobState::WowRedeemed { tx_lock_id } => BobState::WowRedeemed { tx_lock_id },
}) })
} }

@ -1,8 +1,8 @@
pub mod wallet; pub mod wallet;
mod wallet_rpc; mod wallet_rpc;
pub use ::monero::network::Network; pub use ::wownero::network::Network;
pub use ::monero::{Address, PrivateKey, PublicKey}; pub use ::wownero::{Address, PrivateKey, PublicKey};
pub use curve25519_dalek::scalar::Scalar; pub use curve25519_dalek::scalar::Scalar;
pub use wallet::Wallet; pub use wallet::Wallet;
pub use wallet_rpc::{WalletRpc, WalletRpcProcess}; pub use wallet_rpc::{WalletRpc, WalletRpcProcess};
@ -40,7 +40,7 @@ pub fn private_key_from_secp256k1_scalar(scalar: bitcoin::Scalar) -> PrivateKey
} }
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)] #[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)]
pub struct PrivateViewKey(#[serde(with = "monero_private_key")] PrivateKey); pub struct PrivateViewKey(#[serde(with = "wownero_private_key")] PrivateKey);
impl PrivateViewKey { impl PrivateViewKey {
pub fn new_random<R: RngCore + CryptoRng>(rng: &mut R) -> Self { pub fn new_random<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
@ -81,16 +81,16 @@ pub struct PublicViewKey(PublicKey);
#[derive(Debug, Copy, Clone, Deserialize, Serialize, PartialEq, PartialOrd)] #[derive(Debug, Copy, Clone, Deserialize, Serialize, PartialEq, PartialOrd)]
pub struct Amount(u64); pub struct Amount(u64);
// Median tx fees on Monero as found here: https://www.monero.how/monero-transaction-fees, XMR 0.000_015 * 2 (to be on the safe side) // Median tx fees on Wownero as found here: https://www.wownero.how/wownero-transaction-fees, WOW 0.000_015 * 2 (to be on the safe side)
pub const MONERO_FEE: Amount = Amount::from_piconero(30000000); pub const WOWNERO_FEE: Amount = Amount::from_piconero(30000000);
impl Amount { impl Amount {
pub const ZERO: Self = Self(0); pub const ZERO: Self = Self(0);
pub const ONE_XMR: Self = Self(PICONERO_OFFSET); pub const ONE_WOW: Self = Self(PICONERO_OFFSET);
/// Create an [Amount] with piconero precision and the given number of /// Create an [Amount] with piconero precision and the given number of
/// piconeros. /// piconeros.
/// ///
/// A piconero (a.k.a atomic unit) is equal to 1e-12 XMR. /// A piconero (a.k.a atomic unit) is equal to 1e-12 WOW.
pub const fn from_piconero(amount: u64) -> Self { pub const fn from_piconero(amount: u64) -> Self {
Amount(amount) Amount(amount)
} }
@ -99,12 +99,12 @@ impl Amount {
self.0 self.0
} }
pub fn from_monero(amount: f64) -> Result<Self> { pub fn from_wownero(amount: f64) -> Result<Self> {
let decimal = Decimal::try_from(amount)?; let decimal = Decimal::try_from(amount)?;
Self::from_decimal(decimal) Self::from_decimal(decimal)
} }
pub fn parse_monero(amount: &str) -> Result<Self> { pub fn parse_wownero(amount: &str) -> Result<Self> {
let decimal = Decimal::from_str(amount)?; let decimal = Decimal::from_str(amount)?;
Self::from_decimal(decimal) Self::from_decimal(decimal)
} }
@ -159,14 +159,14 @@ impl fmt::Display for Amount {
decimal decimal
.set_scale(12) .set_scale(12)
.expect("12 is smaller than max precision of 28"); .expect("12 is smaller than max precision of 28");
write!(f, "{} XMR", decimal) write!(f, "{} WOW", decimal)
} }
} }
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct TransferProof { pub struct TransferProof {
tx_hash: TxHash, tx_hash: TxHash,
#[serde(with = "monero_private_key")] #[serde(with = "wownero_private_key")]
tx_key: PrivateKey, tx_key: PrivateKey,
} }
@ -209,9 +209,9 @@ pub struct InsufficientFunds {
#[error("Overflow, cannot convert {0} to u64")] #[error("Overflow, cannot convert {0} to u64")]
pub struct OverflowError(pub String); pub struct OverflowError(pub String);
pub mod monero_private_key { pub mod wownero_private_key {
use monero::consensus::{Decodable, Encodable}; use wownero::consensus::{Decodable, Encodable};
use monero::PrivateKey; use wownero::PrivateKey;
use serde::de::Visitor; use serde::de::Visitor;
use serde::ser::Error; use serde::ser::Error;
use serde::{de, Deserializer, Serializer}; use serde::{de, Deserializer, Serializer};
@ -224,7 +224,7 @@ pub mod monero_private_key {
type Value = PrivateKey; type Value = PrivateKey;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "a byte array representing a Monero private key") write!(formatter, "a byte array representing a Wownero private key")
} }
fn visit_bytes<E>(self, s: &[u8]) -> Result<Self::Value, E> fn visit_bytes<E>(self, s: &[u8]) -> Result<Self::Value, E>
@ -257,8 +257,8 @@ pub mod monero_private_key {
} }
} }
pub mod monero_amount { pub mod wownero_amount {
use crate::monero::Amount; use crate::wownero::Amount;
use serde::{Deserialize, Deserializer, Serializer}; use serde::{Deserialize, Deserializer, Serializer};
pub fn serialize<S>(x: &Amount, s: S) -> Result<S::Ok, S::Error> pub fn serialize<S>(x: &Amount, s: S) -> Result<S::Ok, S::Error>
@ -284,57 +284,57 @@ mod tests {
use super::*; use super::*;
#[test] #[test]
fn display_monero_min() { fn display_wownero_min() {
let min_pics = 1; let min_pics = 1;
let amount = Amount::from_piconero(min_pics); let amount = Amount::from_piconero(min_pics);
let monero = amount.to_string(); let wownero = amount.to_string();
assert_eq!("0.000000000001 XMR", monero); assert_eq!("0.000000000001 WOW", wownero);
} }
#[test] #[test]
fn display_monero_one() { fn display_wownero_one() {
let min_pics = 1000000000000; let min_pics = 1000000000000;
let amount = Amount::from_piconero(min_pics); let amount = Amount::from_piconero(min_pics);
let monero = amount.to_string(); let wownero = amount.to_string();
assert_eq!("1.000000000000 XMR", monero); assert_eq!("1.000000000000 WOW", wownero);
} }
#[test] #[test]
fn display_monero_max() { fn display_wownero_max() {
let max_pics = 18_446_744_073_709_551_615; let max_pics = 18_446_744_073_709_551_615;
let amount = Amount::from_piconero(max_pics); let amount = Amount::from_piconero(max_pics);
let monero = amount.to_string(); let wownero = amount.to_string();
assert_eq!("18446744.073709551615 XMR", monero); assert_eq!("18446744.073709551615 WOW", wownero);
} }
#[test] #[test]
fn parse_monero_min() { fn parse_wownero_min() {
let monero_min = "0.000000000001"; let wownero_min = "0.000000000001";
let amount = Amount::parse_monero(monero_min).unwrap(); let amount = Amount::parse_wownero(wownero_min).unwrap();
let pics = amount.0; let pics = amount.0;
assert_eq!(1, pics); assert_eq!(1, pics);
} }
#[test] #[test]
fn parse_monero() { fn parse_wownero() {
let monero = "123"; let wownero = "123";
let amount = Amount::parse_monero(monero).unwrap(); let amount = Amount::parse_wownero(wownero).unwrap();
let pics = amount.0; let pics = amount.0;
assert_eq!(123000000000000, pics); assert_eq!(123000000000000, pics);
} }
#[test] #[test]
fn parse_monero_max() { fn parse_wownero_max() {
let monero = "18446744.073709551615"; let wownero = "18446744.073709551615";
let amount = Amount::parse_monero(monero).unwrap(); let amount = Amount::parse_wownero(wownero).unwrap();
let pics = amount.0; let pics = amount.0;
assert_eq!(18446744073709551615, pics); assert_eq!(18446744073709551615, pics);
} }
#[test] #[test]
fn parse_monero_overflows() { fn parse_wownero_overflows() {
let overflow_pics = "18446744.073709551616"; let overflow_pics = "18446744.073709551616";
let error = Amount::parse_monero(overflow_pics).unwrap_err(); let error = Amount::parse_wownero(overflow_pics).unwrap_err();
assert_eq!( assert_eq!(
error.downcast_ref::<OverflowError>().unwrap(), error.downcast_ref::<OverflowError>().unwrap(),
&OverflowError(overflow_pics.to_owned()) &OverflowError(overflow_pics.to_owned())
@ -345,26 +345,26 @@ mod tests {
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, PartialEq)] #[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct MoneroPrivateKey(#[serde(with = "monero_private_key")] crate::monero::PrivateKey); pub struct WowneroPrivateKey(#[serde(with = "wownero_private_key")] crate::wownero::PrivateKey);
#[derive(Debug, Serialize, Deserialize, PartialEq)] #[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct MoneroAmount(#[serde(with = "monero_amount")] crate::monero::Amount); pub struct WowneroAmount(#[serde(with = "wownero_amount")] crate::wownero::Amount);
#[test] #[test]
fn serde_monero_private_key() { fn serde_wownero_private_key() {
let key = MoneroPrivateKey(monero::PrivateKey::from_scalar( let key = WowneroPrivateKey(wownero::PrivateKey::from_scalar(
crate::monero::Scalar::random(&mut OsRng), crate::wownero::Scalar::random(&mut OsRng),
)); ));
let encoded = serde_cbor::to_vec(&key).unwrap(); let encoded = serde_cbor::to_vec(&key).unwrap();
let decoded: MoneroPrivateKey = serde_cbor::from_slice(&encoded).unwrap(); let decoded: WowneroPrivateKey = serde_cbor::from_slice(&encoded).unwrap();
assert_eq!(key, decoded); assert_eq!(key, decoded);
} }
#[test] #[test]
fn serde_monero_amount() { fn serde_wownero_amount() {
let amount = MoneroAmount(crate::monero::Amount::from_piconero(1000)); let amount = WowneroAmount(crate::wownero::Amount::from_piconero(1000));
let encoded = serde_cbor::to_vec(&amount).unwrap(); let encoded = serde_cbor::to_vec(&amount).unwrap();
let decoded: MoneroAmount = serde_cbor::from_slice(&encoded).unwrap(); let decoded: WowneroAmount = serde_cbor::from_slice(&encoded).unwrap();
assert_eq!(amount, decoded); assert_eq!(amount, decoded);
} }
} }

@ -1,11 +1,11 @@
use crate::env::Config; use crate::env::Config;
use crate::monero::{ use crate::wownero::{
Amount, InsufficientFunds, PrivateViewKey, PublicViewKey, TransferProof, TxHash, Amount, InsufficientFunds, PrivateViewKey, PublicViewKey, TransferProof, TxHash,
}; };
use ::monero::{Address, Network, PrivateKey, PublicKey}; use ::wownero::{Address, Network, PrivateKey, PublicKey};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use monero_rpc::wallet; use wownero_rpc::wallet;
use monero_rpc::wallet::{BlockHeight, CheckTxKey, MoneroWalletRpc as _, Refreshed}; use wownero_rpc::wallet::{BlockHeight, CheckTxKey, WowneroWalletRpc as _, Refreshed};
use std::future::Future; use std::future::Future;
use std::str::FromStr; use std::str::FromStr;
use std::time::Duration; use std::time::Duration;
@ -18,7 +18,7 @@ pub struct Wallet {
inner: Mutex<wallet::Client>, inner: Mutex<wallet::Client>,
network: Network, network: Network,
name: String, name: String,
main_address: monero::Address, main_address: wownero::Address,
sync_interval: Duration, sync_interval: Duration,
} }
@ -30,12 +30,12 @@ impl Wallet {
let open_wallet_response = client.open_wallet(name.clone()).await; let open_wallet_response = client.open_wallet(name.clone()).await;
if open_wallet_response.is_err() { if open_wallet_response.is_err() {
client.create_wallet(name.clone(), "English".to_owned()).await.context( client.create_wallet(name.clone(), "English".to_owned()).await.context(
"Unable to create Monero wallet, please ensure that the monero-wallet-rpc is available", "Unable to create Wownero wallet, please ensure that the wownero-wallet-rpc is available",
)?; )?;
tracing::debug!(monero_wallet_name = %name, "Created Monero wallet"); tracing::debug!(wownero_wallet_name = %name, "Created Wownero wallet");
} else { } else {
tracing::debug!(monero_wallet_name = %name, "Opened Monero wallet"); tracing::debug!(wownero_wallet_name = %name, "Opened Wownero wallet");
} }
Self::connect(client, name, env_config).await Self::connect(client, name, env_config).await
@ -44,13 +44,13 @@ impl Wallet {
/// Connects to a wallet RPC where a wallet is already loaded. /// Connects to a wallet RPC where a wallet is already loaded.
pub async fn connect(client: wallet::Client, name: String, env_config: Config) -> Result<Self> { pub async fn connect(client: wallet::Client, name: String, env_config: Config) -> Result<Self> {
let main_address = let main_address =
monero::Address::from_str(client.get_address(0).await?.address.as_str())?; wownero::Address::from_str(client.get_address(0).await?.address.as_str())?;
Ok(Self { Ok(Self {
inner: Mutex::new(client), inner: Mutex::new(client),
network: env_config.monero_network, network: env_config.wownero_network,
name, name,
main_address, main_address,
sync_interval: env_config.monero_sync_interval(), sync_interval: env_config.wownero_sync_interval(),
}) })
} }
@ -150,14 +150,14 @@ impl Wallet {
for tx in sweep_all.tx_hash_list { for tx in sweep_all.tx_hash_list {
tracing::info!( tracing::info!(
%tx, %tx,
monero_address = %self.main_address, wownero_address = %self.main_address,
"Monero transferred back to default wallet"); "Wownero transferred back to default wallet");
} }
} }
Err(error) => { Err(error) => {
tracing::warn!( tracing::warn!(
address = %self.main_address, address = %self.main_address,
"Failed to transfer Monero to default wallet: {:#}", error "Failed to transfer Wownero to default wallet: {:#}", error
); );
} }
}, },
@ -192,7 +192,7 @@ impl Wallet {
%amount, %amount,
to = %public_spend_key, to = %public_spend_key,
tx_id = %res.tx_hash, tx_id = %res.tx_hash,
"Successfully initiated Monero transfer" "Successfully initiated Wownero transfer"
); );
Ok(TransferProof::new( Ok(TransferProof::new(
@ -216,7 +216,7 @@ impl Wallet {
tracing::info!( tracing::info!(
%txid, %txid,
target_confirmations = %conf_target, target_confirmations = %conf_target,
"Waiting for Monero transaction finality" "Waiting for Wownero transaction finality"
); );
let address = Address::standard(self.network, public_spend_key, public_view_key.into()); let address = Address::standard(self.network, public_spend_key, public_view_key.into());
@ -338,7 +338,7 @@ where
%txid, %txid,
%seen_confirmations, %seen_confirmations,
needed_confirmations = %conf_target, needed_confirmations = %conf_target,
"Received new confirmation for Monero lock tx" "Received new confirmation for Wownero lock tx"
); );
} }
} }
@ -349,7 +349,7 @@ where
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use monero_rpc::wallet::CheckTxKey; use wownero_rpc::wallet::CheckTxKey;
use std::sync::atomic::{AtomicU32, AtomicU64, Ordering}; use std::sync::atomic::{AtomicU32, AtomicU64, Ordering};
use std::sync::Arc; use std::sync::Arc;

@ -1,8 +1,8 @@
use ::monero::Network; use ::wownero::Network;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use big_bytes::BigByte; use big_bytes::BigByte;
use futures::{StreamExt, TryStreamExt}; use futures::{StreamExt, TryStreamExt};
use monero_rpc::wallet::{Client, MoneroWalletRpc as _}; use wownero_rpc::wallet::{Client, WowneroWalletRpc as _};
use reqwest::header::CONTENT_LENGTH; use reqwest::header::CONTENT_LENGTH;
use reqwest::Url; use reqwest::Url;
use std::io::ErrorKind; use std::io::ErrorKind;
@ -18,26 +18,26 @@ use tokio_util::io::StreamReader;
compile_error!("unsupported operating system"); compile_error!("unsupported operating system");
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
const DOWNLOAD_URL: &str = "http://downloads.getmonero.org/cli/monero-mac-x64-v0.17.2.0.tar.bz2"; const DOWNLOAD_URL: &str = "http://downloads.getwownero.org/cli/wownero-mac-x64-v0.17.2.0.tar.bz2";
#[cfg(all(target_os = "linux", target_arch = "x86_64"))] #[cfg(all(target_os = "linux", target_arch = "x86_64"))]
const DOWNLOAD_URL: &str = "https://downloads.getmonero.org/cli/monero-linux-x64-v0.17.2.0.tar.bz2"; const DOWNLOAD_URL: &str = "https://downloads.getwownero.org/cli/wownero-linux-x64-v0.17.2.0.tar.bz2";
#[cfg(all(target_os = "linux", target_arch = "arm"))] #[cfg(all(target_os = "linux", target_arch = "arm"))]
const DOWNLOAD_URL: &str = const DOWNLOAD_URL: &str =
"https://downloads.getmonero.org/cli/monero-linux-armv7-v0.17.2.0.tar.bz2"; "https://downloads.getwownero.org/cli/wownero-linux-armv7-v0.17.2.0.tar.bz2";
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
const DOWNLOAD_URL: &str = "https://downloads.getmonero.org/cli/monero-win-x64-v0.17.2.0.zip"; const DOWNLOAD_URL: &str = "https://downloads.getwownero.org/cli/wownero-win-x64-v0.17.2.0.zip";
#[cfg(any(target_os = "macos", target_os = "linux"))] #[cfg(any(target_os = "macos", target_os = "linux"))]
const PACKED_FILE: &str = "monero-wallet-rpc"; const PACKED_FILE: &str = "wownero-wallet-rpc";
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
const PACKED_FILE: &str = "monero-wallet-rpc.exe"; const PACKED_FILE: &str = "wownero-wallet-rpc.exe";
#[derive(Debug, Clone, Copy, thiserror::Error)] #[derive(Debug, Clone, Copy, thiserror::Error)]
#[error("monero wallet rpc executable not found in downloaded archive")] #[error("wownero wallet rpc executable not found in downloaded archive")]
pub struct ExecutableNotFoundInArchive; pub struct ExecutableNotFoundInArchive;
pub struct WalletRpcProcess { pub struct WalletRpcProcess {
@ -64,21 +64,21 @@ impl WalletRpc {
tokio::fs::create_dir(working_dir).await?; tokio::fs::create_dir(working_dir).await?;
} }
let monero_wallet_rpc = WalletRpc { let wownero_wallet_rpc = WalletRpc {
working_dir: working_dir.to_path_buf(), working_dir: working_dir.to_path_buf(),
}; };
if monero_wallet_rpc.archive_path().exists() { if wownero_wallet_rpc.archive_path().exists() {
remove_file(monero_wallet_rpc.archive_path()).await?; remove_file(wownero_wallet_rpc.archive_path()).await?;
} }
if !monero_wallet_rpc.exec_path().exists() { if !wownero_wallet_rpc.exec_path().exists() {
let mut options = OpenOptions::new(); let mut options = OpenOptions::new();
let mut file = options let mut file = options
.read(true) .read(true)
.write(true) .write(true)
.create_new(true) .create_new(true)
.open(monero_wallet_rpc.archive_path()) .open(wownero_wallet_rpc.archive_path())
.await?; .await?;
let response = reqwest::get(DOWNLOAD_URL).await?; let response = reqwest::get(DOWNLOAD_URL).await?;
@ -89,7 +89,7 @@ impl WalletRpc {
.parse::<u64>()?; .parse::<u64>()?;
tracing::info!( tracing::info!(
"Downloading monero-wallet-rpc ({}) from {}", "Downloading wownero-wallet-rpc ({}) from {}",
content_length.big_byte(2), content_length.big_byte(2),
DOWNLOAD_URL DOWNLOAD_URL
); );
@ -115,9 +115,9 @@ impl WalletRpc {
file.flush().await?; file.flush().await?;
Self::extract_archive(&monero_wallet_rpc).await?; Self::extract_archive(&wownero_wallet_rpc).await?;
} }
Ok(monero_wallet_rpc) Ok(wownero_wallet_rpc)
} }
pub async fn run(&self, network: Network, daemon_address: &str) -> Result<WalletRpcProcess> { pub async fn run(&self, network: Network, daemon_address: &str) -> Result<WalletRpcProcess> {
@ -128,7 +128,7 @@ impl WalletRpc {
tracing::debug!( tracing::debug!(
%port, %port,
"Starting monero-wallet-rpc" "Starting wownero-wallet-rpc"
); );
let network_flag = match network { let network_flag = match network {
@ -154,13 +154,13 @@ impl WalletRpc {
.arg(format!("{}", port)) .arg(format!("{}", port))
.arg("--disable-rpc-login") .arg("--disable-rpc-login")
.arg("--wallet-dir") .arg("--wallet-dir")
.arg(self.working_dir.join("monero-data")) .arg(self.working_dir.join("wownero-data"))
.spawn()?; .spawn()?;
let stdout = child let stdout = child
.stdout .stdout
.take() .take()
.expect("monero wallet rpc stdout was not piped parent process"); .expect("wownero wallet rpc stdout was not piped parent process");
let mut reader = BufReader::new(stdout).lines(); let mut reader = BufReader::new(stdout).lines();
@ -171,7 +171,7 @@ impl WalletRpc {
} }
} }
// If we do not hear from the monero_wallet_rpc process for 3 seconds we assume // If we do not hear from the wownero_wallet_rpc process for 3 seconds we assume
// it is is ready // it is is ready
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
while let Ok(line) = while let Ok(line) =
@ -180,7 +180,7 @@ impl WalletRpc {
line?; line?;
} }
// Send a json rpc request to make sure monero_wallet_rpc is ready // Send a json rpc request to make sure wownero_wallet_rpc is ready
Client::localhost(port)?.get_version().await?; Client::localhost(port)?.get_version().await?;
Ok(WalletRpcProcess { Ok(WalletRpcProcess {
@ -190,7 +190,7 @@ impl WalletRpc {
} }
fn archive_path(&self) -> PathBuf { fn archive_path(&self) -> PathBuf {
self.working_dir.join("monero-cli-wallet.archive") self.working_dir.join("wownero-cli-wallet.archive")
} }
fn exec_path(&self) -> PathBuf { fn exec_path(&self) -> PathBuf {
@ -198,14 +198,14 @@ impl WalletRpc {
} }
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
async fn extract_archive(monero_wallet_rpc: &Self) -> Result<()> { async fn extract_archive(wownero_wallet_rpc: &Self) -> Result<()> {
use anyhow::bail; use anyhow::bail;
use tokio_tar::Archive; use tokio_tar::Archive;
let mut options = OpenOptions::new(); let mut options = OpenOptions::new();
let file = options let file = options
.read(true) .read(true)
.open(monero_wallet_rpc.archive_path()) .open(wownero_wallet_rpc.archive_path())
.await?; .await?;
let mut ar = Archive::new(file); let mut ar = Archive::new(file);
@ -220,7 +220,7 @@ impl WalletRpc {
.context("Could not find convert path to str in tar ball")? .context("Could not find convert path to str in tar ball")?
.contains(PACKED_FILE) .contains(PACKED_FILE)
{ {
f.unpack(monero_wallet_rpc.exec_path()).await?; f.unpack(wownero_wallet_rpc.exec_path()).await?;
break; break;
} }
} }
@ -228,19 +228,19 @@ impl WalletRpc {
} }
} }
remove_file(monero_wallet_rpc.archive_path()).await?; remove_file(wownero_wallet_rpc.archive_path()).await?;
Ok(()) Ok(())
} }
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
async fn extract_archive(monero_wallet_rpc: &Self) -> Result<()> { async fn extract_archive(wownero_wallet_rpc: &Self) -> Result<()> {
use std::fs::File; use std::fs::File;
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
use zip::ZipArchive; use zip::ZipArchive;
let archive_path = monero_wallet_rpc.archive_path(); let archive_path = wownero_wallet_rpc.archive_path();
let exec_path = monero_wallet_rpc.exec_path(); let exec_path = wownero_wallet_rpc.exec_path();
let extract: JoinHandle<Result<()>> = tokio::task::spawn_blocking(|| { let extract: JoinHandle<Result<()>> = tokio::task::spawn_blocking(|| {
let file = File::open(archive_path)?; let file = File::open(archive_path)?;
@ -259,7 +259,7 @@ impl WalletRpc {
}); });
extract.await??; extract.await??;
remove_file(monero_wallet_rpc.archive_path()).await?; remove_file(wownero_wallet_rpc.archive_path()).await?;
Ok(()) Ok(())
} }

@ -5,7 +5,7 @@ pub trait ScalarExt {
fn to_secpfun_scalar(&self) -> ecdsa_fun::fun::Scalar; fn to_secpfun_scalar(&self) -> ecdsa_fun::fun::Scalar;
} }
impl ScalarExt for crate::monero::Scalar { impl ScalarExt for crate::wownero::Scalar {
fn to_secpfun_scalar(&self) -> Scalar<Secret, NonZero> { fn to_secpfun_scalar(&self) -> Scalar<Secret, NonZero> {
let mut little_endian_bytes = self.to_bytes(); let mut little_endian_bytes = self.to_bytes();

@ -1,6 +1,6 @@
pub mod harness; pub mod harness;
use harness::alice_run_until::is_xmr_lock_transaction_sent; use harness::alice_run_until::is_wow_lock_transaction_sent;
use harness::bob_run_until::is_btc_locked; use harness::bob_run_until::is_btc_locked;
use harness::FastCancelConfig; use harness::FastCancelConfig;
use swap::asb::FixedRate; use swap::asb::FixedRate;
@ -19,7 +19,7 @@ async fn given_alice_and_bob_manually_refund_after_funds_locked_both_refund() {
let alice_swap = ctx.alice_next_swap().await; let alice_swap = ctx.alice_next_swap().await;
let alice_swap = tokio::spawn(alice::run_until( let alice_swap = tokio::spawn(alice::run_until(
alice_swap, alice_swap,
is_xmr_lock_transaction_sent, is_wow_lock_transaction_sent,
FixedRate::default(), FixedRate::default(),
)); ));
@ -29,7 +29,7 @@ async fn given_alice_and_bob_manually_refund_after_funds_locked_both_refund() {
let alice_state = alice_swap.await??; let alice_state = alice_swap.await??;
assert!(matches!( assert!(matches!(
alice_state, alice_state,
AliceState::XmrLockTransactionSent { .. } AliceState::WowLockTransactionSent { .. }
)); ));
let (bob_swap, bob_join_handle) = ctx let (bob_swap, bob_join_handle) = ctx
@ -72,7 +72,7 @@ async fn given_alice_and_bob_manually_refund_after_funds_locked_both_refund() {
let alice_swap = ctx.alice_next_swap().await; let alice_swap = ctx.alice_next_swap().await;
assert!(matches!( assert!(matches!(
alice_swap.state, alice_swap.state,
AliceState::XmrLockTransactionSent { .. } AliceState::WowLockTransactionSent { .. }
)); ));
asb::cancel( asb::cancel(
@ -90,7 +90,7 @@ async fn given_alice_and_bob_manually_refund_after_funds_locked_both_refund() {
let alice_state = asb::refund( let alice_state = asb::refund(
alice_swap.swap_id, alice_swap.swap_id,
alice_swap.bitcoin_wallet, alice_swap.bitcoin_wallet,
alice_swap.monero_wallet, alice_swap.wownero_wallet,
alice_swap.db, alice_swap.db,
false, false,
) )

@ -1,6 +1,6 @@
pub mod harness; pub mod harness;
use harness::alice_run_until::is_xmr_lock_transaction_sent; use harness::alice_run_until::is_wow_lock_transaction_sent;
use harness::bob_run_until::is_btc_locked; use harness::bob_run_until::is_btc_locked;
use harness::SlowCancelConfig; use harness::SlowCancelConfig;
use swap::asb::FixedRate; use swap::asb::FixedRate;
@ -19,7 +19,7 @@ async fn given_alice_and_bob_manually_cancel_when_timelock_not_expired_errors()
let alice_swap = ctx.alice_next_swap().await; let alice_swap = ctx.alice_next_swap().await;
let alice_swap = tokio::spawn(alice::run_until( let alice_swap = tokio::spawn(alice::run_until(
alice_swap, alice_swap,
is_xmr_lock_transaction_sent, is_wow_lock_transaction_sent,
FixedRate::default(), FixedRate::default(),
)); ));
@ -34,7 +34,7 @@ async fn given_alice_and_bob_manually_cancel_when_timelock_not_expired_errors()
let alice_state = alice_swap.await??; let alice_state = alice_swap.await??;
assert!(matches!( assert!(matches!(
alice_state, alice_state,
AliceState::XmrLockTransactionSent { .. } AliceState::WowLockTransactionSent { .. }
)); ));
// Bob tries but fails to manually cancel // Bob tries but fails to manually cancel
@ -50,7 +50,7 @@ async fn given_alice_and_bob_manually_cancel_when_timelock_not_expired_errors()
let alice_swap = ctx.alice_next_swap().await; let alice_swap = ctx.alice_next_swap().await;
assert!(matches!( assert!(matches!(
alice_swap.state, alice_swap.state,
AliceState::XmrLockTransactionSent { .. } AliceState::WowLockTransactionSent { .. }
)); ));
// Alice tries but fails manual cancel // Alice tries but fails manual cancel
@ -87,14 +87,14 @@ async fn given_alice_and_bob_manually_cancel_when_timelock_not_expired_errors()
let alice_swap = ctx.alice_next_swap().await; let alice_swap = ctx.alice_next_swap().await;
assert!(matches!( assert!(matches!(
alice_swap.state, alice_swap.state,
AliceState::XmrLockTransactionSent { .. } AliceState::WowLockTransactionSent { .. }
)); ));
// Alice tries but fails manual cancel // Alice tries but fails manual cancel
let result = asb::refund( let result = asb::refund(
alice_swap.swap_id, alice_swap.swap_id,
alice_swap.bitcoin_wallet, alice_swap.bitcoin_wallet,
alice_swap.monero_wallet, alice_swap.wownero_wallet,
alice_swap.db, alice_swap.db,
false, false,
) )
@ -106,7 +106,7 @@ async fn given_alice_and_bob_manually_cancel_when_timelock_not_expired_errors()
let alice_swap = ctx.alice_next_swap().await; let alice_swap = ctx.alice_next_swap().await;
assert!(matches!( assert!(matches!(
alice_swap.state, alice_swap.state,
AliceState::XmrLockTransactionSent { .. } AliceState::WowLockTransactionSent { .. }
)); ));
Ok(()) Ok(())

@ -1,6 +1,6 @@
pub mod harness; pub mod harness;
use harness::alice_run_until::is_xmr_lock_transaction_sent; use harness::alice_run_until::is_wow_lock_transaction_sent;
use harness::bob_run_until::is_btc_locked; use harness::bob_run_until::is_btc_locked;
use harness::SlowCancelConfig; use harness::SlowCancelConfig;
use swap::asb::FixedRate; use swap::asb::FixedRate;
@ -19,7 +19,7 @@ async fn given_alice_and_bob_manually_force_cancel_when_timelock_not_expired_err
let alice_swap = ctx.alice_next_swap().await; let alice_swap = ctx.alice_next_swap().await;
let alice_swap = tokio::spawn(alice::run_until( let alice_swap = tokio::spawn(alice::run_until(
alice_swap, alice_swap,
is_xmr_lock_transaction_sent, is_wow_lock_transaction_sent,
FixedRate::default(), FixedRate::default(),
)); ));
@ -34,7 +34,7 @@ async fn given_alice_and_bob_manually_force_cancel_when_timelock_not_expired_err
let alice_state = alice_swap.await??; let alice_state = alice_swap.await??;
assert!(matches!( assert!(matches!(
alice_state, alice_state,
AliceState::XmrLockTransactionSent { .. } AliceState::WowLockTransactionSent { .. }
)); ));
// Bob tries but fails to manually cancel // Bob tries but fails to manually cancel
@ -45,7 +45,7 @@ async fn given_alice_and_bob_manually_force_cancel_when_timelock_not_expired_err
let alice_swap = ctx.alice_next_swap().await; let alice_swap = ctx.alice_next_swap().await;
assert!(matches!( assert!(matches!(
alice_swap.state, alice_swap.state,
AliceState::XmrLockTransactionSent { .. } AliceState::WowLockTransactionSent { .. }
)); ));
// Alice tries but fails manual cancel // Alice tries but fails manual cancel
@ -79,14 +79,14 @@ async fn given_alice_and_bob_manually_force_cancel_when_timelock_not_expired_err
let alice_swap = ctx.alice_next_swap().await; let alice_swap = ctx.alice_next_swap().await;
assert!(matches!( assert!(matches!(
alice_swap.state, alice_swap.state,
AliceState::XmrLockTransactionSent { .. } AliceState::WowLockTransactionSent { .. }
)); ));
// Alice tries but fails manual cancel // Alice tries but fails manual cancel
let refund_tx_not_published_yet = asb::refund( let refund_tx_not_published_yet = asb::refund(
alice_swap.swap_id, alice_swap.swap_id,
alice_swap.bitcoin_wallet, alice_swap.bitcoin_wallet,
alice_swap.monero_wallet, alice_swap.wownero_wallet,
alice_swap.db, alice_swap.db,
true, true,
) )
@ -101,7 +101,7 @@ async fn given_alice_and_bob_manually_force_cancel_when_timelock_not_expired_err
let alice_swap = ctx.alice_next_swap().await; let alice_swap = ctx.alice_next_swap().await;
assert!(matches!( assert!(matches!(
alice_swap.state, alice_swap.state,
AliceState::XmrLockTransactionSent { .. } AliceState::WowLockTransactionSent { .. }
)); ));
Ok(()) Ok(())

@ -1,6 +1,6 @@
pub mod harness; pub mod harness;
use harness::alice_run_until::is_xmr_lock_transaction_sent; use harness::alice_run_until::is_wow_lock_transaction_sent;
use harness::bob_run_until::is_btc_locked; use harness::bob_run_until::is_btc_locked;
use harness::FastPunishConfig; use harness::FastPunishConfig;
use swap::asb; use swap::asb;
@ -9,7 +9,7 @@ use swap::protocol::alice::AliceState;
use swap::protocol::bob::BobState; use swap::protocol::bob::BobState;
use swap::protocol::{alice, bob}; use swap::protocol::{alice, bob};
/// Bob locks Btc and Alice locks Xmr. Bob does not act; he fails to send Alice /// Bob locks Btc and Alice locks Wow. Bob does not act; he fails to send Alice
/// the encsig and fail to refund or redeem. Alice punishes using the cancel and /// the encsig and fail to refund or redeem. Alice punishes using the cancel and
/// punish command. /// punish command.
#[tokio::test] #[tokio::test]
@ -24,7 +24,7 @@ async fn alice_manually_punishes_after_bob_dead() {
let alice_swap = tokio::spawn(alice::run_until( let alice_swap = tokio::spawn(alice::run_until(
alice_swap, alice_swap,
is_xmr_lock_transaction_sent, is_wow_lock_transaction_sent,
FixedRate::default(), FixedRate::default(),
)); ));
@ -34,7 +34,7 @@ async fn alice_manually_punishes_after_bob_dead() {
let alice_state = alice_swap.await??; let alice_state = alice_swap.await??;
// Ensure cancel timelock is expired // Ensure cancel timelock is expired
if let AliceState::XmrLockTransactionSent { state3, .. } = alice_state { if let AliceState::WowLockTransactionSent { state3, .. } = alice_state {
alice_bitcoin_wallet alice_bitcoin_wallet
.subscribe_to(state3.tx_lock) .subscribe_to(state3.tx_lock)
.await .await

@ -7,7 +7,7 @@ use swap::asb::{Finality, FixedRate};
use swap::protocol::alice::AliceState; use swap::protocol::alice::AliceState;
use swap::protocol::{alice, bob}; use swap::protocol::{alice, bob};
/// Bob locks Btc and Alice locks Xmr. Alice redeems using manual redeem command /// Bob locks Btc and Alice locks Wow. Alice redeems using manual redeem command
/// after learning encsig from Bob /// after learning encsig from Bob
#[tokio::test] #[tokio::test]
async fn alice_manually_redeems_after_enc_sig_learned() { async fn alice_manually_redeems_after_enc_sig_learned() {

@ -1,6 +1,6 @@
pub mod harness; pub mod harness;
use harness::alice_run_until::is_xmr_lock_transaction_sent; use harness::alice_run_until::is_wow_lock_transaction_sent;
use harness::bob_run_until::is_btc_locked; use harness::bob_run_until::is_btc_locked;
use harness::FastPunishConfig; use harness::FastPunishConfig;
use swap::asb::FixedRate; use swap::asb::FixedRate;
@ -8,7 +8,7 @@ use swap::protocol::alice::AliceState;
use swap::protocol::bob::BobState; use swap::protocol::bob::BobState;
use swap::protocol::{alice, bob}; use swap::protocol::{alice, bob};
/// Bob locks Btc and Alice locks Xmr. Bob does not act; he fails to send Alice /// Bob locks Btc and Alice locks Wow. Bob does not act; he fails to send Alice
/// the encsig and fail to refund or redeem. Alice cancels and punishes. /// the encsig and fail to refund or redeem. Alice cancels and punishes.
#[tokio::test] #[tokio::test]
async fn alice_punishes_after_restart_if_bob_dead() { async fn alice_punishes_after_restart_if_bob_dead() {
@ -22,7 +22,7 @@ async fn alice_punishes_after_restart_if_bob_dead() {
let alice_swap = tokio::spawn(alice::run_until( let alice_swap = tokio::spawn(alice::run_until(
alice_swap, alice_swap,
is_xmr_lock_transaction_sent, is_wow_lock_transaction_sent,
FixedRate::default(), FixedRate::default(),
)); ));
@ -33,7 +33,7 @@ async fn alice_punishes_after_restart_if_bob_dead() {
// Ensure cancel timelock is expired (we can only ensure that, because the // Ensure cancel timelock is expired (we can only ensure that, because the
// cancel transaction is not published at this point) // cancel transaction is not published at this point)
if let AliceState::XmrLockTransactionSent { state3, .. } = alice_state { if let AliceState::WowLockTransactionSent { state3, .. } = alice_state {
alice_bitcoin_wallet alice_bitcoin_wallet
.subscribe_to(state3.tx_lock) .subscribe_to(state3.tx_lock)
.await .await

@ -1,12 +1,12 @@
pub mod harness; pub mod harness;
use harness::alice_run_until::is_xmr_lock_transaction_sent; use harness::alice_run_until::is_wow_lock_transaction_sent;
use harness::FastCancelConfig; use harness::FastCancelConfig;
use swap::asb::FixedRate; use swap::asb::FixedRate;
use swap::protocol::alice::AliceState; use swap::protocol::alice::AliceState;
use swap::protocol::{alice, bob}; use swap::protocol::{alice, bob};
/// Bob locks Btc and Alice locks Xmr. Alice does not act so Bob refunds. /// Bob locks Btc and Alice locks Wow. Alice does not act so Bob refunds.
/// Eventually Alice comes back online and refunds as well. /// Eventually Alice comes back online and refunds as well.
#[tokio::test] #[tokio::test]
async fn alice_refunds_after_restart_if_bob_already_refunded() { async fn alice_refunds_after_restart_if_bob_already_refunded() {
@ -17,7 +17,7 @@ async fn alice_refunds_after_restart_if_bob_already_refunded() {
let alice_swap = ctx.alice_next_swap().await; let alice_swap = ctx.alice_next_swap().await;
let alice_swap = tokio::spawn(alice::run_until( let alice_swap = tokio::spawn(alice::run_until(
alice_swap, alice_swap,
is_xmr_lock_transaction_sent, is_wow_lock_transaction_sent,
FixedRate::default(), FixedRate::default(),
)); ));
@ -27,7 +27,7 @@ async fn alice_refunds_after_restart_if_bob_already_refunded() {
let alice_state = alice_swap.await??; let alice_state = alice_swap.await??;
assert!(matches!( assert!(matches!(
alice_state, alice_state,
AliceState::XmrLockTransactionSent { .. } AliceState::WowLockTransactionSent { .. }
)); ));
ctx.restart_alice().await; ctx.restart_alice().await;

@ -1,6 +1,6 @@
pub mod harness; pub mod harness;
use harness::bob_run_until::is_xmr_locked; use harness::bob_run_until::is_wow_locked;
use harness::SlowCancelConfig; use harness::SlowCancelConfig;
use swap::asb::FixedRate; use swap::asb::FixedRate;
use swap::protocol::alice::AliceState; use swap::protocol::alice::AliceState;
@ -8,19 +8,19 @@ use swap::protocol::bob::BobState;
use swap::protocol::{alice, bob}; use swap::protocol::{alice, bob};
#[tokio::test] #[tokio::test]
async fn concurrent_bobs_after_xmr_lock_proof_sent() { async fn concurrent_bobs_after_wow_lock_proof_sent() {
harness::setup_test(SlowCancelConfig, |mut ctx| async move { harness::setup_test(SlowCancelConfig, |mut ctx| async move {
let (bob_swap_1, bob_join_handle_1) = ctx.bob_swap().await; let (bob_swap_1, bob_join_handle_1) = ctx.bob_swap().await;
let swap_id = bob_swap_1.id; let swap_id = bob_swap_1.id;
let bob_swap_1 = tokio::spawn(bob::run_until(bob_swap_1, is_xmr_locked)); let bob_swap_1 = tokio::spawn(bob::run_until(bob_swap_1, is_wow_locked));
let alice_swap_1 = ctx.alice_next_swap().await; let alice_swap_1 = ctx.alice_next_swap().await;
let alice_swap_1 = tokio::spawn(alice::run(alice_swap_1, FixedRate::default())); let alice_swap_1 = tokio::spawn(alice::run(alice_swap_1, FixedRate::default()));
let bob_state_1 = bob_swap_1.await??; let bob_state_1 = bob_swap_1.await??;
assert!(matches!(bob_state_1, BobState::XmrLocked { .. })); assert!(matches!(bob_state_1, BobState::WowLocked { .. }));
// make sure bob_swap_1's event loop is gone // make sure bob_swap_1's event loop is gone
bob_join_handle_1.abort(); bob_join_handle_1.abort();
@ -35,7 +35,7 @@ async fn concurrent_bobs_after_xmr_lock_proof_sent() {
// scenario // scenario
let bob_state_2 = bob_swap_2.await??; let bob_state_2 = bob_swap_2.await??;
assert!(matches!(bob_state_2, BobState::XmrRedeemed { .. })); assert!(matches!(bob_state_2, BobState::WowRedeemed { .. }));
let alice_state_2 = alice_swap_2.await??; let alice_state_2 = alice_swap_2.await??;
assert!(matches!(alice_state_2, AliceState::BtcRedeemed { .. })); assert!(matches!(alice_state_2, AliceState::BtcRedeemed { .. }));
@ -43,14 +43,14 @@ async fn concurrent_bobs_after_xmr_lock_proof_sent() {
let (bob_swap_1, _) = ctx let (bob_swap_1, _) = ctx
.stop_and_resume_bob_from_db(bob_join_handle_2, swap_id) .stop_and_resume_bob_from_db(bob_join_handle_2, swap_id)
.await; .await;
assert!(matches!(bob_swap_1.state, BobState::XmrLocked { .. })); assert!(matches!(bob_swap_1.state, BobState::WowLocked { .. }));
// The 1st (paused) swap ALWAYS finishes successfully in this // The 1st (paused) swap ALWAYS finishes successfully in this
// scenario, because it is ensured that Bob already received the // scenario, because it is ensured that Bob already received the
// transfer proof. // transfer proof.
let bob_state_1 = bob::run(bob_swap_1).await?; let bob_state_1 = bob::run(bob_swap_1).await?;
assert!(matches!(bob_state_1, BobState::XmrRedeemed { .. })); assert!(matches!(bob_state_1, BobState::WowRedeemed { .. }));
let alice_state_1 = alice_swap_1.await??; let alice_state_1 = alice_swap_1.await??;
assert!(matches!(alice_state_1, AliceState::BtcRedeemed { .. })); assert!(matches!(alice_state_1, AliceState::BtcRedeemed { .. }));

@ -8,7 +8,7 @@ use swap::protocol::bob::BobState;
use swap::protocol::{alice, bob}; use swap::protocol::{alice, bob};
#[tokio::test] #[tokio::test]
async fn concurrent_bobs_before_xmr_lock_proof_sent() { async fn concurrent_bobs_before_wow_lock_proof_sent() {
harness::setup_test(SlowCancelConfig, |mut ctx| async move { harness::setup_test(SlowCancelConfig, |mut ctx| async move {
let (bob_swap_1, bob_join_handle_1) = ctx.bob_swap().await; let (bob_swap_1, bob_join_handle_1) = ctx.bob_swap().await;
@ -36,7 +36,7 @@ async fn concurrent_bobs_before_xmr_lock_proof_sent() {
// the event loop. // the event loop.
let bob_state_2 = bob_swap_2.await??; let bob_state_2 = bob_swap_2.await??;
assert!(matches!(bob_state_2, BobState::XmrRedeemed { .. })); assert!(matches!(bob_state_2, BobState::WowRedeemed { .. }));
let alice_state_2 = alice_swap_2.await??; let alice_state_2 = alice_swap_2.await??;
assert!(matches!(alice_state_2, AliceState::BtcRedeemed { .. })); assert!(matches!(alice_state_2, AliceState::BtcRedeemed { .. }));
@ -54,7 +54,7 @@ async fn concurrent_bobs_before_xmr_lock_proof_sent() {
assert!(matches!(bob_state_1, BobState::BtcRefunded { .. })); assert!(matches!(bob_state_1, BobState::BtcRefunded { .. }));
let alice_state_1 = alice_swap_1.await??; let alice_state_1 = alice_swap_1.await??;
assert!(matches!(alice_state_1, AliceState::XmrRefunded { .. })); assert!(matches!(alice_state_1, AliceState::WowRefunded { .. }));
Ok(()) Ok(())
}) })

@ -1,13 +1,13 @@
pub mod harness; pub mod harness;
use harness::alice_run_until::is_xmr_lock_transaction_sent; use harness::alice_run_until::is_wow_lock_transaction_sent;
use harness::SlowCancelConfig; use harness::SlowCancelConfig;
use swap::asb::FixedRate; use swap::asb::FixedRate;
use swap::protocol::alice::AliceState; use swap::protocol::alice::AliceState;
use swap::protocol::{alice, bob}; use swap::protocol::{alice, bob};
#[tokio::test] #[tokio::test]
async fn given_alice_restarts_after_xmr_is_locked_resume_swap() { async fn given_alice_restarts_after_wow_is_locked_resume_swap() {
harness::setup_test(SlowCancelConfig, |mut ctx| async move { harness::setup_test(SlowCancelConfig, |mut ctx| async move {
let (bob_swap, _) = ctx.bob_swap().await; let (bob_swap, _) = ctx.bob_swap().await;
let bob_swap = tokio::spawn(bob::run(bob_swap)); let bob_swap = tokio::spawn(bob::run(bob_swap));
@ -15,7 +15,7 @@ async fn given_alice_restarts_after_xmr_is_locked_resume_swap() {
let alice_swap = ctx.alice_next_swap().await; let alice_swap = ctx.alice_next_swap().await;
let alice_swap = tokio::spawn(alice::run_until( let alice_swap = tokio::spawn(alice::run_until(
alice_swap, alice_swap,
is_xmr_lock_transaction_sent, is_wow_lock_transaction_sent,
FixedRate::default(), FixedRate::default(),
)); ));
@ -23,14 +23,14 @@ async fn given_alice_restarts_after_xmr_is_locked_resume_swap() {
assert!(matches!( assert!(matches!(
alice_state, alice_state,
AliceState::XmrLockTransactionSent { .. } AliceState::WowLockTransactionSent { .. }
)); ));
ctx.restart_alice().await; ctx.restart_alice().await;
let alice_swap = ctx.alice_next_swap().await; let alice_swap = ctx.alice_next_swap().await;
assert!(matches!( assert!(matches!(
alice_swap.state, alice_swap.state,
AliceState::XmrLockTransactionSent { .. } AliceState::WowLockTransactionSent { .. }
)); ));
let alice_state = alice::run(alice_swap, FixedRate::default()).await?; let alice_state = alice::run(alice_swap, FixedRate::default()).await?;

@ -1,29 +1,29 @@
pub mod harness; pub mod harness;
use harness::bob_run_until::is_xmr_locked; use harness::bob_run_until::is_wow_locked;
use harness::SlowCancelConfig; use harness::SlowCancelConfig;
use swap::asb::FixedRate; use swap::asb::FixedRate;
use swap::protocol::bob::BobState; use swap::protocol::bob::BobState;
use swap::protocol::{alice, bob}; use swap::protocol::{alice, bob};
#[tokio::test] #[tokio::test]
async fn given_bob_restarts_after_xmr_is_locked_resume_swap() { async fn given_bob_restarts_after_wow_is_locked_resume_swap() {
harness::setup_test(SlowCancelConfig, |mut ctx| async move { harness::setup_test(SlowCancelConfig, |mut ctx| async move {
let (bob_swap, bob_join_handle) = ctx.bob_swap().await; let (bob_swap, bob_join_handle) = ctx.bob_swap().await;
let bob_swap_id = bob_swap.id; let bob_swap_id = bob_swap.id;
let bob_swap = tokio::spawn(bob::run_until(bob_swap, is_xmr_locked)); let bob_swap = tokio::spawn(bob::run_until(bob_swap, is_wow_locked));
let alice_swap = ctx.alice_next_swap().await; let alice_swap = ctx.alice_next_swap().await;
let alice_swap = tokio::spawn(alice::run(alice_swap, FixedRate::default())); let alice_swap = tokio::spawn(alice::run(alice_swap, FixedRate::default()));
let bob_state = bob_swap.await??; let bob_state = bob_swap.await??;
assert!(matches!(bob_state, BobState::XmrLocked { .. })); assert!(matches!(bob_state, BobState::WowLocked { .. }));
let (bob_swap, _) = ctx let (bob_swap, _) = ctx
.stop_and_resume_bob_from_db(bob_join_handle, bob_swap_id) .stop_and_resume_bob_from_db(bob_join_handle, bob_swap_id)
.await; .await;
assert!(matches!(bob_swap.state, BobState::XmrLocked { .. })); assert!(matches!(bob_swap.state, BobState::WowLocked { .. }));
let bob_state = bob::run(bob_swap).await?; let bob_state = bob::run(bob_swap).await?;

@ -1,29 +1,29 @@
pub mod harness; pub mod harness;
use harness::bob_run_until::is_xmr_locked; use harness::bob_run_until::is_wow_locked;
use harness::SlowCancelConfig; use harness::SlowCancelConfig;
use swap::asb::FixedRate; use swap::asb::FixedRate;
use swap::protocol::bob::BobState; use swap::protocol::bob::BobState;
use swap::protocol::{alice, bob}; use swap::protocol::{alice, bob};
#[tokio::test] #[tokio::test]
async fn given_bob_restarts_after_xmr_is_locked_resume_swap() { async fn given_bob_restarts_after_wow_is_locked_resume_swap() {
harness::setup_test(SlowCancelConfig, |mut ctx| async move { harness::setup_test(SlowCancelConfig, |mut ctx| async move {
let (bob_swap, bob_join_handle) = ctx.bob_swap().await; let (bob_swap, bob_join_handle) = ctx.bob_swap().await;
let bob_swap_id = bob_swap.id; let bob_swap_id = bob_swap.id;
let bob_swap = tokio::spawn(bob::run_until(bob_swap, is_xmr_locked)); let bob_swap = tokio::spawn(bob::run_until(bob_swap, is_wow_locked));
let alice_swap = ctx.alice_next_swap().await; let alice_swap = ctx.alice_next_swap().await;
let alice_swap = tokio::spawn(alice::run(alice_swap, FixedRate::default())); let alice_swap = tokio::spawn(alice::run(alice_swap, FixedRate::default()));
let bob_state = bob_swap.await??; let bob_state = bob_swap.await??;
assert!(matches!(bob_state, BobState::XmrLocked { .. })); assert!(matches!(bob_state, BobState::WowLocked { .. }));
let (bob_swap, _) = ctx let (bob_swap, _) = ctx
.stop_and_resume_bob_from_db(bob_join_handle, bob_swap_id) .stop_and_resume_bob_from_db(bob_join_handle, bob_swap_id)
.await; .await;
assert!(matches!(bob_swap.state, BobState::XmrLocked { .. })); assert!(matches!(bob_swap.state, BobState::WowLocked { .. }));
let bob_state = bob::run(bob_swap).await?; let bob_state = bob::run(bob_swap).await?;

@ -8,7 +8,7 @@ use futures::Future;
use get_port::get_port; use get_port::get_port;
use libp2p::core::Multiaddr; use libp2p::core::Multiaddr;
use libp2p::PeerId; use libp2p::PeerId;
use monero_harness::{image, Monero}; use wownero_harness::{image, Wownero};
use std::cmp::Ordering; use std::cmp::Ordering;
use std::fmt; use std::fmt;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -23,7 +23,7 @@ use swap::protocol::alice::{AliceState, Swap};
use swap::protocol::bob::BobState; use swap::protocol::bob::BobState;
use swap::protocol::{alice, bob}; use swap::protocol::{alice, bob};
use swap::seed::Seed; use swap::seed::Seed;
use swap::{asb, bitcoin, cli, env, monero}; use swap::{asb, bitcoin, cli, env, wownero};
use tempfile::tempdir; use tempfile::tempdir;
use testcontainers::clients::Cli; use testcontainers::clients::Cli;
use testcontainers::{Container, Docker, RunArgs}; use testcontainers::{Container, Docker, RunArgs};
@ -44,20 +44,20 @@ where
let cli = Cli::default(); let cli = Cli::default();
let _guard = tracing_subscriber::fmt() let _guard = tracing_subscriber::fmt()
.with_env_filter("warn,swap=debug,monero_harness=debug,monero_rpc=debug,bitcoin_harness=info,testcontainers=info") // add `reqwest::connect::verbose=trace` if you want to logs of the RPC clients .with_env_filter("warn,swap=debug,wownero_harness=debug,wownero_rpc=debug,bitcoin_harness=info,testcontainers=info") // add `reqwest::connect::verbose=trace` if you want to logs of the RPC clients
.with_test_writer() .with_test_writer()
.set_default(); .set_default();
let env_config = C::get_config(); let env_config = C::get_config();
let (monero, containers) = init_containers(&cli).await; let (wownero, containers) = init_containers(&cli).await;
monero.init_miner().await.unwrap(); wownero.init_miner().await.unwrap();
let btc_amount = bitcoin::Amount::from_sat(1_000_000); let btc_amount = bitcoin::Amount::from_sat(1_000_000);
let xmr_amount = monero::Amount::from_monero(btc_amount.as_btc() / FixedRate::RATE).unwrap(); let wow_amount = wownero::Amount::from_wownero(btc_amount.as_btc() / FixedRate::RATE).unwrap();
let alice_starting_balances = let alice_starting_balances =
StartingBalances::new(bitcoin::Amount::ZERO, xmr_amount, Some(10)); StartingBalances::new(bitcoin::Amount::ZERO, wow_amount, Some(10));
let electrs_rpc_port = containers let electrs_rpc_port = containers
.electrs .electrs
@ -65,10 +65,10 @@ where
.expect("Could not map electrs rpc port"); .expect("Could not map electrs rpc port");
let alice_seed = Seed::random().unwrap(); let alice_seed = Seed::random().unwrap();
let (alice_bitcoin_wallet, alice_monero_wallet) = init_test_wallets( let (alice_bitcoin_wallet, alice_wownero_wallet) = init_test_wallets(
MONERO_WALLET_NAME_ALICE, WOWNERO_WALLET_NAME_ALICE,
containers.bitcoind_url.clone(), containers.bitcoind_url.clone(),
&monero, &wownero,
alice_starting_balances.clone(), alice_starting_balances.clone(),
tempdir().unwrap().path(), tempdir().unwrap().path(),
electrs_rpc_port, electrs_rpc_port,
@ -89,17 +89,17 @@ where
alice_listen_address.clone(), alice_listen_address.clone(),
env_config, env_config,
alice_bitcoin_wallet.clone(), alice_bitcoin_wallet.clone(),
alice_monero_wallet.clone(), alice_wownero_wallet.clone(),
) )
.await; .await;
let bob_seed = Seed::random().unwrap(); let bob_seed = Seed::random().unwrap();
let bob_starting_balances = StartingBalances::new(btc_amount * 10, monero::Amount::ZERO, None); let bob_starting_balances = StartingBalances::new(btc_amount * 10, wownero::Amount::ZERO, None);
let (bob_bitcoin_wallet, bob_monero_wallet) = init_test_wallets( let (bob_bitcoin_wallet, bob_wownero_wallet) = init_test_wallets(
MONERO_WALLET_NAME_BOB, WOWNERO_WALLET_NAME_BOB,
containers.bitcoind_url, containers.bitcoind_url,
&monero, &wownero,
bob_starting_balances.clone(), bob_starting_balances.clone(),
tempdir().unwrap().path(), tempdir().unwrap().path(),
electrs_rpc_port, electrs_rpc_port,
@ -112,36 +112,36 @@ where
seed: Seed::random().unwrap(), seed: Seed::random().unwrap(),
db_path: tempdir().unwrap().path().to_path_buf(), db_path: tempdir().unwrap().path().to_path_buf(),
bitcoin_wallet: bob_bitcoin_wallet.clone(), bitcoin_wallet: bob_bitcoin_wallet.clone(),
monero_wallet: bob_monero_wallet.clone(), wownero_wallet: bob_wownero_wallet.clone(),
alice_address: alice_listen_address.clone(), alice_address: alice_listen_address.clone(),
alice_peer_id: alice_handle.peer_id, alice_peer_id: alice_handle.peer_id,
env_config, env_config,
}; };
monero.start_miner().await.unwrap(); wownero.start_miner().await.unwrap();
let test = TestContext { let test = TestContext {
env_config, env_config,
btc_amount, btc_amount,
xmr_amount, wow_amount,
alice_seed, alice_seed,
alice_db_path, alice_db_path,
alice_listen_address, alice_listen_address,
alice_starting_balances, alice_starting_balances,
alice_bitcoin_wallet, alice_bitcoin_wallet,
alice_monero_wallet, alice_wownero_wallet,
alice_swap_handle, alice_swap_handle,
alice_handle, alice_handle,
bob_params, bob_params,
bob_starting_balances, bob_starting_balances,
bob_bitcoin_wallet, bob_bitcoin_wallet,
bob_monero_wallet, bob_wownero_wallet,
}; };
testfn(test).await.unwrap() testfn(test).await.unwrap()
} }
async fn init_containers(cli: &Cli) -> (Monero, Containers<'_>) { async fn init_containers(cli: &Cli) -> (Wownero, Containers<'_>) {
let prefix = random_prefix(); let prefix = random_prefix();
let bitcoind_name = format!("{}_{}", prefix, "bitcoind"); let bitcoind_name = format!("{}_{}", prefix, "bitcoind");
let (bitcoind, bitcoind_url) = let (bitcoind, bitcoind_url) =
@ -151,16 +151,16 @@ async fn init_containers(cli: &Cli) -> (Monero, Containers<'_>) {
let electrs = init_electrs_container(&cli, prefix.clone(), bitcoind_name, prefix) let electrs = init_electrs_container(&cli, prefix.clone(), bitcoind_name, prefix)
.await .await
.expect("could not init electrs"); .expect("could not init electrs");
let (monero, monerod_container, monero_wallet_rpc_containers) = let (wownero, wownerod_container, wownero_wallet_rpc_containers) =
Monero::new(&cli, vec![MONERO_WALLET_NAME_ALICE, MONERO_WALLET_NAME_BOB]) Wownero::new(&cli, vec![WOWNERO_WALLET_NAME_ALICE, WOWNERO_WALLET_NAME_BOB])
.await .await
.unwrap(); .unwrap();
(monero, Containers { (wownero, Containers {
bitcoind_url, bitcoind_url,
bitcoind, bitcoind,
monerod_container, wownerod_container,
monero_wallet_rpc_containers, wownero_wallet_rpc_containers,
electrs, electrs,
}) })
} }
@ -220,7 +220,7 @@ async fn start_alice(
listen_address: Multiaddr, listen_address: Multiaddr,
env_config: Config, env_config: Config,
bitcoin_wallet: Arc<bitcoin::Wallet>, bitcoin_wallet: Arc<bitcoin::Wallet>,
monero_wallet: Arc<monero::Wallet>, wownero_wallet: Arc<wownero::Wallet>,
) -> (AliceApplicationHandle, Receiver<alice::Swap>) { ) -> (AliceApplicationHandle, Receiver<alice::Swap>) {
let db = Arc::new(Database::open(db_path.as_path()).unwrap()); let db = Arc::new(Database::open(db_path.as_path()).unwrap());
@ -245,7 +245,7 @@ async fn start_alice(
swarm, swarm,
env_config, env_config,
bitcoin_wallet, bitcoin_wallet,
monero_wallet, wownero_wallet,
db, db,
FixedRate::default(), FixedRate::default(),
min_buy, min_buy,
@ -263,18 +263,18 @@ async fn start_alice(
async fn init_test_wallets( async fn init_test_wallets(
name: &str, name: &str,
bitcoind_url: Url, bitcoind_url: Url,
monero: &Monero, wownero: &Wownero,
starting_balances: StartingBalances, starting_balances: StartingBalances,
datadir: &Path, datadir: &Path,
electrum_rpc_port: u16, electrum_rpc_port: u16,
seed: &Seed, seed: &Seed,
env_config: Config, env_config: Config,
) -> (Arc<bitcoin::Wallet>, Arc<monero::Wallet>) { ) -> (Arc<bitcoin::Wallet>, Arc<wownero::Wallet>) {
monero wownero
.init_wallet( .init_wallet(
name, name,
starting_balances starting_balances
.xmr_outputs .wow_outputs
.into_iter() .into_iter()
.map(|amount| amount.as_piconero()) .map(|amount| amount.as_piconero())
.collect(), .collect(),
@ -282,8 +282,8 @@ async fn init_test_wallets(
.await .await
.unwrap(); .unwrap();
let xmr_wallet = swap::monero::Wallet::connect( let wow_wallet = swap::wownero::Wallet::connect(
monero.wallet(name).unwrap().client().clone(), wownero.wallet(name).unwrap().client().clone(),
name.to_string(), name.to_string(),
env_config, env_config,
) )
@ -336,52 +336,52 @@ async fn init_test_wallets(
} }
} }
(Arc::new(btc_wallet), Arc::new(xmr_wallet)) (Arc::new(btc_wallet), Arc::new(wow_wallet))
} }
const MONERO_WALLET_NAME_BOB: &str = "bob"; const WOWNERO_WALLET_NAME_BOB: &str = "bob";
const MONERO_WALLET_NAME_ALICE: &str = "alice"; const WOWNERO_WALLET_NAME_ALICE: &str = "alice";
const BITCOIN_TEST_WALLET_NAME: &str = "testwallet"; const BITCOIN_TEST_WALLET_NAME: &str = "testwallet";
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct StartingBalances { pub struct StartingBalances {
pub xmr: monero::Amount, pub wow: wownero::Amount,
pub xmr_outputs: Vec<monero::Amount>, pub wow_outputs: Vec<wownero::Amount>,
pub btc: bitcoin::Amount, pub btc: bitcoin::Amount,
} }
impl StartingBalances { impl StartingBalances {
/// If monero_outputs is specified the monero balance will be: /// If wownero_outputs is specified the wownero balance will be:
/// monero_outputs * new_xmr = self_xmr /// wownero_outputs * new_wow = self_wow
pub fn new(btc: bitcoin::Amount, xmr: monero::Amount, monero_outputs: Option<u64>) -> Self { pub fn new(btc: bitcoin::Amount, wow: wownero::Amount, wownero_outputs: Option<u64>) -> Self {
match monero_outputs { match wownero_outputs {
None => { None => {
if xmr == monero::Amount::ZERO { if wow == wownero::Amount::ZERO {
return Self { return Self {
xmr, wow,
xmr_outputs: vec![], wow_outputs: vec![],
btc, btc,
}; };
} }
Self { Self {
xmr, wow,
xmr_outputs: vec![xmr], wow_outputs: vec![wow],
btc, btc,
} }
} }
Some(outputs) => { Some(outputs) => {
let mut xmr_outputs = Vec::new(); let mut wow_outputs = Vec::new();
let mut sum_xmr = monero::Amount::ZERO; let mut sum_wow = wownero::Amount::ZERO;
for _ in 0..outputs { for _ in 0..outputs {
xmr_outputs.push(xmr); wow_outputs.push(wow);
sum_xmr = sum_xmr + xmr; sum_wow = sum_wow + wow;
} }
Self { Self {
xmr: sum_xmr, wow: sum_wow,
xmr_outputs, wow_outputs,
btc, btc,
} }
} }
@ -393,7 +393,7 @@ struct BobParams {
seed: Seed, seed: Seed,
db_path: PathBuf, db_path: PathBuf,
bitcoin_wallet: Arc<bitcoin::Wallet>, bitcoin_wallet: Arc<bitcoin::Wallet>,
monero_wallet: Arc<monero::Wallet>, wownero_wallet: Arc<wownero::Wallet>,
alice_address: Multiaddr, alice_address: Multiaddr,
alice_peer_id: PeerId, alice_peer_id: PeerId,
env_config: Config, env_config: Config,
@ -408,10 +408,10 @@ impl BobParams {
db, db,
swap_id, swap_id,
self.bitcoin_wallet.clone(), self.bitcoin_wallet.clone(),
self.monero_wallet.clone(), self.wownero_wallet.clone(),
self.env_config, self.env_config,
handle, handle,
self.monero_wallet.get_main_address(), self.wownero_wallet.get_main_address(),
)?; )?;
Ok((swap, event_loop)) Ok((swap, event_loop))
@ -430,10 +430,10 @@ impl BobParams {
db, db,
swap_id, swap_id,
self.bitcoin_wallet.clone(), self.bitcoin_wallet.clone(),
self.monero_wallet.clone(), self.wownero_wallet.clone(),
self.env_config, self.env_config,
handle, handle,
self.monero_wallet.get_main_address(), self.wownero_wallet.get_main_address(),
self.bitcoin_wallet.new_address().await?, self.bitcoin_wallet.new_address().await?,
btc_amount, btc_amount,
); );
@ -490,7 +490,7 @@ pub struct TestContext {
env_config: Config, env_config: Config,
btc_amount: bitcoin::Amount, btc_amount: bitcoin::Amount,
xmr_amount: monero::Amount, wow_amount: wownero::Amount,
alice_seed: Seed, alice_seed: Seed,
alice_db_path: PathBuf, alice_db_path: PathBuf,
@ -498,14 +498,14 @@ pub struct TestContext {
alice_starting_balances: StartingBalances, alice_starting_balances: StartingBalances,
alice_bitcoin_wallet: Arc<bitcoin::Wallet>, alice_bitcoin_wallet: Arc<bitcoin::Wallet>,
alice_monero_wallet: Arc<monero::Wallet>, alice_wownero_wallet: Arc<wownero::Wallet>,
alice_swap_handle: mpsc::Receiver<Swap>, alice_swap_handle: mpsc::Receiver<Swap>,
alice_handle: AliceApplicationHandle, alice_handle: AliceApplicationHandle,
bob_params: BobParams, bob_params: BobParams,
bob_starting_balances: StartingBalances, bob_starting_balances: StartingBalances,
bob_bitcoin_wallet: Arc<bitcoin::Wallet>, bob_bitcoin_wallet: Arc<bitcoin::Wallet>,
bob_monero_wallet: Arc<monero::Wallet>, bob_wownero_wallet: Arc<wownero::Wallet>,
} }
impl TestContext { impl TestContext {
@ -518,7 +518,7 @@ impl TestContext {
self.alice_listen_address.clone(), self.alice_listen_address.clone(),
self.env_config, self.env_config,
self.alice_bitcoin_wallet.clone(), self.alice_bitcoin_wallet.clone(),
self.alice_monero_wallet.clone(), self.alice_wownero_wallet.clone(),
) )
.await; .await;
@ -570,16 +570,16 @@ impl TestContext {
.unwrap(); .unwrap();
assert_eventual_balance( assert_eventual_balance(
self.alice_monero_wallet.as_ref(), self.alice_wownero_wallet.as_ref(),
Ordering::Less, Ordering::Less,
self.alice_redeemed_xmr_balance(), self.alice_redeemed_wow_balance(),
) )
.await .await
.unwrap(); .unwrap();
} }
pub async fn assert_alice_refunded(&mut self, state: AliceState) { pub async fn assert_alice_refunded(&mut self, state: AliceState) {
assert!(matches!(state, AliceState::XmrRefunded)); assert!(matches!(state, AliceState::WowRefunded));
assert_eventual_balance( assert_eventual_balance(
self.alice_bitcoin_wallet.as_ref(), self.alice_bitcoin_wallet.as_ref(),
@ -591,9 +591,9 @@ impl TestContext {
// Alice pays fees - comparison does not take exact lock fee into account // Alice pays fees - comparison does not take exact lock fee into account
assert_eventual_balance( assert_eventual_balance(
self.alice_monero_wallet.as_ref(), self.alice_wownero_wallet.as_ref(),
Ordering::Greater, Ordering::Greater,
self.alice_refunded_xmr_balance(), self.alice_refunded_wow_balance(),
) )
.await .await
.unwrap(); .unwrap();
@ -611,9 +611,9 @@ impl TestContext {
.unwrap(); .unwrap();
assert_eventual_balance( assert_eventual_balance(
self.alice_monero_wallet.as_ref(), self.alice_wownero_wallet.as_ref(),
Ordering::Less, Ordering::Less,
self.alice_punished_xmr_balance(), self.alice_punished_wow_balance(),
) )
.await .await
.unwrap(); .unwrap();
@ -629,12 +629,12 @@ impl TestContext {
.unwrap(); .unwrap();
// unload the generated wallet by opening the original wallet // unload the generated wallet by opening the original wallet
self.bob_monero_wallet.re_open().await.unwrap(); self.bob_wownero_wallet.re_open().await.unwrap();
assert_eventual_balance( assert_eventual_balance(
self.bob_monero_wallet.as_ref(), self.bob_wownero_wallet.as_ref(),
Ordering::Greater, Ordering::Greater,
self.bob_redeemed_xmr_balance(), self.bob_redeemed_wow_balance(),
) )
.await .await
.unwrap(); .unwrap();
@ -673,9 +673,9 @@ impl TestContext {
assert!(bob_cancelled_and_refunded); assert!(bob_cancelled_and_refunded);
assert_eventual_balance( assert_eventual_balance(
self.bob_monero_wallet.as_ref(), self.bob_wownero_wallet.as_ref(),
Ordering::Equal, Ordering::Equal,
self.bob_refunded_xmr_balance(), self.bob_refunded_wow_balance(),
) )
.await .await
.unwrap(); .unwrap();
@ -691,16 +691,16 @@ impl TestContext {
.unwrap(); .unwrap();
assert_eventual_balance( assert_eventual_balance(
self.bob_monero_wallet.as_ref(), self.bob_wownero_wallet.as_ref(),
Ordering::Equal, Ordering::Equal,
self.bob_punished_xmr_balance(), self.bob_punished_wow_balance(),
) )
.await .await
.unwrap(); .unwrap();
} }
fn alice_redeemed_xmr_balance(&self) -> monero::Amount { fn alice_redeemed_wow_balance(&self) -> wownero::Amount {
self.alice_starting_balances.xmr - self.xmr_amount self.alice_starting_balances.wow - self.wow_amount
} }
async fn alice_redeemed_btc_balance(&self) -> bitcoin::Amount { async fn alice_redeemed_btc_balance(&self) -> bitcoin::Amount {
@ -712,17 +712,17 @@ impl TestContext {
self.alice_starting_balances.btc + self.btc_amount - fee self.alice_starting_balances.btc + self.btc_amount - fee
} }
fn bob_redeemed_xmr_balance(&self) -> monero::Amount { fn bob_redeemed_wow_balance(&self) -> wownero::Amount {
self.bob_starting_balances.xmr self.bob_starting_balances.wow
} }
async fn bob_redeemed_btc_balance(&self, state: BobState) -> Result<bitcoin::Amount> { async fn bob_redeemed_btc_balance(&self, state: BobState) -> Result<bitcoin::Amount> {
self.bob_bitcoin_wallet.sync().await?; self.bob_bitcoin_wallet.sync().await?;
let lock_tx_id = if let BobState::XmrRedeemed { tx_lock_id } = state { let lock_tx_id = if let BobState::WowRedeemed { tx_lock_id } = state {
tx_lock_id tx_lock_id
} else { } else {
bail!("Bob in not in xmr redeemed state: {:?}", state); bail!("Bob in not in wow redeemed state: {:?}", state);
}; };
let lock_tx_bitcoin_fee = self.bob_bitcoin_wallet.transaction_fee(lock_tx_id).await?; let lock_tx_bitcoin_fee = self.bob_bitcoin_wallet.transaction_fee(lock_tx_id).await?;
@ -730,20 +730,20 @@ impl TestContext {
Ok(self.bob_starting_balances.btc - self.btc_amount - lock_tx_bitcoin_fee) Ok(self.bob_starting_balances.btc - self.btc_amount - lock_tx_bitcoin_fee)
} }
fn alice_refunded_xmr_balance(&self) -> monero::Amount { fn alice_refunded_wow_balance(&self) -> wownero::Amount {
self.alice_starting_balances.xmr - self.xmr_amount self.alice_starting_balances.wow - self.wow_amount
} }
fn alice_refunded_btc_balance(&self) -> bitcoin::Amount { fn alice_refunded_btc_balance(&self) -> bitcoin::Amount {
self.alice_starting_balances.btc self.alice_starting_balances.btc
} }
fn bob_refunded_xmr_balance(&self) -> monero::Amount { fn bob_refunded_wow_balance(&self) -> wownero::Amount {
self.bob_starting_balances.xmr self.bob_starting_balances.wow
} }
fn alice_punished_xmr_balance(&self) -> monero::Amount { fn alice_punished_wow_balance(&self) -> wownero::Amount {
self.alice_starting_balances.xmr - self.xmr_amount self.alice_starting_balances.wow - self.wow_amount
} }
async fn alice_punished_btc_balance(&self) -> bitcoin::Amount { async fn alice_punished_btc_balance(&self) -> bitcoin::Amount {
@ -760,8 +760,8 @@ impl TestContext {
self.alice_starting_balances.btc + self.btc_amount - cancel_fee - punish_fee self.alice_starting_balances.btc + self.btc_amount - cancel_fee - punish_fee
} }
fn bob_punished_xmr_balance(&self) -> monero::Amount { fn bob_punished_wow_balance(&self) -> wownero::Amount {
self.bob_starting_balances.xmr self.bob_starting_balances.wow
} }
async fn bob_punished_btc_balance(&self, state: BobState) -> Result<bitcoin::Amount> { async fn bob_punished_btc_balance(&self, state: BobState) -> Result<bitcoin::Amount> {
@ -836,8 +836,8 @@ trait Wallet {
} }
#[async_trait] #[async_trait]
impl Wallet for monero::Wallet { impl Wallet for wownero::Wallet {
type Amount = monero::Amount; type Amount = wownero::Amount;
async fn refresh(&self) -> Result<()> { async fn refresh(&self) -> Result<()> {
self.refresh().await?; self.refresh().await?;
@ -931,16 +931,16 @@ pub async fn mint(node_url: Url, address: bitcoin::Address, amount: bitcoin::Amo
struct Containers<'a> { struct Containers<'a> {
bitcoind_url: Url, bitcoind_url: Url,
bitcoind: Container<'a, Cli, bitcoind::Bitcoind>, bitcoind: Container<'a, Cli, bitcoind::Bitcoind>,
monerod_container: Container<'a, Cli, image::Monerod>, wownerod_container: Container<'a, Cli, image::Wownerod>,
monero_wallet_rpc_containers: Vec<Container<'a, Cli, image::MoneroWalletRpc>>, wownero_wallet_rpc_containers: Vec<Container<'a, Cli, image::WowneroWalletRpc>>,
electrs: Container<'a, Cli, electrs::Electrs>, electrs: Container<'a, Cli, electrs::Electrs>,
} }
pub mod alice_run_until { pub mod alice_run_until {
use swap::protocol::alice::AliceState; use swap::protocol::alice::AliceState;
pub fn is_xmr_lock_transaction_sent(state: &AliceState) -> bool { pub fn is_wow_lock_transaction_sent(state: &AliceState) -> bool {
matches!(state, AliceState::XmrLockTransactionSent { .. }) matches!(state, AliceState::WowLockTransactionSent { .. })
} }
pub fn is_encsig_learned(state: &AliceState) -> bool { pub fn is_encsig_learned(state: &AliceState) -> bool {
@ -956,11 +956,11 @@ pub mod bob_run_until {
} }
pub fn is_lock_proof_received(state: &BobState) -> bool { pub fn is_lock_proof_received(state: &BobState) -> bool {
matches!(state, BobState::XmrLockProofReceived { .. }) matches!(state, BobState::WowLockProofReceived { .. })
} }
pub fn is_xmr_locked(state: &BobState) -> bool { pub fn is_wow_locked(state: &BobState) -> bool {
matches!(state, BobState::XmrLocked(..)) matches!(state, BobState::WowLocked(..))
} }
pub fn is_encsig_sent(state: &BobState) -> bool { pub fn is_encsig_sent(state: &BobState) -> bool {

@ -6,7 +6,7 @@ use swap::asb::FixedRate;
use swap::protocol::bob::BobState; use swap::protocol::bob::BobState;
use swap::protocol::{alice, bob}; use swap::protocol::{alice, bob};
/// Bob locks Btc and Alice locks Xmr. Bob does not act; he fails to send Alice /// Bob locks Btc and Alice locks Wow. Bob does not act; he fails to send Alice
/// the encsig and fail to refund or redeem. Alice punishes. /// the encsig and fail to refund or redeem. Alice punishes.
#[tokio::test] #[tokio::test]
async fn alice_punishes_if_bob_never_acts_after_fund() { async fn alice_punishes_if_bob_never_acts_after_fund() {

@ -1,5 +1,5 @@
[package] [package]
name = "monero-harness" name = "wownero-harness"
version = "0.1.0" version = "0.1.0"
authors = [ "CoBloX Team <team@coblox.tech>" ] authors = [ "CoBloX Team <team@coblox.tech>" ]
edition = "2018" edition = "2018"
@ -8,7 +8,7 @@ publish = false
[dependencies] [dependencies]
anyhow = "1" anyhow = "1"
futures = "0.3" futures = "0.3"
monero-rpc = { path = "../monero-rpc" } wownero-rpc = { path = "../wownero-rpc" }
rand = "0.7" rand = "0.7"
spectral = "0.6" spectral = "0.6"
testcontainers = "0.12" testcontainers = "0.12"

@ -2,30 +2,30 @@ use std::collections::HashMap;
use testcontainers::core::{Container, Docker, WaitForMessage}; use testcontainers::core::{Container, Docker, WaitForMessage};
use testcontainers::Image; use testcontainers::Image;
pub const MONEROD_DAEMON_CONTAINER_NAME: &str = "monerod"; pub const WOWNEROD_DAEMON_CONTAINER_NAME: &str = "wownerod";
pub const MONEROD_DEFAULT_NETWORK: &str = "monero_network"; pub const WOWNEROD_DEFAULT_NETWORK: &str = "wownero_network";
/// The port we use for all RPC communication. /// The port we use for all RPC communication.
/// ///
/// This is the default when running monerod. /// This is the default when running wownerod.
/// For `monero-wallet-rpc` we always need to specify a port. To make things /// For `wownero-wallet-rpc` we always need to specify a port. To make things
/// simpler, we just specify the same one. They are in different containers so /// simpler, we just specify the same one. They are in different containers so
/// this doesn't matter. /// this doesn't matter.
pub const RPC_PORT: u16 = 18081; pub const RPC_PORT: u16 = 34568;
#[derive(Debug)] #[derive(Debug)]
pub struct Monerod { pub struct Wownerod {
args: MonerodArgs, args: WownerodArgs,
} }
impl Image for Monerod { impl Image for Wownerod {
type Args = MonerodArgs; type Args = WownerodArgs;
type EnvVars = HashMap<String, String>; type EnvVars = HashMap<String, String>;
type Volumes = HashMap<String, String>; type Volumes = HashMap<String, String>;
type EntryPoint = str; type EntryPoint = str;
fn descriptor(&self) -> String { fn descriptor(&self) -> String {
"xmrto/monero:v0.17.2.0".to_owned() "wownero:v0.10.1.0".to_owned()
} }
fn wait_until_ready<D: Docker>(&self, container: &Container<'_, D, Self>) { fn wait_until_ready<D: Docker>(&self, container: &Container<'_, D, Self>) {
@ -58,27 +58,27 @@ impl Image for Monerod {
} }
} }
impl Default for Monerod { impl Default for Wownerod {
fn default() -> Self { fn default() -> Self {
Self { Self {
args: MonerodArgs::default(), args: WownerodArgs::default(),
} }
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub struct MoneroWalletRpc { pub struct WowneroWalletRpc {
args: MoneroWalletRpcArgs, args: WowneroWalletRpcArgs,
} }
impl Image for MoneroWalletRpc { impl Image for WowneroWalletRpc {
type Args = MoneroWalletRpcArgs; type Args = WowneroWalletRpcArgs;
type EnvVars = HashMap<String, String>; type EnvVars = HashMap<String, String>;
type Volumes = HashMap<String, String>; type Volumes = HashMap<String, String>;
type EntryPoint = str; type EntryPoint = str;
fn descriptor(&self) -> String { fn descriptor(&self) -> String {
"xmrto/monero:v0.17.2.0".to_owned() "wownero:v0.10.1.0".to_owned()
} }
fn wait_until_ready<D: Docker>(&self, container: &Container<'_, D, Self>) { fn wait_until_ready<D: Docker>(&self, container: &Container<'_, D, Self>) {
@ -111,24 +111,24 @@ impl Image for MoneroWalletRpc {
} }
} }
impl Default for MoneroWalletRpc { impl Default for WowneroWalletRpc {
fn default() -> Self { fn default() -> Self {
Self { Self {
args: MoneroWalletRpcArgs::default(), args: WowneroWalletRpcArgs::default(),
} }
} }
} }
impl MoneroWalletRpc { impl WowneroWalletRpc {
pub fn new(name: &str, daemon_address: String) -> Self { pub fn new(name: &str, daemon_address: String) -> Self {
Self { Self {
args: MoneroWalletRpcArgs::new(name, daemon_address), args: WowneroWalletRpcArgs::new(name, daemon_address),
} }
} }
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct MonerodArgs { pub struct WownerodArgs {
pub regtest: bool, pub regtest: bool,
pub offline: bool, pub offline: bool,
pub rpc_payment_allow_free_loopback: bool, pub rpc_payment_allow_free_loopback: bool,
@ -140,7 +140,7 @@ pub struct MonerodArgs {
pub data_dir: String, pub data_dir: String,
} }
impl Default for MonerodArgs { impl Default for WownerodArgs {
fn default() -> Self { fn default() -> Self {
Self { Self {
regtest: true, regtest: true,
@ -151,18 +151,18 @@ impl Default for MonerodArgs {
hide_my_port: true, hide_my_port: true,
rpc_bind_ip: "0.0.0.0".to_string(), rpc_bind_ip: "0.0.0.0".to_string(),
fixed_difficulty: 1, fixed_difficulty: 1,
data_dir: "/monero".to_string(), data_dir: "/wownero".to_string(),
} }
} }
} }
impl IntoIterator for MonerodArgs { impl IntoIterator for WownerodArgs {
type Item = String; type Item = String;
type IntoIter = ::std::vec::IntoIter<String>; type IntoIter = ::std::vec::IntoIter<String>;
fn into_iter(self) -> <Self as IntoIterator>::IntoIter { fn into_iter(self) -> <Self as IntoIterator>::IntoIter {
let mut args = vec![ let mut args = vec![
"monerod".to_string(), "wownerod".to_string(),
"--log-level=4".to_string(), "--log-level=4".to_string(),
"--non-interactive".to_string(), "--non-interactive".to_string(),
]; ];
@ -208,7 +208,7 @@ impl IntoIterator for MonerodArgs {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct MoneroWalletRpcArgs { pub struct WowneroWalletRpcArgs {
pub disable_rpc_login: bool, pub disable_rpc_login: bool,
pub confirm_external_bind: bool, pub confirm_external_bind: bool,
pub wallet_dir: String, pub wallet_dir: String,
@ -216,13 +216,13 @@ pub struct MoneroWalletRpcArgs {
pub daemon_address: String, pub daemon_address: String,
} }
impl Default for MoneroWalletRpcArgs { impl Default for WowneroWalletRpcArgs {
fn default() -> Self { fn default() -> Self {
unimplemented!("A default instance for `MoneroWalletRpc` doesn't make sense because we always need to connect to a node.") unimplemented!("A default instance for `WowneroWalletRpc` doesn't make sense because we always need to connect to a node.")
} }
} }
impl MoneroWalletRpcArgs { impl WowneroWalletRpcArgs {
pub fn new(wallet_name: &str, daemon_address: String) -> Self { pub fn new(wallet_name: &str, daemon_address: String) -> Self {
Self { Self {
disable_rpc_login: true, disable_rpc_login: true,
@ -234,13 +234,13 @@ impl MoneroWalletRpcArgs {
} }
} }
impl IntoIterator for MoneroWalletRpcArgs { impl IntoIterator for WowneroWalletRpcArgs {
type Item = String; type Item = String;
type IntoIter = ::std::vec::IntoIter<String>; type IntoIter = ::std::vec::IntoIter<String>;
fn into_iter(self) -> <Self as IntoIterator>::IntoIter { fn into_iter(self) -> <Self as IntoIterator>::IntoIter {
let mut args = vec![ let mut args = vec![
"monero-wallet-rpc".to_string(), "wownero-wallet-rpc".to_string(),
format!("--wallet-dir={}", self.wallet_dir), format!("--wallet-dir={}", self.wallet_dir),
format!("--daemon-address={}", self.daemon_address), format!("--daemon-address={}", self.daemon_address),
format!("--rpc-bind-port={}", RPC_PORT), format!("--rpc-bind-port={}", RPC_PORT),

@ -12,21 +12,21 @@
)] )]
#![forbid(unsafe_code)] #![forbid(unsafe_code)]
//! # monero-harness //! # wownero-harness
//! //!
//! A simple lib to start a monero container (incl. monerod and //! A simple lib to start a wownero container (incl. wownerod and
//! monero-wallet-rpc). Provides initialisation methods to generate blocks, //! wownero-wallet-rpc). Provides initialisation methods to generate blocks,
//! create and fund accounts, and start a continuous mining task mining blocks //! create and fund accounts, and start a continuous mining task mining blocks
//! every BLOCK_TIME_SECS seconds. //! every BLOCK_TIME_SECS seconds.
//! //!
//! Also provides standalone JSON RPC clients for monerod and monero-wallet-rpc. //! Also provides standalone JSON RPC clients for wownerod and wownero-wallet-rpc.
pub mod image; pub mod image;
use crate::image::{MONEROD_DAEMON_CONTAINER_NAME, MONEROD_DEFAULT_NETWORK, RPC_PORT}; use crate::image::{WOWNEROD_DAEMON_CONTAINER_NAME, WOWNEROD_DEFAULT_NETWORK, RPC_PORT};
use anyhow::{anyhow, bail, Context, Result}; use anyhow::{anyhow, bail, Context, Result};
use monero_rpc::monerod; use wownero_rpc::wownerod;
use monero_rpc::monerod::MonerodRpc as _; use wownero_rpc::wownerod::WownerodRpc as _;
use monero_rpc::wallet::{self, GetAddress, MoneroWalletRpc as _, Refreshed, Transfer}; use wownero_rpc::wallet::{self, GetAddress, WowneroWalletRpc as _, Refreshed, Transfer};
use std::time::Duration; use std::time::Duration;
use testcontainers::clients::Cli; use testcontainers::clients::Cli;
use testcontainers::{Container, Docker, RunArgs}; use testcontainers::{Container, Docker, RunArgs};
@ -35,43 +35,43 @@ use tokio::time;
/// How often we mine a block. /// How often we mine a block.
const BLOCK_TIME_SECS: u64 = 1; const BLOCK_TIME_SECS: u64 = 1;
/// Poll interval when checking if the wallet has synced with monerod. /// Poll interval when checking if the wallet has synced with wownerod.
const WAIT_WALLET_SYNC_MILLIS: u64 = 1000; const WAIT_WALLET_SYNC_MILLIS: u64 = 1000;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Monero { pub struct Wownero {
monerod: Monerod, wownerod: Wownerod,
wallets: Vec<MoneroWalletRpc>, wallets: Vec<WowneroWalletRpc>,
} }
impl<'c> Monero { impl<'c> Wownero {
/// Starts a new regtest monero container setup consisting out of 1 monerod /// Starts a new regtest wownero container setup consisting out of 1 wownerod
/// node and n wallets. The docker container and network will be prefixed /// node and n wallets. The docker container and network will be prefixed
/// with a randomly generated `prefix`. One miner wallet is started /// with a randomly generated `prefix`. One miner wallet is started
/// automatically. /// automatically.
/// monerod container name is: `prefix`_`monerod` /// wownerod container name is: `prefix`_`wownerod`
/// network is: `prefix`_`monero` /// network is: `prefix`_`wownero`
/// miner wallet container name is: `miner` /// miner wallet container name is: `miner`
pub async fn new( pub async fn new(
cli: &'c Cli, cli: &'c Cli,
additional_wallets: Vec<&'static str>, additional_wallets: Vec<&'static str>,
) -> Result<( ) -> Result<(
Self, Self,
Container<'c, Cli, image::Monerod>, Container<'c, Cli, image::Wownerod>,
Vec<Container<'c, Cli, image::MoneroWalletRpc>>, Vec<Container<'c, Cli, image::WowneroWalletRpc>>,
)> { )> {
let prefix = format!("{}_", random_prefix()); let prefix = format!("{}_", random_prefix());
let monerod_name = format!("{}{}", prefix, MONEROD_DAEMON_CONTAINER_NAME); let wownerod_name = format!("{}{}", prefix, WOWNEROD_DAEMON_CONTAINER_NAME);
let network = format!("{}{}", prefix, MONEROD_DEFAULT_NETWORK); let network = format!("{}{}", prefix, WOWNEROD_DEFAULT_NETWORK);
tracing::info!("Starting monerod: {}", monerod_name); tracing::info!("Starting wownerod: {}", wownerod_name);
let (monerod, monerod_container) = Monerod::new(cli, monerod_name, network)?; let (wownerod, wownerod_container) = Wownerod::new(cli, wownerod_name, network)?;
let mut containers = vec![]; let mut containers = vec![];
let mut wallets = vec![]; let mut wallets = vec![];
let miner = "miner"; let miner = "miner";
tracing::info!("Starting miner wallet: {}", miner); tracing::info!("Starting miner wallet: {}", miner);
let (miner_wallet, miner_container) = let (miner_wallet, miner_container) =
MoneroWalletRpc::new(cli, &miner, &monerod, prefix.clone()).await?; WowneroWalletRpc::new(cli, &miner, &wownerod, prefix.clone()).await?;
wallets.push(miner_wallet); wallets.push(miner_wallet);
containers.push(miner_container); containers.push(miner_container);
@ -83,11 +83,11 @@ impl<'c> Monero {
// trying for 5 minutes // trying for 5 minutes
let (wallet, container) = tokio::time::timeout(Duration::from_secs(300), async { let (wallet, container) = tokio::time::timeout(Duration::from_secs(300), async {
loop { loop {
let result = MoneroWalletRpc::new(cli, &wallet, &monerod, prefix.clone()).await; let result = WowneroWalletRpc::new(cli, &wallet, &wownerod, prefix.clone()).await;
match result { match result {
Ok(tuple) => { return tuple; } Ok(tuple) => { return tuple; }
Err(e) => { tracing::warn!("Monero wallet RPC emitted error {} - retrying to create wallet in 2 seconds...", e); } Err(e) => { tracing::warn!("Wownero wallet RPC emitted error {} - retrying to create wallet in 2 seconds...", e); }
} }
} }
}).await.context("All retry attempts for creating a wallet exhausted")?; }).await.context("All retry attempts for creating a wallet exhausted")?;
@ -96,14 +96,14 @@ impl<'c> Monero {
containers.push(container); containers.push(container);
} }
Ok((Self { monerod, wallets }, monerod_container, containers)) Ok((Self { wownerod, wallets }, wownerod_container, containers))
} }
pub fn monerod(&self) -> &Monerod { pub fn wownerod(&self) -> &Wownerod {
&self.monerod &self.wownerod
} }
pub fn wallet(&self, name: &str) -> Result<&MoneroWalletRpc> { pub fn wallet(&self, name: &str) -> Result<&WowneroWalletRpc> {
let wallet = self let wallet = self
.wallets .wallets
.iter() .iter()
@ -118,8 +118,8 @@ impl<'c> Monero {
let miner_address = miner_wallet.address().await?.address; let miner_address = miner_wallet.address().await?.address;
// generate the first 70 as bulk // generate the first 70 as bulk
let monerod = &self.monerod; let wownerod = &self.wownerod;
let res = monerod let res = wownerod
.client() .client()
.generateblocks(70, miner_address.clone()) .generateblocks(70, miner_address.clone())
.await?; .await?;
@ -132,7 +132,7 @@ impl<'c> Monero {
pub async fn init_wallet(&self, name: &str, amount_in_outputs: Vec<u64>) -> Result<()> { pub async fn init_wallet(&self, name: &str, amount_in_outputs: Vec<u64>) -> Result<()> {
let miner_wallet = self.wallet("miner")?; let miner_wallet = self.wallet("miner")?;
let miner_address = miner_wallet.address().await?.address; let miner_address = miner_wallet.address().await?.address;
let monerod = &self.monerod; let wownerod = &self.wownerod;
let wallet = self.wallet(name)?; let wallet = self.wallet(name)?;
let address = wallet.address().await?.address; let address = wallet.address().await?.address;
@ -141,7 +141,7 @@ impl<'c> Monero {
if amount > 0 { if amount > 0 {
miner_wallet.transfer(&address, amount).await?; miner_wallet.transfer(&address, amount).await?;
tracing::info!("Funded {} wallet with {}", wallet.name, amount); tracing::info!("Funded {} wallet with {}", wallet.name, amount);
monerod wownerod
.client() .client()
.generateblocks(10, miner_address.clone()) .generateblocks(10, miner_address.clone())
.await?; .await?;
@ -155,12 +155,12 @@ impl<'c> Monero {
pub async fn start_miner(&self) -> Result<()> { pub async fn start_miner(&self) -> Result<()> {
let miner_wallet = self.wallet("miner")?; let miner_wallet = self.wallet("miner")?;
let miner_address = miner_wallet.address().await?.address; let miner_address = miner_wallet.address().await?.address;
let monerod = &self.monerod; let wownerod = &self.wownerod;
monerod.start_miner(&miner_address).await?; wownerod.start_miner(&miner_address).await?;
tracing::info!("Waiting for miner wallet to catch up..."); tracing::info!("Waiting for miner wallet to catch up...");
let block_height = monerod.client().get_block_count().await?.count; let block_height = wownerod.client().get_block_count().await?.count;
miner_wallet miner_wallet
.wait_for_wallet_height(block_height) .wait_for_wallet_height(block_height)
.await .await
@ -187,74 +187,74 @@ fn random_prefix() -> String {
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Monerod { pub struct Wownerod {
rpc_port: u16, rpc_port: u16,
name: String, name: String,
network: String, network: String,
client: monerod::Client, client: wownerod::Client,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct MoneroWalletRpc { pub struct WowneroWalletRpc {
rpc_port: u16, rpc_port: u16,
name: String, name: String,
network: String, network: String,
client: wallet::Client, client: wallet::Client,
} }
impl<'c> Monerod { impl<'c> Wownerod {
/// Starts a new regtest monero container. /// Starts a new regtest wownero container.
fn new( fn new(
cli: &'c Cli, cli: &'c Cli,
name: String, name: String,
network: String, network: String,
) -> Result<(Self, Container<'c, Cli, image::Monerod>)> { ) -> Result<(Self, Container<'c, Cli, image::Wownerod>)> {
let image = image::Monerod::default(); let image = image::Wownerod::default();
let run_args = RunArgs::default() let run_args = RunArgs::default()
.with_name(name.clone()) .with_name(name.clone())
.with_network(network.clone()); .with_network(network.clone());
let container = cli.run_with_args(image, run_args); let container = cli.run_with_args(image, run_args);
let monerod_rpc_port = container let wownerod_rpc_port = container
.get_host_port(RPC_PORT) .get_host_port(RPC_PORT)
.context("port not exposed")?; .context("port not exposed")?;
Ok(( Ok((
Self { Self {
rpc_port: monerod_rpc_port, rpc_port: wownerod_rpc_port,
name, name,
network, network,
client: monerod::Client::localhost(monerod_rpc_port)?, client: wownerod::Client::localhost(wownerod_rpc_port)?,
}, },
container, container,
)) ))
} }
pub fn client(&self) -> &monerod::Client { pub fn client(&self) -> &wownerod::Client {
&self.client &self.client
} }
/// Spawns a task to mine blocks in a regular interval to the provided /// Spawns a task to mine blocks in a regular interval to the provided
/// address /// address
pub async fn start_miner(&self, miner_wallet_address: &str) -> Result<()> { pub async fn start_miner(&self, miner_wallet_address: &str) -> Result<()> {
let monerod = self.client().clone(); let wownerod = self.client().clone();
let _ = tokio::spawn(mine(monerod, miner_wallet_address.to_string())); let _ = tokio::spawn(mine(wownerod, miner_wallet_address.to_string()));
Ok(()) Ok(())
} }
} }
impl<'c> MoneroWalletRpc { impl<'c> WowneroWalletRpc {
/// Starts a new wallet container which is attached to /// Starts a new wallet container which is attached to
/// MONEROD_DEFAULT_NETWORK and MONEROD_DAEMON_CONTAINER_NAME /// WOWNEROD_DEFAULT_NETWORK and WOWNEROD_DAEMON_CONTAINER_NAME
async fn new( async fn new(
cli: &'c Cli, cli: &'c Cli,
name: &str, name: &str,
monerod: &Monerod, wownerod: &Wownerod,
prefix: String, prefix: String,
) -> Result<(Self, Container<'c, Cli, image::MoneroWalletRpc>)> { ) -> Result<(Self, Container<'c, Cli, image::WowneroWalletRpc>)> {
let daemon_address = format!("{}:{}", monerod.name, RPC_PORT); let daemon_address = format!("{}:{}", wownerod.name, RPC_PORT);
let image = image::MoneroWalletRpc::new(&name, daemon_address); let image = image::WowneroWalletRpc::new(&name, daemon_address);
let network = monerod.network.clone(); let network = wownerod.network.clone();
let run_args = RunArgs::default() let run_args = RunArgs::default()
// prefix the container name so we can run multiple tests // prefix the container name so we can run multiple tests
.with_name(format!("{}{}", prefix, name)) .with_name(format!("{}{}", prefix, name))
@ -285,13 +285,13 @@ impl<'c> MoneroWalletRpc {
&self.client &self.client
} }
// It takes a little while for the wallet to sync with monerod. // It takes a little while for the wallet to sync with wownerod.
pub async fn wait_for_wallet_height(&self, height: u32) -> Result<()> { pub async fn wait_for_wallet_height(&self, height: u32) -> Result<()> {
let mut retry: u8 = 0; let mut retry: u8 = 0;
while self.client().get_height().await?.height < height { while self.client().get_height().await?.height < height {
if retry >= 30 { if retry >= 30 {
// ~30 seconds // ~30 seconds
bail!("Wallet could not catch up with monerod after 30 retries.") bail!("Wallet could not catch up with wownerod after 30 retries.")
} }
time::sleep(Duration::from_millis(WAIT_WALLET_SYNC_MILLIS)).await; time::sleep(Duration::from_millis(WAIT_WALLET_SYNC_MILLIS)).await;
retry += 1; retry += 1;
@ -320,9 +320,9 @@ impl<'c> MoneroWalletRpc {
} }
} }
/// Mine a block ever BLOCK_TIME_SECS seconds. /// Mine a block ever BLOCK_TIME_SECS seconds.
async fn mine(monerod: monerod::Client, reward_address: String) -> Result<()> { async fn mine(wownerod: wownerod::Client, reward_address: String) -> Result<()> {
loop { loop {
time::sleep(Duration::from_secs(BLOCK_TIME_SECS)).await; time::sleep(Duration::from_secs(BLOCK_TIME_SECS)).await;
monerod.generateblocks(1, reward_address.clone()).await?; wownerod.generateblocks(1, reward_address.clone()).await?;
} }
} }

@ -1,5 +1,5 @@
use monero_harness::{Monero, MoneroWalletRpc}; use wownero_harness::{Wownero, WowneroWalletRpc};
use monero_rpc::wallet::MoneroWalletRpc as _; use wownero_rpc::wallet::WowneroWalletRpc as _;
use spectral::prelude::*; use spectral::prelude::*;
use std::time::Duration; use std::time::Duration;
use testcontainers::clients::Cli; use testcontainers::clients::Cli;
@ -9,7 +9,7 @@ use tracing_subscriber::util::SubscriberInitExt;
#[tokio::test] #[tokio::test]
async fn fund_transfer_and_check_tx_key() { async fn fund_transfer_and_check_tx_key() {
let _guard = tracing_subscriber::fmt() let _guard = tracing_subscriber::fmt()
.with_env_filter("warn,test=debug,monero_harness=debug,monero_rpc=debug") .with_env_filter("warn,test=debug,wownero_harness=debug,wownero_rpc=debug")
.set_default(); .set_default();
let fund_alice: u64 = 1_000_000_000_000; let fund_alice: u64 = 1_000_000_000_000;
@ -17,15 +17,15 @@ async fn fund_transfer_and_check_tx_key() {
let send_to_bob = 5_000_000_000; let send_to_bob = 5_000_000_000;
let tc = Cli::default(); let tc = Cli::default();
let (monero, _monerod_container, _wallet_containers) = let (wownero, _wownerod_container, _wallet_containers) =
Monero::new(&tc, vec!["alice", "bob"]).await.unwrap(); Wownero::new(&tc, vec!["alice", "bob"]).await.unwrap();
let alice_wallet = monero.wallet("alice").unwrap(); let alice_wallet = wownero.wallet("alice").unwrap();
let bob_wallet = monero.wallet("bob").unwrap(); let bob_wallet = wownero.wallet("bob").unwrap();
monero.init_miner().await.unwrap(); wownero.init_miner().await.unwrap();
monero.init_wallet("alice", vec![fund_alice]).await.unwrap(); wownero.init_wallet("alice", vec![fund_alice]).await.unwrap();
monero.init_wallet("bob", vec![fund_bob]).await.unwrap(); wownero.init_wallet("bob", vec![fund_bob]).await.unwrap();
monero.start_miner().await.unwrap(); wownero.start_miner().await.unwrap();
// check alice balance // check alice balance
let got_alice_balance = alice_wallet.balance().await.unwrap(); let got_alice_balance = alice_wallet.balance().await.unwrap();
@ -55,7 +55,7 @@ async fn fund_transfer_and_check_tx_key() {
assert_that!(res.received).is_equal_to(send_to_bob); assert_that!(res.received).is_equal_to(send_to_bob);
} }
async fn wait_for_wallet_to_catch_up(wallet: &MoneroWalletRpc, expected_balance: u64) { async fn wait_for_wallet_to_catch_up(wallet: &WowneroWalletRpc, expected_balance: u64) {
let max_retry = 15; let max_retry = 15;
let mut retry = 0; let mut retry = 0;
loop { loop {

@ -1,5 +1,5 @@
use monero_harness::Monero; use wownero_harness::Wownero;
use monero_rpc::monerod::MonerodRpc as _; use wownero_rpc::wownerod::WownerodRpc as _;
use spectral::prelude::*; use spectral::prelude::*;
use std::time::Duration; use std::time::Duration;
use testcontainers::clients::Cli; use testcontainers::clients::Cli;
@ -9,16 +9,16 @@ use tracing_subscriber::util::SubscriberInitExt;
#[tokio::test] #[tokio::test]
async fn init_miner_and_mine_to_miner_address() { async fn init_miner_and_mine_to_miner_address() {
let _guard = tracing_subscriber::fmt() let _guard = tracing_subscriber::fmt()
.with_env_filter("warn,test=debug,monero_harness=debug,monero_rpc=debug") .with_env_filter("warn,test=debug,wownero_harness=debug,wownero_rpc=debug")
.set_default(); .set_default();
let tc = Cli::default(); let tc = Cli::default();
let (monero, _monerod_container, _wallet_containers) = Monero::new(&tc, vec![]).await.unwrap(); let (wownero, _wownerod_container, _wallet_containers) = Wownero::new(&tc, vec![]).await.unwrap();
monero.init_and_start_miner().await.unwrap(); wownero.init_and_start_miner().await.unwrap();
let monerod = monero.monerod(); let wownerod = wownero.wownerod();
let miner_wallet = monero.wallet("miner").unwrap(); let miner_wallet = wownero.wallet("miner").unwrap();
let got_miner_balance = miner_wallet.balance().await.unwrap(); let got_miner_balance = miner_wallet.balance().await.unwrap();
assert_that!(got_miner_balance).is_greater_than(0); assert_that!(got_miner_balance).is_greater_than(0);
@ -26,7 +26,7 @@ async fn init_miner_and_mine_to_miner_address() {
time::sleep(Duration::from_millis(1010)).await; time::sleep(Duration::from_millis(1010)).await;
// after a bit more than 1 sec another block should have been mined // after a bit more than 1 sec another block should have been mined
let block_height = monerod.client().get_block_count().await.unwrap().count; let block_height = wownerod.client().get_block_count().await.unwrap().count;
assert_that(&block_height).is_greater_than(70); assert_that(&block_height).is_greater_than(70);
} }

@ -1,5 +1,5 @@
[package] [package]
name = "monero-rpc" name = "wownero-rpc"
version = "0.1.0" version = "0.1.0"
authors = [ "CoBloX Team <team@coblox.tech>" ] authors = [ "CoBloX Team <team@coblox.tech>" ]
edition = "2018" edition = "2018"
@ -9,8 +9,8 @@ anyhow = "1"
curve25519-dalek = "3.1" curve25519-dalek = "3.1"
hex = "0.4" hex = "0.4"
jsonrpc_client = { version = "0.7", features = [ "reqwest" ] } jsonrpc_client = { version = "0.7", features = [ "reqwest" ] }
monero = "0.12" wownero = "0.12"
monero-epee-bin-serde = "1" wownero-epee-bin-serde = "1"
rand = "0.7" rand = "0.7"
reqwest = { version = "0.11", default-features = false, features = [ "json" ] } reqwest = { version = "0.11", default-features = false, features = [ "json" ] }
serde = { version = "1.0", features = [ "derive" ] } serde = { version = "1.0", features = [ "derive" ] }

@ -12,5 +12,5 @@
)] )]
#![forbid(unsafe_code)] #![forbid(unsafe_code)]
pub mod monerod; pub mod wownerod;
pub mod wallet; pub mod wallet;

@ -3,7 +3,7 @@ use serde::de::Error;
use serde::{Deserialize, Deserializer, Serialize}; use serde::{Deserialize, Deserializer, Serialize};
#[jsonrpc_client::api(version = "2.0")] #[jsonrpc_client::api(version = "2.0")]
pub trait MoneroWalletRpc { pub trait WowneroWalletRpc {
async fn get_address(&self, account_index: u32) -> GetAddress; async fn get_address(&self, account_index: u32) -> GetAddress;
async fn get_balance(&self, account_index: u32) -> GetBalance; async fn get_balance(&self, account_index: u32) -> GetBalance;
async fn create_account(&self, label: String) -> CreateAccount; async fn create_account(&self, label: String) -> CreateAccount;
@ -35,7 +35,7 @@ pub trait MoneroWalletRpc {
async fn get_version(&self) -> Version; async fn get_version(&self) -> Version;
} }
#[jsonrpc_client::implement(MoneroWalletRpc)] #[jsonrpc_client::implement(WowneroWalletRpc)]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Client { pub struct Client {
inner: reqwest::Client, inner: reqwest::Client,
@ -43,7 +43,7 @@ pub struct Client {
} }
impl Client { impl Client {
/// Constructs a monero-wallet-rpc client with localhost endpoint. /// Constructs a wownero-wallet-rpc client with localhost endpoint.
pub fn localhost(port: u16) -> Result<Self> { pub fn localhost(port: u16) -> Result<Self> {
Client::new( Client::new(
format!("http://127.0.0.1:{}/json_rpc", port) format!("http://127.0.0.1:{}/json_rpc", port)
@ -52,7 +52,7 @@ impl Client {
) )
} }
/// Constructs a monero-wallet-rpc client with `url` endpoint. /// Constructs a wownero-wallet-rpc client with `url` endpoint.
pub fn new(url: reqwest::Url) -> Result<Self> { pub fn new(url: reqwest::Url) -> Result<Self> {
Ok(Self { Ok(Self {
inner: reqwest::ClientBuilder::new() inner: reqwest::ClientBuilder::new()
@ -62,7 +62,7 @@ impl Client {
}) })
} }
/// Transfers `amount` monero from `account_index` to `address`. /// Transfers `amount` wownero from `account_index` to `address`.
pub async fn transfer_single( pub async fn transfer_single(
&self, &self,
account_index: u32, account_index: u32,
@ -129,7 +129,7 @@ pub struct Transfer {
pub tx_blob: String, pub tx_blob: String,
pub tx_hash: String, pub tx_hash: String,
#[serde(deserialize_with = "opt_key_from_blank")] #[serde(deserialize_with = "opt_key_from_blank")]
pub tx_key: Option<monero::PrivateKey>, pub tx_key: Option<wownero::PrivateKey>,
pub tx_metadata: String, pub tx_metadata: String,
pub unsigned_txset: String, pub unsigned_txset: String,
} }
@ -154,7 +154,7 @@ struct CheckTxKeyResponse {
impl From<CheckTxKeyResponse> for CheckTxKey { impl From<CheckTxKeyResponse> for CheckTxKey {
fn from(response: CheckTxKeyResponse) -> Self { fn from(response: CheckTxKeyResponse) -> Self {
// Due to a bug in monerod that causes check_tx_key confirmations // Due to a bug in wownerod that causes check_tx_key confirmations
// to overflow we safeguard the confirmations to avoid unwanted // to overflow we safeguard the confirmations to avoid unwanted
// side effects. // side effects.
let confirmations = if response.confirmations > u64::MAX - 1000 { let confirmations = if response.confirmations > u64::MAX - 1000 {
@ -205,13 +205,13 @@ pub type WalletOpened = Empty;
/// ///
/// With `serde`, an empty JSON object (`{ }`) does not deserialize into Rust's /// With `serde`, an empty JSON object (`{ }`) does not deserialize into Rust's
/// `()`. With the adoption of `jsonrpc_client`, we need to be explicit about /// `()`. With the adoption of `jsonrpc_client`, we need to be explicit about
/// what the response of every RPC call is. Unfortunately, monerod likes to /// what the response of every RPC call is. Unfortunately, wownerod likes to
/// return empty objects instead of `null`s in certain cases. We use this struct /// return empty objects instead of `null`s in certain cases. We use this struct
/// to all the "deserialization" to happily continue. /// to all the "deserialization" to happily continue.
#[derive(Debug, Copy, Clone, Deserialize)] #[derive(Debug, Copy, Clone, Deserialize)]
pub struct Empty {} pub struct Empty {}
fn opt_key_from_blank<'de, D>(deserializer: D) -> Result<Option<monero::PrivateKey>, D::Error> fn opt_key_from_blank<'de, D>(deserializer: D) -> Result<Option<wownero::PrivateKey>, D::Error>
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {

@ -1,12 +1,12 @@
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use monero::cryptonote::hash::Hash; use wownero::cryptonote::hash::Hash;
use monero::util::ringct; use wownero::util::ringct;
use monero::PublicKey; use wownero::PublicKey;
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize, Serializer}; use serde::{Deserialize, Serialize, Serializer};
#[jsonrpc_client::api(version = "2.0")] #[jsonrpc_client::api(version = "2.0")]
pub trait MonerodRpc { pub trait WownerodRpc {
async fn generateblocks(&self, amount_of_blocks: u32, wallet_address: String) async fn generateblocks(&self, amount_of_blocks: u32, wallet_address: String)
-> GenerateBlocks; -> GenerateBlocks;
async fn get_block_header_by_height(&self, height: u32) -> BlockHeader; async fn get_block_header_by_height(&self, height: u32) -> BlockHeader;
@ -14,7 +14,7 @@ pub trait MonerodRpc {
async fn get_block(&self, height: u32) -> GetBlockResponse; async fn get_block(&self, height: u32) -> GetBlockResponse;
} }
#[jsonrpc_client::implement(MonerodRpc)] #[jsonrpc_client::implement(WownerodRpc)]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Client { pub struct Client {
inner: reqwest::Client, inner: reqwest::Client,
@ -24,7 +24,7 @@ pub struct Client {
} }
impl Client { impl Client {
/// New local host monerod RPC client. /// New local host wownerod RPC client.
pub fn localhost(port: u16) -> Result<Self> { pub fn localhost(port: u16) -> Result<Self> {
Self::new("127.0.0.1".to_owned(), port) Self::new("127.0.0.1".to_owned(), port)
} }
@ -66,7 +66,7 @@ impl Client {
let response = self let response = self
.inner .inner
.post(url) .post(url)
.body(monero_epee_bin_serde::to_bytes(&request)?) .body(wownero_epee_bin_serde::to_bytes(&request)?)
.send() .send()
.await?; .await?;
@ -76,7 +76,7 @@ impl Client {
let body = response.bytes().await?; let body = response.bytes().await?;
Ok(monero_epee_bin_serde::from_bytes(body)?) Ok(wownero_epee_bin_serde::from_bytes(body)?)
} }
} }
@ -91,7 +91,7 @@ pub struct BlockCount {
pub count: u32, pub count: u32,
} }
// We should be able to use monero-rs for this but it does not include all // We should be able to use wownero-rs for this but it does not include all
// the fields. // the fields.
#[derive(Clone, Debug, Deserialize)] #[derive(Clone, Debug, Deserialize)]
pub struct BlockHeader { pub struct BlockHeader {
@ -112,8 +112,8 @@ pub struct BlockHeader {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct GetBlockResponse { pub struct GetBlockResponse {
#[serde(with = "monero_serde_hex_block")] #[serde(with = "wownero_serde_hex_block")]
pub blob: monero::Block, pub blob: wownero::Block,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
@ -181,14 +181,14 @@ pub enum Status {
Failed, Failed,
} }
mod monero_serde_hex_block { mod wownero_serde_hex_block {
use super::*; use super::*;
use monero::consensus::Decodable; use wownero::consensus::Decodable;
use serde::de::Error; use serde::de::Error;
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use std::io::Cursor; use std::io::Cursor;
pub fn deserialize<'de, D>(deserializer: D) -> Result<monero::Block, D::Error> pub fn deserialize<'de, D>(deserializer: D) -> Result<wownero::Block, D::Error>
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
@ -197,7 +197,7 @@ mod monero_serde_hex_block {
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 = wownero::Block::consensus_decode(&mut cursor).map_err(D::Error::custom)?;
Ok(block) Ok(block)
} }

@ -1,18 +1,18 @@
[package] [package]
name = "monero-wallet" name = "wownero-wallet"
version = "0.1.0" version = "0.1.0"
authors = [ "CoBloX Team <team@coblox.tech>" ] authors = [ "CoBloX Team <team@coblox.tech>" ]
edition = "2018" edition = "2018"
[dependencies] [dependencies]
anyhow = "1" anyhow = "1"
monero = "0.12" wownero = "0.12"
monero-rpc = { path = "../monero-rpc" } wownero-rpc = { path = "../wownero-rpc" }
rand = "0.7" rand = "0.7"
[dev-dependencies] [dev-dependencies]
curve25519-dalek = "3" curve25519-dalek = "3"
monero-harness = { path = "../monero-harness" } wownero-harness = { path = "../wownero-harness" }
rand = "0.7" rand = "0.7"
testcontainers = "0.12" testcontainers = "0.12"
tokio = { version = "1", features = [ "rt-multi-thread", "time", "macros", "sync", "process", "fs" ] } tokio = { version = "1", features = [ "rt-multi-thread", "time", "macros", "sync", "process", "fs" ] }

@ -1,12 +1,12 @@
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use monero::consensus::encode::VarInt; use wownero::consensus::encode::VarInt;
use monero::cryptonote::hash::Hashable; use wownero::cryptonote::hash::Hashable;
use monero_rpc::monerod; use wownero_rpc::wownerod;
use monero_rpc::monerod::{GetBlockResponse, MonerodRpc as _}; use wownero_rpc::wownerod::{GetBlockResponse, WownerodRpc as _};
use rand::Rng; use rand::Rng;
pub struct Wallet { pub struct Wallet {
client: monerod::Client, client: wownerod::Client,
} }
impl Wallet { impl Wallet {
@ -18,7 +18,7 @@ impl Wallet {
/// possible. /// possible.
pub async fn choose_ten_random_key_offsets(&self) -> Result<[VarInt; 10]> { pub async fn choose_ten_random_key_offsets(&self) -> Result<[VarInt; 10]> {
let latest_block = self.client.get_block_count().await?; let latest_block = self.client.get_block_count().await?;
let latest_spendable_block = latest_block.count - 10; let latest_spendable_block = latest_block.count - 4;
let block: GetBlockResponse = self.client.get_block(latest_spendable_block).await?; let block: GetBlockResponse = self.client.get_block(latest_spendable_block).await?;
@ -58,16 +58,16 @@ impl Wallet {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use monero_harness::image::Monerod; use wownero_harness::image::Wownerod;
use monero_rpc::monerod::{Client, GetOutputsOut}; use wownero_rpc::wownerod::{Client, GetOutputsOut};
use testcontainers::clients::Cli; use testcontainers::clients::Cli;
use testcontainers::Docker; use testcontainers::Docker;
#[tokio::test] #[tokio::test]
async fn get_outs_for_key_offsets() { async fn get_outs_for_key_offsets() {
let cli = Cli::default(); let cli = Cli::default();
let container = cli.run(Monerod::default()); let container = cli.run(Wownerod::default());
let rpc_client = Client::localhost(container.get_host_port(18081).unwrap()).unwrap(); let rpc_client = Client::localhost(container.get_host_port(34568).unwrap()).unwrap();
rpc_client.generateblocks(150, "498AVruCDWgP9Az9LjMm89VWjrBrSZ2W2K3HFBiyzzrRjUJWUcCVxvY1iitfuKoek2FdX6MKGAD9Qb1G1P8QgR5jPmmt3Vj".to_owned()).await.unwrap(); rpc_client.generateblocks(150, "498AVruCDWgP9Az9LjMm89VWjrBrSZ2W2K3HFBiyzzrRjUJWUcCVxvY1iitfuKoek2FdX6MKGAD9Qb1G1P8QgR5jPmmt3Vj".to_owned()).await.unwrap();
let wallet = Wallet { let wallet = Wallet {
client: rpc_client.clone(), client: rpc_client.clone(),
Loading…
Cancel
Save