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