defuse/contract/tokens/nep171/
deposit.rs1use defuse_core::{
2 DefuseError,
3 token_id::{TokenId, nep171::Nep171TokenId},
4 tokens::MAX_TOKEN_ID_LEN,
5};
6use defuse_near_utils::{PanicError, UnwrapOrPanic, UnwrapOrPanicError};
7use near_contract_standards::non_fungible_token::core::NonFungibleTokenReceiver;
8use near_plugins::{Pausable, pause};
9use near_sdk::{AccountId, PromiseOrValue, env, json_types::U128, near};
10
11use crate::{
12 contract::{Contract, ContractExt},
13 intents::{Intents, ext_intents},
14 tokens::{DepositAction, DepositMessage},
15};
16
17#[near]
18impl NonFungibleTokenReceiver for Contract {
19 #[pause]
24 fn nft_on_transfer(
25 &mut self,
26 sender_id: AccountId,
27 previous_owner_id: AccountId,
28 token_id: near_contract_standards::non_fungible_token::TokenId,
29 msg: String,
30 ) -> PromiseOrValue<bool> {
31 if token_id.len() > MAX_TOKEN_ID_LEN {
32 DefuseError::TokenIdTooLarge(token_id.len()).panic_display();
33 }
34
35 let DepositMessage {
36 receiver_id,
37 action,
38 } = if msg.is_empty() {
39 DepositMessage::new(sender_id.clone())
40 } else {
41 msg.parse().unwrap_or_panic_display()
42 };
43
44 let core_token_id: TokenId =
45 Nep171TokenId::new(env::predecessor_account_id(), token_id.clone()).into();
46
47 self.deposit(
48 receiver_id.clone(),
49 [(core_token_id.clone(), 1)],
50 Some("deposit"),
51 )
52 .unwrap_or_panic();
53
54 let Some(action) = action else {
55 return PromiseOrValue::Value(false);
56 };
57
58 match action {
59 DepositAction::Notify(notify) => Self::notify_on_transfer(
60 sender_id,
61 vec![previous_owner_id],
62 receiver_id.clone(),
63 vec![core_token_id.to_string()],
64 vec![U128(1)],
65 notify,
66 )
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: near_contract_standards::non_fungible_token::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}