cml_chain_wasm/
address.rs

1use super::*;
2
3pub use cml_chain::address::{AddressHeaderKind, AddressKind};
4
5use cml_core::CertificateIndex;
6use cml_core_wasm::{impl_wasm_conversions, impl_wasm_json_api};
7
8use crate::certs::StakeCredential;
9
10#[wasm_bindgen]
11#[derive(Clone, Debug)]
12pub struct Address(cml_chain::address::Address);
13
14impl_wasm_conversions!(cml_chain::address::Address, Address);
15
16impl_wasm_json_api!(Address);
17
18#[wasm_bindgen]
19impl Address {
20    /// header has 4 bits addr type discrim then 4 bits network discrim.
21    /// Copied from shelley.cddl:
22    ///
23    /// base address
24    /// bits 7-6: 00
25    /// bit 5: stake cred is keyhash/scripthash
26    /// bit 4: payment cred is keyhash/scripthash
27    /// bits 3-0: network id
28    ///
29    /// pointer address
30    /// bits 7-5: 010
31    /// bit 4: payment cred is keyhash/scripthash
32    /// bits 3-0: network id
33    ///
34    /// enterprise address
35    /// bits 7-5: 010
36    /// bit 4: payment cred is keyhash/scripthash
37    /// bits 3-0: network id
38    ///
39    /// reward addresses:
40    /// bits 7-5: 111
41    /// bit 4: credential is keyhash/scripthash
42    /// bits 3-0: network id
43    ///
44    /// byron addresses:
45    /// bits 7-4: 1000
46    /// bits 3-0: unrelated data (recall: no network ID in Byron addresses)
47    pub fn header(&self) -> u8 {
48        self.0.header()
49    }
50
51    pub fn header_matches_kind(header: u8, kind: AddressHeaderKind) -> bool {
52        cml_chain::address::Address::header_matches_kind(header, kind)
53    }
54
55    pub fn to_bech32(&self, prefix: Option<String>) -> Result<String, JsError> {
56        self.0.to_bech32(prefix).map_err(Into::into)
57    }
58
59    pub fn from_bech32(bech_str: String) -> Result<Address, JsError> {
60        cml_chain::address::Address::from_bech32(&bech_str)
61            .map(Into::into)
62            .map_err(Into::into)
63    }
64
65    /**
66     * Note: bech32-encoded Byron addresses will also pass validation here
67     */
68    pub fn is_valid_bech32(bech_str: String) -> bool {
69        cml_chain::address::Address::is_valid_bech32(&bech_str)
70    }
71
72    // pub fn is_valid_byron(base58: &str) -> bool {
73    //     cml_chain::address::Address::is_valid_byron(base58)
74    // }
75
76    pub fn is_valid(bech_str: String) -> bool {
77        cml_chain::address::Address::is_valid(&bech_str)
78    }
79
80    pub fn network_id(&self) -> Result<u8, JsError> {
81        self.0.network_id().map_err(Into::into)
82    }
83
84    /// Note: by convention, the key inside reward addresses are considered payment credentials
85    pub fn payment_cred(&self) -> Option<StakeCredential> {
86        self.0.payment_cred().cloned().map(Into::into)
87    }
88
89    /// Note: by convention, the key inside reward addresses are NOT considered staking credentials
90    /// Note: None is returned pointer addresses as the chain history is required to resolve its associated cred
91    pub fn staking_cred(&self) -> Option<StakeCredential> {
92        self.0.staking_cred().cloned().map(Into::into)
93    }
94
95    pub fn kind(&self) -> AddressKind {
96        self.0.kind()
97    }
98
99    pub fn to_raw_bytes(&self) -> Vec<u8> {
100        self.0.to_raw_bytes()
101    }
102
103    pub fn from_raw_bytes(data: &[u8]) -> Result<Address, JsError> {
104        cml_chain::address::Address::from_raw_bytes(data)
105            .map(Self)
106            .map_err(Into::into)
107    }
108
109    pub fn to_hex(&self) -> String {
110        self.0.to_hex()
111    }
112
113    pub fn from_hex(hex: &str) -> Result<Address, JsError> {
114        cml_chain::address::Address::from_hex(hex)
115            .map(Into::into)
116            .map_err(Into::into)
117    }
118}
119
120#[wasm_bindgen]
121#[derive(Clone, Debug)]
122pub struct BaseAddress(cml_chain::address::BaseAddress);
123
124impl_wasm_conversions!(cml_chain::address::BaseAddress, BaseAddress);
125
126#[wasm_bindgen]
127impl BaseAddress {
128    pub fn new(network: u8, payment: &StakeCredential, stake: &StakeCredential) -> Self {
129        Self(cml_chain::address::BaseAddress::new(
130            network,
131            payment.as_ref().clone(),
132            stake.as_ref().clone(),
133        ))
134    }
135
136    pub fn to_address(&self) -> Address {
137        Address(self.0.clone().to_address())
138    }
139
140    pub fn from_address(address: &Address) -> Option<BaseAddress> {
141        match &address.0 {
142            cml_chain::address::Address::Base(ba) => Some(ba.clone().into()),
143            _ => None,
144        }
145    }
146
147    pub fn network_id(&self) -> u8 {
148        self.0.network
149    }
150
151    pub fn payment(&self) -> StakeCredential {
152        self.0.payment.clone().into()
153    }
154
155    pub fn stake(&self) -> StakeCredential {
156        self.0.stake.clone().into()
157    }
158}
159
160#[wasm_bindgen]
161#[derive(Clone, Debug)]
162pub struct EnterpriseAddress(cml_chain::address::EnterpriseAddress);
163
164impl_wasm_conversions!(cml_chain::address::EnterpriseAddress, EnterpriseAddress);
165
166#[wasm_bindgen]
167impl EnterpriseAddress {
168    pub fn new(network: u8, payment: &StakeCredential) -> Self {
169        Self(cml_chain::address::EnterpriseAddress::new(
170            network,
171            payment.as_ref().clone(),
172        ))
173    }
174
175    pub fn to_address(&self) -> Address {
176        Address(self.0.clone().to_address())
177    }
178
179    pub fn from_address(address: &Address) -> Option<EnterpriseAddress> {
180        match &address.0 {
181            cml_chain::address::Address::Enterprise(ea) => Some(ea.clone().into()),
182            _ => None,
183        }
184    }
185
186    pub fn network_id(&self) -> u8 {
187        self.0.network
188    }
189
190    pub fn payment(&self) -> StakeCredential {
191        self.0.payment.clone().into()
192    }
193}
194
195#[wasm_bindgen]
196#[derive(Clone, Debug)]
197pub struct Pointer(cml_chain::address::Pointer);
198
199impl_wasm_conversions!(cml_chain::address::Pointer, Pointer);
200
201impl Pointer {
202    pub fn new(slot: Slot, tx_index: TransactionIndex, cert_index: CertificateIndex) -> Self {
203        Self(cml_chain::address::Pointer::new(slot, tx_index, cert_index))
204    }
205
206    /// This will be truncated if above u64::MAX
207    pub fn slot(&self) -> Slot {
208        self.0.slot()
209    }
210
211    /// This will be truncated if above u64::MAX
212    pub fn tx_index(&self) -> Slot {
213        self.0.tx_index()
214    }
215
216    /// This will be truncated if above u64::MAX
217    pub fn cert_index(&self) -> Slot {
218        self.0.cert_index()
219    }
220}
221
222#[wasm_bindgen]
223#[derive(Clone, Debug)]
224pub struct PointerAddress(cml_chain::address::PointerAddress);
225
226impl_wasm_conversions!(cml_chain::address::PointerAddress, PointerAddress);
227
228#[wasm_bindgen]
229impl PointerAddress {
230    pub fn new(network: u8, payment: &StakeCredential, stake: &Pointer) -> Self {
231        Self(cml_chain::address::PointerAddress::new(
232            network,
233            payment.as_ref().clone(),
234            stake.as_ref().clone(),
235        ))
236    }
237
238    pub fn to_address(&self) -> Address {
239        Address(self.0.clone().to_address())
240    }
241
242    pub fn from_address(address: &Address) -> Option<PointerAddress> {
243        match &address.0 {
244            cml_chain::address::Address::Ptr(pa) => Some(pa.clone().into()),
245            _ => None,
246        }
247    }
248
249    pub fn network_id(&self) -> u8 {
250        self.0.network
251    }
252
253    pub fn payment(&self) -> StakeCredential {
254        self.0.payment.clone().into()
255    }
256
257    pub fn stake(&self) -> Pointer {
258        self.0.stake.clone().into()
259    }
260}
261
262pub type RewardAccount = RewardAddress;
263
264#[wasm_bindgen]
265#[derive(Clone, Debug)]
266pub struct RewardAddress(cml_chain::address::RewardAddress);
267
268impl_wasm_conversions!(cml_chain::address::RewardAddress, RewardAddress);
269
270impl_wasm_json_api!(RewardAddress);
271
272#[wasm_bindgen]
273impl RewardAddress {
274    pub fn new(network: u8, payment: &StakeCredential) -> Self {
275        Self(cml_chain::address::RewardAddress::new(
276            network,
277            payment.as_ref().clone(),
278        ))
279    }
280
281    pub fn to_address(&self) -> Address {
282        Address(self.0.clone().to_address())
283    }
284
285    pub fn from_address(address: &Address) -> Option<RewardAddress> {
286        match &address.0 {
287            cml_chain::address::Address::Reward(ra) => Some(ra.clone().into()),
288            _ => None,
289        }
290    }
291
292    pub fn network_id(&self) -> u8 {
293        self.0.network
294    }
295
296    pub fn payment(&self) -> StakeCredential {
297        self.0.payment.clone().into()
298    }
299}