Skip to main content

defuse/contract/tokens/nep171/
deposit.rs

1use defuse_core::{
2    DefuseError,
3    token_id::{
4        TokenId,
5        nep171::{self, Nep171TokenId},
6    },
7    tokens::MAX_TOKEN_ID_LEN,
8};
9use near_contract_standards::non_fungible_token::core::NonFungibleTokenReceiver;
10use near_plugins::{Pausable, pause};
11use near_sdk::{AccountId, FunctionError, PromiseOrValue, env, near};
12
13use crate::{
14    contract::{Contract, ContractExt},
15    intents::{Intents, ext_intents},
16    tokens::{DepositAction, DepositMessage},
17};
18
19#[near]
20impl NonFungibleTokenReceiver for Contract {
21    /// Deposit non-fungible token.
22    ///
23    /// `msg` contains [`AccountId`] of the internal recipient.
24    /// Empty `msg` means deposit to `sender_id`
25    #[pause]
26    fn nft_on_transfer(
27        &mut self,
28        sender_id: AccountId,
29        previous_owner_id: AccountId,
30        token_id: nep171::TokenId,
31        msg: String,
32    ) -> PromiseOrValue<bool> {
33        let _ = previous_owner_id;
34        if token_id.len() > MAX_TOKEN_ID_LEN {
35            DefuseError::TokenIdTooLarge(token_id.len()).panic();
36        }
37
38        let DepositMessage {
39            receiver_id,
40            action,
41        } = if msg.is_empty() {
42            DepositMessage::new(sender_id)
43        } else {
44            msg.parse().unwrap_or_else(|e| panic!("{e}"))
45        };
46
47        let core_token_id: TokenId =
48            Nep171TokenId::new(env::predecessor_account_id(), token_id).into();
49
50        self.deposit(receiver_id, [(core_token_id, 1)], Some("deposit"))
51            .unwrap_or_else(|err| err.panic());
52
53        let Some(action) = action else {
54            return PromiseOrValue::Value(false);
55        };
56
57        match action {
58            // DepositAction::Notify(notify) => Self::notify_on_transfer(
59            //     sender_id,
60            //     vec![previous_owner_id],
61            //     receiver_id.clone(),
62            //     vec![core_token_id.to_string()],
63            //     vec![U128(1)],
64            //     notify,
65            // )
66            // .unwrap_or_else(|err| err.panic())
67            // .then(
68            //     Self::ext(env::current_account_id())
69            //         .with_static_gas(Self::mt_resolve_deposit_gas(1))
70            //         .with_unused_gas_weight(0)
71            //         .nft_resolve_deposit(receiver_id, env::predecessor_account_id(), token_id),
72            // )
73            // .into(),
74            DepositAction::Execute(execute) => {
75                if !execute.execute_intents.is_empty() {
76                    if execute.refund_if_fails {
77                        self.execute_intents(execute.execute_intents);
78                    } else {
79                        ext_intents::ext(env::current_account_id())
80                            .execute_intents(execute.execute_intents)
81                            .detach();
82                    }
83                }
84
85                PromiseOrValue::Value(false)
86            }
87        }
88    }
89}
90
91#[near]
92impl Contract {
93    #[private]
94    #[allow(clippy::needless_pass_by_value)]
95    pub fn nft_resolve_deposit(
96        &mut self,
97        receiver_id: AccountId,
98        contract_id: AccountId,
99        nft_token_id: nep171::TokenId,
100    ) -> PromiseOrValue<bool> {
101        let mut amount = 1u128;
102
103        self.resolve_deposit_internal(
104            &receiver_id,
105            [(
106                Nep171TokenId::new(contract_id, nft_token_id).into(),
107                &mut amount,
108            )],
109        );
110        PromiseOrValue::Value(amount != 0)
111    }
112}