hopper_native/
instruction.rs1use crate::account_view::AccountView;
7use crate::address::Address;
8use core::marker::PhantomData;
9
10#[repr(C)]
14#[derive(Debug, Clone)]
15pub struct InstructionAccount<'a> {
16 pub address: &'a Address,
18 pub is_writable: bool,
20 pub is_signer: bool,
22}
23
24impl<'a> InstructionAccount<'a> {
25 #[inline(always)]
27 pub const fn new(address: &'a Address, is_writable: bool, is_signer: bool) -> Self {
28 Self {
29 address,
30 is_writable,
31 is_signer,
32 }
33 }
34
35 #[inline(always)]
37 pub const fn readonly(address: &'a Address) -> Self {
38 Self {
39 address,
40 is_writable: false,
41 is_signer: false,
42 }
43 }
44
45 #[inline(always)]
47 pub const fn writable(address: &'a Address) -> Self {
48 Self {
49 address,
50 is_writable: true,
51 is_signer: false,
52 }
53 }
54
55 #[inline(always)]
57 pub const fn readonly_signer(address: &'a Address) -> Self {
58 Self {
59 address,
60 is_writable: false,
61 is_signer: true,
62 }
63 }
64
65 #[inline(always)]
67 pub const fn writable_signer(address: &'a Address) -> Self {
68 Self {
69 address,
70 is_writable: true,
71 is_signer: true,
72 }
73 }
74}
75
76impl<'a> From<&'a AccountView> for InstructionAccount<'a> {
77 #[inline(always)]
78 fn from(view: &'a AccountView) -> Self {
79 Self {
80 address: view.address(),
81 is_writable: view.is_writable(),
82 is_signer: view.is_signer(),
83 }
84 }
85}
86
87#[derive(Debug, Clone)]
91pub struct InstructionView<'a, 'b, 'c, 'd>
92where
93 'a: 'b,
94{
95 pub program_id: &'c Address,
97 pub data: &'d [u8],
99 pub accounts: &'b [InstructionAccount<'a>],
101}
102
103#[repr(C)]
109#[derive(Clone, Copy, Debug)]
110pub struct CpiAccount<'a> {
111 address: *const Address,
112 lamports: *const u64,
113 data_len: u64,
114 data: *const u8,
115 owner: *const Address,
116 rent_epoch: u64,
117 is_signer: bool,
118 is_writable: bool,
119 executable: bool,
120 _account_view: PhantomData<&'a AccountView>,
121}
122
123impl<'a> From<&'a AccountView> for CpiAccount<'a> {
124 #[inline(always)]
125 fn from(view: &'a AccountView) -> Self {
126 let raw = view.account_ptr();
127 let header = unsafe { *(raw as *const u32) };
131 Self {
132 address: unsafe { &(*raw).address as *const Address },
133 lamports: unsafe { &(*raw).lamports as *const u64 },
135 data_len: view.data_len() as u64,
136 data: view.data_ptr_unchecked(),
137 owner: unsafe { &(*raw).owner as *const Address },
139 rent_epoch: 0,
140 is_signer: header & 0x0000_FF00 != 0,
141 is_writable: header & 0x00FF_0000 != 0,
142 executable: header & 0xFF00_0000 != 0,
143 _account_view: PhantomData,
144 }
145 }
146}
147
148#[repr(C)]
152#[derive(Debug, Clone)]
153pub struct Seed<'a> {
154 pub(crate) seed: *const u8,
155 pub(crate) len: u64,
156 _bytes: PhantomData<&'a [u8]>,
157}
158
159impl<'a> From<&'a [u8]> for Seed<'a> {
160 #[inline(always)]
161 fn from(bytes: &'a [u8]) -> Self {
162 Self {
163 seed: bytes.as_ptr(),
164 len: bytes.len() as u64,
165 _bytes: PhantomData,
166 }
167 }
168}
169
170impl<'a, const N: usize> From<&'a [u8; N]> for Seed<'a> {
171 #[inline(always)]
172 fn from(bytes: &'a [u8; N]) -> Self {
173 Self {
174 seed: bytes.as_ptr(),
175 len: N as u64,
176 _bytes: PhantomData,
177 }
178 }
179}
180
181impl core::ops::Deref for Seed<'_> {
182 type Target = [u8];
183
184 #[inline(always)]
185 fn deref(&self) -> &[u8] {
186 unsafe { core::slice::from_raw_parts(self.seed, self.len as usize) }
188 }
189}
190
191#[repr(C)]
195#[derive(Debug, Clone)]
196pub struct Signer<'a, 'b> {
197 pub(crate) seeds: *const Seed<'a>,
198 pub(crate) len: u64,
199 _seeds: PhantomData<&'b [Seed<'a>]>,
200}
201
202impl<'a, 'b> From<&'b [Seed<'a>]> for Signer<'a, 'b> {
203 #[inline(always)]
204 fn from(seeds: &'b [Seed<'a>]) -> Self {
205 Self {
206 seeds: seeds.as_ptr(),
207 len: seeds.len() as u64,
208 _seeds: PhantomData,
209 }
210 }
211}
212
213impl<'a, 'b, const N: usize> From<&'b [Seed<'a>; N]> for Signer<'a, 'b> {
214 #[inline(always)]
215 fn from(seeds: &'b [Seed<'a>; N]) -> Self {
216 Self {
217 seeds: seeds.as_ptr(),
218 len: N as u64,
219 _seeds: PhantomData,
220 }
221 }
222}
223
224#[macro_export]
228macro_rules! seeds {
229 ( $($seed:expr),* $(,)? ) => {
230 [$(
231 $crate::instruction::Seed::from($seed),
232 )*]
233 };
234}