1use hopper_runtime::{AccountView, Address, LayoutContract, ProgramError, ProgramResult};
31
32#[inline(always)]
34pub fn require(cond: bool, err: ProgramError) -> ProgramResult {
35 if cond {
36 Ok(())
37 } else {
38 Err(err)
39 }
40}
41
42#[inline(always)]
44pub fn require_eq<T: PartialEq>(a: T, b: T, err: ProgramError) -> ProgramResult {
45 if a == b {
46 Ok(())
47 } else {
48 Err(err)
49 }
50}
51
52#[inline(always)]
54pub fn require_neq<T: PartialEq>(a: T, b: T, err: ProgramError) -> ProgramResult {
55 if a != b {
56 Ok(())
57 } else {
58 Err(err)
59 }
60}
61
62#[inline(always)]
64pub fn require_gte<T: PartialOrd>(a: T, b: T, err: ProgramError) -> ProgramResult {
65 if a >= b {
66 Ok(())
67 } else {
68 Err(err)
69 }
70}
71
72#[inline(always)]
74pub fn require_gt<T: PartialOrd>(a: T, b: T, err: ProgramError) -> ProgramResult {
75 if a > b {
76 Ok(())
77 } else {
78 Err(err)
79 }
80}
81
82#[inline(always)]
84pub fn require_signer(account: &AccountView) -> ProgramResult {
85 account.require_signer()
86}
87
88#[inline(always)]
90pub fn require_writable(account: &AccountView) -> ProgramResult {
91 account.require_writable()
92}
93
94#[inline(always)]
96pub fn require_payer(account: &AccountView) -> ProgramResult {
97 account.require_payer()
98}
99
100#[inline(always)]
102pub fn require_owner(account: &AccountView, owner: &Address) -> ProgramResult {
103 account.require_owned_by(owner)
104}
105
106#[inline(always)]
108pub fn require_address(account: &AccountView, expected: &Address) -> ProgramResult {
109 if hopper_runtime::address::address_eq(account.address(), expected) {
110 Ok(())
111 } else {
112 Err(ProgramError::InvalidArgument)
113 }
114}
115
116#[inline(always)]
118pub fn require_keys_eq(a: &Address, b: &Address, err: ProgramError) -> ProgramResult {
119 if hopper_runtime::address::address_eq(a, b) {
120 Ok(())
121 } else {
122 Err(err)
123 }
124}
125
126#[inline(always)]
128pub fn require_keys_neq(a: &Address, b: &Address, err: ProgramError) -> ProgramResult {
129 if !hopper_runtime::address::address_eq(a, b) {
130 Ok(())
131 } else {
132 Err(err)
133 }
134}
135
136#[inline(always)]
138pub fn require_disc(account: &AccountView, expected: u8) -> ProgramResult {
139 account.require_disc(expected)
140}
141
142#[inline(always)]
144pub fn require_layout<T: LayoutContract>(account: &AccountView) -> ProgramResult {
145 account.check_layout::<T>().map(|_| ())
146}
147
148#[inline(always)]
150pub fn require_has_data(account: &AccountView) -> ProgramResult {
151 if !account.is_data_empty() {
152 Ok(())
153 } else {
154 Err(ProgramError::AccountDataTooSmall)
155 }
156}
157
158#[inline(always)]
160pub fn require_data_len(account: &AccountView, min_len: usize) -> ProgramResult {
161 if account.data_len() >= min_len {
162 Ok(())
163 } else {
164 Err(ProgramError::AccountDataTooSmall)
165 }
166}
167
168#[inline(always)]
172pub fn require_unique_2(a: &AccountView, b: &AccountView) -> ProgramResult {
173 if hopper_runtime::address::address_eq(a.address(), b.address()) {
174 Err(ProgramError::InvalidArgument)
175 } else {
176 Ok(())
177 }
178}
179
180#[inline(always)]
182pub fn require_version<T: LayoutContract>(account: &AccountView) -> ProgramResult {
183 account.check_version(T::VERSION).map(|_| ())
184}
185
186#[inline(always)]
188pub fn require_unique_3(a: &AccountView, b: &AccountView, c: &AccountView) -> ProgramResult {
189 require_unique_2(a, b)?;
190 require_unique_2(a, c)?;
191 require_unique_2(b, c)
192}