1use std::sync::Arc;
2
3use elements::hashes::hex::FromHex;
4
5use crate::{types::AssetId, LwkError, TxIn};
6
7#[derive(uniffi::Object)]
9#[uniffi::export(Display)]
10pub struct Contract {
11 inner: lwk_wollet::Contract,
12}
13
14impl From<lwk_wollet::Contract> for Contract {
15 fn from(inner: lwk_wollet::Contract) -> Self {
16 Self { inner }
17 }
18}
19
20impl From<Contract> for lwk_wollet::Contract {
21 fn from(contract: Contract) -> Self {
22 contract.inner
23 }
24}
25
26impl From<&Contract> for lwk_wollet::Contract {
27 fn from(contract: &Contract) -> Self {
28 contract.inner.clone()
29 }
30}
31
32impl AsRef<lwk_wollet::Contract> for Contract {
33 fn as_ref(&self) -> &lwk_wollet::Contract {
34 &self.inner
35 }
36}
37
38impl std::fmt::Display for Contract {
39 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40 let json = serde_json::to_string(&self.inner).expect("contain simple types");
41 write!(f, "{}", &json)
42 }
43}
44
45#[uniffi::export]
46impl Contract {
47 #[uniffi::constructor]
49 pub fn new(
50 domain: String,
51 issuer_pubkey: &str,
52 name: String,
53 precision: u8,
54 ticker: String,
55 version: u8,
56 ) -> Result<Arc<Self>, LwkError> {
57 let inner = lwk_wollet::Contract {
58 entity: lwk_wollet::Entity::Domain(domain),
59 issuer_pubkey: Vec::<u8>::from_hex(issuer_pubkey)
60 .map_err(|e| format!("invalid issuer pubkey: {e}"))?,
61 name,
62 precision,
63 ticker,
64 version,
65 };
66 inner.validate()?; Ok(Arc::new(Self { inner }))
68 }
69}
70
71#[uniffi::export]
73pub fn derive_asset_id(txin: &TxIn, contract: &Contract) -> Result<AssetId, LwkError> {
74 let (asset_id, _token_id) = lwk_wollet::asset_ids(txin.as_ref(), contract.as_ref())?;
75 Ok(asset_id.into())
76}
77
78#[uniffi::export]
80pub fn derive_token_id(txin: &TxIn, contract: &Contract) -> Result<AssetId, LwkError> {
81 let (_asset_id, token_id) = lwk_wollet::asset_ids(txin.as_ref(), contract.as_ref())?;
82 Ok(token_id.into())
83}