Skip to content
Merged
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
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ anyhow = { version = "1.0.100" }

tracing = { version = "0.1.41" }

contracts = { git = "https://github.com/BlockstreamResearch/simplicity-contracts.git", rev = "1a692a6", package = "contracts" }
cli-helper = { git = "https://github.com/BlockstreamResearch/simplicity-contracts.git", rev = "1a692a6", package = "cli" }
simplicityhl-core = { version = "0.3.4", features = ["encoding"] }
contracts = { git = "https://github.com/BlockstreamResearch/simplicity-contracts.git", rev = "61616fb", package = "contracts" }
cli-helper = { git = "https://github.com/BlockstreamResearch/simplicity-contracts.git", rev = "61616fb", package = "cli" }
simplicityhl-core = { version = "0.4.0", features = ["encoding"] }

simplicityhl = { version = "0.4.0" }

Expand Down
36 changes: 18 additions & 18 deletions crates/cli-client/src/cli/browse.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use crate::cli::Cli;
use crate::cli::interactive::{
SwapDisplay, TokenDisplay, format_relative_time, format_settlement_asset, truncate_with_ellipsis,
};
use crate::cli::tables::{display_swap_table, display_token_table};
use crate::cli::interactive::{TokenDisplay, format_relative_time, format_settlement_asset, truncate_with_ellipsis};
use crate::cli::option_offer::ActiveOptionOfferDisplay;
use crate::cli::tables::{display_active_option_offers_table, display_token_table};
use crate::config::Config;
use crate::error::Error;

use options_relay::{OptionCreatedEvent, SwapCreatedEvent};
use options_relay::{OptionCreatedEvent, OptionOfferCreatedEvent};
use simplicityhl::elements::AssetId;
use simplicityhl::elements::hex::ToHex;
use simplicityhl_core::LIQUID_TESTNET_BITCOIN_ASSET;
Expand All @@ -15,7 +14,7 @@ impl Cli {
pub(crate) async fn run_browse(&self, config: Config) -> Result<(), Error> {
let client = self.get_read_only_client(&config).await?;

println!("Browsing available options and swaps from NOSTR...");
println!("Browsing available options and option offers from NOSTR...");
println!();

let options_results = client.fetch_options(config.address_params()).await?;
Expand Down Expand Up @@ -47,32 +46,33 @@ impl Cli {

println!();

let swaps_results = client.fetch_swaps(config.address_params()).await?;
let valid_swaps: Vec<SwapCreatedEvent> = swaps_results.into_iter().filter_map(Result::ok).collect();
let offers_results = client.fetch_option_offers(config.address_params()).await?;
let valid_offers: Vec<OptionOfferCreatedEvent> = offers_results.into_iter().filter_map(Result::ok).collect();

println!("Available Swaps (from NOSTR):");
println!("-----------------------------");
println!("Available Option Offers (from NOSTR):");
println!("-------------------------------------");

if valid_swaps.is_empty() {
println!(" (No swaps found)");
if valid_offers.is_empty() {
println!(" (No option offers found)");
} else {
let swap_displays: Vec<SwapDisplay> = valid_swaps
let offer_displays: Vec<ActiveOptionOfferDisplay> = valid_offers
.iter()
.enumerate()
.map(|(idx, event)| {
let args = &event.swap_args;
SwapDisplay {
let args = &event.option_offer_args;
ActiveOptionOfferDisplay {
index: idx + 1,
offering: format_asset_amount(args.collateral_per_contract(), args.get_collateral_asset_id()),
price: args.collateral_per_contract().to_string(),
wants: format_settlement_asset(&args.get_settlement_asset_id()),
expires: format_relative_time(i64::from(args.expiry_time())),
seller: truncate_with_ellipsis(&event.pubkey.to_hex(), 12),
}
})
.collect();

display_swap_table(&swap_displays);
println!(" (Note: Actual availability shown in `swap take` after syncing)");
display_active_option_offers_table(&offer_displays);
println!(" (Note: Actual availability shown in `option-offer take` after syncing)");
}

client.disconnect().await;
Expand All @@ -81,7 +81,7 @@ impl Cli {
println!("To interact with these offers:");
println!(" 1. Run `sync nostr` to sync events to your local wallet");
println!(" 2. Run `sync spent` to update UTXO status from blockchain");
println!(" 3. Run `swap take` to take a swap offer");
println!(" 3. Run `option-offer take` to take an option offer");

Ok(())
}
Expand Down
53 changes: 31 additions & 22 deletions crates/cli-client/src/cli/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ pub enum Command {
command: OptionCommand,
},

/// Swap lifecycle (create, take, cancel, withdraw)
Swap {
/// Option Offer lifecycle (create, take, cancel, withdraw)
OptionOffer {
#[command(subcommand)]
command: SwapCommand,
command: OptionOfferCommand,
},

/// Fetch options/swaps from NOSTR, sync to coin-store, display
Expand Down Expand Up @@ -242,23 +242,32 @@ pub enum OptionCommand {
},
}

/// Swap lifecycle commands
/// Option Offer lifecycle commands
#[derive(Debug, Subcommand)]
pub enum SwapCommand {
/// Create a swap offer (offer Grantor Token for premium)
pub enum OptionOfferCommand {
/// Create an option offer (deposit collateral + premium for settlement)
Create {
/// Grantor token outpoint (interactive selection if not provided)
/// Collateral asset ID to deposit (interactive selection if not provided)
#[arg(long)]
grantor_token: Option<OutPoint>,
/// Premium asset ID (defaults to native LBTC)
collateral_asset: Option<AssetId>,
/// Amount of collateral to deposit (prompted if not provided)
#[arg(long)]
collateral_amount: Option<u64>,
/// Premium asset ID (interactive selection if not provided, excludes contract tokens)
#[arg(long)]
premium_asset: Option<AssetId>,
/// Premium amount
/// Total premium amount to deposit (used to calculate `premium_per_collateral`)
#[arg(long)]
premium_amount: Option<u64>,
/// Settlement asset ID (interactive selection if not provided, excludes contract tokens)
#[arg(long)]
premium_amount: u64,
/// Expiry time (defaults to same as option)
settlement_asset: Option<AssetId>,
/// Total settlement amount expected (used to calculate `collateral_per_contract`)
#[arg(long)]
expiry: Option<String>,
settlement_amount: Option<u64>,
/// Expiry time as Unix timestamp or duration (e.g., +30d)
#[arg(long)]
expiry: String,
/// Fee amount in satoshis (auto-estimated if not specified)
#[arg(long)]
fee: Option<u64>,
Expand All @@ -267,11 +276,11 @@ pub enum SwapCommand {
broadcast: bool,
},

/// Take a swap offer (atomic swap: premium for Grantor Token)
/// Take an option offer (pay settlement to receive collateral + premium)
Take {
/// Swap event ID from NOSTR (interactive selection if not provided)
/// Offer event ID from NOSTR (interactive selection if not provided)
#[arg(long)]
swap_event: Option<String>,
offer_event: Option<String>,
/// Fee amount in satoshis (auto-estimated if not specified)
#[arg(long)]
fee: Option<u64>,
Expand All @@ -280,11 +289,11 @@ pub enum SwapCommand {
broadcast: bool,
},

/// Cancel a swap offer after expiry (reclaim collateral if no one took it)
/// Cancel an option offer after expiry (reclaim collateral + premium)
Cancel {
/// Swap event ID from NOSTR (interactive selection if not provided)
/// Offer event ID from NOSTR (interactive selection if not provided)
#[arg(long)]
swap_event: Option<String>,
offer_event: Option<String>,
/// Fee amount in satoshis (auto-estimated if not specified)
#[arg(long)]
fee: Option<u64>,
Expand All @@ -293,11 +302,11 @@ pub enum SwapCommand {
broadcast: bool,
},

/// Withdraw settlement after swap was taken (claim your payment)
/// Withdraw settlement after offer was taken (claim your payment)
Withdraw {
/// Swap event ID from NOSTR (interactive selection if not provided)
/// Offer event ID from NOSTR (interactive selection if not provided)
#[arg(long)]
swap_event: Option<String>,
offer_event: Option<String>,
/// Fee amount in satoshis (auto-estimated if not specified)
#[arg(long)]
fee: Option<u64>,
Expand Down
Loading