1use std::convert::TryFrom;
4
5use ergo_lib::{
6 ergo_chain_types::{Base16DecodedBytes, Digest32},
7 ergotree_ir::chain,
8};
9
10use crate::{
11 ergo_box::ConstBoxIdPtr,
12 json::TokenJsonEip12,
13 util::{const_ptr_as_ref, mut_ptr_as_mut},
14 Error,
15};
16
17#[derive(PartialEq, Eq, Debug, Clone)]
19pub struct TokenId(pub(crate) chain::token::TokenId);
20pub type TokenIdPtr = *mut TokenId;
21pub type ConstTokenIdPtr = *const TokenId;
22
23pub unsafe fn token_id_from_box_id(
25 box_id_ptr: ConstBoxIdPtr,
26 token_id_out: *mut TokenIdPtr,
27) -> Result<(), Error> {
28 let box_id = const_ptr_as_ref(box_id_ptr, "box_id_ptr")?;
29 let token_id_out = mut_ptr_as_mut(token_id_out, "token_id_out")?;
30 *token_id_out = Box::into_raw(Box::new(TokenId(chain::token::TokenId::from(box_id.0))));
31 Ok(())
32}
33
34pub unsafe fn token_id_from_str(str: &str, token_id_out: *mut TokenIdPtr) -> Result<(), Error> {
36 let token_id_out = mut_ptr_as_mut(token_id_out, "token_id_out")?;
37 let base_16_decoded_bytes = Base16DecodedBytes::try_from(str.to_string())?;
38
39 let token_id = Digest32::try_from(base_16_decoded_bytes)
40 .map(|dig| dig.into())
41 .map(TokenId)?;
42 *token_id_out = Box::into_raw(Box::new(token_id));
43 Ok(())
44}
45
46pub unsafe fn token_id_to_str(token_id_ptr: ConstTokenIdPtr) -> Result<String, Error> {
48 let token_id = const_ptr_as_ref(token_id_ptr, "token_id_ptr")?;
49 Ok(token_id.0.into())
50}
51
52#[derive(PartialEq, Eq, Debug, Clone)]
54pub struct TokenAmount(pub(crate) chain::token::TokenAmount);
55pub type TokenAmountPtr = *mut TokenAmount;
56pub type ConstTokenAmountPtr = *const TokenAmount;
57
58pub unsafe fn token_amount_from_i64(
60 amount: i64,
61 token_amount_out: *mut TokenAmountPtr,
62) -> Result<(), Error> {
63 let token_amount_out = mut_ptr_as_mut(token_amount_out, "token_amount_out")?;
64 let inner = chain::token::TokenAmount::try_from(amount as u64)?;
65 *token_amount_out = Box::into_raw(Box::new(TokenAmount(inner)));
66 Ok(())
67}
68
69pub unsafe fn token_amount_as_i64(token_amount_ptr: ConstTokenAmountPtr) -> Result<i64, Error> {
71 let token_amount = const_ptr_as_ref(token_amount_ptr, "token_amount_ptr")?;
72 Ok(i64::from(token_amount.0))
73}
74
75#[derive(PartialEq, Eq, Debug, Clone, derive_more::From, derive_more::Into)]
77pub struct Token(pub(crate) chain::token::Token);
78pub type TokenPtr = *mut Token;
79pub type ConstTokenPtr = *const Token;
80
81pub unsafe fn token_new(
83 token_id_ptr: ConstTokenIdPtr,
84 token_amount_ptr: ConstTokenAmountPtr,
85 token_out: *mut TokenPtr,
86) -> Result<(), Error> {
87 let token_id = const_ptr_as_ref(token_id_ptr, "token_id_ptr")?;
88 let token_amount = const_ptr_as_ref(token_amount_ptr, "token_amount_ptr")?;
89 let token_out = mut_ptr_as_mut(token_out, "token_out")?;
90 *token_out = Box::into_raw(Box::new(Token(chain::token::Token {
91 token_id: token_id.0,
92 amount: token_amount.0,
93 })));
94 Ok(())
95}
96
97pub unsafe fn token_get_id(
99 token_ptr: ConstTokenPtr,
100 token_id_out: *mut TokenIdPtr,
101) -> Result<(), Error> {
102 let token = const_ptr_as_ref(token_ptr, "token_ptr")?;
103 let token_id_out = mut_ptr_as_mut(token_id_out, "token_id_out")?;
104 *token_id_out = Box::into_raw(Box::new(TokenId(token.0.token_id)));
105 Ok(())
106}
107
108pub unsafe fn token_get_amount(
110 token_ptr: ConstTokenPtr,
111 token_amount_out: *mut TokenAmountPtr,
112) -> Result<(), Error> {
113 let token = const_ptr_as_ref(token_ptr, "token_ptr")?;
114 let token_amount_out = mut_ptr_as_mut(token_amount_out, "token_amount_out")?;
115 *token_amount_out = Box::into_raw(Box::new(TokenAmount(token.0.amount)));
116 Ok(())
117}
118
119pub unsafe fn token_to_json_eip12(token_ptr: ConstTokenPtr) -> Result<String, Error> {
121 let token = const_ptr_as_ref(token_ptr, "token_ptr")?;
122 let t_dapp: TokenJsonEip12 = token.0.clone().into();
123 let s = serde_json::to_string(&t_dapp)?;
124 Ok(s)
125}