mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
Add secp256k1 keypair type for btc
This commit is contained in:
@@ -415,24 +415,27 @@ impl Cashierd {
|
||||
#[cfg(feature = "btc")]
|
||||
NetworkName::Bitcoin => {
|
||||
debug!(target: "CASHIER DAEMON", "Add btc network");
|
||||
//use drk::service::btc::{BtcClient, BitcoinKeys};
|
||||
use drk::service::btc::{BtcClient, Keypair};
|
||||
|
||||
//let _btc_client = BtcClient::new("testnet")?;
|
||||
// NOTE bitcoin is not implemented yet
|
||||
//let _main_keypair: BitcoinKeys;
|
||||
let main_keypair: Keypair;
|
||||
|
||||
let _main_keypairs =
|
||||
self.cashier_wallet.get_main_keys(&NetworkName::Bitcoin)?;
|
||||
// if main_keypairs.is_empty() {
|
||||
// //main_keypair = BitcoinKeys::new(bitcoin::network::constants::Network::Testnet)?;
|
||||
// } else {
|
||||
// //main_keypair = deserialize(&main_keypairs[0].0)?;
|
||||
// }
|
||||
//
|
||||
// TODO check if there is main_keypair inside
|
||||
// cashierdb before generating new one
|
||||
//
|
||||
//bridge2.add_clients("btc".into(), btc_client).await?;
|
||||
let main_keypairs = self.cashier_wallet.get_main_keys(&NetworkName::Bitcoin)?;
|
||||
|
||||
if main_keypairs.is_empty() {
|
||||
main_keypair = Keypair::new();
|
||||
self.cashier_wallet.put_main_keys(
|
||||
&serialize(&main_keypair),
|
||||
&serialize(&main_keypair.pubkey()),
|
||||
&NetworkName::Bitcoin,
|
||||
)?;
|
||||
|
||||
} else {
|
||||
main_keypair = deserialize(&main_keypairs[0].0)?;
|
||||
}
|
||||
|
||||
let btc_client = BtcClient::new(serialize(&main_keypair), &chain).await?;
|
||||
|
||||
bridge2.add_clients(NetworkName::Bitcoin, btc_client).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use super::bridge::{NetworkClient, TokenNotification, TokenSubscribtion};
|
||||
use crate::serial::{serialize, Decodable, Encodable};
|
||||
use crate::serial::{serialize, deserialize, Decodable, Encodable};
|
||||
use crate::{Error, Result};
|
||||
|
||||
use std::convert::From;
|
||||
use async_trait::async_trait;
|
||||
use bitcoin::blockdata::script::Script;
|
||||
use bitcoin::hash_types::{PubkeyHash as BtcPubKeyHash, Txid};
|
||||
@@ -12,6 +12,7 @@ use electrum_client::{Client as ElectrumClient, ElectrumApi};
|
||||
use log::*;
|
||||
|
||||
use secp256k1::key::{PublicKey, SecretKey};
|
||||
use secp256k1::constants::{SECRET_KEY_SIZE, PUBLIC_KEY_SIZE};
|
||||
use secp256k1::{rand::rngs::OsRng, Secp256k1};
|
||||
|
||||
use async_std::sync::Arc;
|
||||
@@ -22,8 +23,47 @@ pub type PubAddress = Address;
|
||||
pub type PubKey = BtcPubKey;
|
||||
pub type PrivKey = BtcPrivKey;
|
||||
|
||||
const KEYPAIR_LENGTH: usize = SECRET_KEY_SIZE + PUBLIC_KEY_SIZE;
|
||||
|
||||
pub struct Keypair {
|
||||
secret: SecretKey,
|
||||
public: PublicKey,
|
||||
}
|
||||
impl Keypair {
|
||||
pub fn new() -> Self {
|
||||
let secp = Secp256k1::new();
|
||||
let mut rng = OsRng::new().expect("OsRng");
|
||||
|
||||
let (secret, public) = secp.generate_keypair(&mut rng);
|
||||
Self {
|
||||
secret,
|
||||
public,
|
||||
}
|
||||
}
|
||||
pub fn to_bytes(&self) -> [u8; KEYPAIR_LENGTH] {
|
||||
let mut bytes: [u8; KEYPAIR_LENGTH] = [0u8; KEYPAIR_LENGTH];
|
||||
|
||||
bytes[..SECRET_KEY_SIZE].copy_from_slice(self.secret.as_ref());
|
||||
bytes[SECRET_KEY_SIZE..].copy_from_slice(&self.public.serialize());
|
||||
bytes
|
||||
|
||||
}
|
||||
pub fn from_bytes<'a>(bytes: &'a [u8]) -> Result<Keypair> {
|
||||
if bytes.len() != KEYPAIR_LENGTH {
|
||||
return Err(Error::BtcFailed("Not right size".to_string()));
|
||||
}
|
||||
//TODO: Map to errors properly
|
||||
let secret = SecretKey::from_slice(&bytes[..SECRET_KEY_SIZE]).unwrap();
|
||||
let public = PublicKey::from_slice(&bytes[SECRET_KEY_SIZE..]).unwrap();
|
||||
|
||||
Ok(Keypair{ secret: secret, public: public })
|
||||
}
|
||||
pub fn pubkey(&self) -> PublicKey {
|
||||
self.public
|
||||
}
|
||||
}
|
||||
pub struct BitcoinKeys {
|
||||
secret_key: SecretKey,
|
||||
_secret_key: SecretKey,
|
||||
public_key: PublicKey,
|
||||
_context: Secp256k1<secp256k1::All>,
|
||||
btc_privkey: BtcPrivKey,
|
||||
@@ -42,7 +82,7 @@ impl BitcoinKeys {
|
||||
let btc_pubkey = btc_privkey.public_key(&secp);
|
||||
|
||||
Ok(Arc::new(BitcoinKeys {
|
||||
secret_key,
|
||||
_secret_key: secret_key,
|
||||
public_key,
|
||||
_context: secp,
|
||||
btc_privkey,
|
||||
@@ -74,11 +114,13 @@ impl BitcoinKeys {
|
||||
pub struct BtcClient {
|
||||
client: Arc<ElectrumClient>,
|
||||
network: Network,
|
||||
keypair: BitcoinKeys,
|
||||
keypair: Keypair,
|
||||
}
|
||||
|
||||
impl BtcClient {
|
||||
pub fn new(network: &str, keypair: BitcoinKeys) -> Result<Arc<Self>> {
|
||||
pub async fn new(keypair: Vec<u8>, network: &str) -> Result<Arc<Self>> {
|
||||
let keypair: Keypair = deserialize(&keypair)?;
|
||||
|
||||
let (network, url) = match network {
|
||||
"mainnet" => (Network::Bitcoin, "ssl://electrum.blockstream.info:50002"),
|
||||
"testnet" => (Network::Testnet, "ssl://electrum.blockstream.info:60002"),
|
||||
@@ -246,6 +288,40 @@ impl Decodable for bitcoin::PrivateKey {
|
||||
Ok(key)
|
||||
}
|
||||
}
|
||||
impl Encodable for secp256k1::key::PublicKey {
|
||||
fn encode<S: std::io::Write>(&self, s: S) -> Result<usize> {
|
||||
let key: Vec<u8> = self.serialize().to_vec();
|
||||
let len = key.encode(s)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
impl Decodable for secp256k1::key::PublicKey {
|
||||
fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
|
||||
let key: Vec<u8> = Decodable::decode(&mut d)?;
|
||||
let key = secp256k1::key::PublicKey::from_slice(&key)
|
||||
.map_err(|err| crate::Error::from(BtcFailed::from(err)))?;
|
||||
Ok(key)
|
||||
}
|
||||
}
|
||||
impl Encodable for Keypair {
|
||||
fn encode<S: std::io::Write>(&self, s: S) -> Result<usize> {
|
||||
let key: Vec<u8> = self.to_bytes().to_vec();
|
||||
let len = key.encode(s)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for Keypair {
|
||||
fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
|
||||
let key: Vec<u8> = Decodable::decode(&mut d)?;
|
||||
let key = Keypair::from_bytes(key.as_slice()).map_err(|_| {
|
||||
crate::Error::from(BtcFailed::DecodeAndEncodeError(
|
||||
"load keypair from slice".into(),
|
||||
))
|
||||
})?;
|
||||
Ok(key)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum BtcFailed {
|
||||
@@ -254,6 +330,7 @@ pub enum BtcFailed {
|
||||
ElectrumError(String),
|
||||
BtcError(String),
|
||||
DecodeAndEncodeError(String),
|
||||
KeypairError(String)
|
||||
}
|
||||
|
||||
impl std::error::Error for BtcFailed {}
|
||||
@@ -271,6 +348,9 @@ impl std::fmt::Display for BtcFailed {
|
||||
BtcFailed::DecodeAndEncodeError(ref err) => {
|
||||
write!(f, "Decode and decode keys error: {}", err)
|
||||
}
|
||||
BtcFailed::KeypairError(ref err) => {
|
||||
write!(f, "Keypair error from Secp256k1: {}", err)
|
||||
}
|
||||
BtcFailed::BtcError(i) => {
|
||||
write!(f, "BtcFailed: {}", i)
|
||||
}
|
||||
@@ -283,7 +363,11 @@ impl From<crate::error::Error> for BtcFailed {
|
||||
BtcFailed::BtcError(err.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<secp256k1::Error> for BtcFailed {
|
||||
fn from(err: secp256k1::Error) -> BtcFailed {
|
||||
BtcFailed::KeypairError(err.to_string())
|
||||
}
|
||||
}
|
||||
impl From<bitcoin::util::address::Error> for BtcFailed {
|
||||
fn from(err: bitcoin::util::address::Error) -> BtcFailed {
|
||||
BtcFailed::BadBtcAddress(err.to_string())
|
||||
|
||||
Reference in New Issue
Block a user