typhoon_token/
lib.rs

1#![no_std]
2
3use {
4    core::{mem::transmute, ops::Deref},
5    five8_const::decode_32_const,
6    pinocchio::pubkey::{find_program_address, Pubkey},
7    pinocchio_associated_token_account::ID as ATA_PROGRAM_ID,
8    pinocchio_token::{
9        state::{Mint as SplMint, TokenAccount as SplTokenAccount},
10        ID as TOKEN_PROGRAM_ID,
11    },
12    typhoon_accounts::{Discriminator, Owner, Owners, ProgramId, ProgramIds, RefFromBytes},
13};
14
15mod traits;
16
17pub use {
18    pinocchio_associated_token_account::instructions as ata_instructions,
19    pinocchio_token::instructions as spl_instructions, traits::*,
20};
21
22const TOKEN_2022_PROGRAM_ID: Pubkey =
23    decode_32_const("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb");
24
25pub struct AtaTokenProgram;
26
27impl ProgramId for AtaTokenProgram {
28    const ID: Pubkey = ATA_PROGRAM_ID;
29}
30
31pub struct TokenProgram;
32
33impl ProgramId for TokenProgram {
34    const ID: Pubkey = TOKEN_PROGRAM_ID;
35}
36
37impl ProgramIds for TokenProgram {
38    const IDS: &'static [Pubkey] = &[TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID];
39}
40
41#[repr(transparent)]
42pub struct Mint(SplMint);
43
44impl Mint {
45    pub const LEN: usize = SplMint::LEN;
46}
47
48impl RefFromBytes for Mint {
49    fn read(data: &[u8]) -> Option<&Self> {
50        Some(unsafe { transmute::<&SplMint, &Mint>(SplMint::from_bytes_unchecked(data)) })
51    }
52
53    fn read_mut(_data: &mut [u8]) -> Option<&mut Self> {
54        unimplemented!()
55    }
56}
57
58impl Discriminator for Mint {
59    const DISCRIMINATOR: &'static [u8] = &[];
60}
61
62impl Owner for Mint {
63    const OWNER: Pubkey = TOKEN_PROGRAM_ID;
64}
65
66impl Owners for Mint {
67    const OWNERS: &'static [Pubkey] = &[TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID];
68}
69
70impl Deref for Mint {
71    type Target = SplMint;
72
73    fn deref(&self) -> &Self::Target {
74        &self.0
75    }
76}
77
78#[repr(transparent)]
79pub struct TokenAccount(SplTokenAccount);
80
81impl TokenAccount {
82    pub const LEN: usize = SplTokenAccount::LEN;
83}
84
85impl RefFromBytes for TokenAccount {
86    fn read(data: &[u8]) -> Option<&Self> {
87        Some(unsafe {
88            transmute::<&SplTokenAccount, &TokenAccount>(SplTokenAccount::from_bytes_unchecked(
89                data,
90            ))
91        })
92    }
93
94    fn read_mut(_data: &mut [u8]) -> Option<&mut Self> {
95        unimplemented!()
96    }
97}
98
99impl Discriminator for TokenAccount {
100    const DISCRIMINATOR: &'static [u8] = &[];
101}
102
103impl Owner for TokenAccount {
104    const OWNER: Pubkey = TOKEN_PROGRAM_ID;
105}
106
107impl Owners for TokenAccount {
108    const OWNERS: &'static [Pubkey] = &[TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID];
109}
110
111impl Deref for TokenAccount {
112    type Target = SplTokenAccount;
113
114    fn deref(&self) -> &Self::Target {
115        &self.0
116    }
117}
118
119pub fn find_associated_token_address(mint: &Pubkey, owner: &Pubkey) -> Pubkey {
120    find_program_address(
121        &[owner.as_ref(), TOKEN_PROGRAM_ID.as_ref(), mint.as_ref()],
122        &ATA_PROGRAM_ID,
123    )
124    .0
125}