1#![allow(clippy::arithmetic_side_effects)]
2#![deny(missing_docs)]
3#![cfg_attr(not(test), forbid(unsafe_code))]
4
5pub mod error;
8pub mod instruction;
9pub mod native_mint;
10pub mod processor;
11pub mod state;
12
13#[cfg(not(feature = "no-entrypoint"))]
14mod entrypoint;
15
16pub mod solana_program {
19 #![allow(missing_docs)]
20 pub mod entrypoint {
21 pub use solana_program_error::ProgramResult;
22 }
23 pub mod instruction {
24 pub use solana_instruction::{AccountMeta, Instruction};
25 }
26 pub mod program_error {
27 pub use solana_program_error::{PrintProgramError, ProgramError};
28 }
29 pub mod program_option {
30 pub use solana_program_option::COption;
31 }
32 pub mod program_pack {
33 pub use solana_program_pack::{IsInitialized, Pack, Sealed};
34 }
35 pub mod pubkey {
36 pub use solana_pubkey::{Pubkey, PUBKEY_BYTES};
37 }
38}
39use {
40 solana_program_error::{ProgramError, ProgramResult},
41 solana_pubkey::Pubkey,
42};
43
44pub fn ui_amount_to_amount(ui_amount: f64, decimals: u8) -> u64 {
47 (ui_amount * 10_usize.pow(decimals as u32) as f64) as u64
48}
49
50pub fn amount_to_ui_amount(amount: u64, decimals: u8) -> f64 {
53 amount as f64 / 10_usize.pow(decimals as u32) as f64
54}
55
56pub fn amount_to_ui_amount_string(amount: u64, decimals: u8) -> String {
59 let decimals = decimals as usize;
60 if decimals > 0 {
61 let mut s = format!("{:01$}", amount, decimals + 1);
63 s.insert(s.len() - decimals, '.');
65 s
66 } else {
67 amount.to_string()
68 }
69}
70
71pub fn amount_to_ui_amount_string_trimmed(amount: u64, decimals: u8) -> String {
74 let mut s = amount_to_ui_amount_string(amount, decimals);
75 if decimals > 0 {
76 let zeros_trimmed = s.trim_end_matches('0');
77 s = zeros_trimmed.trim_end_matches('.').to_string();
78 }
79 s
80}
81
82pub fn try_ui_amount_into_amount(ui_amount: String, decimals: u8) -> Result<u64, ProgramError> {
85 let decimals = decimals as usize;
86 let mut parts = ui_amount.split('.');
87 let mut amount_str = parts.next().unwrap().to_string();
90 let after_decimal = parts.next().unwrap_or("");
91 let after_decimal = after_decimal.trim_end_matches('0');
92 if (amount_str.is_empty() && after_decimal.is_empty())
93 || parts.next().is_some()
94 || after_decimal.len() > decimals
95 {
96 return Err(ProgramError::InvalidArgument);
97 }
98
99 amount_str.push_str(after_decimal);
100 for _ in 0..decimals.saturating_sub(after_decimal.len()) {
101 amount_str.push('0');
102 }
103 amount_str
104 .parse::<u64>()
105 .map_err(|_| ProgramError::InvalidArgument)
106}
107
108solana_pubkey::declare_id!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
109
110pub fn check_program_account(spl_token_program_id: &Pubkey) -> ProgramResult {
112 if spl_token_program_id != &id() {
113 return Err(ProgramError::IncorrectProgramId);
114 }
115 Ok(())
116}