1use ifx_core::wire::{LetBinding, ValueType};
4use solana_sdk::instruction::AccountMeta;
5use solana_sdk::pubkey::Pubkey;
6
7use crate::error::ScratchError;
8use crate::scratch::FrameScratch;
9use crate::typed::ScratchValue;
10
11fn readonly_meta(pubkey: Pubkey) -> AccountMeta {
12 AccountMeta {
13 pubkey,
14 is_signer: false,
15 is_writable: false,
16 }
17}
18
19macro_rules! let_one_account {
20 ($($fn_name:ident => $variant:ident),* $(,)?) => {
21 $(
22 pub fn $fn_name(&mut self, account: Pubkey) -> Result<ScratchValue, ScratchError> {
23 self.plan(
24 LetBinding::$variant { account_index: 0 },
25 &[readonly_meta(account)],
26 )
27 }
28 )*
29 };
30}
31
32impl FrameScratch {
33 let_one_account! {
34 let_spl_token_amount => SplTokenAccountAmount,
35 let_spl_token_delegated_amount => SplTokenAccountDelegatedAmount,
36 let_spl_token_account_state => SplTokenAccountState,
37 let_spl_mint_supply => SplMintSupply,
38 let_spl_mint_decimals => SplMintDecimals,
39 let_spl_token2022_amount => SplToken2022AccountAmount,
40 let_spl_token2022_delegated_amount => SplToken2022AccountDelegatedAmount,
41 let_spl_token2022_account_state => SplToken2022AccountState,
42 let_spl_token2022_transfer_fee_withheld => SplToken2022AccountTransferFeeWithheld,
43 let_spl_token2022_mint_supply => SplToken2022MintSupply,
44 let_spl_token2022_mint_decimals => SplToken2022MintDecimals,
45 let_spl_token2022_mint_transfer_fee_bps => SplToken2022MintTransferFeeBasisPoints,
46 let_spl_token2022_mint_transfer_fee_max => SplToken2022MintTransferFeeMaximum,
47 let_spl_token2022_mint_withheld_amount => SplToken2022MintWithheldAmount,
48 let_spl_token2022_mint_default_account_state => SplToken2022MintDefaultAccountState,
49 let_account_key => AccountKey,
50 let_stake_authorized_staker => StakeAuthorizedStaker,
51 let_stake_authorized_withdrawer => StakeAuthorizedWithdrawer,
52 let_stake_lockup_unix_timestamp => StakeLockupUnixTimestamp,
53 let_stake_lockup_epoch => StakeLockupEpoch,
54 let_stake_delegation_stake => StakeDelegationStake,
55 }
56
57 pub fn let_const_pubkey(&mut self, bytes: [u8; 32]) -> Result<ScratchValue, ScratchError> {
58 self.plan(LetBinding::ConstPubkey { bytes }, &[])
59 }
60
61 pub fn let_frame_generation(&mut self) -> Result<ScratchValue, ScratchError> {
62 self.plan(LetBinding::FrameGeneration, &[])
63 }
64
65 pub fn let_frame_index_count(&mut self) -> Result<ScratchValue, ScratchError> {
66 self.plan(LetBinding::FrameIndexCount, &[])
67 }
68
69 pub fn clock_slot(&mut self) -> Result<ScratchValue, ScratchError> {
70 self.plan(LetBinding::SysvarClockSlot, &[])
71 }
72
73 pub fn clock_epoch_start_timestamp(&mut self) -> Result<ScratchValue, ScratchError> {
74 self.plan(LetBinding::SysvarClockEpochStartTimestamp, &[])
75 }
76
77 pub fn clock_epoch(&mut self) -> Result<ScratchValue, ScratchError> {
78 self.plan(LetBinding::SysvarClockEpoch, &[])
79 }
80
81 pub fn clock_leader_schedule_epoch(&mut self) -> Result<ScratchValue, ScratchError> {
82 self.plan(LetBinding::SysvarClockLeaderScheduleEpoch, &[])
83 }
84
85 pub fn clock_unix_timestamp(&mut self) -> Result<ScratchValue, ScratchError> {
86 self.plan(LetBinding::SysvarClockUnixTimestamp, &[])
87 }
88
89 pub fn rent_minimum_balance(&mut self, data_len: u32) -> Result<ScratchValue, ScratchError> {
90 self.plan(LetBinding::SysvarRentMinimumBalance { data_len }, &[])
91 }
92
93 pub fn let_account_data_slice(
94 &mut self,
95 account: Pubkey,
96 expected_owner: Pubkey,
97 ty: ValueType,
98 offset: u32,
99 ) -> Result<ScratchValue, ScratchError> {
100 self.plan(
101 LetBinding::AccountDataSlice {
102 ty,
103 account_index: 0,
104 offset,
105 expected_program_owner: 1,
106 },
107 &[readonly_meta(account), readonly_meta(expected_owner)],
108 )
109 }
110}