whisky_csl/utils/
address.rs

1use cardano_serialization_lib::{self as csl};
2use whisky_common::{DeserializedAddress, WError};
3
4pub fn script_to_address(
5    network_id: u8,
6    script_hash: &str,
7    stake_hash: Option<(&str, bool)>,
8) -> String {
9    match stake_hash {
10        Some((stake, is_script)) => {
11            let stake_cred = if is_script {
12                csl::Credential::from_scripthash(&csl::ScriptHash::from_hex(stake).unwrap())
13            } else {
14                csl::Credential::from_keyhash(&csl::Ed25519KeyHash::from_hex(stake).unwrap())
15            };
16
17            csl::BaseAddress::new(
18                network_id,
19                &csl::Credential::from_scripthash(&csl::ScriptHash::from_hex(script_hash).unwrap()),
20                &stake_cred,
21            )
22            .to_address()
23            .to_bech32(None)
24            .unwrap()
25        }
26
27        None => csl::EnterpriseAddress::new(
28            network_id,
29            &csl::Credential::from_scripthash(&csl::ScriptHash::from_hex(script_hash).unwrap()),
30        )
31        .to_address()
32        .to_bech32(None)
33        .unwrap(),
34    }
35}
36
37pub fn serialize_address_obj(
38    address_obj: DeserializedAddress,
39    network_id: u8,
40) -> Result<String, WError> {
41    let payment_cred = match (
42        address_obj.pub_key_hash.as_str(),
43        address_obj.script_hash.as_str(),
44    ) {
45        (pub_key_hash, "") => {
46            csl::Credential::from_keyhash(&csl::Ed25519KeyHash::from_hex(pub_key_hash).unwrap())
47        }
48        ("", script_hash) => {
49            csl::Credential::from_scripthash(&csl::ScriptHash::from_hex(script_hash).unwrap())
50        }
51        _ => Err(WError::new(
52            "serialze_address_obj",
53            &format!(
54                "Must provide exactly one of pub_key_hash or script_hash, pub_key_hash: {}, script_hash: {}",
55                address_obj.pub_key_hash, address_obj.script_hash
56            ),
57        ))?,
58    };
59
60    let stake_cred_opt = match (
61        address_obj.stake_key_hash.as_str(),
62        address_obj.stake_key_script_hash.as_str(),
63    ) {
64        ("", "") => None,
65        (stake_key_hash, "") => Some(csl::Credential::from_keyhash(
66            &csl::Ed25519KeyHash::from_hex(stake_key_hash).unwrap(),
67        )),
68        ("", stake_key_script_hash) => Some(csl::Credential::from_scripthash(
69            &csl::ScriptHash::from_hex(stake_key_script_hash).unwrap(),
70        )),
71        _ => Err(WError::new(
72            "serialze_address_obj",
73            &format!(
74                "Invalid address object, stake_key_hash: {}, stake_key_script_hash: {}",
75                address_obj.stake_key_hash, address_obj.stake_key_script_hash
76            ),
77        ))?,
78    };
79
80    match stake_cred_opt {
81        Some(stake_cred) => {
82            let base_address = csl::BaseAddress::new(network_id, &payment_cred, &stake_cred)
83                .to_address()
84                .to_bech32(None)
85                .unwrap();
86            Ok(base_address)
87        }
88        None => {
89            let enterprise_address = csl::EnterpriseAddress::new(network_id, &payment_cred)
90                .to_address()
91                .to_bech32(None)
92                .unwrap();
93            Ok(enterprise_address)
94        }
95    }
96}
97
98pub fn deserialize_address(bech32_addr: &str) -> DeserializedAddress {
99    let csl_address =
100        csl::BaseAddress::from_address(&csl::Address::from_bech32(bech32_addr).unwrap());
101    match csl_address {
102        Some(address) => {
103            let csl_key_hash = address
104                .payment_cred()
105                .to_keyhash()
106                .map(|key_hash| key_hash.to_hex());
107
108            let csl_script_hash = address
109                .payment_cred()
110                .to_scripthash()
111                .map(|script_hash| script_hash.to_hex());
112
113            let csl_stake_key_hash = address
114                .stake_cred()
115                .to_keyhash()
116                .map(|stake_key_hash| stake_key_hash.to_hex());
117
118            let csl_stake_key_script_hash = address
119                .stake_cred()
120                .to_scripthash()
121                .map(|stake_key_script_hash| stake_key_script_hash.to_hex());
122
123            DeserializedAddress::new(
124                &csl_key_hash.unwrap_or("".to_string()),
125                &csl_script_hash.unwrap_or("".to_string()),
126                &csl_stake_key_hash.unwrap_or("".to_string()),
127                &csl_stake_key_script_hash.unwrap_or("".to_string()),
128            )
129        }
130        None => {
131            let csl_enterprize_address = csl::EnterpriseAddress::from_address(
132                &csl::Address::from_bech32(bech32_addr).unwrap(),
133            )
134            .unwrap();
135
136            let csl_key_hash = csl_enterprize_address
137                .payment_cred()
138                .to_keyhash()
139                .map(|key_hash| key_hash.to_hex());
140
141            let csl_script_hash = csl_enterprize_address
142                .payment_cred()
143                .to_scripthash()
144                .map(|script_hash| script_hash.to_hex());
145
146            DeserializedAddress::new(
147                &csl_key_hash.unwrap_or("".to_string()),
148                &csl_script_hash.unwrap_or("".to_string()),
149                "",
150                "",
151            )
152        }
153    }
154}