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