plutus_ledger_api/v1/
crypto.rs1use std::str::FromStr;
4
5use anyhow::anyhow;
6use cardano_serialization_lib as csl;
7#[cfg(feature = "lbf")]
8use lbr_prelude::json::{Error, Json};
9use nom::combinator::all_consuming;
10use nom::Finish;
11use nom::{combinator::map_res, error::VerboseError, IResult};
12#[cfg(feature = "serde")]
13use serde::{Deserialize, Serialize};
14#[cfg(feature = "serde")]
15use serde_with::{DeserializeFromStr, SerializeDisplay};
16
17use crate as plutus_ledger_api;
18use crate::error::ConversionError;
19use crate::{
20 csl::{
21 csl_to_pla::FromCSL,
22 pla_to_csl::{TryFromPLA, TryFromPLAError},
23 },
24 plutus_data::IsPlutusData,
25};
26
27#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)]
35#[is_plutus_data_derive_strategy = "Newtype"]
36#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
37#[cfg_attr(feature = "lbf", derive(Json))]
38pub struct Ed25519PubKeyHash(pub LedgerBytes);
39
40impl FromCSL<csl::Ed25519KeyHash> for Ed25519PubKeyHash {
41 fn from_csl(value: &csl::Ed25519KeyHash) -> Self {
42 Ed25519PubKeyHash(LedgerBytes(value.to_bytes()))
43 }
44}
45
46impl TryFromPLA<Ed25519PubKeyHash> for csl::Ed25519KeyHash {
47 fn try_from_pla(val: &Ed25519PubKeyHash) -> Result<Self, TryFromPLAError> {
48 csl::Ed25519KeyHash::from_bytes(val.0 .0.to_owned())
49 .map_err(TryFromPLAError::CSLDeserializeError)
50 }
51}
52
53impl FromCSL<csl::RequiredSigners> for Vec<Ed25519PubKeyHash> {
54 fn from_csl(value: &csl::RequiredSigners) -> Self {
55 (0..value.len())
56 .map(|idx| Ed25519PubKeyHash::from_csl(&value.get(idx)))
57 .collect()
58 }
59}
60
61#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)]
67#[is_plutus_data_derive_strategy = "Newtype"]
68#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
69#[cfg_attr(feature = "lbf", derive(Json))]
70pub struct PaymentPubKeyHash(pub Ed25519PubKeyHash);
71
72#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)]
78#[is_plutus_data_derive_strategy = "Newtype"]
79#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
80#[cfg_attr(feature = "lbf", derive(Json))]
81pub struct StakePubKeyHash(pub Ed25519PubKeyHash);
82
83#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, IsPlutusData)]
89#[is_plutus_data_derive_strategy = "Newtype"]
90#[cfg_attr(feature = "serde", derive(SerializeDisplay, DeserializeFromStr))]
91pub struct LedgerBytes(pub Vec<u8>);
92
93impl std::fmt::Debug for LedgerBytes {
94 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95 write!(f, "{}", hex::encode(&self.0))
96 }
97}
98
99impl std::fmt::Display for LedgerBytes {
100 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101 write!(f, "{}", hex::encode(&self.0))
102 }
103}
104
105impl FromStr for LedgerBytes {
106 type Err = ConversionError;
107
108 fn from_str(s: &str) -> Result<Self, Self::Err> {
109 all_consuming(ledger_bytes)(s)
110 .finish()
111 .map_err(|err| {
112 ConversionError::ParseError(anyhow!(
113 "Error while parsing CurrencySymbol '{}': {}",
114 s,
115 err
116 ))
117 })
118 .map(|(_, cs)| cs)
119 }
120}
121pub(crate) fn ledger_bytes(input: &str) -> IResult<&str, LedgerBytes, VerboseError<&str>> {
125 map_res(nom::character::complete::hex_digit0, |hex_bytes: &str| {
126 hex::decode(&hex_bytes.to_owned().to_ascii_lowercase().into_bytes()).map(LedgerBytes)
127 })(input)
128}
129
130#[cfg(feature = "lbf")]
131impl Json for LedgerBytes {
132 fn to_json(&self) -> serde_json::Value {
133 String::to_json(&hex::encode(&self.0))
134 }
135
136 fn from_json(value: &serde_json::Value) -> Result<Self, Error> {
137 let bytes = String::from_json(value).and_then(|str| {
138 hex::decode(&str.into_bytes()).map_err(|_| Error::UnexpectedJsonInvariant {
139 wanted: "base16 string".to_owned(),
140 got: "unexpected string".to_owned(),
141 parser: "Plutus.V1.Bytes".to_owned(),
142 })
143 })?;
144
145 Ok(Self(bytes))
146 }
147}