1#![no_std]
2
3pub use {accounts::*, discriminator::*, programs::*};
4use {
5 bytemuck::{AnyBitPattern, NoUninit},
6 pinocchio::{
7 account_info::{AccountInfo, Ref, RefMut},
8 pubkey::Pubkey,
9 },
10 sealed::Sealed,
11 typhoon_errors::Error,
12};
13
14mod accounts;
15mod discriminator;
16mod programs;
17
18pub trait FromAccountInfo<'a>: Sized {
19 fn try_from_info(info: &'a AccountInfo) -> Result<Self, Error>;
20}
21
22pub trait ReadableAccount: AsRef<AccountInfo> {
23 type DataUnchecked: ?Sized;
24 type Data<'a>
25 where
26 Self: 'a;
27
28 #[inline(always)]
29 fn key(&self) -> &Pubkey {
30 self.as_ref().key()
31 }
32
33 #[inline(always)]
34 fn is_owned_by(&self, owner: &Pubkey) -> bool {
35 self.as_ref().is_owned_by(owner)
36 }
37
38 #[inline(always)]
39 fn lamports(&self) -> Result<Ref<'_, u64>, Error> {
40 self.as_ref().try_borrow_lamports().map_err(Into::into)
41 }
42
43 fn data<'a>(&'a self) -> Result<Self::Data<'a>, Error>;
44
45 fn data_unchecked(&self) -> Result<&Self::DataUnchecked, Error>;
46}
47
48pub trait WritableAccount: ReadableAccount + Sealed {
49 type DataMut<'a>
50 where
51 Self: 'a;
52
53 #[inline(always)]
54 fn assign(&self, new_owner: &Pubkey) {
55 unsafe {
56 self.as_ref().assign(new_owner);
57 }
58 }
59
60 #[inline(always)]
61 fn resize(&self, new_len: usize) -> Result<(), Error> {
62 self.as_ref().resize(new_len).map_err(Into::into)
63 }
64
65 #[inline(always)]
66 fn mut_lamports(&self) -> Result<RefMut<'_, u64>, Error> {
67 self.as_ref().try_borrow_mut_lamports().map_err(Into::into)
68 }
69
70 fn mut_data<'a>(&'a self) -> Result<Self::DataMut<'a>, Error>;
71}
72
73pub trait SignerAccount: ReadableAccount + Sealed {}
74
75mod sealed {
76 use {
77 super::{Mut, ReadableAccount, Signer},
78 crate::SignerCheck,
79 pinocchio::account_info::AccountInfo,
80 };
81
82 pub trait Sealed {}
83
84 impl<T> Sealed for Mut<T> where T: ReadableAccount + AsRef<AccountInfo> {}
85 impl<T, C> Sealed for Signer<'_, T, C>
86 where
87 T: ReadableAccount,
88 C: SignerCheck,
89 {
90 }
91}
92
93pub trait ProgramId {
94 const ID: Pubkey;
95}
96
97pub trait ProgramIds {
98 const IDS: &'static [Pubkey];
99}
100
101pub trait Owner {
102 const OWNER: Pubkey;
103}
104
105pub trait Owners {
106 const OWNERS: &'static [Pubkey];
107}
108
109pub trait Discriminator {
110 const DISCRIMINATOR: &'static [u8];
111}
112
113pub trait RefFromBytes {
114 fn read(data: &[u8]) -> Option<&Self>;
115 fn read_mut(data: &mut [u8]) -> Option<&mut Self>;
116}
117
118impl<T> RefFromBytes for T
119where
120 T: Discriminator + AnyBitPattern + NoUninit,
121{
122 fn read(data: &[u8]) -> Option<&Self> {
123 let dis_len = T::DISCRIMINATOR.len();
124 let total_len = dis_len + core::mem::size_of::<T>();
125
126 if data.len() < total_len {
127 return None;
128 }
129
130 let data_ptr = data[dis_len..total_len].as_ptr();
131
132 if data_ptr.align_offset(core::mem::align_of::<T>()) != 0 {
133 return None;
134 }
135
136 Some(unsafe { &*(data_ptr as *const T) })
137 }
138
139 fn read_mut(data: &mut [u8]) -> Option<&mut Self> {
140 let dis_len = T::DISCRIMINATOR.len();
141 let total_len = dis_len + core::mem::size_of::<T>();
142
143 if data.len() < total_len {
144 return None;
145 }
146
147 let data_ptr = data[dis_len..total_len].as_mut_ptr();
148
149 if data_ptr.align_offset(core::mem::align_of::<T>()) != 0 {
150 return None;
151 }
152
153 Some(unsafe { &mut *(data_ptr as *mut T) })
154 }
155}
156
157pub trait FromRaw<'a> {
158 fn from_raw(info: &'a AccountInfo) -> Self;
159}