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