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
2 changes: 1 addition & 1 deletion crates/cli/assets/example-run.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ cargo run -p cli -- basic transfer-native \
cargo run -p cli -- basic split-native \
--broadcast \
--fee-utxo a35f7fc317cf8cf2eec88b1046de046e8c7e186259bf54c01eb0ead391f1505b:4 \
--split-parts 2 \
--split-parts 5 \
--fee-amount 100
```

Expand Down
43 changes: 39 additions & 4 deletions crates/cli/src/commands/options.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use anyhow::Result;
use clap::Subcommand;
use contracts::options::build_witness::ExtraInputs;
use contracts::options::{OptionsArguments, finalize_options_transaction, get_options_program};
use contracts::sdk::taproot_pubkey_gen::{TaprootPubkeyGen, get_random_seed};
use std::str::FromStr;
Expand Down Expand Up @@ -75,6 +76,9 @@
/// Account index that will pay for transaction fees and that owns a tokens to send
#[arg(long = "account-index")]
account_index: u32,
/// Transaction id (hex) and output index (vout) of the LBTC UTXO used to pay fees
#[arg(long = "fee-utxo")]
fee_utxo: Option<OutPoint>,
/// Fee amount in satoshis (LBTC)
#[arg(long = "fee-amount")]
fee_amount: u64,
Expand Down Expand Up @@ -348,16 +352,17 @@
option_taproot_pubkey_gen,
collateral_amount,
account_index,
fee_utxo,
fee_amount,
broadcast,
} => {
let store = Store::load()?;
let keypair = derive_keypair(*account_index);
let blinder_keypair = derive_public_blinder_key();

Check warning on line 362 in crates/cli/src/commands/options.rs

View workflow job for this annotation

GitHub Actions / Format and Clippy

Diff in /home/runner/work/simplicity-contracts/simplicity-contracts/crates/cli/src/commands/options.rs

Check warning on line 362 in crates/cli/src/commands/options.rs

View workflow job for this annotation

GitHub Actions / Format and Clippy

Diff in /home/runner/work/simplicity-contracts/simplicity-contracts/crates/cli/src/commands/options.rs
let option_arguments: OptionsArguments =
store.get_arguments(option_taproot_pubkey_gen)?;

let taproot_pubkey_gen = TaprootPubkeyGen::build_from_str(
option_taproot_pubkey_gen,
&option_arguments,
Expand All @@ -365,9 +370,16 @@
&contracts::options::get_options_address,
)?;

let option_tx_out = fetch_utxo(*option_asset_utxo).await?;

Check warning on line 373 in crates/cli/src/commands/options.rs

View workflow job for this annotation

GitHub Actions / Format and Clippy

Diff in /home/runner/work/simplicity-contracts/simplicity-contracts/crates/cli/src/commands/options.rs

Check warning on line 373 in crates/cli/src/commands/options.rs

View workflow job for this annotation

GitHub Actions / Format and Clippy

Diff in /home/runner/work/simplicity-contracts/simplicity-contracts/crates/cli/src/commands/options.rs
let grantor_tx_out = fetch_utxo(*grantor_asset_utxo).await?;
let collateral_tx_out = fetch_utxo(*collateral_and_fee_utxo).await?;

let fee_utxo = if let Some(outpoint) = *fee_utxo {
let fee_tx_out = fetch_utxo(outpoint).await?;
Some(&(outpoint, fee_tx_out.clone()))
} else {
None
};

let option_tx_out_secrets =
option_tx_out.unblind(SECP256K1, blinder_keypair.secret_key())?;
Expand All @@ -387,16 +399,33 @@
grantor_tx_out_secrets,
),
(*collateral_and_fee_utxo, collateral_tx_out.clone()),
None,
fee_utxo,
&option_arguments,
*collateral_amount,
*fee_amount,
)?;

let tx = pst.extract_tx()?;
let extra_inputs = (|| {
// .ok() converts Result<T, E> to Option<T>
// ? on an Option returns None immediately if it is None
let final_option_tx_out_secrets = tx.output[0]
.unblind(SECP256K1, blinder_keypair.secret_key())
.ok()?;

let final_grantor_tx_out_secrets = tx.output[1]
.unblind(SECP256K1, blinder_keypair.secret_key())
.ok()?;

Some(ExtraInputs {
option_tx_out_secrets: final_option_tx_out_secrets,
grantor_tx_out_secrets: final_grantor_tx_out_secrets,
})
})();

Check warning on line 424 in crates/cli/src/commands/options.rs

View workflow job for this annotation

GitHub Actions / Format and Clippy

Diff in /home/runner/work/simplicity-contracts/simplicity-contracts/crates/cli/src/commands/options.rs

Check warning on line 424 in crates/cli/src/commands/options.rs

View workflow job for this annotation

GitHub Actions / Format and Clippy

Diff in /home/runner/work/simplicity-contracts/simplicity-contracts/crates/cli/src/commands/options.rs

let utxos = vec![
option_tx_out.clone(),
grantor_tx_out.clone(),
tx.output[0].clone(), // option_tx_out
tx.output[1].clone(), // grantor_tx_out
collateral_tx_out.clone(),
];

Expand All @@ -407,6 +436,7 @@
&utxos,
0,
option_branch,
extra_inputs.as_ref(),
&AddressParams::LIQUID_TESTNET,
*LIQUID_TESTNET_GENESIS,
)?;
Expand All @@ -418,6 +448,7 @@
&utxos,
1,
option_branch,
extra_inputs.as_ref(),
&AddressParams::LIQUID_TESTNET,
*LIQUID_TESTNET_GENESIS,
)?;
Expand Down Expand Up @@ -502,6 +533,7 @@
&utxos,
0,
option_branch,
None,
&AddressParams::LIQUID_TESTNET,
*LIQUID_TESTNET_GENESIS,
)?;
Expand Down Expand Up @@ -620,6 +652,7 @@
&utxos,
0,
option_branch,
None,
&AddressParams::LIQUID_TESTNET,
*LIQUID_TESTNET_GENESIS,
)?;
Expand Down Expand Up @@ -719,6 +752,7 @@
&utxos,
0,
option_branch,
None,
&AddressParams::LIQUID_TESTNET,
*LIQUID_TESTNET_GENESIS,
)?;
Expand Down Expand Up @@ -822,6 +856,7 @@
&utxos,
0,
option_branch,
None,
&AddressParams::LIQUID_TESTNET,
*LIQUID_TESTNET_GENESIS,
)?;
Expand Down
51 changes: 47 additions & 4 deletions crates/contracts/src/options/build_witness.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::collections::HashMap;

use simplicityhl::{
ResolvedType, WitnessValues, parse::ParseFromStr, str::WitnessName, types::TypeConstructible,
ResolvedType, WitnessValues, elements::TxOutSecrets, num::U256, parse::ParseFromStr,
str::WitnessName, types::TypeConstructible, value::UIntValue,
};

#[derive(Debug, Clone, Copy)]
Expand Down Expand Up @@ -32,12 +33,20 @@ pub enum OptionBranch {
},
}

pub struct ExtraInputs {
pub option_tx_out_secrets: TxOutSecrets,
pub grantor_tx_out_secrets: TxOutSecrets,
}

/// Build witness values for options program execution.
///
/// # Panics
/// Panics if type parsing fails (should never happen with valid constants).
#[must_use]
pub fn build_option_witness(branch: OptionBranch) -> WitnessValues {
pub fn build_option_witness(
branch: OptionBranch,
extra_inputs: Option<&ExtraInputs>,
) -> WitnessValues {
let single = ResolvedType::parse_from_str("u64").unwrap();
let quadruple = ResolvedType::parse_from_str("(bool, u64, u64, u64)").unwrap();
let triple = ResolvedType::parse_from_str("(bool, u64, u64)").unwrap();
Expand Down Expand Up @@ -90,8 +99,42 @@ pub fn build_option_witness(branch: OptionBranch) -> WitnessValues {
}
};

simplicityhl::WitnessValues::from(HashMap::from([(
let mut witness_map = HashMap::new();

witness_map.insert(
WitnessName::from_str_unchecked("PATH"),
simplicityhl::Value::parse_from_str(&branch_str, &path_type).unwrap(),
)]))
);

let (option_asset_blind, option_value_blind, grantor_asset_blind, grantor_value_blind) =
if let Some(inputs) = extra_inputs {
(
U256::from_byte_array(*inputs.option_tx_out_secrets.asset_bf.into_inner().as_ref()),
U256::from_byte_array(*inputs.option_tx_out_secrets.value_bf.into_inner().as_ref()),
U256::from_byte_array(
*inputs.grantor_tx_out_secrets.asset_bf.into_inner().as_ref(),
),
U256::from_byte_array(
*inputs.grantor_tx_out_secrets.value_bf.into_inner().as_ref(),
),
)
} else {
let zero = U256::from(0u64);
(zero, zero, zero, zero)
};

let mut insert_witness = |name: &str, val: U256| {
witness_map.insert(
WitnessName::from_str_unchecked(name),
simplicityhl::Value::from(UIntValue::U256(val)),
);
};

insert_witness("OPTION_ABF", option_asset_blind);
insert_witness("OPTION_VBF", option_value_blind);

insert_witness("GRANTOR_ABF", grantor_asset_blind);
insert_witness("GRANTOR_VBF", grantor_value_blind);

simplicityhl::WitnessValues::from(witness_map)
}
Loading
Loading