ui_amount_to_amount.rs 1.0 KB

1234567891011121314151617181920212223242526272829303132
  1. use core::str::from_utf8;
  2. use pinocchio::{
  3. account_info::AccountInfo, program::set_return_data, program_error::ProgramError, ProgramResult,
  4. };
  5. use token_interface::{
  6. error::TokenError,
  7. state::{load, mint::Mint},
  8. };
  9. use super::{check_account_owner, try_ui_amount_into_amount};
  10. #[inline(always)]
  11. pub fn process_ui_amount_to_amount(
  12. accounts: &[AccountInfo],
  13. instruction_data: &[u8],
  14. ) -> ProgramResult {
  15. let ui_amount =
  16. from_utf8(instruction_data).map_err(|_error| ProgramError::InvalidInstructionData)?;
  17. let mint_info = accounts.first().ok_or(ProgramError::NotEnoughAccountKeys)?;
  18. check_account_owner(mint_info)?;
  19. // SAFETY: single immutable borrow to `mint_info` account data and
  20. // `load` validates that the mint is initialized.
  21. let mint = unsafe {
  22. load::<Mint>(mint_info.borrow_data_unchecked()).map_err(|_| TokenError::InvalidMint)?
  23. };
  24. let amount = try_ui_amount_into_amount(ui_amount, mint.decimals)?;
  25. set_return_data(&amount.to_le_bytes());
  26. Ok(())
  27. }