hopper_runtime/
instruction.rs1use crate::account::AccountView;
8use crate::address::Address;
9use core::marker::PhantomData;
10
11#[repr(C)]
15#[derive(Debug, Clone)]
16pub struct InstructionAccount<'a> {
17 pub address: &'a Address,
19 pub is_writable: bool,
21 pub is_signer: bool,
23}
24
25impl<'a> InstructionAccount<'a> {
26 #[inline(always)]
28 pub const fn new(address: &'a Address, is_writable: bool, is_signer: bool) -> Self {
29 Self {
30 address,
31 is_writable,
32 is_signer,
33 }
34 }
35
36 #[inline(always)]
38 pub const fn readonly(address: &'a Address) -> Self {
39 Self {
40 address,
41 is_writable: false,
42 is_signer: false,
43 }
44 }
45
46 #[inline(always)]
48 pub const fn writable(address: &'a Address) -> Self {
49 Self {
50 address,
51 is_writable: true,
52 is_signer: false,
53 }
54 }
55
56 #[inline(always)]
58 pub const fn readonly_signer(address: &'a Address) -> Self {
59 Self {
60 address,
61 is_writable: false,
62 is_signer: true,
63 }
64 }
65
66 #[inline(always)]
68 pub const fn writable_signer(address: &'a Address) -> Self {
69 Self {
70 address,
71 is_writable: true,
72 is_signer: true,
73 }
74 }
75}
76
77impl<'a> From<&'a AccountView> for InstructionAccount<'a> {
78 #[inline(always)]
79 fn from(view: &'a AccountView) -> Self {
80 Self {
81 address: view.address(),
82 is_writable: view.is_writable(),
83 is_signer: view.is_signer(),
84 }
85 }
86}
87
88#[derive(Debug, Clone)]
92pub struct InstructionView<'a, 'b, 'c, 'd>
93where
94 'a: 'b,
95{
96 pub program_id: &'c Address,
98 pub data: &'d [u8],
100 pub accounts: &'b [InstructionAccount<'a>],
102}
103
104#[cfg(feature = "hopper-native-backend")]
112#[repr(C)]
113#[derive(Clone, Copy, Debug)]
114pub struct CpiAccount<'a> {
115 address: *const Address,
116 lamports: *const u64,
117 data_len: u64,
118 data: *const u8,
119 owner: *const Address,
120 rent_epoch: u64,
121 is_signer: bool,
122 is_writable: bool,
123 executable: bool,
124 _account_view: PhantomData<&'a AccountView>,
125}
126
127#[cfg(feature = "hopper-native-backend")]
128impl<'a> From<&'a AccountView> for CpiAccount<'a> {
129 #[inline]
130 fn from(view: &'a AccountView) -> Self {
131 let raw = view.account_ptr();
132 Self {
136 address: unsafe { core::ptr::addr_of!((*raw).address) as *const Address },
138 lamports: unsafe { core::ptr::addr_of!((*raw).lamports) },
139 data_len: view.data_len() as u64,
140 data: view.data_ptr_unchecked(),
141 owner: unsafe { core::ptr::addr_of!((*raw).owner) as *const Address },
143 rent_epoch: 0,
144 is_signer: view.is_signer(),
145 is_writable: view.is_writable(),
146 executable: view.executable(),
147 _account_view: PhantomData,
148 }
149 }
150}
151
152#[repr(C)]
156#[derive(Debug, Clone)]
157pub struct Seed<'a> {
158 pub(crate) seed: *const u8,
159 pub(crate) len: u64,
160 _bytes: PhantomData<&'a [u8]>,
161}
162
163impl<'a> From<&'a [u8]> for Seed<'a> {
164 #[inline(always)]
165 fn from(bytes: &'a [u8]) -> Self {
166 Self {
167 seed: bytes.as_ptr(),
168 len: bytes.len() as u64,
169 _bytes: PhantomData,
170 }
171 }
172}
173
174impl<'a, const N: usize> From<&'a [u8; N]> for Seed<'a> {
175 #[inline(always)]
176 fn from(bytes: &'a [u8; N]) -> Self {
177 Self {
178 seed: bytes.as_ptr(),
179 len: N as u64,
180 _bytes: PhantomData,
181 }
182 }
183}
184
185impl core::ops::Deref for Seed<'_> {
186 type Target = [u8];
187
188 #[inline(always)]
189 fn deref(&self) -> &[u8] {
190 unsafe { core::slice::from_raw_parts(self.seed, self.len as usize) }
192 }
193}
194
195#[repr(C)]
199#[derive(Debug, Clone)]
200pub struct Signer<'a, 'b> {
201 pub(crate) seeds: *const Seed<'a>,
202 pub(crate) len: u64,
203 _seeds: PhantomData<&'b [Seed<'a>]>,
204}
205
206impl<'a, 'b> From<&'b [Seed<'a>]> for Signer<'a, 'b> {
207 #[inline(always)]
208 fn from(seeds: &'b [Seed<'a>]) -> Self {
209 Self {
210 seeds: seeds.as_ptr(),
211 len: seeds.len() as u64,
212 _seeds: PhantomData,
213 }
214 }
215}
216
217impl<'a, 'b, const N: usize> From<&'b [Seed<'a>; N]> for Signer<'a, 'b> {
218 #[inline(always)]
219 fn from(seeds: &'b [Seed<'a>; N]) -> Self {
220 Self {
221 seeds: seeds.as_ptr(),
222 len: N as u64,
223 _seeds: PhantomData,
224 }
225 }
226}
227
228#[macro_export]
232macro_rules! seeds {
233 ( $($seed:expr),* $(,)? ) => {
234 [$(
235 $crate::instruction::Seed::from($seed),
236 )*]
237 };
238}