|
@@ -1,7 +1,8 @@
|
|
|
-use crate::serial::{Decodable, Encodable};
|
|
|
|
|
-use crate::Result;
|
|
|
|
|
use super::bridge::CoinClient;
|
|
use super::bridge::CoinClient;
|
|
|
|
|
+use crate::serial::{Decodable, Encodable, serialize};
|
|
|
|
|
+use crate::Result;
|
|
|
|
|
|
|
|
|
|
+use async_trait::async_trait;
|
|
|
use bitcoin::blockdata::script::Script;
|
|
use bitcoin::blockdata::script::Script;
|
|
|
use bitcoin::network::constants::Network;
|
|
use bitcoin::network::constants::Network;
|
|
|
use bitcoin::util::address::Address;
|
|
use bitcoin::util::address::Address;
|
|
@@ -11,7 +12,6 @@ use log::*;
|
|
|
use rand::distributions::Alphanumeric;
|
|
use rand::distributions::Alphanumeric;
|
|
|
use rand::{thread_rng, Rng};
|
|
use rand::{thread_rng, Rng};
|
|
|
use secp256k1::key::SecretKey;
|
|
use secp256k1::key::SecretKey;
|
|
|
-use async_trait::async_trait;
|
|
|
|
|
|
|
|
|
|
use async_std::sync::Arc;
|
|
use async_std::sync::Arc;
|
|
|
use std::str::FromStr;
|
|
use std::str::FromStr;
|
|
@@ -132,6 +132,48 @@ impl BitcoinKeys {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
+pub struct BtcClient {
|
|
|
|
|
+ client: Arc<ElectrumClient>,
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+impl BtcClient {
|
|
|
|
|
+ pub fn new(client_address: String) -> Result<Self> {
|
|
|
|
|
+ let client = ElectrumClient::new(&client_address)
|
|
|
|
|
+ .map_err(|err| crate::Error::from(super::BtcFailed::from(err)))?;
|
|
|
|
|
+ Ok(Self {
|
|
|
|
|
+ client: Arc::new(client),
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#[async_trait]
|
|
|
|
|
+impl CoinClient for BtcClient {
|
|
|
|
|
+ async fn watch(&self) -> Result<(Vec<u8>, Vec<u8>)> {
|
|
|
|
|
+ //// Generate bitcoin Address
|
|
|
|
|
+ let btc_keys = BitcoinKeys::new(self.client.clone())?;
|
|
|
|
|
+
|
|
|
|
|
+ let btc_pub = btc_keys.clone();
|
|
|
|
|
+ let btc_pub = btc_pub.get_pubkey();
|
|
|
|
|
+ let btc_priv = btc_keys.clone();
|
|
|
|
|
+ let btc_priv = btc_priv.get_privkey();
|
|
|
|
|
+
|
|
|
|
|
+ // let _ = btc_keys.start_subscribe().await?;
|
|
|
|
|
+
|
|
|
|
|
+ // start scheduler for checking balance
|
|
|
|
|
+ debug!(target: "BRIDGE BITCOIN", "Subscribing for deposit");
|
|
|
|
|
+ //let _script = btc_keys.get_script();
|
|
|
|
|
+ //
|
|
|
|
|
+
|
|
|
|
|
+ Ok((serialize(&btc_priv.to_bytes()), serialize(&btc_pub.to_bytes())))
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async fn send(&self, _address: Vec<u8>, _amount: u64) -> Result<()> {
|
|
|
|
|
+ // TODO
|
|
|
|
|
+ Ok(())
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
impl Encodable for bitcoin::Address {
|
|
impl Encodable for bitcoin::Address {
|
|
|
fn encode<S: std::io::Write>(&self, s: S) -> Result<usize> {
|
|
fn encode<S: std::io::Write>(&self, s: S) -> Result<usize> {
|
|
|
let addr = self.to_string();
|
|
let addr = self.to_string();
|
|
@@ -149,12 +191,48 @@ impl Decodable for bitcoin::Address {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+impl Encodable for bitcoin::PublicKey {
|
|
|
|
|
+ fn encode<S: std::io::Write>(&self, s: S) -> Result<usize> {
|
|
|
|
|
+ let key = self.to_bytes();
|
|
|
|
|
+ let len = key.encode(s)?;
|
|
|
|
|
+ Ok(len)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+impl Decodable for bitcoin::PublicKey {
|
|
|
|
|
+ fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
|
|
|
|
|
+ let key: Vec<u8> = Decodable::decode(&mut d)?;
|
|
|
|
|
+ let key = bitcoin::PublicKey::from_slice(&key)
|
|
|
|
|
+ .map_err(|err| crate::Error::from(BtcFailed::from(err)))?;
|
|
|
|
|
+ Ok(key)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+impl Encodable for bitcoin::PrivateKey {
|
|
|
|
|
+ fn encode<S: std::io::Write>(&self, s: S) -> Result<usize> {
|
|
|
|
|
+ let key = self.to_bytes();
|
|
|
|
|
+ let len = key.encode(s)?;
|
|
|
|
|
+ Ok(len)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+impl Decodable for bitcoin::PrivateKey {
|
|
|
|
|
+ fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
|
|
|
|
|
+ let key: Vec<u8> = Decodable::decode(&mut d)?;
|
|
|
|
|
+ let key = bitcoin::PrivateKey::from_slice(&key, Network::Testnet)
|
|
|
|
|
+ .map_err(|err| crate::Error::from(BtcFailed::from(err)))?;
|
|
|
|
|
+ Ok(key)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
#[derive(Debug)]
|
|
#[derive(Debug)]
|
|
|
pub enum BtcFailed {
|
|
pub enum BtcFailed {
|
|
|
NotEnoughValue(u64),
|
|
NotEnoughValue(u64),
|
|
|
BadBTCAddress(String),
|
|
BadBTCAddress(String),
|
|
|
ElectrumError(String),
|
|
ElectrumError(String),
|
|
|
BtcError(String),
|
|
BtcError(String),
|
|
|
|
|
+ DecodeAndEncodeError(String),
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
impl std::error::Error for BtcFailed {}
|
|
impl std::error::Error for BtcFailed {}
|
|
@@ -169,6 +247,7 @@ impl std::fmt::Display for BtcFailed {
|
|
|
write!(f, "Unable to create Electrum Client: {}", err)
|
|
write!(f, "Unable to create Electrum Client: {}", err)
|
|
|
}
|
|
}
|
|
|
BtcFailed::ElectrumError(ref err) => write!(f, "could not parse BTC address: {}", err),
|
|
BtcFailed::ElectrumError(ref err) => write!(f, "could not parse BTC address: {}", err),
|
|
|
|
|
+ BtcFailed::DecodeAndEncodeError(ref err) => write!(f, "Decode and decode keys error: {}", err),
|
|
|
BtcFailed::BtcError(i) => {
|
|
BtcFailed::BtcError(i) => {
|
|
|
write!(f, "BtcFailed: {}", i)
|
|
write!(f, "BtcFailed: {}", i)
|
|
|
}
|
|
}
|
|
@@ -177,46 +256,6 @@ impl std::fmt::Display for BtcFailed {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
-pub struct BtcClient {
|
|
|
|
|
- client: Arc<ElectrumClient>,
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-impl BtcClient {
|
|
|
|
|
- pub fn new(client_address: String) -> Result<Self> {
|
|
|
|
|
- let client = ElectrumClient::new(&client_address)
|
|
|
|
|
- .map_err(|err| crate::Error::from(super::BtcFailed::from(err)))?;
|
|
|
|
|
- Ok(Self {
|
|
|
|
|
- client: Arc::new(client),
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-#[async_trait]
|
|
|
|
|
-impl CoinClient for BtcClient {
|
|
|
|
|
- async fn watch(&self) -> Result<(Vec<u8>, Vec<u8>)> {
|
|
|
|
|
- //// Generate bitcoin Address
|
|
|
|
|
- let btc_keys = BitcoinKeys::new(self.client.clone())?;
|
|
|
|
|
-
|
|
|
|
|
- let btc_pub = btc_keys.clone();
|
|
|
|
|
- let btc_pub = btc_pub.get_pubkey();
|
|
|
|
|
- let btc_priv = btc_keys.clone();
|
|
|
|
|
- let btc_priv = btc_priv.get_privkey();
|
|
|
|
|
-
|
|
|
|
|
- // let _ = btc_keys.start_subscribe().await?;
|
|
|
|
|
-
|
|
|
|
|
- // start scheduler for checking balance
|
|
|
|
|
- debug!(target: "BRIDGE BITCOIN", "Subscribing for deposit");
|
|
|
|
|
- //let _script = btc_keys.get_script();
|
|
|
|
|
- //
|
|
|
|
|
-
|
|
|
|
|
- Ok((btc_priv.to_bytes(), btc_pub.to_bytes()))
|
|
|
|
|
- }
|
|
|
|
|
- async fn send(&self, _address: Vec<u8>, _amount: u64) -> Result<()> {
|
|
|
|
|
- // TODO
|
|
|
|
|
- Ok(())
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
impl From<crate::error::Error> for BtcFailed {
|
|
impl From<crate::error::Error> for BtcFailed {
|
|
|
fn from(err: crate::error::Error) -> BtcFailed {
|
|
fn from(err: crate::error::Error) -> BtcFailed {
|
|
|
BtcFailed::BtcError(err.to_string())
|
|
BtcFailed::BtcError(err.to_string())
|
|
@@ -234,6 +273,12 @@ impl From<electrum_client::Error> for BtcFailed {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+impl From<bitcoin::util::key::Error> for BtcFailed {
|
|
|
|
|
+ fn from(err: bitcoin::util::key::Error) -> BtcFailed {
|
|
|
|
|
+ BtcFailed::DecodeAndEncodeError(err.to_string())
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
pub type BtcResult<T> = std::result::Result<T, BtcFailed>;
|
|
pub type BtcResult<T> = std::result::Result<T, BtcFailed>;
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
#[cfg(test)]
|