-
Notifications
You must be signed in to change notification settings - Fork 90
chore: csdk macros3 #2062
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore: csdk macros3 #2062
Changes from all commits
53aa4c6
a125346
93596ca
42638dd
68a3129
a6003c5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,187 @@ | ||
| //! Runtime helpers for token decompression. | ||
| use light_ctoken_types::instructions::transfer2::MultiInputTokenDataWithContext; | ||
| use light_sdk::{cpi::v2::CpiAccounts, instruction::ValidityProof}; | ||
| use light_sdk_types::instruction::account_meta::CompressedAccountMetaNoLamportsNoAddress; | ||
| use solana_account_info::AccountInfo; | ||
| use solana_msg::msg; | ||
| use solana_program_error::ProgramError; | ||
| use solana_pubkey::Pubkey; | ||
|
|
||
| use crate::compat::PackedCTokenData; | ||
|
|
||
| /// Trait for getting token account seeds. | ||
| pub trait CTokenSeedProvider: Copy { | ||
| /// Type of accounts struct needed for seed derivation. | ||
| type Accounts<'info>; | ||
|
|
||
| /// Get seeds for the token account PDA (used for decompression). | ||
| fn get_seeds<'a, 'info>( | ||
| &self, | ||
| accounts: &'a Self::Accounts<'info>, | ||
| remaining_accounts: &'a [AccountInfo<'info>], | ||
| ) -> Result<(Vec<Vec<u8>>, Pubkey), ProgramError>; | ||
|
|
||
| /// Get authority seeds for signing during compression. | ||
| /// | ||
| /// TODO: consider removing. | ||
| fn get_authority_seeds<'a, 'info>( | ||
| &self, | ||
| accounts: &'a Self::Accounts<'info>, | ||
| remaining_accounts: &'a [AccountInfo<'info>], | ||
| ) -> Result<(Vec<Vec<u8>>, Pubkey), ProgramError>; | ||
| } | ||
|
Comment on lines
+12
to
+32
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Safety fixes in decompression runtime look solid; consider clarifying The runtime now:
This resolves the earlier panic/logic risks in this path. The only remaining nit is the Also applies to: 60-79, 81-163 🤖 Prompt for AI Agents |
||
|
|
||
| /// Token decompression processor. | ||
| #[inline(never)] | ||
| #[allow(clippy::too_many_arguments)] | ||
| pub fn process_decompress_tokens_runtime<'info, 'a, 'b, V, A>( | ||
| accounts_for_seeds: &A, | ||
| remaining_accounts: &[AccountInfo<'info>], | ||
| fee_payer: &AccountInfo<'info>, | ||
| ctoken_program: &AccountInfo<'info>, | ||
| ctoken_rent_sponsor: &AccountInfo<'info>, | ||
| ctoken_cpi_authority: &AccountInfo<'info>, | ||
| ctoken_config: &AccountInfo<'info>, | ||
| config: &AccountInfo<'info>, | ||
| ctoken_accounts: Vec<( | ||
| PackedCTokenData<V>, | ||
| CompressedAccountMetaNoLamportsNoAddress, | ||
| )>, | ||
| proof: ValidityProof, | ||
| cpi_accounts: &CpiAccounts<'b, 'info>, | ||
| post_system_accounts: &[AccountInfo<'info>], | ||
| has_pdas: bool, | ||
| program_id: &Pubkey, | ||
| ) -> Result<(), ProgramError> | ||
| where | ||
| V: CTokenSeedProvider<Accounts<'info> = A>, | ||
| A: 'info, | ||
| { | ||
| let mut token_decompress_indices: Vec< | ||
| crate::compressed_token::decompress_full::DecompressFullIndices, | ||
| > = Vec::with_capacity(ctoken_accounts.len()); | ||
| let mut token_signers_seed_groups: Vec<Vec<Vec<u8>>> = | ||
| Vec::with_capacity(ctoken_accounts.len()); | ||
| let packed_accounts = post_system_accounts; | ||
|
|
||
| let authority = cpi_accounts | ||
| .authority() | ||
| .map_err(|_| ProgramError::MissingRequiredSignature)?; | ||
| let cpi_context_pubkey = if has_pdas { | ||
| Some( | ||
| *cpi_accounts | ||
| .cpi_context() | ||
| .map_err(|_| ProgramError::MissingRequiredSignature)? | ||
| .key, | ||
| ) | ||
| } else { | ||
| None | ||
| }; | ||
|
|
||
| for (token_data, meta) in ctoken_accounts.into_iter() { | ||
| let owner_index: u8 = token_data.token_data.owner; | ||
| let mint_index: u8 = token_data.token_data.mint; | ||
|
|
||
| let mint_index_usize = mint_index as usize; | ||
| if mint_index_usize >= packed_accounts.len() { | ||
| msg!( | ||
| "mint_index {} out of bounds (len: {})", | ||
| mint_index_usize, | ||
| packed_accounts.len() | ||
| ); | ||
| return Err(ProgramError::InvalidAccountData); | ||
| } | ||
| let mint_info = &packed_accounts[mint_index_usize]; | ||
|
|
||
| let owner_index_usize = owner_index as usize; | ||
| if owner_index_usize >= packed_accounts.len() { | ||
| msg!( | ||
| "owner_index {} out of bounds (len: {})", | ||
| owner_index_usize, | ||
| packed_accounts.len() | ||
| ); | ||
| return Err(ProgramError::InvalidAccountData); | ||
| } | ||
| let owner_info = &packed_accounts[owner_index_usize]; | ||
|
|
||
| // Use trait method to get seeds (program-specific) | ||
| let (ctoken_signer_seeds, derived_token_account_address) = token_data | ||
| .variant | ||
| .get_seeds(accounts_for_seeds, remaining_accounts)?; | ||
|
|
||
| if derived_token_account_address != *owner_info.key { | ||
| msg!( | ||
| "derived_token_account_address: {:?}", | ||
| derived_token_account_address | ||
| ); | ||
| msg!("owner_info.key: {:?}", owner_info.key); | ||
| return Err(ProgramError::InvalidAccountData); | ||
| } | ||
|
|
||
| let seed_refs: Vec<&[u8]> = ctoken_signer_seeds.iter().map(|s| s.as_slice()).collect(); | ||
SwenSchaeferjohann marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| let seeds_slice: &[&[u8]] = &seed_refs; | ||
|
|
||
| crate::ctoken::create_token_account::create_ctoken_account_signed( | ||
| *program_id, | ||
| fee_payer.clone(), | ||
| (*owner_info).clone(), | ||
| (*mint_info).clone(), | ||
| *authority.key, | ||
| seeds_slice, | ||
| ctoken_rent_sponsor.clone(), | ||
| ctoken_config.clone(), | ||
| Some(2), | ||
| None, | ||
| )?; | ||
|
|
||
| let source = MultiInputTokenDataWithContext { | ||
| owner: token_data.token_data.owner, | ||
| amount: token_data.token_data.amount, | ||
| has_delegate: token_data.token_data.has_delegate, | ||
| delegate: token_data.token_data.delegate, | ||
| mint: token_data.token_data.mint, | ||
| version: token_data.token_data.version, | ||
| merkle_context: meta.tree_info.into(), | ||
| root_index: meta.tree_info.root_index, | ||
| }; | ||
| let decompress_index = crate::compressed_token::decompress_full::DecompressFullIndices { | ||
| source, | ||
| destination_index: owner_index, | ||
| }; | ||
| token_decompress_indices.push(decompress_index); | ||
| token_signers_seed_groups.push(ctoken_signer_seeds); | ||
| } | ||
|
|
||
| let ctoken_ix = | ||
| crate::compressed_token::decompress_full::decompress_full_ctoken_accounts_with_indices( | ||
| *fee_payer.key, | ||
| proof, | ||
| cpi_context_pubkey, | ||
| &token_decompress_indices, | ||
| packed_accounts, | ||
| ) | ||
| .map_err(ProgramError::from)?; | ||
|
|
||
| let mut all_account_infos: Vec<AccountInfo<'info>> = | ||
| Vec::with_capacity(1 + post_system_accounts.len() + 3); | ||
| all_account_infos.push(fee_payer.clone()); | ||
| all_account_infos.push(ctoken_cpi_authority.clone()); | ||
| all_account_infos.push(ctoken_program.clone()); | ||
| all_account_infos.push(ctoken_rent_sponsor.clone()); | ||
| all_account_infos.push(config.clone()); | ||
| all_account_infos.extend_from_slice(post_system_accounts); | ||
|
|
||
| let signer_seed_refs: Vec<Vec<&[u8]>> = token_signers_seed_groups | ||
| .iter() | ||
| .map(|group| group.iter().map(|s| s.as_slice()).collect()) | ||
| .collect(); | ||
| let signer_seed_slices: Vec<&[&[u8]]> = signer_seed_refs.iter().map(|g| g.as_slice()).collect(); | ||
|
|
||
| solana_cpi::invoke_signed( | ||
| &ctoken_ix, | ||
| all_account_infos.as_slice(), | ||
| signer_seed_slices.as_slice(), | ||
| )?; | ||
|
|
||
| Ok(()) | ||
| } | ||
SwenSchaeferjohann marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,7 @@ | ||
| pub mod claim; | ||
| pub mod decompress_runtime; | ||
| pub mod withdraw_funding_pool; | ||
|
|
||
| pub use claim::*; | ||
| pub use decompress_runtime::{process_decompress_tokens_runtime, CTokenSeedProvider}; | ||
| pub use withdraw_funding_pool::*; |
Uh oh!
There was an error while loading. Please reload this page.