diff --git a/src/bin/cashierd.rs b/src/bin/cashierd.rs index 85bfeb770..f851fdf74 100644 --- a/src/bin/cashierd.rs +++ b/src/bin/cashierd.rs @@ -120,10 +120,11 @@ impl Cashierd { for (network, _) in features.iter() { let keypairs_to_watch = cashier_wallet.get_deposit_token_keys_by_network(&network)?; - for (private_key, public_key, _token_id, mint_address) in keypairs_to_watch { + for (drk_pub_key, private_key, public_key, _token_id, mint_address) in keypairs_to_watch + { let bridge = bridge.clone(); - let bridge_subscribtion = bridge.subscribe(Some(mint_address)).await; + let bridge_subscribtion = bridge.subscribe(drk_pub_key, Some(mint_address)).await; bridge_subscribtion .sender @@ -157,8 +158,7 @@ impl Cashierd { // send a request to bridge to send equivalent amount of // received drk coin to token publickey if let Some((addr, network, _token_id, mint_address)) = token { - - let bridge_subscribtion = bridge.subscribe(Some(mint_address)).await; + let bridge_subscribtion = bridge.subscribe(drk_pub_key, Some(mint_address)).await; bridge_subscribtion .sender @@ -175,7 +175,6 @@ impl Cashierd { if error_code == 0 { match res.payload { bridge::BridgeResponsePayload::Send => { - // TODO Send the received coins to the main address cashier_wallet.confirm_withdraw_key_record(&addr, &network)?; } _ => {} @@ -227,7 +226,7 @@ impl Cashierd { .get_deposit_token_keys_by_dkey_public(&drk_pub_key, &network)?; let bridge = self.bridge.clone(); - let bridge_subscribtion = bridge.subscribe(mint_address_opt).await; + let bridge_subscribtion = bridge.subscribe(drk_pub_key, mint_address_opt).await; if check.is_empty() { bridge_subscribtion @@ -458,31 +457,41 @@ impl Cashierd { let cashier_wallet = self.cashier_wallet.clone(); let bridge = self.bridge.clone(); - let listen_for_receiving_coins_task = smol::spawn(async move { + let listen_for_receiving_coins_task: smol::Task> = smol::spawn(async move { loop { Self::listen_for_receiving_coins( bridge.clone(), cashier_wallet.clone(), recv_coin.clone(), ) - .await - .expect(" listen for receiving coins"); + .await?; } }); let bridge2 = self.bridge.clone(); - let listen_for_notification_from_bridge_task = smol::spawn(async move { - loop { - if let Some(token_notification) = bridge2.clone().listen().await { - let token_notification = - token_notification.expect("listen for notification from bridge"); + let client2 = self.client.clone(); + let listen_for_notification_from_bridge_task: smol::Task> = smol::spawn( + async move { + loop { + if let Some(token_notification) = bridge2.clone().listen().await { + let token_notification = token_notification?; - debug!(target: "CASHIER DAEMON", "Notification from birdge: {:?}", token_notification); + debug!(target: "CASHIER DAEMON", "Notification from birdge: {:?}", token_notification); - // TODO should send drk coins + client2 + .lock() + .await + .send( + token_notification.drk_pub_key, + token_notification.received_balance, + token_notification.token_id, + true, + ) + .await?; + } } - } - }); + }, + ); let cfg = RpcServerConfig { socket_addr: self.config.rpc_listen_address.clone(), diff --git a/src/bin/darkfid.rs b/src/bin/darkfid.rs index e82125dad..440133fb2 100644 --- a/src/bin/darkfid.rs +++ b/src/bin/darkfid.rs @@ -17,9 +17,7 @@ use drk::{ rpcserver::{listen_and_serve, RequestHandler, RpcServerConfig}, }, serial::{deserialize, serialize}, - util::{ - expand_path, join_config_path, parse_network, parse_wrapped_token, search_id, - }, + util::{expand_path, join_config_path, parse_network, parse_wrapped_token, search_id}, wallet::WalletDb, Result, }; @@ -78,7 +76,8 @@ impl Darkfid { expand_path(&config.spend_params_path.clone())?, ), wallet.clone(), - ).await?; + ) + .await?; let client = Arc::new(Mutex::new(client)); @@ -334,10 +333,11 @@ impl Darkfid { let token_id = parse_wrapped_token(token)?; let address = bs58::decode(&address).into_vec()?; let address: jubjub::SubgroupPoint = deserialize(&address)?; + // TODO FIX THE AMOUNT self.client .lock() .await - .transfer(token_id, address, amount) + .transfer(token_id, address, amount as u64) .await?; Ok(()) } diff --git a/src/bin/sol-test.rs b/src/bin/sol-test similarity index 100% rename from src/bin/sol-test.rs rename to src/bin/sol-test diff --git a/src/client/client.rs b/src/client/client.rs index e0ed91de5..d6aba006a 100644 --- a/src/client/client.rs +++ b/src/client/client.rs @@ -112,14 +112,13 @@ impl Client { &mut self, asset_id: jubjub::Fr, pub_key: jubjub::SubgroupPoint, - // TODO: FIX THIS - amount: f64, + amount: u64, ) -> Result<()> { - if amount <= 0.0 { + if amount <= 0 { return Err(ClientFailed::InvalidAmount(amount as u64).into()); } - self.send(pub_key, amount as u64, asset_id, false).await?; + self.send(pub_key, amount, asset_id, false).await?; Ok(()) } @@ -150,7 +149,7 @@ impl Client { let mut outputs: Vec = vec![]; if clear_input { - let signature_secret = self.state.wallet.get_keypairs()?[0].private; + let signature_secret = self.main_keypair.private; let input = tx::TransactionBuilderClearInputInfo { value, asset_id, diff --git a/src/service/bridge.rs b/src/service/bridge.rs index d545807c9..4aef9d30c 100644 --- a/src/service/bridge.rs +++ b/src/service/bridge.rs @@ -50,8 +50,8 @@ pub struct TokenSubscribtion { #[derive(Debug)] pub struct TokenNotification { pub network: NetworkName, - pub asset_id: jubjub::Fr, - pub secret_key: Vec, + pub token_id: jubjub::Fr, + pub drk_pub_key: jubjub::SubgroupPoint, pub received_balance: u64, } @@ -93,12 +93,12 @@ impl Bridge { .map(|o| o.map_err(Error::from)) } - pub async fn subscribe(self: Arc, mint: Option) -> BridgeSubscribtion { + pub async fn subscribe(self: Arc, drk_pub_key: jubjub::SubgroupPoint, mint: Option) -> BridgeSubscribtion { debug!(target: "BRIDGE", "Start new subscription"); let (sender, req) = async_channel::unbounded(); let (rep, receiver) = async_channel::unbounded(); - smol::spawn(self.listen_for_new_subscription(req, rep, mint)).detach(); + smol::spawn(self.listen_for_new_subscription(req, rep, drk_pub_key, mint)).detach(); BridgeSubscribtion { sender, receiver } } @@ -107,6 +107,7 @@ impl Bridge { self: Arc, req: async_channel::Receiver, rep: async_channel::Sender, + drk_pub_key: jubjub::SubgroupPoint, mint: Option, ) -> Result<()> { debug!(target: "BRIDGE", "Listen for new subscription"); @@ -142,7 +143,7 @@ impl Bridge { BridgeRequestsPayload::Watch(val) => match val { Some((private_key, public_key)) => { let pub_key = client - .subscribe_with_keypair(private_key, public_key, mint_address) + .subscribe_with_keypair(private_key, public_key, drk_pub_key, mint_address) .await?; let res = BridgeResponse { error: BridgeResponseError::NoError, @@ -151,7 +152,7 @@ impl Bridge { rep.send(res).await?; } None => { - let sub = client.subscribe(mint_address).await?; + let sub = client.subscribe(drk_pub_key, mint_address).await?; let res = BridgeResponse { error: BridgeResponseError::NoError, payload: BridgeResponsePayload::Watch(sub.secret_key, sub.public_key), @@ -175,13 +176,14 @@ impl Bridge { #[async_trait] pub trait NetworkClient { - async fn subscribe(self: Arc, mint: Option) -> Result; + async fn subscribe(self: Arc, drk_pub_key: jubjub::SubgroupPoint, mint: Option) -> Result; // should check if the keypair in not already subscribed async fn subscribe_with_keypair( self: Arc, private_key: Vec, public_key: Vec, + drk_pub_key: jubjub::SubgroupPoint, mint: Option, ) -> Result; diff --git a/src/service/btc.rs b/src/service/btc.rs index 5431200c3..a8ea2119e 100644 --- a/src/service/btc.rs +++ b/src/service/btc.rs @@ -149,7 +149,11 @@ impl BtcClient { #[async_trait] impl NetworkClient for BtcClient { - async fn subscribe(self: Arc, _mint: Option) -> Result { + async fn subscribe( + self: Arc, + _drk_pub_key: jubjub::SubgroupPoint, + _mint: Option, + ) -> Result { // Generate bitcoin keys let btc_keys = BitcoinKeys::new(self.network)?; let btc_privkey = btc_keys.clone(); @@ -174,6 +178,7 @@ impl NetworkClient for BtcClient { self: Arc, _private_key: Vec, _public_key: Vec, + _drk_pub_key: jubjub::SubgroupPoint, _mint: Option, ) -> Result { // TODO this not implemented yet diff --git a/src/service/sol.rs b/src/service/sol.rs index abc574cb7..d62ea5811 100644 --- a/src/service/sol.rs +++ b/src/service/sol.rs @@ -24,10 +24,13 @@ use tungstenite::Message; use crate::rpc::{jsonrpc, jsonrpc::JsonResult, websockets}; use crate::serial::{deserialize, serialize, Decodable, Encodable}; +use crate::util::{generate_id, NetworkName}; use crate::{Error, Result}; use super::bridge::{NetworkClient, TokenNotification, TokenSubscribtion}; +pub const SOL_NATIVE_TOKEN_ID: &str = "So11111111111111111111111111111111111111112"; + #[derive(Serialize)] struct SubscribeParams { encoding: Value, @@ -85,6 +88,7 @@ impl SolClient { async fn handle_subscribe_request( self: Arc, keypair: Keypair, + drk_pub_key: jubjub::SubgroupPoint, mint: Option, ) -> SolResult<()> { debug!(target: "SOL BRIDGE", "handle_subscribe_request()"); @@ -200,11 +204,35 @@ impl SolClient { if mint.is_some() { let amnt = cur_balance - prev_balance; let ui_amnt = amnt / u64::pow(10, decimals as u32); + + self.notify_channel + .0 + .send(TokenNotification { + network: NetworkName::Solana, + token_id: generate_id(&mint.unwrap().to_string())?, + drk_pub_key, + received_balance: amnt, + }) + .await + .map_err(Error::from)?; + debug!(target: "SOL BRIDGE", "Received {} {:?} tokens", ui_amnt, mint.unwrap()); let _ = self.send_tok_to_main_wallet(&rpc, &mint.unwrap(), amnt, decimals, &keypair)?; } else { let amnt = cur_balance - prev_balance; let ui_amnt = lamports_to_sol(amnt); + + self.notify_channel + .0 + .send(TokenNotification { + network: NetworkName::Solana, + token_id: generate_id(SOL_NATIVE_TOKEN_ID)?, + drk_pub_key, + received_balance: amnt, + }) + .await + .map_err(Error::from)?; + debug!(target: "SOL BRIDGE", "Received {} SOL", ui_amnt); let _ = self.send_sol_to_main_wallet(&rpc, amnt, &keypair)?; } @@ -329,7 +357,11 @@ impl SolClient { #[async_trait] impl NetworkClient for SolClient { - async fn subscribe(self: Arc, mint_address: Option) -> Result { + async fn subscribe( + self: Arc, + drk_pub_key: jubjub::SubgroupPoint, + mint_address: Option, + ) -> Result { let keypair = Keypair::generate(&mut OsRng); let public_key = keypair.pubkey().to_string(); @@ -337,7 +369,7 @@ impl NetworkClient for SolClient { let mint = self.check_mint_address(mint_address)?; - smol::spawn(self.handle_subscribe_request(keypair, mint)).detach(); + smol::spawn(self.handle_subscribe_request(keypair, drk_pub_key, mint)).detach(); Ok(TokenSubscribtion { secret_key, @@ -350,6 +382,7 @@ impl NetworkClient for SolClient { self: Arc, private_key: Vec, _public_key: Vec, + drk_pub_key: jubjub::SubgroupPoint, mint_address: Option, ) -> Result { let keypair: Keypair = deserialize(&private_key)?; @@ -358,7 +391,7 @@ impl NetworkClient for SolClient { let mint = self.check_mint_address(mint_address)?; - smol::spawn(self.handle_subscribe_request(keypair, mint)).detach(); + smol::spawn(self.handle_subscribe_request(keypair, drk_pub_key, mint)).detach(); Ok(public_key) } diff --git a/src/wallet/cashierdb.rs b/src/wallet/cashierdb.rs index a0fcd9e1e..a97116705 100644 --- a/src/wallet/cashierdb.rs +++ b/src/wallet/cashierdb.rs @@ -305,11 +305,11 @@ impl CashierDb { Ok(keys) } - // return private key, public key, token_id, and mint_address as a tuple + // return drk_pub_key, private key, public key, token_id, and mint_address as a tuple pub fn get_deposit_token_keys_by_network( &self, network: &NetworkName, - ) -> Result, Vec, jubjub::Fr, String)>> { + ) -> Result, Vec, jubjub::Fr, String)>> { debug!(target: "CASHIERDB", "Check for existing dkey"); // open connection let conn = Connection::open(&self.path)?; @@ -320,25 +320,26 @@ impl CashierDb { let confirm = self.get_value_serialized(&false)?; let mut stmt = conn.prepare( - "SELECT token_key_private, token_key_public, token_id, mint_address + "SELECT d_pub_key, token_key_private, token_key_public, token_id, mint_address FROM deposit_keypairs WHERE network = :network AND confirm = :confirm ;", )?; let keys_iter = stmt .query_map(&[(":network", &network), (":confirm", &confirm)], |row| { - Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?)) + Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?, row.get(4)?)) })?; let mut keys = vec![]; for key in keys_iter { let key = key?; - let private_key = key.0; - let pub_key = key.1; - let token_id: jubjub::Fr = self.get_value_deserialized(key.2)?; - let mint_address: String = self.get_value_deserialized(key.3)?; - keys.push((private_key, pub_key, token_id, mint_address)); + let drk_pub_key: jubjub::SubgroupPoint = self.get_value_deserialized(key.0)?; + let private_key = key.1; + let pub_key = key.2; + let token_id: jubjub::Fr = self.get_value_deserialized(key.3)?; + let mint_address: String = self.get_value_deserialized(key.4)?; + keys.push((drk_pub_key, private_key, pub_key, token_id, mint_address)); } Ok(keys)