gmsol_programs/utils/
treasury.rs1use bytemuck::Zeroable;
2
3use crate::gmsol_treasury::types::{TokenBalance, TokenBalancesEntry, TokenConfig, TokenMapEntry};
4
5impl Default for TokenBalance {
6 fn default() -> Self {
7 Zeroable::zeroed()
8 }
9}
10
11impl Default for TokenBalancesEntry {
12 fn default() -> Self {
13 Zeroable::zeroed()
14 }
15}
16
17impl Default for TokenConfig {
18 fn default() -> Self {
19 Zeroable::zeroed()
20 }
21}
22
23impl Default for TokenMapEntry {
24 fn default() -> Self {
25 Zeroable::zeroed()
26 }
27}
28
29#[cfg(feature = "gmsol-utils")]
30mod utils {
31 use crate::gmsol_treasury::{
32 accounts::{GtBank, TreasuryVaultConfig},
33 types::{
34 GtBankFlagsContainer, TokenBalance, TokenBalances, TokenBalancesEntry, TokenConfig,
35 TokenFlagContainer, TokenMap, TokenMapEntry,
36 },
37 };
38 use anchor_lang::prelude::Pubkey;
39 use gmsol_utils::{
40 gt::{GtBankFlags, MAX_GT_BANK_FLAGS},
41 impl_fixed_map, impl_flags,
42 pubkey::to_bytes,
43 token_config::{
44 TokenFlag, TokenMapAccess, TokenRecord, TokensWithFeed, MAX_TREASURY_TOKEN_FLAGS,
45 },
46 };
47
48 const MAX_TOKENS: usize = 16;
49
50 impl_fixed_map!(TokenBalances, Pubkey, to_bytes, TokenBalance, MAX_TOKENS);
51 impl_fixed_map!(TokenMap, Pubkey, to_bytes, TokenConfig, MAX_TOKENS);
52
53 impl_flags!(TokenFlag, MAX_TREASURY_TOKEN_FLAGS, u8);
54 impl_flags!(GtBankFlags, MAX_GT_BANK_FLAGS, u8);
55
56 impl GtBank {
57 pub fn num_tokens(&self) -> usize {
59 self.balances.len()
60 }
61
62 pub fn tokens(&self) -> impl Iterator<Item = Pubkey> + '_ {
64 self.balances
65 .entries()
66 .map(|(key, _)| Pubkey::new_from_array(*key))
67 }
68
69 pub fn to_feeds(
71 &self,
72 map: &impl TokenMapAccess,
73 treasury_vault_config: &TreasuryVaultConfig,
74 ) -> crate::Result<TokensWithFeed> {
75 use std::collections::BTreeSet;
76
77 let tokens = self
78 .tokens()
79 .chain(treasury_vault_config.tokens())
80 .collect::<BTreeSet<_>>();
81 let records = tokens
82 .iter()
83 .map(|token| {
84 let config = map
85 .get(token)
86 .ok_or_else(|| crate::Error::custom("unknown token"))?;
87 TokenRecord::from_config(*token, config).map_err(crate::Error::custom)
88 })
89 .collect::<Result<Vec<_>, _>>()?;
90
91 TokensWithFeed::try_from_records(records).map_err(crate::Error::custom)
92 }
93 }
94
95 impl TreasuryVaultConfig {
96 pub fn num_tokens(&self) -> usize {
98 self.tokens.len()
99 }
100
101 pub fn tokens(&self) -> impl Iterator<Item = Pubkey> + '_ {
103 self.tokens
104 .entries()
105 .map(|(key, _)| Pubkey::new_from_array(*key))
106 }
107 }
108}