Skip to main content

ifx_sdk/
let_bindings.rs

1//! `FrameScratch` typed `let_*` planners (SPL, clock, stake, …).
2
3use 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}