1pub mod account;
2pub mod auth;
3pub mod token_diff;
4pub mod tokens;
5
6use defuse_serde_utils::base58::Base58;
7use derive_more::derive::From;
8use near_sdk::{AccountIdRef, CryptoHash, near};
9use serde_with::serde_as;
10use tokens::{NativeWithdraw, StorageDeposit};
11
12use crate::{
13 Result,
14 engine::{Engine, Inspector, State},
15 intents::{account::SetAuthByPredecessorId, auth::AuthCall},
16};
17
18use self::{
19 account::{AddPublicKey, RemovePublicKey},
20 token_diff::TokenDiff,
21 tokens::{FtWithdraw, MtWithdraw, NftWithdraw, Transfer},
22};
23
24#[near(serializers = [json])]
25#[derive(Debug, Clone)]
26pub struct DefuseIntents {
27 #[serde(default, skip_serializing_if = "Vec::is_empty")]
32 pub intents: Vec<Intent>,
33}
34
35#[near(serializers = [json])]
36#[serde(tag = "intent", rename_all = "snake_case")]
37#[derive(Debug, Clone, From)]
38pub enum Intent {
39 AddPublicKey(AddPublicKey),
41
42 RemovePublicKey(RemovePublicKey),
44
45 Transfer(Transfer),
47
48 FtWithdraw(FtWithdraw),
50
51 NftWithdraw(NftWithdraw),
53
54 MtWithdraw(MtWithdraw),
56
57 NativeWithdraw(NativeWithdraw),
59
60 StorageDeposit(StorageDeposit),
62
63 TokenDiff(TokenDiff),
65
66 SetAuthByPredecessorId(SetAuthByPredecessorId),
68
69 AuthCall(AuthCall),
71}
72
73pub trait ExecutableIntent {
74 fn execute_intent<S, I>(
75 self,
76 signer_id: &AccountIdRef,
77 engine: &mut Engine<S, I>,
78 intent_hash: CryptoHash,
79 ) -> Result<()>
80 where
81 S: State,
82 I: Inspector;
83}
84
85impl ExecutableIntent for DefuseIntents {
86 fn execute_intent<S, I>(
87 self,
88 signer_id: &AccountIdRef,
89 engine: &mut Engine<S, I>,
90 intent_hash: CryptoHash,
91 ) -> Result<()>
92 where
93 S: State,
94 I: Inspector,
95 {
96 for intent in self.intents {
97 intent.execute_intent(signer_id, engine, intent_hash)?;
98 }
99 Ok(())
100 }
101}
102
103impl ExecutableIntent for Intent {
104 fn execute_intent<S, I>(
105 self,
106 signer_id: &AccountIdRef,
107 engine: &mut Engine<S, I>,
108 intent_hash: CryptoHash,
109 ) -> Result<()>
110 where
111 S: State,
112 I: Inspector,
113 {
114 match self {
115 Self::AddPublicKey(intent) => intent.execute_intent(signer_id, engine, intent_hash),
116 Self::RemovePublicKey(intent) => intent.execute_intent(signer_id, engine, intent_hash),
117 Self::Transfer(intent) => intent.execute_intent(signer_id, engine, intent_hash),
118 Self::FtWithdraw(intent) => intent.execute_intent(signer_id, engine, intent_hash),
119 Self::NftWithdraw(intent) => intent.execute_intent(signer_id, engine, intent_hash),
120 Self::MtWithdraw(intent) => intent.execute_intent(signer_id, engine, intent_hash),
121 Self::NativeWithdraw(intent) => intent.execute_intent(signer_id, engine, intent_hash),
122 Self::StorageDeposit(intent) => intent.execute_intent(signer_id, engine, intent_hash),
123 Self::TokenDiff(intent) => intent.execute_intent(signer_id, engine, intent_hash),
124 Self::SetAuthByPredecessorId(intent) => {
125 intent.execute_intent(signer_id, engine, intent_hash)
126 }
127 Self::AuthCall(intent) => intent.execute_intent(signer_id, engine, intent_hash),
128 }
129 }
130}
131
132#[must_use = "make sure to `.emit()` this event"]
133#[cfg_attr(
134 all(feature = "abi", not(target_arch = "wasm32")),
135 serde_as(schemars = true)
136)]
137#[cfg_attr(
138 not(all(feature = "abi", not(target_arch = "wasm32"))),
139 serde_as(schemars = false)
140)]
141#[near(serializers = [json])]
142#[derive(Debug, Clone)]
143pub struct IntentEvent<T> {
144 #[serde_as(as = "Base58")]
145 pub intent_hash: CryptoHash,
146
147 #[serde(flatten)]
148 pub event: T,
149}
150
151impl<T> IntentEvent<T> {
152 #[inline]
153 pub const fn new(event: T, intent_hash: CryptoHash) -> Self {
154 Self { intent_hash, event }
155 }
156}