1use defuse_core::{
2 Deadline, Result,
3 accounts::{AccountEvent, NonceEvent},
4 engine::deltas::InvariantViolated,
5 fees::Pips,
6 intents::IntentEvent,
7 payload::multi::MultiPayload,
8};
9
10use near_plugins::AccessControllable;
11use near_sdk::{Promise, PublicKey, ext_contract, near};
12use serde_with::serde_as;
13
14use crate::fees::FeesManager;
15
16#[ext_contract(ext_intents)]
17pub trait Intents: FeesManager {
18 fn execute_intents(&mut self, signed: Vec<MultiPayload>);
19
20 fn simulate_intents(&self, signed: Vec<MultiPayload>) -> SimulationOutput;
21}
22
23#[cfg_attr(
24 all(feature = "abi", not(target_arch = "wasm32")),
25 serde_as(schemars = true)
26)]
27#[cfg_attr(
28 not(all(feature = "abi", not(target_arch = "wasm32"))),
29 serde_as(schemars = false)
30)]
31#[near(serializers = [json])]
32#[derive(Debug, Clone)]
33pub struct SimulationOutput {
34 pub intents_executed: Vec<IntentEvent<AccountEvent<'static, NonceEvent>>>,
36
37 pub min_deadline: Deadline,
39
40 #[serde(default, skip_serializing_if = "Option::is_none")]
43 pub invariant_violated: Option<InvariantViolated>,
44
45 pub state: StateOutput,
47}
48
49impl SimulationOutput {
50 pub fn into_result(self) -> Result<(), InvariantViolated> {
51 if let Some(unmatched_deltas) = self.invariant_violated {
52 return Err(unmatched_deltas);
53 }
54 Ok(())
55 }
56}
57
58#[near(serializers = [json])]
59#[derive(Debug, Clone)]
60pub struct StateOutput {
61 pub fee: Pips,
62}
63
64#[ext_contract(ext_relayer_keys)]
65pub trait RelayerKeys: AccessControllable {
66 fn add_relayer_key(&mut self, public_key: PublicKey) -> Promise;
70
71 fn do_add_relayer_key(&mut self, public_key: PublicKey);
72
73 fn delete_relayer_key(&mut self, public_key: PublicKey) -> Promise;
75}