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