Skip to main content

magicblock_magic_program_api/
args.rs

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