Skip to content

Commit

Permalink
Merge pull request #305 from KnowWhoami/create_wallet
Browse files Browse the repository at this point in the history
Check for any existing wallet file in case `wallet_file_name` is  given `None`.
  • Loading branch information
Shourya742 authored Dec 22, 2024
2 parents 92a9440 + 3096859 commit 9c1f324
Show file tree
Hide file tree
Showing 21 changed files with 154 additions and 182 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bip39 = { version = "1.0.1", features = ["rand"] }
bitcoin = { version = "0.32", features = ["rand"] }
bip39 = { version = "2.1.0", features = ["rand"] }
bitcoin = "0.32"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_cbor = "0.11.2"
Expand Down
75 changes: 25 additions & 50 deletions src/maker/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,9 @@ use crate::{
messages::{FidelityProof, ReqContractSigsForSender},
Hash160,
},
utill::{
get_maker_dir, redeemscript_to_scriptpubkey, seed_phrase_to_unique_id, ConnectionType,
},
utill::{get_maker_dir, redeemscript_to_scriptpubkey, ConnectionType},
wallet::{RPCConfig, SwapCoin, WalletSwapCoin},
};
use bip39::Mnemonic;
use bitcoin::{
ecdsa::Signature,
secp256k1::{self, Secp256k1},
Expand Down Expand Up @@ -176,15 +173,17 @@ pub struct Maker {
impl Maker {
/// Initializes a Maker structure.
///
/// The `data_dir` and `wallet_name_path` can be selectively provided to perform wallet load/creation.
/// data_dir: Some(value) = Create data directory at given value.
/// data_dir: None = Create default data directory. For linux "~/.coinswap"
/// wallet_file_name: Some(value) = Try loading wallet file with name "value". If doesn't exist create a new wallet with the given name.
/// wallet_file_name: None = Create a new default wallet file. Ex: "9d317f933-maker".
///
/// rpc_conf: None = Use the default [RPCConfig].
/// This function sets up a Maker instance with configurable parameters.
/// It handles the initialization of data directories, wallet files, and RPC configurations.
///
/// behavior: Defines special Maker behavior. Only applicable in integration-tests.
/// ### Parameters:
/// - `data_dir`:
/// - `Some(value)`: Use the specified directory for storing data.
/// - `None`: Use the default data directory (e.g., for Linux: `~/.coinswap/maker`).
/// - `wallet_file_name`:
/// - `Some(value)`: Attempt to load a wallet file named `value`. If it does not exist, a new wallet with the given name will be created.
/// - `None`: Create a new wallet file with the default name `maker-wallet`.
/// - If `rpc_config` = `None`: Use the default [`RPCConfig`]
pub fn init(
data_dir: Option<PathBuf>,
wallet_file_name: Option<String>,
Expand All @@ -195,50 +194,26 @@ impl Maker {
connection_type: Option<ConnectionType>,
behavior: MakerBehavior,
) -> Result<Self, MakerError> {
// Only allow MakerBehavior in functional tests
let behavior = if cfg!(feature = "integration-test") {
behavior
} else {
MakerBehavior::Normal
};

// Get provided data directory or the default data directory.
let data_dir = data_dir.unwrap_or(get_maker_dir());
let wallets_dir = data_dir.join("wallets");

let wallet_dir = data_dir.join("wallets");
// Use the provided name or default to `maker-wallet` if not specified.
let wallet_file_name = wallet_file_name.unwrap_or_else(|| "maker-wallet".to_string());
let wallet_path = wallets_dir.join(&wallet_file_name);

let mut rpc_config = rpc_config.unwrap_or_default();

// Load/Create wallet depending on if a wallet with wallet_file_name exists.
let mut wallet = if let Some(file_name) = wallet_file_name {
let wallet_path = wallet_dir.join(&file_name);
rpc_config.wallet_name = file_name;
if wallet_path.exists() {
// Try loading wallet
let wallet = Wallet::load(&rpc_config, &wallet_path)?;
log::info!("Wallet file at {:?} successfully loaded.", wallet_path);
wallet
} else {
// Create wallet with the given name.
let mnemonic = Mnemonic::generate(12).map_err(WalletError::BIP39)?;
let seedphrase = mnemonic.to_string();
rpc_config.wallet_name = wallet_file_name;

let wallet = Wallet::init(&wallet_path, &rpc_config, seedphrase, "".to_string())?;
log::info!("New Wallet created at : {:?}", wallet_path);
wallet
}
let mut wallet = if wallet_path.exists() {
// wallet already exists , load the wallet
let wallet = Wallet::load(&wallet_path, &rpc_config)?;
log::info!("Wallet file at {:?} successfully loaded.", wallet_path);
wallet
} else {
// Create default wallet
let mnemonic = Mnemonic::generate(12).map_err(WalletError::BIP39)?;
let seedphrase = mnemonic.to_string();

// File names are unique for default wallets
let unique_id = seed_phrase_to_unique_id(&seedphrase);
let file_name = unique_id + "-maker";
let wallet_path = wallet_dir.join(&file_name);
rpc_config.wallet_name = file_name;

let wallet = Wallet::init(&wallet_path, &rpc_config, seedphrase, "".to_string())?;
// wallet doesn't exists at the given path , create a new one
let wallet = Wallet::init(&wallet_path, &rpc_config)?;
log::info!("New Wallet created at : {:?}", wallet_path);
wallet
};
Expand All @@ -262,7 +237,7 @@ impl Maker {
config.connection_type = connection_type;
}

let thread_pool_port = config.port;
let port = config.port;

config.write_to_file(&data_dir.join("config.toml"))?;

Expand All @@ -279,7 +254,7 @@ impl Maker {
highest_fidelity_proof: RwLock::new(None),
is_setup_complete: AtomicBool::new(false),
data_dir,
thread_pool: Arc::new(ThreadPool::new(thread_pool_port)),
thread_pool: Arc::new(ThreadPool::new(port)),
})
}

Expand Down
9 changes: 5 additions & 4 deletions src/maker/config.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Maker Configuration. Controlling various behaviors.
use crate::utill::parse_toml;
use std::{io, path::PathBuf};
use std::{io, path::Path};

use bitcoin::Amount;
use std::io::Write;
Expand Down Expand Up @@ -62,7 +62,7 @@ impl MakerConfig {
///
/// Default data-dir for linux: `~/.coinswap/maker`
/// Default config locations:`~/.coinswap/maker/config.toml`.
pub fn new(config_path: Option<&PathBuf>) -> io::Result<Self> {
pub fn new(config_path: Option<&Path>) -> io::Result<Self> {
let default_config_path = get_maker_dir().join("config.toml");

let config_path = config_path.unwrap_or(&default_config_path);
Expand Down Expand Up @@ -119,7 +119,7 @@ impl MakerConfig {
}

// Method to serialize the MakerConfig into a TOML string and write it to a file
pub fn write_to_file(&self, path: &PathBuf) -> std::io::Result<()> {
pub fn write_to_file(&self, path: &Path) -> std::io::Result<()> {
let toml_data = format!(
"port = {}
rpc_port = {}
Expand Down Expand Up @@ -158,6 +158,7 @@ mod tests {
use std::{
fs::{self, File},
io::Write,
path::PathBuf,
};

fn create_temp_config(contents: &str, file_name: &str) -> PathBuf {
Expand All @@ -167,7 +168,7 @@ mod tests {
file_path
}

fn remove_temp_config(path: &PathBuf) {
fn remove_temp_config(path: &Path) {
fs::remove_file(path).unwrap();
}

Expand Down
2 changes: 1 addition & 1 deletion src/market/directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ impl DirectoryServer {
}
}

fn write_default_directory_config(config_path: &PathBuf) -> Result<(), DirectoryServerError> {
fn write_default_directory_config(config_path: &Path) -> Result<(), DirectoryServerError> {
let config_string = String::from(
"\
port = 8080\n\
Expand Down
73 changes: 24 additions & 49 deletions src/taker/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use std::{
time::{Duration, Instant},
};

use bip39::Mnemonic;
use bitcoind::bitcoincore_rpc::RpcApi;
use socks::Socks5Stream;

Expand Down Expand Up @@ -135,10 +134,9 @@ struct NextPeerInfo {
}

/// Enum representing different behaviors of the Taker in a coinswap protocol.
#[derive(Default, PartialEq, Eq, PartialOrd, Ord)]
#[derive(PartialEq, Eq, PartialOrd, Ord)]
pub enum TakerBehavior {
/// No special behavior.
#[default]
Normal,
/// This depicts the behavior when the taker drops connections after the full coinswap setup.
DropConnectionAfterFullSetup,
Expand All @@ -161,68 +159,45 @@ pub struct Taker {
impl Taker {
// ######## MAIN PUBLIC INTERFACE ############

/// Initializes a Taker structure.
///
/// The `data_dir` and `wallet_name_path` can be selectively provided to perform wallet load/creation.
/// Initializes a Maker structure.
///
/// data_dir: Some(value) = Create data directory at given value.
/// data_dir: None = Create default data directory. For linux "~/.coinswap"
/// wallet_file_name: Some(value) = Try loading wallet file with name "value". If doesn't exist create a new wallet with the given name.
/// wallet_file_name: None = Create a new default wallet file. Ex: "9d317f933-taker".
/// This function sets up a Maker instance with configurable parameters.
/// It handles the initialization of data directories, wallet files, and RPC configurations.
///
/// rpc_conf: None = Use the default [RPCConfig].
///
/// behavior: Defines special Maker behavior. Only applicable in integration-tests.
/// ### Parameters:
/// - `data_dir`:
/// - `Some(value)`: Use the specified directory for storing data.
/// - `None`: Use the default data directory (e.g., for Linux: `~/.coinswap/maker`).
/// - `wallet_file_name`:
/// - `Some(value)`: Attempt to load a wallet file named `value`. If it does not exist, a new wallet with the given name will be created.
/// - `None`: Create a new wallet file with the default name `maker-wallet`.
/// - If `rpc_config` = `None`: Use the default [`RPCConfig`]
pub fn init(
data_dir: Option<PathBuf>,
wallet_file_name: Option<String>,
rpc_config: Option<RPCConfig>,
behavior: TakerBehavior,
connection_type: Option<ConnectionType>,
) -> Result<Taker, TakerError> {
// Only allow Special Behavior in functional tests
let behavior = if cfg!(feature = "integration-test") {
behavior
} else {
TakerBehavior::Normal
};

// Get provided data directory or the default data directory.
let data_dir = data_dir.unwrap_or(get_taker_dir());
let wallets_dir = data_dir.join("wallets");

let mut rpc_config = rpc_config.unwrap_or_default();
// Use the provided name or default to `taker-wallet` if not specified.
let wallet_file_name = wallet_file_name.unwrap_or_else(|| "taker-wallet".to_string());
let wallet_path = wallets_dir.join(&wallet_file_name);

// Load/Create wallet depending on if a wallet with wallet_file_name exists.
let mut wallet = if let Some(file_name) = wallet_file_name {
let wallet_path = wallets_dir.join(&file_name);
rpc_config.wallet_name = file_name;
if wallet_path.exists() {
// Try loading wallet
let wallet = Wallet::load(&rpc_config, &wallet_path)?;
log::info!("Wallet file at {:?} successfully loaded.", wallet_path);
wallet
} else {
// Create wallet with the given name.
let mnemonic = Mnemonic::generate(12).map_err(WalletError::BIP39)?;
let seedphrase = mnemonic.to_string();
let mut rpc_config = rpc_config.unwrap_or_default();
rpc_config.wallet_name = wallet_file_name;

let wallet = Wallet::init(&wallet_path, &rpc_config, seedphrase, "".to_string())?;
log::info!("New Wallet created at : {:?}", wallet_path);
wallet
}
let mut wallet = if wallet_path.exists() {
// wallet already exists , load the wallet
let wallet = Wallet::load(&wallet_path, &rpc_config)?;
log::info!("Wallet file at {:?} successfully loaded.", wallet_path);
wallet
} else {
// Create default wallet
let mnemonic = Mnemonic::generate(12).map_err(WalletError::BIP39)?;
let seedphrase = mnemonic.to_string();

// File names are unique for default wallets
let unique_id = seed_phrase_to_unique_id(&seedphrase);
let file_name = unique_id + "-taker";
let wallet_path = wallets_dir.join(&file_name);
rpc_config.wallet_name = file_name;

let wallet = Wallet::init(&wallet_path, &rpc_config, seedphrase, "".to_string())?;
// wallet doesn't exists at the given path , create a new one
let wallet = Wallet::init(&wallet_path, &rpc_config)?;
log::info!("New Wallet created at : {:?}", wallet_path);
wallet
};
Expand Down
9 changes: 5 additions & 4 deletions src/taker/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! such as refund locktime, connection attempts, sleep delays, and timeouts.
use crate::utill::{get_taker_dir, parse_field, parse_toml, ConnectionType};
use std::{io, io::Write, path::PathBuf};
use std::{io, io::Write, path::Path};

/// Taker configuration with refund, connection, and sleep settings.
#[derive(Debug, Clone, PartialEq)]
Expand Down Expand Up @@ -44,7 +44,7 @@ impl TakerConfig {
///
/// Default data-dir for linux: `~/.coinswap/taker`
/// Default config locations: `~/.coinswap/taker/config.toml`.
pub fn new(config_path: Option<&PathBuf>) -> io::Result<Self> {
pub fn new(config_path: Option<&Path>) -> io::Result<Self> {
let default_config_path = get_taker_dir().join("config.toml");

let config_path = config_path.unwrap_or(&default_config_path);
Expand Down Expand Up @@ -82,7 +82,7 @@ impl TakerConfig {
}

// Method to manually serialize the Taker Config into a TOML string
pub fn write_to_file(&self, path: &PathBuf) -> std::io::Result<()> {
pub fn write_to_file(&self, path: &Path) -> std::io::Result<()> {
let toml_data = format!(
"port = {}
socks_port = {}
Expand Down Expand Up @@ -112,6 +112,7 @@ mod tests {
use std::{
fs::{self, File},
io::Write,
path::PathBuf,
};

fn create_temp_config(contents: &str, file_name: &str) -> PathBuf {
Expand All @@ -121,7 +122,7 @@ mod tests {
file_path
}

fn remove_temp_config(path: &PathBuf) {
fn remove_temp_config(path: &Path) {
fs::remove_file(path).unwrap();
}

Expand Down
11 changes: 2 additions & 9 deletions src/utill.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Various utility and helper functions for both Taker and Maker.
use bitcoin::{
hashes::{sha256, Hash},
hashes::Hash,
key::{rand::thread_rng, Keypair},
secp256k1::{Secp256k1, SecretKey},
PublicKey, ScriptBuf, WitnessProgram, WitnessVersion,
Expand Down Expand Up @@ -120,13 +120,6 @@ pub fn get_dns_dir() -> PathBuf {
get_data_dir().join("dns")
}

/// Generate an unique identifier from the seedphrase.
pub fn seed_phrase_to_unique_id(seed: &str) -> String {
let mut hash = sha256::Hash::hash(seed.as_bytes()).to_string();
let _ = hash.split_off(9);
hash
}

pub fn setup_taker_logger(filter: LevelFilter) {
env::set_var("RUST_LOG", "coinswap=info");
let log_dir = get_taker_dir().join("debug.log");
Expand Down Expand Up @@ -394,7 +387,7 @@ pub fn parse_field<T: std::str::FromStr>(value: Option<&String>, default: T) ->
}

/// Function to check if tor log contains a pattern
pub fn monitor_log_for_completion(log_file: &PathBuf, pattern: &str) -> io::Result<()> {
pub fn monitor_log_for_completion(log_file: &Path, pattern: &str) -> io::Result<()> {
let mut last_size = 0;

loop {
Expand Down
Loading

0 comments on commit 9c1f324

Please sign in to comment.