1use std::fmt;
2
3use celestia_proto::cosmos::base::abci::v1beta1::AbciMessageLog;
4use serde::{Deserialize, Serialize};
5use serde_repr::Deserialize_repr;
6use serde_repr::Serialize_repr;
7use tendermint_proto::Protobuf;
8use tendermint_proto::google::protobuf::Any;
9use tendermint_proto::v0_38::abci::Event;
10#[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))]
11use wasm_bindgen::prelude::*;
12
13#[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))]
14use crate::any::JsAny;
15use crate::bail_validation;
16use crate::hash::Hash;
17#[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))]
18use crate::signature::JsSignature;
19use crate::state::bit_array::BitVector;
20#[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))]
21use crate::state::bit_array::JsBitVector;
22use crate::state::{Address, Coin};
23use crate::{Error, Height};
24
25pub use celestia_proto::cosmos::base::abci::v1beta1::TxResponse as RawTxResponse;
26pub use celestia_proto::cosmos::tx::v1beta1::AuthInfo as RawAuthInfo;
27pub use celestia_proto::cosmos::tx::v1beta1::Fee as RawFee;
28pub use celestia_proto::cosmos::tx::v1beta1::ModeInfo as RawModeInfo;
29pub use celestia_proto::cosmos::tx::v1beta1::SignerInfo as RawSignerInfo;
30pub use celestia_proto::cosmos::tx::v1beta1::Tx as RawTx;
31pub use celestia_proto::cosmos::tx::v1beta1::TxBody as RawTxBody;
32pub use celestia_proto::cosmos::tx::v1beta1::mode_info::Sum as RawSum;
33pub use celestia_proto::cosmos::tx::v1beta1::mode_info::{Multi, Single};
34
35pub type Signature = Vec<u8>;
36
37pub const BOND_DENOM: &str = "utia";
39
40#[derive(Debug, Clone)]
42#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
43#[cfg_attr(
44 all(target_arch = "wasm32", feature = "wasm-bindgen"),
45 wasm_bindgen(getter_with_clone)
46)]
47pub struct Tx {
48 pub body: TxBody,
50
51 pub auth_info: AuthInfo,
54
55 #[cfg_attr(
61 all(target_arch = "wasm32", feature = "wasm-bindgen"),
62 wasm_bindgen(skip)
63 )]
64 pub signatures: Vec<Signature>,
65}
66
67#[derive(Debug, Clone)]
69#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
70#[cfg_attr(
71 all(target_arch = "wasm32", feature = "wasm-bindgen"),
72 wasm_bindgen(getter_with_clone)
73)]
74pub struct TxBody {
75 #[cfg_attr(
84 all(target_arch = "wasm32", feature = "wasm-bindgen"),
85 wasm_bindgen(skip)
86 )]
87 pub messages: Vec<Any>,
88 pub memo: String,
90 #[cfg_attr(
93 all(target_arch = "wasm32", feature = "wasm-bindgen"),
94 wasm_bindgen(skip)
95 )]
96 pub timeout_height: Height,
97 #[cfg_attr(
101 all(target_arch = "wasm32", feature = "wasm-bindgen"),
102 wasm_bindgen(skip)
103 )]
104 pub extension_options: Vec<Any>,
105 #[cfg_attr(
109 all(target_arch = "wasm32", feature = "wasm-bindgen"),
110 wasm_bindgen(skip)
111 )]
112 pub non_critical_extension_options: Vec<Any>,
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize)]
117#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
118#[cfg_attr(
119 all(target_arch = "wasm32", feature = "wasm-bindgen"),
120 wasm_bindgen(getter_with_clone)
121)]
122pub struct TxResponse {
123 #[cfg_attr(
125 all(target_arch = "wasm32", feature = "wasm-bindgen"),
126 wasm_bindgen(skip)
127 )]
128 pub height: Height,
129
130 #[serde(with = "crate::serializers::hash")]
132 #[cfg_attr(
133 all(target_arch = "wasm32", feature = "wasm-bindgen"),
134 wasm_bindgen(skip)
135 )]
136 pub txhash: Hash,
137
138 pub codespace: String,
140
141 pub code: ErrorCode,
143
144 pub data: String,
146
147 pub raw_log: String,
150
151 pub logs: Vec<AbciMessageLog>,
153
154 pub info: String,
156
157 pub gas_wanted: i64,
159
160 pub gas_used: i64,
162
163 #[cfg_attr(
165 all(target_arch = "wasm32", feature = "wasm-bindgen"),
166 wasm_bindgen(skip)
167 )]
168 pub tx: Option<Any>,
169
170 pub timestamp: String,
174
175 #[cfg_attr(
180 all(target_arch = "wasm32", feature = "wasm-bindgen"),
181 wasm_bindgen(skip)
182 )]
183 pub events: Vec<Event>,
184}
185
186#[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))]
187#[wasm_bindgen]
188impl TxResponse {
189 #[wasm_bindgen(getter)]
191 pub fn height(&self) -> u64 {
192 self.height.value()
193 }
194
195 #[wasm_bindgen(getter)]
200 pub fn events(&self) -> Vec<JsEvent> {
201 self.events.iter().cloned().map(Into::into).collect()
202 }
203}
204
205#[derive(Debug, Clone)]
207#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
208#[cfg_attr(
209 all(target_arch = "wasm32", feature = "wasm-bindgen"),
210 wasm_bindgen(getter_with_clone)
211)]
212pub struct AuthInfo {
213 pub signer_infos: Vec<SignerInfo>,
219 pub fee: Fee,
225}
226
227#[derive(Debug, Clone, PartialEq)]
230#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
231#[cfg_attr(
232 all(target_arch = "wasm32", feature = "wasm-bindgen"),
233 wasm_bindgen(getter_with_clone)
234)]
235pub struct SignerInfo {
236 #[cfg_attr(
240 all(target_arch = "wasm32", feature = "wasm-bindgen"),
241 wasm_bindgen(skip)
242 )]
243 pub public_key: Option<Any>,
244 pub mode_info: ModeInfo,
247 pub sequence: u64,
251}
252
253#[derive(Debug, Clone, PartialEq)]
255#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
256#[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen"), wasm_bindgen)]
257pub struct ModeInfo {
258 #[cfg_attr(
261 all(target_arch = "wasm32", feature = "wasm-bindgen"),
262 wasm_bindgen(skip)
263 )]
264 pub sum: Sum,
265}
266
267#[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))]
268#[wasm_bindgen]
269impl ModeInfo {
270 pub fn signature_mode(&self) -> SignatureMode {
272 match self.sum {
273 Sum::Single { .. } => SignatureMode::Single,
274 Sum::Multi { .. } => SignatureMode::Multi,
275 }
276 }
277
278 #[wasm_bindgen(getter)]
282 pub fn mode(&self) -> Option<i32> {
283 match self.sum {
284 Sum::Single { mode } => Some(mode),
285 _ => None,
286 }
287 }
288
289 #[wasm_bindgen(getter)]
292 pub fn bitarray(&self) -> Option<JsBitVector> {
293 match &self.sum {
294 Sum::Multi { bitarray, .. } => Some(bitarray.clone().into()),
295 Sum::Single { .. } => None,
296 }
297 }
298
299 #[wasm_bindgen(getter)]
303 pub fn mode_infos(&self) -> Option<Vec<ModeInfo>> {
304 match &self.sum {
305 Sum::Multi { mode_infos, .. } => Some(mode_infos.clone()),
306 Sum::Single { .. } => None,
307 }
308 }
309}
310
311#[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))]
312#[wasm_bindgen]
313pub enum SignatureMode {
314 Single,
315 Multi,
316}
317
318#[derive(Debug, Clone, PartialEq)]
321#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
322pub enum Sum {
323 Single {
327 mode: i32,
329 },
330 Multi {
332 bitarray: BitVector,
334 mode_infos: Vec<ModeInfo>,
337 },
338}
339
340#[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))]
341#[wasm_bindgen]
342impl Tx {
343 #[wasm_bindgen(getter)]
346 pub fn signatures(&self) -> Vec<JsSignature> {
347 self.signatures
348 .iter()
349 .map(|s| JsSignature::from(&s[..]))
350 .collect()
351 }
352}
353
354#[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))]
355#[wasm_bindgen]
356impl TxBody {
357 pub fn messages(&self) -> Vec<JsAny> {
366 self.messages.iter().cloned().map(Into::into).collect()
367 }
368
369 #[wasm_bindgen(getter)]
372 pub fn timeout_height(&self) -> u64 {
373 self.timeout_height.value()
374 }
375
376 pub fn extension_options(&self) -> Vec<JsAny> {
380 self.extension_options
381 .iter()
382 .cloned()
383 .map(Into::into)
384 .collect()
385 }
386
387 pub fn non_critical_extension_options(&self) -> Vec<JsAny> {
391 self.non_critical_extension_options
392 .iter()
393 .cloned()
394 .map(Into::into)
395 .collect()
396 }
397}
398
399#[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))]
400#[wasm_bindgen]
401impl SignerInfo {
402 pub fn public_key(&self) -> Option<JsAny> {
406 self.public_key.clone().map(Into::into)
407 }
408}
409
410#[derive(Debug, Clone, PartialEq, Default)]
414#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
415#[cfg_attr(
416 all(target_arch = "wasm32", feature = "wasm-bindgen"),
417 wasm_bindgen(getter_with_clone)
418)]
419pub struct Fee {
420 pub amount: Vec<Coin>,
422 pub gas_limit: u64,
425 #[cfg_attr(
429 all(target_arch = "wasm32", feature = "wasm-bindgen"),
430 wasm_bindgen(skip)
431 )]
432 pub payer: Option<Address>,
433 #[cfg_attr(
437 all(target_arch = "wasm32", feature = "wasm-bindgen"),
438 wasm_bindgen(skip)
439 )]
440 pub granter: Option<Address>,
441}
442
443impl Fee {
444 pub fn new(utia_fee: u64, gas_limit: u64) -> Self {
448 Fee {
449 amount: vec![Coin::utia(utia_fee)],
450 gas_limit,
451 ..Default::default()
452 }
453 }
454}
455
456#[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))]
457#[wasm_bindgen]
458impl Fee {
459 #[wasm_bindgen(getter)]
463 pub fn payer(&self) -> Option<String> {
464 self.payer.as_ref().map(|a| a.to_string())
465 }
466 #[wasm_bindgen(getter)]
470 pub fn granter(&self) -> Option<String> {
471 self.granter.as_ref().map(|a| a.to_string())
472 }
473}
474
475#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize_repr, Deserialize_repr)]
477#[repr(u32)]
478#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
479#[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen"), wasm_bindgen)]
480pub enum ErrorCode {
481 Success = 0,
484 TxDecode = 2,
486 InvalidSequence = 3,
488 Unauthorized = 4,
490 InsufficientFunds = 5,
492 UnknownRequest = 6,
494 InvalidAddress = 7,
496 InvalidPubKey = 8,
498 UnknownAddress = 9,
500 InvalidCoins = 10,
502 OutOfGas = 11,
504 MemoTooLarge = 12,
506 InsufficientFee = 13,
508 TooManySignatures = 14,
510 NoSignatures = 15,
512 JSONMarshal = 16,
514 JSONUnmarshal = 17,
516 InvalidRequest = 18,
518 TxInMempoolCache = 19,
520 MempoolIsFull = 20,
522 TxTooLarge = 21,
524 KeyNotFound = 22,
526 WrongPassword = 23,
528 InvalidSigner = 24,
530 InvalidGasAdjustment = 25,
532 InvalidHeight = 26,
534 InvalidVersion = 27,
536 InvalidChainID = 28,
538 InvalidType = 29,
540 TxTimeoutHeight = 30,
542 UnknownExtensionOptions = 31,
544 WrongSequence = 32,
546 PackAny = 33,
548 UnpackAny = 34,
550 Logic = 35,
552 Conflict = 36,
554 NotSupported = 37,
556 NotFound = 38,
558 IO = 39,
560 AppConfig = 40,
562 InvalidGasLimit = 41,
564 Panic = 111222,
566
567 ReservedNamespace = 11110,
570 InvalidNamespaceLen = 11111,
572 InvalidDataSize = 11112,
574 BlobSizeMismatch = 11113,
576 CommittedSquareSizeNotPowOf2 = 11114,
578 CalculateCommitment = 11115,
580 InvalidShareCommitment = 11116,
582 ParitySharesNamespace = 11117,
584 TailPaddingNamespace = 11118,
586 TxNamespace = 11119,
588 InvalidShareCommitments = 11122,
590 UnsupportedShareVersion = 11123,
592 ZeroBlobSize = 11124,
594 MismatchedNumberOfPFBorBlob = 11125,
596 NoPFB = 11126,
598 NamespaceMismatch = 11127,
600 ProtoParsing = 11128,
602 MultipleMsgsInBlobTx = 11129,
604 MismatchedNumberOfPFBComponent = 11130,
606 NoBlobs = 11131,
608 NoNamespaces = 11132,
610 NoShareVersions = 11133,
612 NoBlobSizes = 11134,
614 NoShareCommitments = 11135,
616 InvalidNamespace = 11136,
618 InvalidNamespaceVersion = 11137,
620 TotalBlobSizeTooLarge = 11138,
624 BlobsTooLarge = 11139,
626 InvalidBlobSigner = 11140,
628}
629
630impl fmt::Display for ErrorCode {
631 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
632 write!(f, "{self:?}")
633 }
634}
635
636impl TryFrom<u32> for ErrorCode {
637 type Error = Error;
638
639 fn try_from(value: u32) -> Result<ErrorCode, Self::Error> {
640 let error_code = match value {
641 0 => ErrorCode::Success,
643 2 => ErrorCode::TxDecode,
644 3 => ErrorCode::InvalidSequence,
645 4 => ErrorCode::Unauthorized,
646 5 => ErrorCode::InsufficientFunds,
647 6 => ErrorCode::UnknownRequest,
648 7 => ErrorCode::InvalidAddress,
649 8 => ErrorCode::InvalidPubKey,
650 9 => ErrorCode::UnknownAddress,
651 10 => ErrorCode::InvalidCoins,
652 11 => ErrorCode::OutOfGas,
653 12 => ErrorCode::MemoTooLarge,
654 13 => ErrorCode::InsufficientFee,
655 14 => ErrorCode::TooManySignatures,
656 15 => ErrorCode::NoSignatures,
657 16 => ErrorCode::JSONMarshal,
658 17 => ErrorCode::JSONUnmarshal,
659 18 => ErrorCode::InvalidRequest,
660 19 => ErrorCode::TxInMempoolCache,
661 20 => ErrorCode::MempoolIsFull,
662 21 => ErrorCode::TxTooLarge,
663 22 => ErrorCode::KeyNotFound,
664 23 => ErrorCode::WrongPassword,
665 24 => ErrorCode::InvalidSigner,
666 25 => ErrorCode::InvalidGasAdjustment,
667 26 => ErrorCode::InvalidHeight,
668 27 => ErrorCode::InvalidVersion,
669 28 => ErrorCode::InvalidChainID,
670 29 => ErrorCode::InvalidType,
671 30 => ErrorCode::TxTimeoutHeight,
672 31 => ErrorCode::UnknownExtensionOptions,
673 32 => ErrorCode::WrongSequence,
674 33 => ErrorCode::PackAny,
675 34 => ErrorCode::UnpackAny,
676 35 => ErrorCode::Logic,
677 36 => ErrorCode::Conflict,
678 37 => ErrorCode::NotSupported,
679 38 => ErrorCode::NotFound,
680 39 => ErrorCode::IO,
681 40 => ErrorCode::AppConfig,
682 41 => ErrorCode::InvalidGasLimit,
683 111222 => ErrorCode::Panic,
684 11110 => ErrorCode::ReservedNamespace,
686 11111 => ErrorCode::InvalidNamespaceLen,
687 11112 => ErrorCode::InvalidDataSize,
688 11113 => ErrorCode::BlobSizeMismatch,
689 11114 => ErrorCode::CommittedSquareSizeNotPowOf2,
690 11115 => ErrorCode::CalculateCommitment,
691 11116 => ErrorCode::InvalidShareCommitment,
692 11117 => ErrorCode::ParitySharesNamespace,
693 11118 => ErrorCode::TailPaddingNamespace,
694 11119 => ErrorCode::TxNamespace,
695 11122 => ErrorCode::InvalidShareCommitments,
696 11123 => ErrorCode::UnsupportedShareVersion,
697 11124 => ErrorCode::ZeroBlobSize,
698 11125 => ErrorCode::MismatchedNumberOfPFBorBlob,
699 11126 => ErrorCode::NoPFB,
700 11127 => ErrorCode::NamespaceMismatch,
701 11128 => ErrorCode::ProtoParsing,
702 11129 => ErrorCode::MultipleMsgsInBlobTx,
703 11130 => ErrorCode::MismatchedNumberOfPFBComponent,
704 11131 => ErrorCode::NoBlobs,
705 11132 => ErrorCode::NoNamespaces,
706 11133 => ErrorCode::NoShareVersions,
707 11134 => ErrorCode::NoBlobSizes,
708 11135 => ErrorCode::NoShareCommitments,
709 11136 => ErrorCode::InvalidNamespace,
710 11137 => ErrorCode::InvalidNamespaceVersion,
711 11138 => ErrorCode::TotalBlobSizeTooLarge,
712 11139 => ErrorCode::BlobsTooLarge,
713 11140 => ErrorCode::InvalidBlobSigner,
714 _ => bail_validation!("error code ({}) unknown", value),
715 };
716 Ok(error_code)
717 }
718}
719
720impl TryFrom<RawTxBody> for TxBody {
721 type Error = Error;
722
723 fn try_from(value: RawTxBody) -> Result<Self, Self::Error> {
724 Ok(TxBody {
725 messages: value.messages,
726 memo: value.memo,
727 timeout_height: value.timeout_height.try_into()?,
728 extension_options: value.extension_options,
729 non_critical_extension_options: value.non_critical_extension_options,
730 })
731 }
732}
733
734impl From<TxBody> for RawTxBody {
735 fn from(value: TxBody) -> Self {
736 RawTxBody {
737 messages: value.messages,
738 memo: value.memo,
739 timeout_height: value.timeout_height.into(),
740 extension_options: value.extension_options,
741 non_critical_extension_options: value.non_critical_extension_options,
742 }
743 }
744}
745
746impl TryFrom<RawAuthInfo> for AuthInfo {
747 type Error = Error;
748
749 fn try_from(value: RawAuthInfo) -> Result<Self, Self::Error> {
750 let signer_infos = value
751 .signer_infos
752 .into_iter()
753 .map(TryFrom::try_from)
754 .collect::<Result<_, Error>>()?;
755 Ok(AuthInfo {
756 signer_infos,
757 fee: value.fee.ok_or(Error::MissingFee)?.try_into()?,
758 })
759 }
760}
761
762impl From<AuthInfo> for RawAuthInfo {
763 fn from(value: AuthInfo) -> Self {
764 let signer_infos = value.signer_infos.into_iter().map(Into::into).collect();
765 #[allow(deprecated)] RawAuthInfo {
767 signer_infos,
768 fee: Some(value.fee.into()),
769 tip: None,
770 }
771 }
772}
773
774impl TryFrom<RawTxResponse> for TxResponse {
775 type Error = Error;
776
777 fn try_from(response: RawTxResponse) -> Result<TxResponse, Self::Error> {
778 Ok(TxResponse {
779 height: response.height.try_into()?,
780 txhash: response.txhash.parse()?,
781 codespace: response.codespace,
782 code: response.code.try_into()?,
783 data: response.data,
784 raw_log: response.raw_log,
785 logs: response.logs,
786 info: response.info,
787 gas_wanted: response.gas_wanted,
788 gas_used: response.gas_used,
789 tx: response.tx,
790 timestamp: response.timestamp,
791 events: response.events,
792 })
793 }
794}
795
796impl TryFrom<RawSignerInfo> for SignerInfo {
797 type Error = Error;
798
799 fn try_from(value: RawSignerInfo) -> Result<Self, Self::Error> {
800 Ok(SignerInfo {
801 public_key: value.public_key,
802 mode_info: value.mode_info.ok_or(Error::MissingModeInfo)?.try_into()?,
803 sequence: value.sequence,
804 })
805 }
806}
807
808impl From<SignerInfo> for RawSignerInfo {
809 fn from(value: SignerInfo) -> Self {
810 RawSignerInfo {
811 public_key: value.public_key,
812 mode_info: Some(value.mode_info.into()),
813 sequence: value.sequence,
814 }
815 }
816}
817
818impl TryFrom<RawFee> for Fee {
819 type Error = Error;
820
821 fn try_from(value: RawFee) -> Result<Fee, Self::Error> {
822 let amount = value
823 .amount
824 .into_iter()
825 .map(TryInto::try_into)
826 .collect::<Result<_, Error>>()?;
827
828 Ok(Fee {
829 amount,
830 gas_limit: value.gas_limit,
831 payer: (!value.payer.is_empty())
832 .then(|| value.payer.parse())
833 .transpose()?,
834 granter: (!value.granter.is_empty())
835 .then(|| value.granter.parse())
836 .transpose()?,
837 })
838 }
839}
840
841impl From<Fee> for RawFee {
842 fn from(value: Fee) -> Self {
843 let amount = value.amount.into_iter().map(Into::into).collect();
844 RawFee {
845 amount,
846 gas_limit: value.gas_limit,
847 payer: value.payer.map(|acc| acc.to_string()).unwrap_or_default(),
848 granter: value.granter.map(|acc| acc.to_string()).unwrap_or_default(),
849 }
850 }
851}
852
853impl TryFrom<RawModeInfo> for ModeInfo {
854 type Error = Error;
855
856 fn try_from(value: RawModeInfo) -> Result<Self, Self::Error> {
857 Ok(ModeInfo {
858 sum: value.sum.ok_or(Error::MissingSum)?.try_into()?,
859 })
860 }
861}
862
863impl From<ModeInfo> for RawModeInfo {
864 fn from(value: ModeInfo) -> Self {
865 RawModeInfo {
866 sum: Some(value.sum.into()),
867 }
868 }
869}
870
871impl TryFrom<RawSum> for Sum {
872 type Error = Error;
873
874 fn try_from(value: RawSum) -> Result<Self, Self::Error> {
875 let sum = match value {
876 RawSum::Single(Single { mode }) => Sum::Single { mode },
877 RawSum::Multi(Multi {
878 bitarray,
879 mode_infos,
880 }) => {
881 let bitarray = bitarray.ok_or(Error::MissingBitarray)?.try_into()?;
882 let mode_infos = mode_infos
883 .into_iter()
884 .map(TryInto::try_into)
885 .collect::<Result<_, Error>>()?;
886 Sum::Multi {
887 bitarray,
888 mode_infos,
889 }
890 }
891 };
892 Ok(sum)
893 }
894}
895
896impl From<Sum> for RawSum {
897 fn from(value: Sum) -> Self {
898 match value {
899 Sum::Single { mode } => RawSum::Single(Single { mode }),
900 Sum::Multi {
901 bitarray,
902 mode_infos,
903 } => {
904 let mode_infos = mode_infos.into_iter().map(Into::into).collect();
905 RawSum::Multi(Multi {
906 bitarray: Some(bitarray.into()),
907 mode_infos,
908 })
909 }
910 }
911 }
912}
913
914#[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))]
915pub use wbg::*;
916
917#[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))]
918mod wbg {
919 use tendermint_proto::v0_38::abci::{Event, EventAttribute};
920 use wasm_bindgen::prelude::*;
921
922 #[derive(Clone)]
926 #[wasm_bindgen(getter_with_clone)]
927 pub struct JsEvent {
928 pub r#type: String,
929 pub attributes: Vec<JsEventAttribute>,
930 }
931
932 impl From<Event> for JsEvent {
933 fn from(value: Event) -> Self {
934 JsEvent {
935 r#type: value.r#type,
936 attributes: value.attributes.into_iter().map(Into::into).collect(),
937 }
938 }
939 }
940
941 #[derive(Clone)]
942 #[wasm_bindgen(getter_with_clone)]
943 pub struct JsEventAttribute {
944 pub key: String,
945 pub value: String,
946 pub index: bool,
947 }
948
949 impl From<EventAttribute> for JsEventAttribute {
951 fn from(value: EventAttribute) -> Self {
952 JsEventAttribute {
953 key: value.key,
954 value: value.value,
955 index: value.index,
956 }
957 }
958 }
959}
960
961impl Protobuf<RawTxBody> for TxBody {}
962impl Protobuf<RawAuthInfo> for AuthInfo {}
963
964#[cfg(feature = "uniffi")]
965mod uniffi_types {
966 use tendermint_proto::v0_38::abci::{Event, EventAttribute};
967
968 #[uniffi::remote(Record)]
969 pub struct Event {
970 pub r#type: String,
971 pub attributes: Vec<EventAttribute>,
972 }
973
974 #[uniffi::remote(Record)]
975 pub struct EventAttribute {
976 pub key: String,
977 pub value: String,
978 pub index: bool,
979 }
980}