Skip to main content

defuse_core/
tokens.rs

1use serde::{Deserialize, Serialize};
2use serde_with::{DisplayFromStr, serde_as};
3use std::{borrow::Cow, collections::BTreeMap};
4
5use crate::{AccountIdRef, Gas, amounts::Amounts, intents::tokens::Transfer};
6
7pub const MAX_TOKEN_ID_LEN: usize = 127;
8
9pub const MT_ON_TRANSFER_GAS_MIN: Gas = Gas::from_tgas(5);
10pub const MT_ON_TRANSFER_GAS_DEFAULT: Gas = Gas::from_tgas(30);
11
12#[cfg(feature = "imt")]
13pub mod imt {
14    use defuse_token_id::{TokenId, imt::ImtTokenId};
15    use serde::{Deserialize, Serialize};
16    use serde_with::{DisplayFromStr, serde_as};
17    use std::{borrow::Cow, collections::BTreeMap};
18
19    use crate::{
20        AccountIdRef, DefuseError, Result, amounts::Amounts, intents::imt::ImtMint,
21        tokens::MAX_TOKEN_ID_LEN,
22    };
23
24    pub type ImtTokens = Amounts<BTreeMap<defuse_nep245::TokenId, u128>>;
25
26    impl ImtTokens {
27        #[inline]
28        pub fn into_generic_tokens(
29            self,
30            minter_id: &AccountIdRef,
31        ) -> Result<Amounts<BTreeMap<TokenId, u128>>> {
32            let tokens = self
33                .into_iter()
34                .map(|(token_id, amount)| {
35                    if token_id.len() > MAX_TOKEN_ID_LEN {
36                        return Err(DefuseError::TokenIdTooLarge(token_id.len()));
37                    }
38
39                    let token = ImtTokenId::new(minter_id, token_id).into();
40
41                    Ok((token, amount))
42                })
43                .collect::<Result<_, _>>()?;
44
45            Ok(Amounts::new(tokens))
46        }
47    }
48
49    #[serde_as]
50    #[cfg_attr(feature = "schemars-v0_8", derive(::schemars::JsonSchema))]
51    #[derive(Debug, Clone, Serialize, Deserialize)]
52    pub struct ImtMintEvent<'a> {
53        pub receiver_id: Cow<'a, AccountIdRef>,
54
55        #[serde_as(as = "Amounts<BTreeMap<_, DisplayFromStr>>")]
56        pub tokens: ImtTokens,
57
58        #[serde(default, skip_serializing_if = "Option::is_none")]
59        pub memo: Option<Cow<'a, str>>,
60    }
61
62    impl<'a> From<&'a ImtMint> for ImtMintEvent<'a> {
63        #[inline]
64        fn from(intent: &'a ImtMint) -> Self {
65            Self {
66                receiver_id: Cow::Borrowed(&intent.receiver_id),
67                tokens: intent.tokens.clone(),
68                memo: intent.memo.as_deref().map(Cow::Borrowed),
69            }
70        }
71    }
72}
73
74#[serde_as]
75#[cfg_attr(feature = "schemars-v0_8", derive(::schemars::JsonSchema))]
76#[derive(Debug, Clone, Serialize, Deserialize)]
77pub struct TransferEvent<'a> {
78    pub receiver_id: Cow<'a, AccountIdRef>,
79
80    #[serde_as(as = "Amounts<BTreeMap<_, DisplayFromStr>>")]
81    pub tokens: Amounts,
82
83    #[serde(default, skip_serializing_if = "Option::is_none")]
84    pub memo: Option<Cow<'a, str>>,
85}
86
87impl<'a> From<&'a Transfer> for TransferEvent<'a> {
88    #[inline]
89    fn from(intent: &'a Transfer) -> Self {
90        Self {
91            receiver_id: Cow::Borrowed(&intent.receiver_id),
92            tokens: intent.tokens.clone(),
93            memo: intent.memo.as_deref().map(Cow::Borrowed),
94        }
95    }
96}