1use crate::runtime::Runtime;
2
3use crate::error::Error;
4use crate::pb::{self, request::Request, response::Response};
5use crate::Keypath;
6use crate::PairedBitBox;
7
8#[cfg(feature = "wasm")]
9pub(crate) fn serde_deserialize_network<'de, D>(deserializer: D) -> Result<i32, D::Error>
10where
11 D: serde::Deserializer<'de>,
12{
13 use serde::Deserialize;
14 let network = pb::CardanoNetwork::deserialize(deserializer)?;
15 Ok(network as i32)
16}
17
18#[cfg(feature = "wasm")]
19pub(crate) fn serde_deserialize_drep_type<'de, D>(deserializer: D) -> Result<i32, D::Error>
20where
21 D: serde::Deserializer<'de>,
22{
23 use serde::Deserialize;
24 let drep_type = pb::cardano_sign_transaction_request::certificate::vote_delegation::CardanoDRepType::deserialize(deserializer)?;
25 Ok(drep_type as i32)
26}
27
28#[cfg(feature = "wasm")]
29#[derive(serde::Deserialize)]
30pub(crate) struct SerdeScriptConfig(pb::cardano_script_config::Config);
31
32#[cfg(feature = "wasm")]
33impl From<SerdeScriptConfig> for pb::CardanoScriptConfig {
34 fn from(value: SerdeScriptConfig) -> Self {
35 pb::CardanoScriptConfig {
36 config: Some(value.0),
37 }
38 }
39}
40
41#[cfg(feature = "wasm")]
42#[derive(serde::Deserialize)]
43pub(crate) struct SerdeCert(pb::cardano_sign_transaction_request::certificate::Cert);
44
45#[cfg(feature = "wasm")]
46impl From<SerdeCert> for pb::cardano_sign_transaction_request::Certificate {
47 fn from(value: SerdeCert) -> Self {
48 pb::cardano_sign_transaction_request::Certificate {
49 cert: Some(value.0),
50 }
51 }
52}
53
54pub fn make_script_config_pkh_skh(
57 keypath_payment: &Keypath,
58 keypath_stake: &Keypath,
59) -> pb::CardanoScriptConfig {
60 pb::CardanoScriptConfig {
61 config: Some(pb::cardano_script_config::Config::PkhSkh(
62 pb::cardano_script_config::PkhSkh {
63 keypath_payment: keypath_payment.to_vec(),
64 keypath_stake: keypath_stake.to_vec(),
65 },
66 )),
67 }
68}
69
70impl<R: Runtime> PairedBitBox<R> {
71 async fn query_proto_cardano(
72 &self,
73 request: pb::cardano_request::Request,
74 ) -> Result<pb::cardano_response::Response, Error> {
75 self.validate_version(">=9.8.0")?; match self
78 .query_proto(Request::Cardano(pb::CardanoRequest {
79 request: Some(request),
80 }))
81 .await?
82 {
83 Response::Cardano(pb::CardanoResponse {
84 response: Some(response),
85 }) => Ok(response),
86 _ => Err(Error::UnexpectedResponse),
87 }
88 }
89
90 pub fn cardano_supported(&self) -> bool {
92 self.is_multi_edition()
93 }
94
95 pub async fn cardano_xpubs(&self, keypaths: &[Keypath]) -> Result<Vec<Vec<u8>>, Error> {
98 match self
99 .query_proto_cardano(pb::cardano_request::Request::Xpubs(
100 pb::CardanoXpubsRequest {
101 keypaths: keypaths.iter().map(|kp| kp.into()).collect(),
102 },
103 ))
104 .await?
105 {
106 pb::cardano_response::Response::Xpubs(pb::CardanoXpubsResponse { xpubs }) => Ok(xpubs),
107 _ => Err(Error::UnexpectedResponse),
108 }
109 }
110
111 pub async fn cardano_address(
113 &self,
114 network: pb::CardanoNetwork,
115 script_config: &pb::CardanoScriptConfig,
116 display: bool,
117 ) -> Result<String, Error> {
118 match self
119 .query_proto_cardano(pb::cardano_request::Request::Address(
120 pb::CardanoAddressRequest {
121 network: network.into(),
122 display,
123 script_config: Some(script_config.clone()),
124 },
125 ))
126 .await?
127 {
128 pb::cardano_response::Response::Pub(pb::PubResponse { r#pub: address }) => Ok(address),
129 _ => Err(Error::UnexpectedResponse),
130 }
131 }
132
133 pub async fn cardano_sign_transaction(
135 &self,
136 transaction: pb::CardanoSignTransactionRequest,
137 ) -> Result<pb::CardanoSignTransactionResponse, Error> {
138 if transaction.tag_cbor_sets {
139 self.validate_version(">=9.22.0")?;
140 }
141 match self
142 .query_proto_cardano(pb::cardano_request::Request::SignTransaction(transaction))
143 .await?
144 {
145 pb::cardano_response::Response::SignTransaction(response) => Ok(response),
146 _ => Err(Error::UnexpectedResponse),
147 }
148 }
149}