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