Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 61 additions & 14 deletions crates/dex-cli/src/cli/processor.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::cli::helper::HelperCommands;
use crate::cli::{DexCommands, MakerCommands, TakerCommands};
use crate::common::config::AggregatedConfig;
use crate::common::config::{AggregatedConfig, Seed};
use crate::common::{DEFAULT_CLIENT_TIMEOUT_SECS, InitOrderArgs, write_into_stdout};
use crate::contract_handlers;
use clap::{Parser, Subcommand};
Expand Down Expand Up @@ -30,6 +30,14 @@ pub struct Cli {
#[arg(short = 'c', long, default_value = DEFAULT_CONFIG_PATH, env = "DEX_NOSTR_CONFIG_PATH")]
pub(crate) nostr_config_path: PathBuf,

/// Hex-encoded 32-byte seed used to derive internal wallet keys
#[arg(short = 's', long, env = "DEX_SEED_HEX")]
pub(crate) seed_hex: Option<Seed>,

/// Expiration time for the maker order in seconds
#[arg(short = 'e', long)]
pub(crate) maker_expiration_time: Option<u64>,

/// Command to execute
#[command(subcommand)]
command: Command,
Expand Down Expand Up @@ -241,6 +249,7 @@ impl Cli {
fee_amount,
common_options,
} => Self::_process_maker_init_order(
cli_app_context,
MakerInitCliContext {
first_lbtc_utxo,
second_lbtc_utxo,
Expand Down Expand Up @@ -354,6 +363,7 @@ impl Cli {
}

fn _process_maker_init_order(
cli_app_context: &CliAppContext,
MakerInitCliContext {
first_lbtc_utxo,
second_lbtc_utxo,
Expand All @@ -368,7 +378,7 @@ impl Cli {
) -> crate::error::Result<String> {
use contract_handlers::maker_init::{Utxos, handle, process_args, save_args_to_cache};

let processed_args = process_args(account_index, init_order_args.into())?;
let processed_args = process_args(account_index, init_order_args.into(), &cli_app_context.agg_config)?;
let (tx_res, args_to_save) = handle(
processed_args,
Utxos {
Expand Down Expand Up @@ -406,7 +416,7 @@ impl Cli {

agg_config.check_nostr_keypair_existence()?;

let processed_args = process_args(account_index, dcd_taproot_pubkey_gen)?;
let processed_args = process_args(account_index, dcd_taproot_pubkey_gen, agg_config)?;
let event_to_publish = processed_args.extract_event();
let (tx_id, args_to_save) = handle(
processed_args,
Expand All @@ -420,7 +430,10 @@ impl Cli {
fee_amount,
is_offline,
)?;
let res = relay_processor.place_order(event_to_publish, tx_id).await?;
let expiration_time = agg_config.maker_expiration_time;
let res = relay_processor
.place_order(event_to_publish, tx_id, expiration_time)
.await?;
save_args_to_cache(&args_to_save)?;
Ok(format!("[Maker] Creating order, tx_id: {tx_id}, event_id: {res:#?}"))
}
Expand Down Expand Up @@ -451,6 +464,7 @@ impl Cli {
grantor_collateral_amount_to_burn,
maker_order_event_id,
relay_processor,
agg_config,
)
.await?;
let (tx_id, args_to_save) = handle(
Expand Down Expand Up @@ -498,6 +512,7 @@ impl Cli {
grantor_settlement_amount_to_burn,
maker_order_event_id,
relay_processor,
agg_config,
)
.await?;
let (tx_id, args_to_save) = handle(
Expand Down Expand Up @@ -551,6 +566,7 @@ impl Cli {
grantor_amount_to_burn,
maker_order_event_id,
relay_processor,
agg_config,
)
.await?;
let (tx_id, args_to_save) = handle(
Expand Down Expand Up @@ -598,6 +614,7 @@ impl Cli {
collateral_amount_to_deposit,
maker_order_event_id,
relay_processor,
agg_config,
)
.await?;
let (tx_id, args_to_save) = handle(
Expand Down Expand Up @@ -632,6 +649,7 @@ impl Cli {
filler_token_amount_to_return,
maker_order_event_id,
relay_processor,
agg_config,
)
.await?;
let (tx_id, args_to_save) = handle(
Expand Down Expand Up @@ -671,6 +689,7 @@ impl Cli {
oracle_signature,
maker_order_event_id,
relay_processor,
agg_config,
)
.await?;
let (tx_id, args_to_save) = handle(
Expand Down Expand Up @@ -704,7 +723,14 @@ impl Cli {
issue_amount,
fee_amount,
common_options,
} => Self::_process_helper_faucet(fee_utxo_outpoint, asset_name, issue_amount, fee_amount, common_options)?,
} => Self::_process_helper_faucet(
cli_app_context,
fee_utxo_outpoint,
asset_name,
issue_amount,
fee_amount,
common_options,
)?,
HelperCommands::MintTokens {
reissue_asset_outpoint,
fee_utxo_outpoint,
Expand All @@ -713,6 +739,7 @@ impl Cli {
fee_amount,
common_options,
} => Self::_process_helper_mint_tokens(
cli_app_context,
reissue_asset_outpoint,
fee_utxo_outpoint,
asset_name,
Expand All @@ -725,13 +752,20 @@ impl Cli {
fee_utxo,
fee_amount,
common_options,
} => Self::_process_helper_split_native_three(split_amount, fee_utxo, fee_amount, common_options)?,
HelperCommands::Address { account_index: index } => Self::_process_helper_address(index)?,
} => Self::_process_helper_split_native_three(
cli_app_context,
split_amount,
fee_utxo,
fee_amount,
common_options,
)?,
HelperCommands::Address { account_index: index } => Self::_process_helper_address(cli_app_context, index)?,
HelperCommands::OracleSignature {
price_at_current_block_height,
settlement_height,
oracle_account_index,
} => Self::_process_helper_oracle_signature(
cli_app_context,
price_at_current_block_height,
settlement_height,
oracle_account_index,
Expand Down Expand Up @@ -809,6 +843,7 @@ impl Cli {
}

fn _process_helper_faucet(
cli_app_context: &CliAppContext,
fee_utxo_outpoint: OutPoint,
asset_name: String,
issue_amount: u64,
Expand All @@ -825,11 +860,13 @@ impl Cli {
fee_amount,
issue_amount,
is_offline,
&cli_app_context.agg_config,
)?;
Ok("Asset creation -- done".to_string())
}

fn _process_helper_mint_tokens(
cli_app_context: &CliAppContext,
reissue_asset_outpoint: OutPoint,
fee_utxo_outpoint: OutPoint,
asset_name: String,
Expand All @@ -848,11 +885,13 @@ impl Cli {
reissue_amount,
fee_amount,
is_offline,
&cli_app_context.agg_config,
)?;
Ok("Asset minting -- done".to_string())
}

fn _process_helper_split_native_three(
cli_app_context: &CliAppContext,
split_amount: u64,
fee_utxo: OutPoint,
fee_amount: u64,
Expand All @@ -861,17 +900,24 @@ impl Cli {
is_offline,
}: CommonOrderOptions,
) -> crate::error::Result<String> {
let tx_res =
contract_handlers::split_utxo::handle(account_index, split_amount, fee_utxo, fee_amount, is_offline)?;
let tx_res = contract_handlers::split_utxo::handle(
account_index,
split_amount,
fee_utxo,
fee_amount,
is_offline,
&cli_app_context.agg_config,
)?;
Ok(format!("Split utxo result tx_id: {tx_res:?}"))
}

fn _process_helper_address(index: u32) -> crate::error::Result<String> {
let (x_only_pubkey, addr) = contract_handlers::address::handle(index)?;
fn _process_helper_address(cli_app_context: &CliAppContext, index: u32) -> crate::error::Result<String> {
let (x_only_pubkey, addr) = contract_handlers::address::handle(index, &cli_app_context.agg_config)?;
Ok(format!("X Only Public Key: '{x_only_pubkey}', P2PK Address: '{addr}'"))
}

fn _process_helper_oracle_signature(
cli_app_context: &CliAppContext,
price_at_current_block_height: u64,
settlement_height: u32,
oracle_account_index: Option<u32>,
Expand All @@ -880,6 +926,7 @@ impl Cli {
oracle_account_index,
price_at_current_block_height,
settlement_height,
&cli_app_context.agg_config,
)?;
Ok(format!(
"Oracle signature for msg: '{}', signature: '{}', pubkey used: '{}'",
Expand Down Expand Up @@ -912,7 +959,7 @@ impl Cli {
};

agg_config.check_nostr_keypair_existence()?;
let processed_args = process_args(account_index, maker_order_event_id, relay_processor).await?;
let processed_args = process_args(account_index, maker_order_event_id, relay_processor, agg_config).await?;
let (tx_id, args_to_save) = handle(
processed_args,
Utxos2 {
Expand Down Expand Up @@ -956,7 +1003,7 @@ impl Cli {
};

agg_config.check_nostr_keypair_existence()?;
let processed_args = process_args(account_index, maker_order_event_id, relay_processor).await?;
let processed_args = process_args(account_index, maker_order_event_id, relay_processor, agg_config).await?;
let (tx_id, args_to_save) = handle(
processed_args,
Utxos3 {
Expand Down Expand Up @@ -1002,7 +1049,7 @@ impl Cli {
};

agg_config.check_nostr_keypair_existence()?;
let processed_args = process_args(account_index, maker_order_event_id, relay_processor).await?;
let processed_args = process_args(account_index, maker_order_event_id, relay_processor, agg_config).await?;
let (tx_id, args_to_save) = handle(
processed_args,
Utxos4 {
Expand Down
77 changes: 71 additions & 6 deletions crates/dex-cli/src/common/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,19 @@ use serde::{Deserialize, Deserializer};
use crate::error::CliError;
use tracing::instrument;

/// `MAKER_EXPIRATION_TIME` = 31 days
const MAKER_EXPIRATION_TIME: u64 = 2_678_400;

#[derive(Debug, Clone)]
pub struct Seed(pub SeedInner);
pub type SeedInner = [u8; 32];

#[derive(Debug)]
pub struct AggregatedConfig {
pub nostr_keypair: Option<Keys>,
pub relays: Vec<RelayUrl>,
pub seed_hex: Seed,
pub maker_expiration_time: u64,
}

#[derive(Debug, Clone)]
Expand All @@ -32,6 +41,38 @@ impl<'de> Deserialize<'de> for KeysWrapper {
}
}

impl FromStr for Seed {
type Err = CliError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let bytes = hex::decode(s).map_err(|err| crate::error::CliError::FromHex(err, s.to_string()))?;
if bytes.len() != 32 {
return Err(CliError::InvalidSeedLength {
got: bytes.len(),
expected: 32,
});
}
let mut inner = [0u8; 32];
inner.copy_from_slice(&bytes);
Ok(Seed(inner))
}
}

impl<'de> Deserialize<'de> for Seed {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Seed::from_str(&s).map_err(serde::de::Error::custom)
}
}

impl From<Seed> for ValueKind {
fn from(val: Seed) -> Self {
ValueKind::String(hex::encode(val.0))
}
}

impl From<KeysWrapper> for ValueKind {
fn from(val: KeysWrapper) -> Self {
ValueKind::String(val.0.secret_key().to_secret_hex())
Expand All @@ -53,20 +94,26 @@ impl AggregatedConfig {
pub struct AggregatedConfigInner {
pub nostr_keypair: Option<KeysWrapper>,
pub relays: Option<Vec<RelayUrl>>,
pub seed_hex: Option<Seed>,
pub maker_expiration_time: u64,
}

let Cli {
nostr_key,
relays_list,
nostr_config_path,
seed_hex,
maker_expiration_time,
..
} = cli;

let mut config_builder = Config::builder().add_source(
File::from(nostr_config_path.clone())
.format(FileFormat::Toml)
.required(DEFAULT_CONFIG_PATH != nostr_config_path.to_string_lossy().as_ref()),
);
let mut config_builder = Config::builder()
.add_source(
File::from(nostr_config_path.clone())
.format(FileFormat::Toml)
.required(DEFAULT_CONFIG_PATH != nostr_config_path.to_string_lossy().as_ref()),
)
.set_default("maker_expiration_time", MAKER_EXPIRATION_TIME)?;

if let Some(nostr_key) = nostr_key {
tracing::debug!("Adding keypair value from CLI");
Expand All @@ -87,7 +134,19 @@ impl AggregatedConfig {
)?;
}

// TODO(Alex): add Liquid private key
if let Some(seed_hex) = seed_hex {
tracing::debug!("Adding SeedHex value from CLI");
config_builder = config_builder.set_override_option("seed_hex", Some(seed_hex.clone()))?;
}

if let Some(maker_expiration_time) = maker_expiration_time {
tracing::debug!(
"Adding expiration time from config, expiration_time: '{:?}'",
maker_expiration_time
);
config_builder =
config_builder.set_override_option("maker_expiration_time", Some(*maker_expiration_time))?;
}

let config = match config_builder.build()?.try_deserialize::<AggregatedConfigInner>() {
Ok(conf) => Ok(conf),
Expand All @@ -104,9 +163,15 @@ impl AggregatedConfig {
return Err(ConfigExtended("Relays configuration is empty..".to_string()));
}

let seed_hex = config
.seed_hex
.ok_or_else(|| ConfigExtended("No seed found in configuration and CLI".to_string()))?;

let aggregated_config = AggregatedConfig {
nostr_keypair: config.nostr_keypair.map(|x| x.0),
relays,
seed_hex,
maker_expiration_time: config.maker_expiration_time,
};

tracing::debug!("Config gathered: '{:?}'", aggregated_config);
Expand Down
Loading
Loading