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}
89
90#[derive(Clone, Default, Serialize, Deserialize, Debug, PartialEq, Eq)]
91pub struct MagicIntentBundleArgs {
92    pub commit: Option<CommitTypeArgs>,
93    pub commit_and_undelegate: Option<CommitAndUndelegateArgs>,
94    pub standalone_actions: Vec<BaseActionArgs>,
95}
96
97impl From<MagicBaseIntentArgs> for MagicIntentBundleArgs {
98    fn from(value: MagicBaseIntentArgs) -> Self {
99        let mut this = Self::default();
100        match value {
101            MagicBaseIntentArgs::BaseActions(value) => {
102                this.standalone_actions.extend(value)
103            }
104            MagicBaseIntentArgs::Commit(value) => this.commit = Some(value),
105            MagicBaseIntentArgs::CommitAndUndelegate(value) => {
106                this.commit_and_undelegate = Some(value)
107            }
108        }
109
110        this
111    }
112}
113
114/// A compact account meta used for base-layer actions.
115///
116/// Unlike `solana_instruction::AccountMeta`, this type **does not** carry an
117/// `is_signer` flag. Users cannot request signatures: the only signer available
118/// is the validator.
119#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
120pub struct ShortAccountMeta {
121    pub pubkey: Pubkey,
122    /// Whether this account should be marked **writable**
123    /// in the Base layer instruction built from this action.
124    pub is_writable: bool,
125}
126impl From<AccountMeta> for ShortAccountMeta {
127    fn from(value: AccountMeta) -> Self {
128        Self {
129            pubkey: value.pubkey,
130            is_writable: value.is_writable,
131        }
132    }
133}
134
135impl<'a> From<AccountInfo<'a>> for ShortAccountMeta {
136    fn from(value: AccountInfo<'a>) -> Self {
137        Self::from(&value)
138    }
139}
140
141impl<'a> From<&AccountInfo<'a>> for ShortAccountMeta {
142    fn from(value: &AccountInfo<'a>) -> Self {
143        Self {
144            pubkey: *value.key,
145            is_writable: value.is_writable,
146        }
147    }
148}
149
150#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
151pub struct ScheduleTaskArgs {
152    pub task_id: i64,
153    pub execution_interval_millis: i64,
154    pub iterations: i64,
155    pub instructions: Vec<Instruction>,
156}
157
158#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
159pub enum TaskRequest {
160    Schedule(ScheduleTaskRequest),
161    Cancel(CancelTaskRequest),
162}
163
164#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
165pub struct ScheduleTaskRequest {
166    /// Unique identifier for this task
167    pub id: i64,
168    /// Unsigned instructions to execute when triggered
169    pub instructions: Vec<Instruction>,
170    /// Authority that can modify or cancel this task
171    pub authority: Pubkey,
172    /// How frequently the task should be executed, in milliseconds
173    pub execution_interval_millis: i64,
174    /// Number of times this task will be executed
175    pub iterations: i64,
176}
177
178#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
179pub struct CancelTaskRequest {
180    /// Unique identifier for the task to cancel
181    pub task_id: i64,
182    /// Authority that can cancel this task
183    pub authority: Pubkey,
184}
185
186impl TaskRequest {
187    pub fn id(&self) -> i64 {
188        match self {
189            Self::Schedule(request) => request.id,
190            Self::Cancel(request) => request.task_id,
191        }
192    }
193}