hopper_runtime/
instruction.rs1use core::marker::PhantomData;
8use crate::address::Address;
9use crate::account::AccountView;
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 { address, is_writable, is_signer }
30 }
31
32 #[inline(always)]
34 pub const fn readonly(address: &'a Address) -> Self {
35 Self { address, is_writable: false, is_signer: false }
36 }
37
38 #[inline(always)]
40 pub const fn writable(address: &'a Address) -> Self {
41 Self { address, is_writable: true, is_signer: false }
42 }
43
44 #[inline(always)]
46 pub const fn readonly_signer(address: &'a Address) -> Self {
47 Self { address, is_writable: false, is_signer: true }
48 }
49
50 #[inline(always)]
52 pub const fn writable_signer(address: &'a Address) -> Self {
53 Self { address, is_writable: true, is_signer: true }
54 }
55}
56
57impl<'a> From<&'a AccountView> for InstructionAccount<'a> {
58 #[inline(always)]
59 fn from(view: &'a AccountView) -> Self {
60 Self {
61 address: view.address(),
62 is_writable: view.is_writable(),
63 is_signer: view.is_signer(),
64 }
65 }
66}
67
68#[derive(Debug, Clone)]
72pub struct InstructionView<'a, 'b, 'c, 'd>
73where
74 'a: 'b,
75{
76 pub program_id: &'c Address,
78 pub data: &'d [u8],
80 pub accounts: &'b [InstructionAccount<'a>],
82}
83
84#[cfg(feature = "hopper-native-backend")]
92#[repr(C)]
93#[derive(Clone, Copy, Debug)]
94pub struct CpiAccount<'a> {
95 address: *const Address,
96 lamports: *const u64,
97 data_len: u64,
98 data: *const u8,
99 owner: *const Address,
100 rent_epoch: u64,
101 is_signer: bool,
102 is_writable: bool,
103 executable: bool,
104 _account_view: PhantomData<&'a AccountView>,
105}
106
107#[cfg(feature = "hopper-native-backend")]
108impl<'a> From<&'a AccountView> for CpiAccount<'a> {
109 #[inline]
110 fn from(view: &'a AccountView) -> Self {
111 let raw = view.account_ptr();
112 Self {
116 address: unsafe { core::ptr::addr_of!((*raw).address) as *const Address },
117 lamports: unsafe { core::ptr::addr_of!((*raw).lamports) },
118 data_len: view.data_len() as u64,
119 data: view.data_ptr_unchecked(),
120 owner: unsafe { core::ptr::addr_of!((*raw).owner) as *const Address },
121 rent_epoch: 0,
122 is_signer: view.is_signer(),
123 is_writable: view.is_writable(),
124 executable: view.executable(),
125 _account_view: PhantomData,
126 }
127 }
128}
129
130#[repr(C)]
134#[derive(Debug, Clone)]
135pub struct Seed<'a> {
136 pub(crate) seed: *const u8,
137 pub(crate) len: u64,
138 _bytes: PhantomData<&'a [u8]>,
139}
140
141impl<'a> From<&'a [u8]> for Seed<'a> {
142 #[inline(always)]
143 fn from(bytes: &'a [u8]) -> Self {
144 Self {
145 seed: bytes.as_ptr(),
146 len: bytes.len() as u64,
147 _bytes: PhantomData,
148 }
149 }
150}
151
152impl<'a, const N: usize> From<&'a [u8; N]> for Seed<'a> {
153 #[inline(always)]
154 fn from(bytes: &'a [u8; N]) -> Self {
155 Self {
156 seed: bytes.as_ptr(),
157 len: N as u64,
158 _bytes: PhantomData,
159 }
160 }
161}
162
163impl core::ops::Deref for Seed<'_> {
164 type Target = [u8];
165
166 #[inline(always)]
167 fn deref(&self) -> &[u8] {
168 unsafe { core::slice::from_raw_parts(self.seed, self.len as usize) }
169 }
170}
171
172#[repr(C)]
176#[derive(Debug, Clone)]
177pub struct Signer<'a, 'b> {
178 pub(crate) seeds: *const Seed<'a>,
179 pub(crate) len: u64,
180 _seeds: PhantomData<&'b [Seed<'a>]>,
181}
182
183impl<'a, 'b> From<&'b [Seed<'a>]> for Signer<'a, 'b> {
184 #[inline(always)]
185 fn from(seeds: &'b [Seed<'a>]) -> Self {
186 Self {
187 seeds: seeds.as_ptr(),
188 len: seeds.len() as u64,
189 _seeds: PhantomData,
190 }
191 }
192}
193
194impl<'a, 'b, const N: usize> From<&'b [Seed<'a>; N]> for Signer<'a, 'b> {
195 #[inline(always)]
196 fn from(seeds: &'b [Seed<'a>; N]) -> Self {
197 Self {
198 seeds: seeds.as_ptr(),
199 len: N as u64,
200 _seeds: PhantomData,
201 }
202 }
203}
204
205#[macro_export]
209macro_rules! seeds {
210 ( $($seed:expr),* $(,)? ) => {
211 [$(
212 $crate::instruction::Seed::from($seed),
213 )*]
214 };
215}