amount_to_ui_amount.rs 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. use core::str::from_utf8_unchecked;
  2. use pinocchio::{
  3. account_info::AccountInfo, program::set_return_data, program_error::ProgramError, ProgramResult,
  4. };
  5. use pinocchio_log::logger::{Argument, Logger};
  6. use token_interface::state::mint::Mint;
  7. use super::{check_account_owner, MAX_DIGITS_U64};
  8. #[inline(always)]
  9. pub fn process_amount_to_ui_amount(
  10. accounts: &[AccountInfo],
  11. instruction_data: &[u8],
  12. ) -> ProgramResult {
  13. let amount = u64::from_le_bytes(
  14. instruction_data
  15. .try_into()
  16. .map_err(|_error| ProgramError::InvalidInstructionData)?,
  17. );
  18. let mint_info = accounts.first().ok_or(ProgramError::NotEnoughAccountKeys)?;
  19. check_account_owner(mint_info)?;
  20. let mint = unsafe { Mint::from_bytes(mint_info.borrow_data_unchecked()) };
  21. let mut logger = Logger::<MAX_DIGITS_U64>::default();
  22. logger.append_with_args(amount, &[Argument::Precision(mint.decimals)]);
  23. let mut s = unsafe { from_utf8_unchecked(&logger) };
  24. if mint.decimals > 0 {
  25. let zeros_trimmed = s.trim_end_matches('0');
  26. s = zeros_trimmed.trim_end_matches('.');
  27. }
  28. set_return_data(s.as_bytes());
  29. Ok(())
  30. }