1use crate::account::AccountView;
14use crate::address::Address;
15use crate::instruction::{InstructionAccount, InstructionView, Signer};
16use crate::ProgramResult;
17
18pub const SYSTEM_PROGRAM_ID: Address = Address::new_from_array([
20 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
21 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22]);
23
24pub struct CreateAccount<'a, 'b> {
28 pub from: &'a AccountView,
29 pub to: &'a AccountView,
30 pub lamports: u64,
31 pub space: u64,
32 pub owner: &'b Address,
33}
34
35impl CreateAccount<'_, '_> {
36 #[inline]
37 pub fn invoke(&self) -> ProgramResult {
38 self.invoke_signed(&[])
39 }
40
41 #[inline]
42 pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
43 let mut data = [0u8; 52];
44 data[4..12].copy_from_slice(&self.lamports.to_le_bytes());
46 data[12..20].copy_from_slice(&self.space.to_le_bytes());
47 data[20..52].copy_from_slice(self.owner.as_array());
48
49 let accounts = [
50 InstructionAccount::writable_signer(self.from.address()),
51 InstructionAccount::writable_signer(self.to.address()),
52 ];
53 let views = [self.from, self.to];
54 let instruction = InstructionView {
55 program_id: &SYSTEM_PROGRAM_ID,
56 data: &data,
57 accounts: &accounts,
58 };
59
60 crate::cpi::invoke_signed(&instruction, &views, signers)
61 }
62}
63
64pub struct Transfer<'a> {
68 pub from: &'a AccountView,
69 pub to: &'a AccountView,
70 pub lamports: u64,
71}
72
73impl Transfer<'_> {
74 #[inline]
75 pub fn invoke(&self) -> ProgramResult {
76 self.invoke_signed(&[])
77 }
78
79 #[inline]
80 pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
81 let mut data = [0u8; 12];
82 data[0] = 2;
83 data[4..12].copy_from_slice(&self.lamports.to_le_bytes());
84
85 let accounts = [
86 InstructionAccount::writable_signer(self.from.address()),
87 InstructionAccount::writable(self.to.address()),
88 ];
89 let views = [self.from, self.to];
90 let instruction = InstructionView {
91 program_id: &SYSTEM_PROGRAM_ID,
92 data: &data,
93 accounts: &accounts,
94 };
95
96 crate::cpi::invoke_signed(&instruction, &views, signers)
97 }
98}
99
100pub struct Assign<'a, 'b> {
104 pub account: &'a AccountView,
105 pub owner: &'b Address,
106}
107
108impl Assign<'_, '_> {
109 #[inline]
110 pub fn invoke(&self) -> ProgramResult {
111 self.invoke_signed(&[])
112 }
113
114 #[inline]
115 pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
116 let mut data = [0u8; 36];
117 data[0] = 1;
118 data[4..36].copy_from_slice(self.owner.as_array());
119
120 let accounts = [InstructionAccount::writable_signer(self.account.address())];
121 let views = [self.account];
122 let instruction = InstructionView {
123 program_id: &SYSTEM_PROGRAM_ID,
124 data: &data,
125 accounts: &accounts,
126 };
127
128 crate::cpi::invoke_signed(&instruction, &views, signers)
129 }
130}
131
132pub struct Allocate<'a> {
136 pub account: &'a AccountView,
137 pub space: u64,
138}
139
140impl Allocate<'_> {
141 #[inline]
142 pub fn invoke(&self) -> ProgramResult {
143 self.invoke_signed(&[])
144 }
145
146 #[inline]
147 pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
148 let mut data = [0u8; 12];
149 data[0] = 8;
150 data[4..12].copy_from_slice(&self.space.to_le_bytes());
151
152 let accounts = [InstructionAccount::writable_signer(self.account.address())];
153 let views = [self.account];
154 let instruction = InstructionView {
155 program_id: &SYSTEM_PROGRAM_ID,
156 data: &data,
157 accounts: &accounts,
158 };
159
160 crate::cpi::invoke_signed(&instruction, &views, signers)
161 }
162}
163
164pub mod instructions {
166 pub use super::{CreateAccount, Transfer, Assign, Allocate};
167}