1pub type Hash = tendermint::hash::Hash;
5
6pub trait HashExt {
10 fn default_sha256() -> Hash;
14}
15
16impl HashExt for Hash {
17 fn default_sha256() -> Hash {
18 Hash::Sha256([
19 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f,
20 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b,
21 0x78, 0x52, 0xb8, 0x55,
22 ])
23 }
24}
25
26#[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))]
27pub use wbg::*;
28
29#[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))]
30mod wbg {
31 use super::Hash;
32 use js_sys::Uint8Array;
33 use tendermint::hash::{Algorithm, SHA256_HASH_SIZE};
34
35 pub struct JsHash {
37 hash: Option<Uint8Array>,
39 }
40
41 impl From<Hash> for JsHash {
42 fn from(value: Hash) -> Self {
43 match value {
44 Hash::None => JsHash { hash: None },
45 Hash::Sha256(digest) => {
46 let array = Uint8Array::new_with_length(
47 SHA256_HASH_SIZE.try_into().expect("valid hash size"),
48 );
49 array.copy_from(&digest);
50 JsHash { hash: Some(array) }
51 }
52 }
53 }
54 }
55
56 impl TryFrom<JsHash> for Hash {
57 type Error = tendermint::Error;
58
59 fn try_from(value: JsHash) -> Result<Self, Self::Error> {
60 let Some(digest) = value.hash else {
61 return Ok(Hash::None);
62 };
63
64 Hash::from_bytes(Algorithm::Sha256, &digest.to_vec())
65 }
66 }
67}
68
69#[cfg(feature = "uniffi")]
71pub mod uniffi_types {
72 use super::Hash as TendermintHash;
73 use tendermint::hash::Algorithm;
74 use tendermint::hash::AppHash as TendermintAppHash;
75
76 use uniffi::{Enum, Record};
77
78 use crate::error::UniffiConversionError;
79
80 #[derive(Enum)]
82 pub enum UniffiHash {
83 Sha256 {
85 hash: Vec<u8>,
87 },
88 None,
90 }
91
92 impl TryFrom<UniffiHash> for TendermintHash {
93 type Error = UniffiConversionError;
94
95 fn try_from(value: UniffiHash) -> Result<Self, Self::Error> {
96 Ok(match value {
97 UniffiHash::Sha256 { hash } => TendermintHash::from_bytes(Algorithm::Sha256, &hash)
98 .map_err(|_| UniffiConversionError::InvalidHashLength)?,
99 UniffiHash::None => TendermintHash::None,
100 })
101 }
102 }
103
104 impl From<TendermintHash> for UniffiHash {
105 fn from(value: TendermintHash) -> Self {
106 match value {
107 TendermintHash::Sha256(hash) => UniffiHash::Sha256 {
108 hash: hash.to_vec(),
109 },
110 TendermintHash::None => UniffiHash::None,
111 }
112 }
113 }
114
115 uniffi::custom_type!(TendermintHash, UniffiHash, {
116 remote,
117 try_lift: |value| Ok(value.try_into()?),
118 lower: |value| value.into()
119 });
120
121 #[derive(Record)]
123 pub struct AppHash {
124 pub hash: Vec<u8>,
126 }
127
128 impl TryFrom<AppHash> for TendermintAppHash {
129 type Error = UniffiConversionError;
130
131 fn try_from(value: AppHash) -> Result<Self, Self::Error> {
132 Ok(TendermintAppHash::try_from(value.hash).expect("conversion to be infallible"))
133 }
134 }
135
136 impl From<TendermintAppHash> for AppHash {
137 fn from(value: TendermintAppHash) -> Self {
138 AppHash {
139 hash: value.as_bytes().to_vec(),
140 }
141 }
142 }
143
144 uniffi::custom_type!(TendermintAppHash, AppHash, {
145 remote,
146 try_lift: |value| Ok(value.try_into()?),
147 lower: |value| value.into(),
148 });
149}