Add config file + bug fix
This commit is contained in:
parent
e5e7496611
commit
9f2c4ed2e1
6
.conf.model
Normal file
6
.conf.model
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
core_url=""
|
||||||
|
ws_url=""
|
||||||
|
wallet_name="default"
|
||||||
|
network="signet"
|
||||||
|
electrum_url="tcp://localhost:60601"
|
||||||
|
zmq_url=""
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
/target
|
/target
|
||||||
|
.conf
|
||||||
|
77
src/config.rs
Normal file
77
src/config.rs
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{self, BufRead};
|
||||||
|
|
||||||
|
use anyhow::{Error, Result};
|
||||||
|
|
||||||
|
use sdk_common::sp_client::bitcoin::Network;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Config {
|
||||||
|
pub core_url: String,
|
||||||
|
pub core_wallet: Option<String>,
|
||||||
|
pub ws_url: String,
|
||||||
|
pub wallet_name: String,
|
||||||
|
pub network: Network,
|
||||||
|
pub electrum_url: String,
|
||||||
|
pub zmq_url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
pub fn read_from_file(filename: &str) -> Result<Self> {
|
||||||
|
let mut file_content = HashMap::new();
|
||||||
|
if let Ok(file) = File::open(filename) {
|
||||||
|
let reader = io::BufReader::new(file);
|
||||||
|
|
||||||
|
// Read the file line by line
|
||||||
|
for line in reader.lines() {
|
||||||
|
if let Ok(l) = line {
|
||||||
|
// Ignore comments and empty lines
|
||||||
|
if l.starts_with('#') || l.trim().is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split the line into key and value
|
||||||
|
if let Some((k, v)) = l.split_once('=') {
|
||||||
|
file_content.insert(k.to_owned(), v.trim_matches('\"').to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(anyhow::Error::msg("Failed to find conf file"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now set the Config
|
||||||
|
let config = Config {
|
||||||
|
core_url: file_content
|
||||||
|
.remove("core_url")
|
||||||
|
.ok_or(Error::msg("No \"core_url\""))?
|
||||||
|
.to_owned(),
|
||||||
|
core_wallet: file_content.remove("core_wallet").map(|s| s.to_owned()),
|
||||||
|
ws_url: file_content
|
||||||
|
.remove("ws_url")
|
||||||
|
.ok_or(Error::msg("No \"ws_url\""))?
|
||||||
|
.to_owned(),
|
||||||
|
wallet_name: file_content
|
||||||
|
.remove("wallet_name")
|
||||||
|
.ok_or(Error::msg("No \"wallet_name\""))?
|
||||||
|
.to_owned(),
|
||||||
|
network: Network::from_core_arg(
|
||||||
|
&file_content
|
||||||
|
.remove("network")
|
||||||
|
.ok_or(Error::msg("no \"network\""))?
|
||||||
|
.trim_matches('\"'),
|
||||||
|
)?,
|
||||||
|
electrum_url: file_content
|
||||||
|
.remove("electrum_url")
|
||||||
|
.ok_or(Error::msg("No \"electrum_url\""))?
|
||||||
|
.to_owned(),
|
||||||
|
zmq_url: file_content
|
||||||
|
.remove("zmq_url")
|
||||||
|
.ok_or(Error::msg("No \"zmq_url\""))?
|
||||||
|
.to_owned(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(config)
|
||||||
|
}
|
||||||
|
}
|
@ -1,15 +1,14 @@
|
|||||||
use electrum_client::{Client, ConfigBuilder};
|
use electrum_client::{Client, ConfigBuilder};
|
||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
const ELECTRS_URI: &str = "ssl://silentpayments.dev:51002";
|
|
||||||
const VALIDATE_DOMAIN: bool = false; // self-signed cert, so we don't validate
|
const VALIDATE_DOMAIN: bool = false; // self-signed cert, so we don't validate
|
||||||
|
|
||||||
pub fn create_electrum_client() -> anyhow::Result<Client> {
|
pub fn create_electrum_client(electrum_url: String) -> anyhow::Result<Client> {
|
||||||
let config = ConfigBuilder::new()
|
let config = ConfigBuilder::new()
|
||||||
.validate_domain(VALIDATE_DOMAIN)
|
.validate_domain(VALIDATE_DOMAIN)
|
||||||
.build();
|
.build();
|
||||||
let electrum_client = Client::from_config(ELECTRS_URI, config)?;
|
let electrum_client = Client::from_config(&electrum_url, config)?;
|
||||||
info!("ssl client {}", ELECTRS_URI);
|
info!("ssl client {}", electrum_url);
|
||||||
|
|
||||||
Ok(electrum_client)
|
Ok(electrum_client)
|
||||||
}
|
}
|
||||||
|
65
src/main.rs
65
src/main.rs
@ -13,14 +13,13 @@ use std::{
|
|||||||
|
|
||||||
use bitcoincore_rpc::json::{self as bitcoin_json};
|
use bitcoincore_rpc::json::{self as bitcoin_json};
|
||||||
use futures_util::{future, pin_mut, stream::TryStreamExt, FutureExt, StreamExt};
|
use futures_util::{future, pin_mut, stream::TryStreamExt, FutureExt, StreamExt};
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, warn};
|
||||||
use scan::compute_partial_tweak_to_transaction;
|
use scan::compute_partial_tweak_to_transaction;
|
||||||
use sdk_common::sp_client::bitcoin::{
|
use sdk_common::sp_client::bitcoin::{
|
||||||
consensus::{deserialize, serialize},
|
consensus::deserialize,
|
||||||
hex::{DisplayHex, FromHex},
|
hex::{DisplayHex, FromHex},
|
||||||
Amount, Network, Transaction,
|
Amount, Network, Transaction,
|
||||||
};
|
};
|
||||||
use sdk_common::sp_client::silentpayments::utils::Network as SpNetwork;
|
|
||||||
use sdk_common::sp_client::{
|
use sdk_common::sp_client::{
|
||||||
bitcoin::secp256k1::rand::{thread_rng, Rng},
|
bitcoin::secp256k1::rand::{thread_rng, Rng},
|
||||||
spclient::SpWallet,
|
spclient::SpWallet,
|
||||||
@ -42,11 +41,13 @@ use tokio_tungstenite::tungstenite::Message;
|
|||||||
use anyhow::{Error, Result};
|
use anyhow::{Error, Result};
|
||||||
use zeromq::{Socket, SocketRecv};
|
use zeromq::{Socket, SocketRecv};
|
||||||
|
|
||||||
|
mod config;
|
||||||
mod daemon;
|
mod daemon;
|
||||||
mod electrumclient;
|
mod electrumclient;
|
||||||
mod faucet;
|
mod faucet;
|
||||||
mod scan;
|
mod scan;
|
||||||
|
|
||||||
|
use crate::config::Config;
|
||||||
use crate::faucet::handle_faucet_request;
|
use crate::faucet::handle_faucet_request;
|
||||||
use crate::{daemon::Daemon, scan::scan_blocks};
|
use crate::{daemon::Daemon, scan::scan_blocks};
|
||||||
|
|
||||||
@ -448,10 +449,10 @@ fn create_new_tx_message(transaction: Vec<u8>, daemon: Arc<Mutex<Daemon>>) -> Re
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_zmq(peers: PeerMap, shared_daemon: SharedDaemon) {
|
async fn handle_zmq(peers: PeerMap, shared_daemon: SharedDaemon, zmq_url: String) {
|
||||||
debug!("Starting listening on Core");
|
debug!("Starting listening on Core");
|
||||||
let mut socket = zeromq::SubSocket::new();
|
let mut socket = zeromq::SubSocket::new();
|
||||||
socket.connect("tcp://127.0.0.1:29100").await.unwrap();
|
socket.connect(&zmq_url).await.unwrap();
|
||||||
socket.subscribe("rawtx").await.unwrap();
|
socket.subscribe("rawtx").await.unwrap();
|
||||||
// socket.subscribe("hashblock");
|
// socket.subscribe("hashblock");
|
||||||
loop {
|
loop {
|
||||||
@ -466,7 +467,7 @@ async fn handle_zmq(peers: PeerMap, shared_daemon: SharedDaemon) {
|
|||||||
|
|
||||||
let payload: String = if let (Some(topic), Some(data)) = (core_msg.get(0), core_msg.get(1))
|
let payload: String = if let (Some(topic), Some(data)) = (core_msg.get(0), core_msg.get(1))
|
||||||
{
|
{
|
||||||
// debug!("topic: {}", std::str::from_utf8(&topic).unwrap());
|
debug!("topic: {}", std::str::from_utf8(&topic).unwrap());
|
||||||
match std::str::from_utf8(&topic) {
|
match std::str::from_utf8(&topic) {
|
||||||
Ok("rawtx") => match create_new_tx_message(data.to_vec(), shared_daemon.clone()) {
|
Ok("rawtx") => match create_new_tx_message(data.to_vec(), shared_daemon.clone()) {
|
||||||
Ok(m) => {
|
Ok(m) => {
|
||||||
@ -502,28 +503,9 @@ async fn handle_zmq(peers: PeerMap, shared_daemon: SharedDaemon) {
|
|||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
// This is rudimentary, if you change the network don't forget to change rpc_url either, we won't do that for you
|
let config = Config::read_from_file(".conf")?;
|
||||||
let rpc_url = env::args()
|
|
||||||
.nth(1)
|
|
||||||
.unwrap_or_else(|| "127.0.0.1:38332".to_owned());
|
|
||||||
let listening_addr = env::args()
|
|
||||||
.nth(2)
|
|
||||||
.unwrap_or_else(|| "127.0.0.1:8090".to_string());
|
|
||||||
let wallet_name = env::args().nth(3).unwrap_or_else(|| "default".to_owned());
|
|
||||||
let network_arg: String = env::args().nth(4).unwrap_or_else(|| "signet".to_owned());
|
|
||||||
let core_wallet: Option<String> = env::args().nth(5);
|
|
||||||
|
|
||||||
let network: Network = match network_arg.as_str() {
|
if config.network == Network::Bitcoin {
|
||||||
"main" => Network::Bitcoin,
|
|
||||||
"test" => Network::Testnet,
|
|
||||||
"signet" => Network::Testnet,
|
|
||||||
"regtest" => Network::Regtest,
|
|
||||||
_ => return Err(Error::msg("Invalid network")),
|
|
||||||
};
|
|
||||||
|
|
||||||
// let network = Network::from_core_arg(&network_arg)?;
|
|
||||||
|
|
||||||
if network == Network::Bitcoin {
|
|
||||||
warn!("Running on mainnet, you're on your own");
|
warn!("Running on mainnet, you're on your own");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -535,9 +517,9 @@ async fn main() -> Result<()> {
|
|||||||
|
|
||||||
// Connect the rpc daemon
|
// Connect the rpc daemon
|
||||||
let shared_daemon = Arc::new(Mutex::new(Daemon::connect(
|
let shared_daemon = Arc::new(Mutex::new(Daemon::connect(
|
||||||
core_wallet,
|
config.core_wallet,
|
||||||
rpc_url,
|
config.core_url,
|
||||||
Network::from_core_arg(&network_arg)?,
|
config.network,
|
||||||
)?));
|
)?));
|
||||||
|
|
||||||
let current_tip: u32 = shared_daemon
|
let current_tip: u32 = shared_daemon
|
||||||
@ -545,11 +527,12 @@ async fn main() -> Result<()> {
|
|||||||
.get_current_height()?
|
.get_current_height()?
|
||||||
.try_into()?;
|
.try_into()?;
|
||||||
|
|
||||||
let mut config_dir = PathBuf::from_str(&env::var("HOME")?)?;
|
let mut app_dir = PathBuf::from_str(&env::var("HOME")?)?;
|
||||||
config_dir.push(".4nk");
|
app_dir.push(".4nk");
|
||||||
config_dir.push(&wallet_name);
|
let mut wallet_file = app_dir.clone();
|
||||||
|
wallet_file.push(&config.wallet_name);
|
||||||
|
|
||||||
let wallet_file = WalletFile::new(config_dir);
|
let wallet_file = WalletFile::new(wallet_file);
|
||||||
|
|
||||||
// load an existing sp_wallet, or create a new one
|
// load an existing sp_wallet, or create a new one
|
||||||
let sp_wallet = match wallet_file.load() {
|
let sp_wallet = match wallet_file.load() {
|
||||||
@ -557,14 +540,14 @@ async fn main() -> Result<()> {
|
|||||||
wallet_file.create()?;
|
wallet_file.create()?;
|
||||||
let mut seed = [0u8; 64];
|
let mut seed = [0u8; 64];
|
||||||
thread_rng().fill(&mut seed);
|
thread_rng().fill(&mut seed);
|
||||||
let (scan_sk, spend_sk) =
|
let (scan_sk, spend_sk) = derive_keys_from_seed(&seed, config.network)
|
||||||
derive_keys_from_seed(&seed, network).expect("Couldn't generate a new sp_wallet");
|
.expect("Couldn't generate a new sp_wallet");
|
||||||
let new_client = SpClient::new(
|
let new_client = SpClient::new(
|
||||||
wallet_name,
|
config.wallet_name,
|
||||||
scan_sk,
|
scan_sk,
|
||||||
SpendKey::Secret(spend_sk),
|
SpendKey::Secret(spend_sk),
|
||||||
None,
|
None,
|
||||||
network,
|
config.network,
|
||||||
)
|
)
|
||||||
.expect("Failed to create a new SpClient");
|
.expect("Failed to create a new SpClient");
|
||||||
|
|
||||||
@ -610,16 +593,16 @@ async fn main() -> Result<()> {
|
|||||||
shared_daemon.clone(),
|
shared_daemon.clone(),
|
||||||
sp_wallet.clone(),
|
sp_wallet.clone(),
|
||||||
current_tip - last_scan,
|
current_tip - last_scan,
|
||||||
|
config.electrum_url,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subscribe to Bitcoin Core
|
// Subscribe to Bitcoin Core
|
||||||
tokio::spawn(handle_zmq(peers.clone(), shared_daemon.clone()));
|
tokio::spawn(handle_zmq(peers.clone(), shared_daemon.clone(), config.zmq_url));
|
||||||
|
|
||||||
// Create the event loop and TCP listener we'll accept connections on.
|
// Create the event loop and TCP listener we'll accept connections on.
|
||||||
let try_socket = TcpListener::bind(&listening_addr).await;
|
let try_socket = TcpListener::bind("127.0.0.1:9090").await;
|
||||||
let listener = try_socket.expect("Failed to bind");
|
let listener = try_socket.expect("Failed to bind");
|
||||||
debug!("Listening on: {}", listening_addr);
|
|
||||||
|
|
||||||
tokio::spawn(MessageCache::clean_up());
|
tokio::spawn(MessageCache::clean_up());
|
||||||
|
|
||||||
|
@ -220,9 +220,10 @@ pub fn scan_blocks(
|
|||||||
shared_daemon: SharedDaemon,
|
shared_daemon: SharedDaemon,
|
||||||
sp_wallet: Arc<SilentPaymentWallet>,
|
sp_wallet: Arc<SilentPaymentWallet>,
|
||||||
mut n_blocks_to_scan: u32,
|
mut n_blocks_to_scan: u32,
|
||||||
|
electrum_url: String,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
log::info!("Starting a rescan");
|
log::info!("Starting a rescan");
|
||||||
let electrum_client = electrumclient::create_electrum_client()?;
|
let electrum_client = electrumclient::create_electrum_client(electrum_url)?;
|
||||||
|
|
||||||
let core = shared_daemon.lock_anyhow()?;
|
let core = shared_daemon.lock_anyhow()?;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user