diff --git a/Cargo.lock b/Cargo.lock index 4fe73af1..7aa5028a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -564,7 +564,7 @@ dependencies = [ "config", "electrum-client", "hex", - "mercurylib", + "mercuryrustlib", "rand", "reqwest", "schemars", @@ -1626,6 +1626,31 @@ dependencies = [ "uniffi", ] +[[package]] +name = "mercuryrustlib" +version = "0.1.0" +dependencies = [ + "anyhow", + "bech32", + "bip39", + "bitcoin", + "chrono", + "clap", + "config", + "electrum-client", + "hex", + "mercurylib", + "rand", + "reqwest", + "schemars", + "secp256k1-zkp", + "serde", + "serde_json", + "sqlx", + "tokio", + "uuid 1.4.1", +] + [[package]] name = "mime" version = "0.3.17" diff --git a/Cargo.toml b/Cargo.toml index 3dcae802..ebfebba3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,2 +1,2 @@ [workspace] -members = ["clients/rust", "server", "wasm", "lib", "token-server"] +members = ["clients/rust", "server", "wasm", "lib", "token-server", "clients/libs/rust"] diff --git a/clients/libs/rust/Cargo.toml b/clients/libs/rust/Cargo.toml new file mode 100644 index 00000000..89b57b43 --- /dev/null +++ b/clients/libs/rust/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "mercuryrustlib" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0" +bech32 = { version = "0.9.1", default-features = false } +bitcoin = { version = "0.30.1", features = ["serde", "base64", "rand-std", "std", "bitcoinconsensus"], default-features = false } +bip39 = "1.2.0" +clap = { version = "4.2.5", features = ["derive"]} +chrono = "0.4.31" +config = "0.13.1" +electrum-client = "0.18.0" +hex = "0.4.3" +rand = "0.8.5" +reqwest = { version = "0.11.16", features = ["blocking", "json", "socks"] } +schemars = { version = "0.8.12", features = ["chrono", "uuid"] } +secp256k1-zkp = { git = "https://github.com/ssantos21/rust-secp256k1-zkp.git", branch = "blinded-musig-scheme", features = [ "rand-std", "bitcoin_hashes", "std" ] } +serde = { version = "1.0.163", features = ["derive"] } +serde_json = "1.0.96" +sqlx = { version = "0.7", features = [ "runtime-tokio", "sqlite", "time", "uuid" ] } +tokio = { version = "1.27.0", features = ["full"] } +uuid = { version = "1.3.1", features = ["v4", "serde"] } +mercurylib = { path = "../../../lib" } diff --git a/clients/rust/migrations/0001_signer_data_table.sql b/clients/libs/rust/migrations/0001_signer_data_table.sql similarity index 100% rename from clients/rust/migrations/0001_signer_data_table.sql rename to clients/libs/rust/migrations/0001_signer_data_table.sql diff --git a/clients/libs/rust/rust-toolchain.toml b/clients/libs/rust/rust-toolchain.toml new file mode 100644 index 00000000..624eb0ea --- /dev/null +++ b/clients/libs/rust/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "1.76.0" diff --git a/clients/rust/src/broadcast_backup_tx.rs b/clients/libs/rust/src/broadcast_backup_tx.rs similarity index 100% rename from clients/rust/src/broadcast_backup_tx.rs rename to clients/libs/rust/src/broadcast_backup_tx.rs diff --git a/clients/rust/src/client_config.rs b/clients/libs/rust/src/client_config.rs similarity index 96% rename from clients/rust/src/client_config.rs rename to clients/libs/rust/src/client_config.rs index b6e1294b..ad8e2068 100644 --- a/clients/rust/src/client_config.rs +++ b/clients/libs/rust/src/client_config.rs @@ -101,3 +101,8 @@ impl ClientConfig { } } } + +pub async fn load() -> ClientConfig { + let client_config = ClientConfig::load().await; + client_config +} \ No newline at end of file diff --git a/clients/rust/src/coin_status.rs b/clients/libs/rust/src/coin_status.rs similarity index 100% rename from clients/rust/src/coin_status.rs rename to clients/libs/rust/src/coin_status.rs diff --git a/clients/rust/src/deposit.rs b/clients/libs/rust/src/deposit.rs similarity index 95% rename from clients/rust/src/deposit.rs rename to clients/libs/rust/src/deposit.rs index 454986fe..f827e1b8 100644 --- a/clients/rust/src/deposit.rs +++ b/clients/libs/rust/src/deposit.rs @@ -1,7 +1,7 @@ use anyhow::{anyhow, Result, Ok}; use mercurylib::{deposit::{create_deposit_msg1, create_aggregated_address}, wallet::{Wallet, BackupTx, CoinStatus, Coin}, transaction:: get_user_backup_address, utils::get_blockheight}; -use crate::{sqlite_manager::update_wallet, get_wallet, client_config::ClientConfig, transaction::new_transaction}; +use crate::{client_config::ClientConfig, sqlite_manager::{get_wallet, update_wallet}, transaction::new_transaction}; pub async fn get_deposit_bitcoin_address(client_config: &ClientConfig, wallet_name: &str, token_id: &str, amount: u32) -> Result { @@ -100,10 +100,6 @@ pub async fn init(client_config: &ClientConfig, wallet: &Wallet, token_id: uuid: let deposit_msg_1_response: mercurylib::deposit::DepositMsg1Response = serde_json::from_str(value.as_str())?; - // println!("value: {:?}", value); - - // println!("response: {:?}", deposit_msg_1_response); - let deposit_init_result = mercurylib::deposit::handle_deposit_msg_1_response(&coin, &deposit_msg_1_response)?; let coin = wallet.coins.last_mut().unwrap(); diff --git a/clients/libs/rust/src/lib.rs b/clients/libs/rust/src/lib.rs new file mode 100644 index 00000000..dd50f66b --- /dev/null +++ b/clients/libs/rust/src/lib.rs @@ -0,0 +1,26 @@ +pub mod broadcast_backup_tx; +pub mod client_config; +pub mod coin_status; +pub mod deposit; +pub mod sqlite_manager; +pub mod transaction; +pub mod transfer_receiver; +pub mod transfer_sender; +pub mod utils; +pub mod wallet; +pub mod withdraw; + +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/clients/rust/src/sqlite_manager.rs b/clients/libs/rust/src/sqlite_manager.rs similarity index 100% rename from clients/rust/src/sqlite_manager.rs rename to clients/libs/rust/src/sqlite_manager.rs diff --git a/clients/rust/src/transaction.rs b/clients/libs/rust/src/transaction.rs similarity index 100% rename from clients/rust/src/transaction.rs rename to clients/libs/rust/src/transaction.rs diff --git a/clients/rust/src/transfer_receiver.rs b/clients/libs/rust/src/transfer_receiver.rs similarity index 100% rename from clients/rust/src/transfer_receiver.rs rename to clients/libs/rust/src/transfer_receiver.rs diff --git a/clients/rust/src/transfer_sender.rs b/clients/libs/rust/src/transfer_sender.rs similarity index 100% rename from clients/rust/src/transfer_sender.rs rename to clients/libs/rust/src/transfer_sender.rs diff --git a/clients/rust/src/utils.rs b/clients/libs/rust/src/utils.rs similarity index 100% rename from clients/rust/src/utils.rs rename to clients/libs/rust/src/utils.rs diff --git a/clients/rust/src/wallet.rs b/clients/libs/rust/src/wallet.rs similarity index 100% rename from clients/rust/src/wallet.rs rename to clients/libs/rust/src/wallet.rs diff --git a/clients/rust/src/withdraw.rs b/clients/libs/rust/src/withdraw.rs similarity index 100% rename from clients/rust/src/withdraw.rs rename to clients/libs/rust/src/withdraw.rs diff --git a/clients/rust/Cargo.toml b/clients/rust/Cargo.toml index 725da835..c681cc35 100644 --- a/clients/rust/Cargo.toml +++ b/clients/rust/Cargo.toml @@ -24,4 +24,4 @@ serde_json = "1.0.96" sqlx = { version = "0.7", features = [ "runtime-tokio", "sqlite", "time", "uuid" ] } tokio = { version = "1.27.0", features = ["full"] } uuid = { version = "1.3.1", features = ["v4", "serde"] } -mercurylib = { path = "../../lib" } +mercuryrustlib = { path = "../libs/rust" } diff --git a/clients/rust/src/main.rs b/clients/rust/src/main.rs index 8de6c6c0..e4151257 100644 --- a/clients/rust/src/main.rs +++ b/clients/rust/src/main.rs @@ -1,22 +1,7 @@ -mod client_config; -mod wallet; -mod utils; -mod sqlite_manager; -mod deposit; -mod transaction; -mod broadcast_backup_tx; -mod withdraw; -mod transfer_sender; -mod transfer_receiver; -mod coin_status; - use anyhow::Result; use clap::{Parser, Subcommand}; -use client_config::ClientConfig; use serde_json::json; -use crate::{wallet::create_wallet, sqlite_manager::get_wallet}; - #[derive(Parser)] #[command(author, version, about, long_about = None)] #[command(propagate_version = true)] @@ -81,38 +66,38 @@ async fn main() -> Result<()> { let cli = Cli::parse(); - let client_config = ClientConfig::load().await; + let client_config = mercuryrustlib::client_config::load().await; match cli.command { Commands::CreateWallet { name } => { - let wallet = create_wallet( + let wallet = mercuryrustlib::wallet::create_wallet( &name, &client_config).await?; - sqlite_manager::insert_wallet(&client_config.pool, &wallet).await?; + mercuryrustlib::sqlite_manager::insert_wallet(&client_config.pool, &wallet).await?; println!("Wallet created: {:?}", wallet); }, Commands::NewToken { } => { - let token_id = deposit::get_token(&client_config).await?; + let token_id = mercuryrustlib::deposit::get_token(&client_config).await?; let obj = json!({"token": token_id}); println!("{}", serde_json::to_string_pretty(&obj).unwrap()); }, Commands::NewDepositAddress { wallet_name, token_id, amount } => { - let address = deposit::get_deposit_bitcoin_address(&client_config, &wallet_name, &token_id, amount).await?; + let address = mercuryrustlib::deposit::get_deposit_bitcoin_address(&client_config, &wallet_name, &token_id, amount).await?; let obj = json!({"address": address}); println!("{}", serde_json::to_string_pretty(&obj).unwrap()); }, Commands::BroadcastBackupTransaction { wallet_name, statechain_id, to_address, fee_rate } => { - coin_status::update_coins(&client_config, &wallet_name).await?; - broadcast_backup_tx::execute(&client_config, &wallet_name, &statechain_id, &to_address, fee_rate).await?; + mercuryrustlib::coin_status::update_coins(&client_config, &wallet_name).await?; + mercuryrustlib::broadcast_backup_tx::execute(&client_config, &wallet_name, &statechain_id, &to_address, fee_rate).await?; }, Commands::ListStatecoins { wallet_name } => { - coin_status::update_coins(&client_config, &wallet_name).await?; - let wallet: mercurylib::wallet::Wallet = get_wallet(&client_config.pool, &wallet_name).await?; + mercuryrustlib::coin_status::update_coins(&client_config, &wallet_name).await?; + let wallet = mercuryrustlib::sqlite_manager::get_wallet(&client_config.pool, &wallet_name).await?; let mut coins_json = Vec::new(); @@ -134,11 +119,11 @@ async fn main() -> Result<()> { println!("{}", coins_json_string); }, Commands::Withdraw { wallet_name, statechain_id, to_address, fee_rate } => { - coin_status::update_coins(&client_config, &wallet_name).await?; - withdraw::execute(&client_config, &wallet_name, &statechain_id, &to_address, fee_rate).await?; + mercuryrustlib::coin_status::update_coins(&client_config, &wallet_name).await?; + mercuryrustlib::withdraw::execute(&client_config, &wallet_name, &statechain_id, &to_address, fee_rate).await?; }, Commands::NewTransferAddress { wallet_name, generate_batch_id } => { - let address = transfer_receiver::new_transfer_address(&client_config, &wallet_name).await?; + let address = mercuryrustlib::transfer_receiver::new_transfer_address(&client_config, &wallet_name).await?; let mut obj = json!({"new_transfer_address:": address}); @@ -152,16 +137,16 @@ async fn main() -> Result<()> { println!("{}", serde_json::to_string_pretty(&obj).unwrap()); }, Commands::TransferSend { wallet_name, statechain_id, to_address, batch_id } => { - coin_status::update_coins(&client_config, &wallet_name).await?; - transfer_sender::execute(&client_config, &to_address, &wallet_name, &statechain_id, batch_id).await?; + mercuryrustlib::coin_status::update_coins(&client_config, &wallet_name).await?; + mercuryrustlib::transfer_sender::execute(&client_config, &to_address, &wallet_name, &statechain_id, batch_id).await?; let obj = json!({"Transfer": "sent"}); println!("{}", serde_json::to_string_pretty(&obj).unwrap()); }, Commands::TransferReceive { wallet_name } => { - coin_status::update_coins(&client_config, &wallet_name).await?; - let received_statechain_ids = transfer_receiver::execute(&client_config, &wallet_name).await?; + mercuryrustlib::coin_status::update_coins(&client_config, &wallet_name).await?; + let received_statechain_ids = mercuryrustlib::transfer_receiver::execute(&client_config, &wallet_name).await?; let obj = json!(received_statechain_ids); diff --git a/server/src/endpoints/transfer_sender.rs b/server/src/endpoints/transfer_sender.rs index be87ea79..d418710f 100644 --- a/server/src/endpoints/transfer_sender.rs +++ b/server/src/endpoints/transfer_sender.rs @@ -31,6 +31,9 @@ pub async fn validate_batch_transfer(statechain_entity: &State let (batch_id, batch_time) = batch_info.unwrap(); if !is_batch_expired(&statechain_entity, batch_time) { + + // TODO: check if the batch is complete. If complete, should return success. + // the batch time has not expired return BatchTransferValidationResult::StatecoinBatchLockedError("Statecoin batch locked (the batch time has not expired).".to_string()) } else {