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) };
130 Self {
131 address: unsafe { &(*raw).address as *const Address },
132 lamports: unsafe { &(*raw).lamports as *const u64 },
133 data_len: view.data_len() as u64,
134 data: view.data_ptr_unchecked(),
135 owner: unsafe { &(*raw).owner as *const Address },
136 rent_epoch: 0,
137 is_signer: header & 0x0000_FF00 != 0,
138 is_writable: header & 0x00FF_0000 != 0,
139 executable: header & 0xFF00_0000 != 0,
140 _account_view: PhantomData,
141 }
142 }
143}
144
145#[repr(C)]
149#[derive(Debug, Clone)]
150pub struct Seed<'a> {
151 pub(crate) seed: *const u8,
152 pub(crate) len: u64,
153 _bytes: PhantomData<&'a [u8]>,
154}
155
156impl<'a> From<&'a [u8]> for Seed<'a> {
157 #[inline(always)]
158 fn from(bytes: &'a [u8]) -> Self {
159 Self {
160 seed: bytes.as_ptr(),
161 len: bytes.len() as u64,
162 _bytes: PhantomData,
163 }
164 }
165}
166
167impl<'a, const N: usize> From<&'a [u8; N]> for Seed<'a> {
168 #[inline(always)]
169 fn from(bytes: &'a [u8; N]) -> Self {
170 Self {
171 seed: bytes.as_ptr(),
172 len: N as u64,
173 _bytes: PhantomData,
174 }
175 }
176}
177
178impl core::ops::Deref for Seed<'_> {
179 type Target = [u8];
180
181 #[inline(always)]
182 fn deref(&self) -> &[u8] {
183 unsafe { core::slice::from_raw_parts(self.seed, self.len as usize) }
184 }
185}
186
187#[repr(C)]
191#[derive(Debug, Clone)]
192pub struct Signer<'a, 'b> {
193 pub(crate) seeds: *const Seed<'a>,
194 pub(crate) len: u64,
195 _seeds: PhantomData<&'b [Seed<'a>]>,
196}
197
198impl<'a, 'b> From<&'b [Seed<'a>]> for Signer<'a, 'b> {
199 #[inline(always)]
200 fn from(seeds: &'b [Seed<'a>]) -> Self {
201 Self {
202 seeds: seeds.as_ptr(),
203 len: seeds.len() as u64,
204 _seeds: PhantomData,
205 }
206 }
207}
208
209impl<'a, 'b, const N: usize> From<&'b [Seed<'a>; N]> for Signer<'a, 'b> {
210 #[inline(always)]
211 fn from(seeds: &'b [Seed<'a>; N]) -> Self {
212 Self {
213 seeds: seeds.as_ptr(),
214 len: N as u64,
215 _seeds: PhantomData,
216 }
217 }
218}
219
220#[macro_export]
224macro_rules! seeds {
225 ( $($seed:expr),* $(,)? ) => {
226 [$(
227 $crate::instruction::Seed::from($seed),
228 )*]
229 };
230}