1pub mod account;
2pub mod auth;
3pub mod token_diff;
4pub mod tokens;
5
6#[cfg(feature = "imt")]
7pub mod imt;
8
9use defuse_serde_utils::base58::Base58;
10use derive_more::derive::From;
11use near_sdk::{AccountIdRef, CryptoHash, near};
12use serde_with::serde_as;
13use tokens::{NativeWithdraw, StorageDeposit};
14
15#[cfg(feature = "imt")]
16use crate::intents::imt::{ImtBurn, ImtMint};
17
18use crate::{
19 Result,
20 engine::{Engine, Inspector, State},
21 intents::{account::SetAuthByPredecessorId, auth::AuthCall},
22};
23
24use self::{
25 account::{AddPublicKey, RemovePublicKey},
26 token_diff::TokenDiff,
27 tokens::{FtWithdraw, MtWithdraw, NftWithdraw, Transfer},
28};
29
30#[near(serializers = [json])]
31#[derive(Debug, Clone)]
32pub struct DefuseIntents {
33 #[serde(default, skip_serializing_if = "Vec::is_empty")]
38 pub intents: Vec<Intent>,
39}
40
41#[near(serializers = [json])]
42#[serde(tag = "intent", rename_all = "snake_case")]
43#[derive(Debug, Clone, From)]
44pub enum Intent {
45 AddPublicKey(AddPublicKey),
47
48 RemovePublicKey(RemovePublicKey),
50
51 Transfer(Transfer),
53
54 FtWithdraw(FtWithdraw),
56
57 NftWithdraw(NftWithdraw),
59
60 MtWithdraw(MtWithdraw),
62
63 NativeWithdraw(NativeWithdraw),
65
66 StorageDeposit(StorageDeposit),
68
69 TokenDiff(TokenDiff),
71
72 SetAuthByPredecessorId(SetAuthByPredecessorId),
74
75 AuthCall(AuthCall),
77
78 #[cfg(feature = "imt")]
80 ImtMint(ImtMint),
81
82 #[cfg(feature = "imt")]
84 ImtBurn(ImtBurn),
85}
86
87pub trait ExecutableIntent {
88 fn execute_intent<S, I>(
89 self,
90 signer_id: &AccountIdRef,
91 engine: &mut Engine<S, I>,
92 intent_hash: CryptoHash,
93 ) -> Result<()>
94 where
95 S: State,
96 I: Inspector;
97}
98
99impl ExecutableIntent for DefuseIntents {
100 fn execute_intent<S, I>(
101 self,
102 signer_id: &AccountIdRef,
103 engine: &mut Engine<S, I>,
104 intent_hash: CryptoHash,
105 ) -> Result<()>
106 where
107 S: State,
108 I: Inspector,
109 {
110 for intent in self.intents {
111 intent.execute_intent(signer_id, engine, intent_hash)?;
112 }
113 Ok(())
114 }
115}
116
117impl ExecutableIntent for Intent {
118 fn execute_intent<S, I>(
119 self,
120 signer_id: &AccountIdRef,
121 engine: &mut Engine<S, I>,
122 intent_hash: CryptoHash,
123 ) -> Result<()>
124 where
125 S: State,
126 I: Inspector,
127 {
128 match self {
129 Self::AddPublicKey(intent) => intent.execute_intent(signer_id, engine, intent_hash),
130 Self::RemovePublicKey(intent) => intent.execute_intent(signer_id, engine, intent_hash),
131 Self::Transfer(intent) => intent.execute_intent(signer_id, engine, intent_hash),
132 Self::FtWithdraw(intent) => intent.execute_intent(signer_id, engine, intent_hash),
133 Self::NftWithdraw(intent) => intent.execute_intent(signer_id, engine, intent_hash),
134 Self::MtWithdraw(intent) => intent.execute_intent(signer_id, engine, intent_hash),
135 Self::NativeWithdraw(intent) => intent.execute_intent(signer_id, engine, intent_hash),
136 Self::StorageDeposit(intent) => intent.execute_intent(signer_id, engine, intent_hash),
137 Self::TokenDiff(intent) => intent.execute_intent(signer_id, engine, intent_hash),
138 Self::SetAuthByPredecessorId(intent) => {
139 intent.execute_intent(signer_id, engine, intent_hash)
140 }
141 Self::AuthCall(intent) => intent.execute_intent(signer_id, engine, intent_hash),
142 #[cfg(feature = "imt")]
143 Self::ImtMint(intent) => intent.execute_intent(signer_id, engine, intent_hash),
144 #[cfg(feature = "imt")]
145 Self::ImtBurn(intent) => intent.execute_intent(signer_id, engine, intent_hash),
146 }
147 }
148}
149
150#[must_use = "make sure to `.emit()` this event"]
153#[near(serializers = [json])]
154#[derive(Debug, Clone)]
155pub struct MaybeIntentEvent<T> {
156 #[serde_as(as = "Option<Base58>")]
157 #[serde(default, skip_serializing_if = "Option::is_none")]
158 pub intent_hash: Option<CryptoHash>,
159
160 #[serde(flatten)]
161 pub event: T,
162}
163
164impl<T> MaybeIntentEvent<T> {
165 #[inline]
166 pub const fn new_fn_call(event: T) -> Self {
167 Self {
168 intent_hash: None,
169 event,
170 }
171 }
172
173 #[inline]
174 pub const fn new_intent(event: T, intent_hash: CryptoHash) -> Self {
175 Self {
176 intent_hash: Some(intent_hash),
177 event,
178 }
179 }
180}
181
182impl<T> From<T> for MaybeIntentEvent<T> {
183 fn from(event: T) -> Self {
184 Self::new_fn_call(event)
185 }
186}
187
188#[cfg(feature = "abi")]
190use near_sdk::serde;