defuse/contract/tokens/nep171/
deposit.rs1use 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, json_types::U128, 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 #[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 if token_id.len() > MAX_TOKEN_ID_LEN {
34 DefuseError::TokenIdTooLarge(token_id.len()).panic();
35 }
36
37 let DepositMessage {
38 receiver_id,
39 action,
40 } = if msg.is_empty() {
41 DepositMessage::new(sender_id.clone())
42 } else {
43 msg.parse().unwrap_or_else(|e| panic!("{e}"))
44 };
45
46 let core_token_id: TokenId =
47 Nep171TokenId::new(env::predecessor_account_id(), token_id.clone()).into();
48
49 self.deposit(
50 receiver_id.clone(),
51 [(core_token_id.clone(), 1)],
52 Some("deposit"),
53 )
54 .unwrap_or_else(|err| err.panic());
55
56 let Some(action) = action else {
57 return PromiseOrValue::Value(false);
58 };
59
60 match action {
61 DepositAction::Notify(notify) => Self::notify_on_transfer(
62 sender_id,
63 vec![previous_owner_id],
64 receiver_id.clone(),
65 vec![core_token_id.to_string()],
66 vec![U128(1)],
67 notify,
68 )
69 .then(
70 Self::ext(env::current_account_id())
71 .with_static_gas(Self::mt_resolve_deposit_gas(1))
72 .with_unused_gas_weight(0)
73 .nft_resolve_deposit(receiver_id, env::predecessor_account_id(), token_id),
74 )
75 .into(),
76 DepositAction::Execute(execute) => {
77 if !execute.execute_intents.is_empty() {
78 if execute.refund_if_fails {
79 self.execute_intents(execute.execute_intents);
80 } else {
81 ext_intents::ext(env::current_account_id())
82 .execute_intents(execute.execute_intents)
83 .detach();
84 }
85 }
86
87 PromiseOrValue::Value(false)
88 }
89 }
90 }
91}
92
93#[near]
94impl Contract {
95 #[private]
96 #[allow(clippy::needless_pass_by_value)]
97 pub fn nft_resolve_deposit(
98 &mut self,
99 receiver_id: AccountId,
100 contract_id: AccountId,
101 nft_token_id: nep171::TokenId,
102 ) -> PromiseOrValue<bool> {
103 let mut amount = 1u128;
104
105 self.resolve_deposit_internal(
106 &receiver_id,
107 [(
108 Nep171TokenId::new(contract_id, nft_token_id).into(),
109 &mut amount,
110 )],
111 );
112 PromiseOrValue::Value(amount != 0)
113 }
114}