1use crate::account_view::AccountView;
7use crate::address::Address;
8use crate::instruction::{CpiAccount, Signer};
9use crate::ProgramResult;
10
11pub const SYSTEM_PROGRAM_ID: Address = Address::new_from_array([
13 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
14]);
15
16pub struct CreateAccount<'a, 'b> {
20 pub from: &'a AccountView,
21 pub to: &'a AccountView,
22 pub lamports: u64,
23 pub space: u64,
24 pub owner: &'b Address,
25}
26
27impl CreateAccount<'_, '_> {
28 #[inline]
30 pub fn invoke(&self) -> ProgramResult {
31 self.invoke_signed(&[])
32 }
33
34 #[inline]
36 pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
37 let mut data = [0u8; 52];
39 data[4..12].copy_from_slice(&self.lamports.to_le_bytes());
41 data[12..20].copy_from_slice(&self.space.to_le_bytes());
42 data[20..52].copy_from_slice(self.owner.as_array());
43
44 let accounts = [CpiAccount::from(self.from), CpiAccount::from(self.to)];
45
46 invoke_system(&data, &accounts, signers)
47 }
48}
49
50pub struct Transfer<'a> {
54 pub from: &'a AccountView,
55 pub to: &'a AccountView,
56 pub lamports: u64,
57}
58
59impl Transfer<'_> {
60 #[inline]
62 pub fn invoke(&self) -> ProgramResult {
63 self.invoke_signed(&[])
64 }
65
66 #[inline]
68 pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
69 let mut data = [0u8; 12];
71 data[0] = 2;
72 data[4..12].copy_from_slice(&self.lamports.to_le_bytes());
73
74 let accounts = [CpiAccount::from(self.from), CpiAccount::from(self.to)];
75
76 invoke_system(&data, &accounts, signers)
77 }
78}
79
80pub struct Assign<'a, 'b> {
84 pub account: &'a AccountView,
85 pub owner: &'b Address,
86}
87
88impl Assign<'_, '_> {
89 #[inline]
91 pub fn invoke(&self) -> ProgramResult {
92 self.invoke_signed(&[])
93 }
94
95 #[inline]
97 pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
98 let mut data = [0u8; 36];
100 data[0] = 1;
101 data[4..36].copy_from_slice(self.owner.as_array());
102
103 let accounts = [CpiAccount::from(self.account)];
104
105 invoke_system(&data, &accounts, signers)
106 }
107}
108
109pub struct Allocate<'a> {
113 pub account: &'a AccountView,
114 pub space: u64,
115}
116
117impl Allocate<'_> {
118 #[inline]
120 pub fn invoke(&self) -> ProgramResult {
121 self.invoke_signed(&[])
122 }
123
124 #[inline]
126 pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
127 let mut data = [0u8; 12];
129 data[0] = 8;
130 data[4..12].copy_from_slice(&self.space.to_le_bytes());
131
132 let accounts = [CpiAccount::from(self.account)];
133
134 invoke_system(&data, &accounts, signers)
135 }
136}
137
138#[inline]
142fn invoke_system(data: &[u8], accounts: &[CpiAccount], signers: &[Signer]) -> ProgramResult {
143 #[cfg(target_os = "solana")]
145 {
146 let ix = crate::instruction::InstructionView {
147 program_id: &SYSTEM_PROGRAM_ID,
148 data,
149 accounts: &[], };
151 let result = unsafe {
152 crate::syscalls::sol_invoke_signed_c(
153 &ix as *const _ as *const u8,
154 accounts.as_ptr() as *const u8,
155 accounts.len() as u64,
156 signers.as_ptr() as *const u8,
157 signers.len() as u64,
158 )
159 };
160 if result == 0 {
161 Ok(())
162 } else {
163 Err(crate::ProgramError::from(result))
164 }
165 }
166 #[cfg(not(target_os = "solana"))]
167 {
168 let _ = (data, accounts, signers);
169 Ok(())
170 }
171}
172
173pub mod instructions {
175 pub use super::{Allocate, Assign, CreateAccount, Transfer};
176}