Skip to content

Commit 63d87b8

Browse files
ikripakaKyrylR
authored andcommitted
Added simplicity contracts support to the coin-store
1 parent 5bfaedd commit 63d87b8

22 files changed

Lines changed: 1437 additions & 655 deletions

File tree

Cargo.toml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ resolver = "3"
33
members = [
44
"crates/*"
55
]
6+
exclude = [
7+
"crates/cli-client"
8+
]
69

710
[workspace.package]
811
version = "0.1.0"
@@ -19,8 +22,8 @@ anyhow = { version = "1.0.100" }
1922

2023
tracing = { version = "0.1.41" }
2124

22-
contracts = { git = "https://github.com/BlockstreamResearch/simplicity-contracts.git", rev = "6a53bf7", package = "contracts" }
23-
cli-helper = { git = "https://github.com/BlockstreamResearch/simplicity-contracts.git", rev = "6a53bf7", package = "cli" }
24-
simplicityhl-core = { version = "0.3.0", features = ["encoding"] }
25+
contracts = { git = "https://github.com/BlockstreamResearch/simplicity-contracts.git", rev = "b3d1ae9", package = "contracts" }
26+
cli-helper = { git = "https://github.com/BlockstreamResearch/simplicity-contracts.git", rev = "b3d1ae9", package = "cli" }
27+
simplicityhl-core = { version = "0.3.1", features = ["encoding"] }
2528

2629
simplicityhl = { version = "0.4.0" }

crates/cli-client/Cargo.toml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ tracing = { workspace = true }
3737
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
3838

3939
serde = { version = "1", features = ["derive"] }
40-
toml = "0.8"
41-
hex = "0.4"
42-
dotenvy = "0.15"
43-
40+
toml = { version = "0.8" }
41+
hex = { version = "0.4" }
42+
dotenvy = { version = "0.15" }

crates/cli-client/src/cli/basic.rs

Lines changed: 468 additions & 34 deletions
Large diffs are not rendered by default.

crates/cli-client/src/cli/commands.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use clap::Subcommand;
2-
use simplicityhl::elements::OutPoint;
2+
use simplicityhl::elements::{Address, OutPoint};
33

44
#[derive(Debug, Subcommand)]
55
pub enum Command {
@@ -75,7 +75,7 @@ pub enum HelperCommand {
7575
/// Show wallet balance
7676
Balance,
7777

78-
/// List UTXOs
78+
/// List all UTXOs stored in wallet
7979
Utxos,
8080

8181
/// Import a UTXO into the wallet
@@ -96,7 +96,7 @@ pub enum BasicCommand {
9696
TransferNative {
9797
/// Recipient address
9898
#[arg(long)]
99-
to: String,
99+
to: Address,
100100
/// Amount to send in satoshis
101101
#[arg(long)]
102102
amount: u64,
@@ -128,7 +128,7 @@ pub enum BasicCommand {
128128
asset: String,
129129
/// Recipient address
130130
#[arg(long)]
131-
to: String,
131+
to: Address,
132132
/// Amount to send
133133
#[arg(long)]
134134
amount: u64,
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use crate::error::Error;
2+
use simplicityhl::elements::Transaction;
3+
use simplicityhl::elements::pset::serialize::Serialize;
4+
use simplicityhl::simplicity::hex::DisplayHex;
5+
6+
#[derive(Debug, Clone, Copy)]
7+
pub enum Broadcaster {
8+
Offline,
9+
Online,
10+
}
11+
12+
impl From<bool> for Broadcaster {
13+
fn from(b: bool) -> Self {
14+
if b { Broadcaster::Online } else { Broadcaster::Offline }
15+
}
16+
}
17+
18+
impl Broadcaster {
19+
pub async fn broadcast_tx(&self, tx: &Transaction) -> Result<(), Error> {
20+
match self {
21+
Broadcaster::Offline => {
22+
println!("{}", tx.serialize().to_lower_hex_string());
23+
}
24+
Broadcaster::Online => {
25+
cli_helper::explorer::broadcast_tx(tx).await?;
26+
let txid = tx.txid();
27+
println!("Broadcasted: {txid}");
28+
}
29+
}
30+
Ok(())
31+
}
32+
}

crates/cli-client/src/cli/helper.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use crate::cli::{Cli, HelperCommand};
22
use crate::config::Config;
33
use crate::error::Error;
44
use crate::wallet::Wallet;
5+
use coin_store::utxo_store::UtxoStore;
6+
use simplicityhl::elements::bitcoin::secp256k1;
57

68
impl Cli {
79
pub(crate) async fn run_helper(&self, config: Config, command: &HelperCommand) -> Result<(), Error> {
@@ -26,14 +28,14 @@ impl Cli {
2628
HelperCommand::Balance => {
2729
let wallet = self.get_wallet(&config).await?;
2830

29-
let filter = coin_store::Filter::new()
31+
let filter = coin_store::UtxoFilter::new()
3032
.script_pubkey(wallet.signer().p2pk_address(config.address_params())?.script_pubkey());
31-
let results = wallet.store().query(&[filter]).await?;
33+
let results = <_ as UtxoStore>::query_utxos(wallet.store(), &[filter]).await?;
3234

3335
let mut balances: std::collections::HashMap<simplicityhl::elements::AssetId, u64> =
3436
std::collections::HashMap::new();
3537

36-
if let Some(coin_store::QueryResult::Found(entries)) = results.into_iter().next() {
38+
if let Some(coin_store::UtxoQueryResult::Found(entries)) = results.into_iter().next() {
3739
for entry in entries {
3840
let (asset, value) = match entry {
3941
coin_store::UtxoEntry::Confidential { secrets, .. } => (secrets.asset, secrets.value),
@@ -59,10 +61,10 @@ impl Cli {
5961
HelperCommand::Utxos => {
6062
let wallet = self.get_wallet(&config).await?;
6163

62-
let filter = coin_store::Filter::new();
63-
let results = wallet.store().query(&[filter]).await?;
64+
let filter = coin_store::UtxoFilter::new();
65+
let results = wallet.store().query_utxos(&[filter]).await?;
6466

65-
if let Some(coin_store::QueryResult::Found(entries)) = results.into_iter().next() {
67+
if let Some(coin_store::UtxoQueryResult::Found(entries)) = results.into_iter().next() {
6668
for entry in &entries {
6769
let outpoint = entry.outpoint();
6870
let (asset, value) = match entry {
@@ -88,7 +90,7 @@ impl Cli {
8890

8991
let blinder = match blinding_key {
9092
Some(key_hex) => {
91-
let bytes: [u8; 32] = hex::decode(key_hex)
93+
let bytes: [u8; secp256k1::constants::SECRET_KEY_SIZE] = hex::decode(key_hex)
9294
.map_err(|e| Error::Config(format!("Invalid blinding key hex: {e}")))?
9395
.try_into()
9496
.map_err(|_| Error::Config("Blinding key must be 32 bytes".to_string()))?;

crates/cli-client/src/cli/maker.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
use crate::cli::{Cli, MakerCommand};
2+
use crate::config::Config;
3+
use crate::error::Error;
4+
5+
impl Cli {
6+
pub(crate) async fn run_maker(&self, config: Config, command: &MakerCommand) -> Result<(), Error> {
7+
match command {
8+
MakerCommand::Create => {}
9+
MakerCommand::Fund => {}
10+
MakerCommand::Exercise => {}
11+
MakerCommand::Cancel => {}
12+
MakerCommand::List => {}
13+
}
14+
15+
Ok(())
16+
}
17+
}

crates/cli-client/src/cli/mod.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
mod basic;
22
mod commands;
3+
mod common;
34
mod helper;
5+
mod maker;
6+
mod taker;
47

58
use std::path::PathBuf;
69

710
use clap::Parser;
811

912
use crate::config::{Config, default_config_path};
1013
use crate::error::Error;
14+
pub use commands::{BasicCommand, Command, HelperCommand, MakerCommand, TakerCommand};
15+
use signer::Signer;
1116

1217
use crate::wallet::Wallet;
13-
pub use commands::{BasicCommand, Command, HelperCommand, MakerCommand, TakerCommand};
1418

1519
#[derive(Debug, Parser)]
1620
#[command(name = "simplicity-dex")]
@@ -32,17 +36,21 @@ impl Cli {
3236
Config::load_or_default(&self.config)
3337
}
3438

35-
fn parse_seed(&self) -> Result<[u8; 32], Error> {
39+
fn parse_seed(&self) -> Result<[u8; Signer::SEED_LEN], Error> {
3640
let seed_hex = self
3741
.seed
3842
.as_ref()
3943
.ok_or_else(|| Error::Config("Seed is required. Use --seed or SIMPLICITY_DEX_SEED".to_string()))?;
4044

4145
let bytes = hex::decode(seed_hex).map_err(|e| Error::Config(format!("Invalid seed hex: {e}")))?;
4246

43-
bytes
44-
.try_into()
45-
.map_err(|_| Error::Config("Seed must be exactly 32 bytes (64 hex chars)".to_string()))
47+
bytes.try_into().map_err(|_| {
48+
Error::Config(format!(
49+
"Seed must be exactly {} bytes ({} hex chars)",
50+
Signer::SEED_LEN,
51+
Signer::SEED_LEN * 2
52+
))
53+
})
4654
}
4755

4856
async fn get_wallet(&self, config: &Config) -> Result<Wallet, Error> {
@@ -57,8 +65,8 @@ impl Cli {
5765

5866
match &self.command {
5967
Command::Basic { command } => self.run_basic(config, command).await,
60-
Command::Maker { command: _ } => todo!(),
61-
Command::Taker { command: _ } => todo!(),
68+
Command::Maker { command } => self.run_maker(config, command).await,
69+
Command::Taker { command } => self.run_taker(config, command).await,
6270
Command::Helper { command } => self.run_helper(config, command).await,
6371
Command::Config => {
6472
println!("{config:#?}");

crates/cli-client/src/cli/taker.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use crate::cli::{Cli, TakerCommand};
2+
use crate::config::Config;
3+
use crate::error::Error;
4+
5+
impl Cli {
6+
pub(crate) async fn run_taker(&self, config: Config, command: &TakerCommand) -> Result<(), Error> {
7+
match command {
8+
TakerCommand::Browse => {}
9+
TakerCommand::Take => {}
10+
TakerCommand::Claim => {}
11+
TakerCommand::List => {}
12+
}
13+
14+
Ok(())
15+
}
16+
}

crates/cli-client/src/error.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use simplicityhl::simplicity::hex::HexToArrayError;
2+
13
#[derive(thiserror::Error, Debug)]
24
pub enum Error {
35
#[error("Configuration error: {0}")]
@@ -29,4 +31,7 @@ pub enum Error {
2931

3032
#[error("Hex error: {0}")]
3133
Hex(#[from] hex::FromHexError),
34+
35+
#[error("Hex to array error: {0}")]
36+
HexToArray(#[from] HexToArrayError),
3237
}

0 commit comments

Comments
 (0)