hal_simplicity/actions/simplicity/
mod.rs1pub mod info;
2pub mod pset;
3pub mod sighash;
4
5pub use info::*;
6pub use sighash::*;
7
8use crate::simplicity::bitcoin::{Amount, Denomination};
9use crate::simplicity::elements::confidential;
10use crate::simplicity::elements::hex::FromHex as _;
11use crate::simplicity::jet::elements::ElementsUtxo;
12
13#[derive(Debug, thiserror::Error)]
14pub enum ParseElementsUtxoError {
15 #[error("invalid format: expected <scriptPubKey>:<asset>:<value>")]
16 InvalidFormat,
17
18 #[error("invalid scriptPubKey hex: {0}")]
19 ScriptPubKeyParsing(elements::hex::Error),
20
21 #[error("invalid asset hex: {0}")]
22 AssetHexParsing(elements::hashes::hex::HexToArrayError),
23
24 #[error("invalid asset commitment hex: {0}")]
25 AssetCommitmentHexParsing(elements::hex::Error),
26
27 #[error("invalid asset commitment: {0}")]
28 AssetCommitmentDecoding(elements::encode::Error),
29
30 #[error("invalid value commitment hex: {0}")]
31 ValueCommitmentHexParsing(elements::hex::Error),
32
33 #[error("invalid value commitment: {0}")]
34 ValueCommitmentDecoding(elements::encode::Error),
35}
36
37pub fn parse_elements_utxo(s: &str) -> Result<ElementsUtxo, ParseElementsUtxoError> {
38 let parts: Vec<&str> = s.split(':').collect();
39 if parts.len() != 3 {
40 return Err(ParseElementsUtxoError::InvalidFormat);
41 }
42 let script_pubkey: elements::Script =
44 parts[0].parse().map_err(ParseElementsUtxoError::ScriptPubKeyParsing)?;
45
46 let asset = if parts[1].len() == 64 {
48 let asset_id: elements::AssetId =
50 parts[1].parse().map_err(ParseElementsUtxoError::AssetHexParsing)?;
51 confidential::Asset::Explicit(asset_id)
52 } else {
53 let commitment_bytes =
55 Vec::from_hex(parts[1]).map_err(ParseElementsUtxoError::AssetCommitmentHexParsing)?;
56 elements::confidential::Asset::from_commitment(&commitment_bytes)
57 .map_err(ParseElementsUtxoError::AssetCommitmentDecoding)?
58 };
59
60 let value = if let Ok(btc_amount) = Amount::from_str_in(parts[2], Denomination::Bitcoin) {
62 elements::confidential::Value::Explicit(btc_amount.to_sat())
64 } else {
65 let commitment_bytes =
67 Vec::from_hex(parts[2]).map_err(ParseElementsUtxoError::ValueCommitmentHexParsing)?;
68 elements::confidential::Value::from_commitment(&commitment_bytes)
69 .map_err(ParseElementsUtxoError::ValueCommitmentDecoding)?
70 };
71
72 Ok(ElementsUtxo {
73 script_pubkey,
74 asset,
75 value,
76 })
77}