mirror of
https://github.com/RoboSats/taptrade-core.git
synced 2025-07-23 11:13:17 +00:00
musig nonce and key derivation
This commit is contained in:
@ -3,7 +3,7 @@ use sha2::{Digest, Sha256};
|
|||||||
use std::env;
|
use std::env;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
|
||||||
use crate::wallet::{get_wallet_xprv, WalletDescriptors};
|
use crate::wallet::get_wallet_xprv;
|
||||||
use bdk::bitcoin::bip32::ExtendedPrivKey;
|
use bdk::bitcoin::bip32::ExtendedPrivKey;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -121,8 +121,8 @@ impl CliSettings {
|
|||||||
get_wallet_xprv(None)
|
get_wallet_xprv(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_from_env() -> Result<TraderSettings> {
|
fn load_from_env(filename: &str) -> Result<TraderSettings> {
|
||||||
dotenv::from_filename(".env")?;
|
dotenv::from_filename(filename)?;
|
||||||
Ok(TraderSettings {
|
Ok(TraderSettings {
|
||||||
electrum_endpoint: env::var("ELECTRUM_ENDPOINT")?,
|
electrum_endpoint: env::var("ELECTRUM_ENDPOINT")?,
|
||||||
coordinator_endpoint: env::var("COORDINATOR_ENDPOINT")?,
|
coordinator_endpoint: env::var("COORDINATOR_ENDPOINT")?,
|
||||||
@ -134,16 +134,20 @@ impl CliSettings {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_trader_settings(maybe_filename: &str) -> Result<TraderSettings> {
|
||||||
|
match Self::get_user_input("Load from .env (y/N): ").trim() {
|
||||||
|
"y" => Self::load_from_env(maybe_filename),
|
||||||
|
"N" => Self::get_trader_settings(),
|
||||||
|
_ => Err(anyhow!("Not a valid input!")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn parse_cli_args() -> Result<Self> {
|
pub fn parse_cli_args() -> Result<Self> {
|
||||||
let mode = Self::get_user_input("Enter mode, 'taker' or 'maker': ");
|
let mode = Self::get_user_input("Enter mode, 'taker' or 'maker': ");
|
||||||
let trader_settings = match Self::get_user_input("Load from .env (y/N): ").trim() {
|
|
||||||
"y" => Self::load_from_env()?,
|
|
||||||
"N" => Self::get_trader_settings()?,
|
|
||||||
_ => return Err(anyhow!("Not a valid input!")),
|
|
||||||
};
|
|
||||||
match mode.to_lowercase().as_str() {
|
match mode.to_lowercase().as_str() {
|
||||||
"maker" => Ok(Self::Maker(trader_settings)),
|
"maker" => Ok(Self::Maker(Self::parse_trader_settings("maker.env")?)),
|
||||||
"taker" => Ok(Self::Taker(trader_settings)),
|
"taker" => Ok(Self::Taker(Self::parse_trader_settings("taker.env")?)),
|
||||||
_ => Err(anyhow!("Either select maker or taker!")),
|
_ => Err(anyhow!("Either select maker or taker!")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
// use maker_utils;
|
|
||||||
// use taker_utils;
|
|
||||||
// mod utils;
|
|
||||||
|
|
||||||
use std::borrow::Borrow;
|
|
||||||
|
|
||||||
use crate::cli::TraderSettings;
|
use crate::cli::TraderSettings;
|
||||||
use crate::communication::api::OfferCreationResponse;
|
use crate::communication::api::OfferCreationResponse;
|
||||||
use crate::wallet::musig2::MusigNonce;
|
use crate::wallet::{
|
||||||
use crate::wallet::{bond::Bond, load_wallet};
|
bond::Bond,
|
||||||
|
load_wallet,
|
||||||
|
musig2::{MuSigData, MusigNonce},
|
||||||
|
};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use bdk::{
|
use bdk::{
|
||||||
bitcoin::block,
|
bitcoin::block,
|
||||||
@ -19,11 +16,12 @@ use bdk::{
|
|||||||
pub fn run_maker(maker_config: &TraderSettings) -> Result<()> {
|
pub fn run_maker(maker_config: &TraderSettings) -> Result<()> {
|
||||||
let blockchain = ElectrumBlockchain::from(Client::new(&maker_config.electrum_endpoint)?);
|
let blockchain = ElectrumBlockchain::from(Client::new(&maker_config.electrum_endpoint)?);
|
||||||
|
|
||||||
let offer_conditions = OfferCreationResponse::fetch(maker_config)?;
|
// let offer_conditions = OfferCreationResponse::fetch(maker_config)?;
|
||||||
// let offer_conditions = OfferCreationResponse { // hardcoded for testing, locking_address is owned by .env xprv
|
let offer_conditions = OfferCreationResponse {
|
||||||
// locking_amount: 90000,
|
// hardcoded for testing, locking_address is owned by .env xprv
|
||||||
// bond_address: "tb1pfdvgfzwp8vhmelpv8w9kezz7nsmxw68jz6yehgze6mzx0t6r9t2qv9ynmm".to_string(),
|
locking_amount: 90000,
|
||||||
// };
|
bond_address: "tb1pfdvgfzwp8vhmelpv8w9kezz7nsmxw68jz6yehgze6mzx0t6r9t2qv9ynmm".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
let wallet = load_wallet(maker_config, &blockchain)?; // initialize the wallet with xprv
|
let wallet = load_wallet(maker_config, &blockchain)?; // initialize the wallet with xprv
|
||||||
|
|
||||||
@ -31,10 +29,9 @@ pub fn run_maker(maker_config: &TraderSettings) -> Result<()> {
|
|||||||
// blockchain.broadcast(&bond.extract_tx())?; // publish bond to be mined for testing
|
// blockchain.broadcast(&bond.extract_tx())?; // publish bond to be mined for testing
|
||||||
let payout_pubkey = wallet.get_address(bdk::wallet::AddressIndex::LastUnused)?;
|
let payout_pubkey = wallet.get_address(bdk::wallet::AddressIndex::LastUnused)?;
|
||||||
|
|
||||||
let musig_nonce: MusigNonce = MusigNonce::generate()?; // will be moved to a more suitable place
|
let musig = MuSigData::create(&maker_config.wallet_xprv, wallet.secp_ctx())?;
|
||||||
|
|
||||||
dbg!(&bond.extract_tx().txid());
|
|
||||||
|
|
||||||
|
// dbg!(&bond.extract_tx().txid());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,10 +18,10 @@ use bdk::{
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use wallet_utils::get_seed;
|
use wallet_utils::get_seed;
|
||||||
|
|
||||||
pub struct WalletDescriptors {
|
// pub struct WalletDescriptors {
|
||||||
pub descriptor: Bip86<ExtendedPrivKey>,
|
// pub descriptor: Bip86<ExtendedPrivKey>,
|
||||||
pub change_descriptor: Option<Bip86<ExtendedPrivKey>>,
|
// pub change_descriptor: Option<Bip86<ExtendedPrivKey>>,
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn get_wallet_xprv(xprv_input: Option<String>) -> Result<ExtendedPrivKey> {
|
pub fn get_wallet_xprv(xprv_input: Option<String>) -> Result<ExtendedPrivKey> {
|
||||||
let xprv: ExtendedPrivKey;
|
let xprv: ExtendedPrivKey;
|
||||||
@ -52,6 +52,6 @@ pub fn load_wallet(
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
wallet.sync(blockchain, SyncOptions::default())?;
|
wallet.sync(blockchain, SyncOptions::default())?;
|
||||||
println!("Descriptor balance: {} SAT", wallet.get_balance()?);
|
println!("Balance: {} SAT", wallet.get_balance()?);
|
||||||
Ok(wallet)
|
Ok(wallet)
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,25 @@
|
|||||||
use crate::wallet::wallet_utils::get_seed;
|
use crate::wallet::bitcoin::key::{Parity, Secp256k1, XOnlyPublicKey};
|
||||||
|
use crate::wallet::{wallet_utils::get_seed, KeychainKind};
|
||||||
use anyhow::{anyhow, Error, Result};
|
use anyhow::{anyhow, Error, Result};
|
||||||
|
use bdk::{
|
||||||
|
bitcoin::{
|
||||||
|
bip32::ExtendedPrivKey,
|
||||||
|
secp256k1::{All, SecretKey},
|
||||||
|
},
|
||||||
|
keys::{DescriptorPublicKey, DescriptorSecretKey},
|
||||||
|
template::{Bip86, DescriptorTemplate},
|
||||||
|
};
|
||||||
use musig2::{PubNonce, SecNonce, SecNonceBuilder};
|
use musig2::{PubNonce, SecNonce, SecNonceBuilder};
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
// https://docs.rs/musig2/latest/musig2/
|
// https://docs.rs/musig2/latest/musig2/
|
||||||
|
|
||||||
|
pub struct MuSigData {
|
||||||
|
pub nonce: MusigNonce,
|
||||||
|
pub public_key: (XOnlyPublicKey, Parity),
|
||||||
|
pub secret_key: SecretKey,
|
||||||
|
}
|
||||||
|
|
||||||
// secret nonce has to be used only one time!
|
// secret nonce has to be used only one time!
|
||||||
pub struct MusigNonce {
|
pub struct MusigNonce {
|
||||||
secret_nonce: SecNonce,
|
secret_nonce: SecNonce,
|
||||||
@ -46,3 +61,16 @@ impl MusigNonce {
|
|||||||
Ok(self.secret_nonce.public_nonce())
|
Ok(self.secret_nonce.public_nonce())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl MuSigData {
|
||||||
|
pub fn create(xprv: &ExtendedPrivKey, secp_ctx: &Secp256k1<All>) -> Result<MuSigData> {
|
||||||
|
let nonce = MusigNonce::generate()?;
|
||||||
|
let keypair = xprv.to_owned().to_keypair(secp_ctx); // double check keypair, which derivation should we use?
|
||||||
|
|
||||||
|
Ok(MuSigData {
|
||||||
|
nonce,
|
||||||
|
public_key: keypair.x_only_public_key(),
|
||||||
|
secret_key: keypair.secret_key(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user