Skip to main content

magicblock_magic_program_api/
args.rs

1use serde::{Deserialize, Serialize};
2use solana_program::{
3    account_info::AccountInfo,
4    instruction::{AccountMeta, Instruction},
5};
6
7use crate::Pubkey;
8
9#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
10pub struct ActionArgs {
11    pub escrow_index: u8,
12    pub data: Vec<u8>,
13}
14
15impl ActionArgs {
16    pub fn new(data: Vec<u8>) -> Self {
17        Self {
18            escrow_index: 255,
19            data,
20        }
21    }
22    pub fn escrow_index(&self) -> u8 {
23        self.escrow_index
24    }
25
26    pub fn data(&self) -> &Vec<u8> {
27        &self.data
28    }
29
30    pub fn with_escrow_index(mut self, index: u8) -> Self {
31        self.escrow_index = index;
32        self
33    }
34}
35
36#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
37pub struct BaseActionArgs {
38    pub args: ActionArgs,
39    pub compute_units: u32, // compute units your action will use
40    pub escrow_authority: u8, // index of account authorizing action on actor pda
41    pub destination_program: Pubkey, // address of destination program
42    pub accounts: Vec<ShortAccountMeta>, // short account metas
43}
44
45#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
46pub enum CommitTypeArgs {
47    Standalone(Vec<u8>), // indices on accounts
48    WithBaseActions {
49        committed_accounts: Vec<u8>, // indices of accounts
50        base_actions: Vec<BaseActionArgs>,
51    },
52}
53
54impl CommitTypeArgs {
55    pub fn committed_accounts_indices(&self) -> &Vec<u8> {
56        match self {
57            Self::Standalone(value) => value,
58            Self::WithBaseActions {
59                committed_accounts, ..
60            } => committed_accounts,
61        }
62    }
63}
64
65#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
66pub enum UndelegateTypeArgs {
67    Standalone,
68    WithBaseActions { base_actions: Vec<BaseActionArgs> },
69}
70
71#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
72pub struct CommitAndUndelegateArgs {
73    pub commit_type: CommitTypeArgs,
74    pub undelegate_type: UndelegateTypeArgs,
75}
76
77impl CommitAndUndelegateArgs {
78    pub fn committed_accounts_indices(&self) -> &Vec<u8> {
79        self.commit_type.committed_accounts_indices()
80    }
81}
82
83#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
84pub enum MagicBaseIntentArgs {
85    BaseActions(Vec<BaseActionArgs>),
86    Commit(CommitTypeArgs),
87    CommitAndUndelegate(CommitAndUndelegateArgs),
88    CommitFinalize(CommitTypeArgs),
89    CommitFinalizeAndUndelegate(CommitAndUndelegateArgs),
90}
91
92#[derive(Clone, Default, Serialize, Deserialize, Debug, PartialEq, Eq)]
93pub struct MagicIntentBundleArgs {
94    pub commit: Option<CommitTypeArgs>,
95    pub commit_and_undelegate: Option<CommitAndUndelegateArgs>,
96    pub commit_finalize: Option<CommitTypeArgs>,
97    pub commit_finalize_and_undelegate: Option<CommitAndUndelegateArgs>,
98    pub standalone_actions: Vec<BaseActionArgs>,
99}
100
101impl From<MagicBaseIntentArgs> for MagicIntentBundleArgs {
102    fn from(value: MagicBaseIntentArgs) -> Self {
103        let mut this = Self::default();
104        match value {
105            MagicBaseIntentArgs::BaseActions(value) => {
106                this.standalone_actions.extend(value)
107            }
108            MagicBaseIntentArgs::Commit(value) => this.commit = Some(value),
109            MagicBaseIntentArgs::CommitAndUndelegate(value) => {
110                this.commit_and_undelegate = Some(value)
111            }
112            MagicBaseIntentArgs::CommitFinalize(value) => {
113                this.commit_finalize = Some(value)
114            }
115            MagicBaseIntentArgs::CommitFinalizeAndUndelegate(value) => {
116                this.commit_finalize_and_undelegate = Some(value)
117            }
118        }
119
120        this
121    }
122}
123
124/// A compact account meta used for base-layer actions.
125///
126/// Unlike `solana_instruction::AccountMeta`, this type **does not** carry an
127/// `is_signer` flag. Users cannot request signatures: the only signer available
128/// is the validator.
129#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
130pub struct ShortAccountMeta {
131    pub pubkey: Pubkey,
132    /// Whether this account should be marked **writable**
133    /// in the Base layer instruction built from this action.
134    pub is_writable: bool,
135}
136impl From<AccountMeta> for ShortAccountMeta {
137    fn from(value: AccountMeta) -> Self {
138        Self {
139            pubkey: value.pubkey,
140            is_writable: value.is_writable,
141        }
142    }
143}
144
145impl<'a> From<AccountInfo<'a>> for ShortAccountMeta {
146    fn from(value: AccountInfo<'a>) -> Self {
147        Self::from(&value)
148    }
149}
150
151impl<'a> From<&AccountInfo<'a>> for ShortAccountMeta {
152    fn from(value: &AccountInfo<'a>) -> Self {
153        Self {
154            pubkey: *value.key,
155            is_writable: value.is_writable,
156        }
157    }
158}
159
160#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
161pub struct ScheduleTaskArgs {
162    pub task_id: i64,
163    pub execution_interval_millis: i64,
164    pub iterations: i64,
165    pub instructions: Vec<Instruction>,
166}
167
168#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
169pub enum TaskRequest {
170    Schedule(ScheduleTaskRequest),
171    Cancel(CancelTaskRequest),
172}
173
174#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
175pub struct ScheduleTaskRequest {
176    /// Unique identifier for this task
177    pub id: i64,
178    /// Unsigned instructions to execute when triggered
179    pub instructions: Vec<Instruction>,
180    /// Authority that can modify or cancel this task
181    pub authority: Pubkey,
182    /// How frequently the task should be executed, in milliseconds
183    pub execution_interval_millis: i64,
184    /// Number of times this task will be executed
185    pub iterations: i64,
186}
187
188#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
189pub struct CancelTaskRequest {
190    /// Unique identifier for the task to cancel
191    pub task_id: i64,
192    /// Authority that can cancel this task
193    pub authority: Pubkey,
194}
195
196impl TaskRequest {
197    pub fn id(&self) -> i64 {
198        match self {
199            Self::Schedule(request) => request.id,
200            Self::Cancel(request) => request.task_id,
201        }
202    }
203}