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