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 TokenBalance, TokenBalances, TokenBalancesEntry, TokenConfig, TokenMap, TokenMapEntry,
35 },
36 };
37 use anchor_lang::prelude::Pubkey;
38 use gmsol_utils::{
39 impl_fixed_map,
40 pubkey::to_bytes,
41 token_config::{TokenMapAccess, TokenRecord, TokensWithFeed},
42 };
43
44 const MAX_TOKENS: usize = 16;
45
46 impl_fixed_map!(TokenBalances, Pubkey, to_bytes, TokenBalance, MAX_TOKENS);
47 impl_fixed_map!(TokenMap, Pubkey, to_bytes, TokenConfig, MAX_TOKENS);
48
49 impl GtBank {
50 pub fn num_tokens(&self) -> usize {
52 self.balances.len()
53 }
54
55 pub fn tokens(&self) -> impl Iterator<Item = Pubkey> + '_ {
57 self.balances
58 .entries()
59 .map(|(key, _)| Pubkey::new_from_array(*key))
60 }
61
62 pub fn to_feeds(
64 &self,
65 map: &impl TokenMapAccess,
66 treasury_vault_config: &TreasuryVaultConfig,
67 ) -> crate::Result<TokensWithFeed> {
68 use std::collections::BTreeSet;
69
70 let tokens = self
71 .tokens()
72 .chain(treasury_vault_config.tokens())
73 .collect::<BTreeSet<_>>();
74 let records = tokens
75 .iter()
76 .map(|token| {
77 let config = map
78 .get(token)
79 .ok_or_else(|| crate::Error::custom("unknown token"))?;
80 TokenRecord::from_config(*token, config).map_err(crate::Error::custom)
81 })
82 .collect::<Result<Vec<_>, _>>()?;
83
84 TokensWithFeed::try_from_records(records).map_err(crate::Error::custom)
85 }
86 }
87
88 impl TreasuryVaultConfig {
89 pub fn num_tokens(&self) -> usize {
91 self.tokens.len()
92 }
93
94 pub fn tokens(&self) -> impl Iterator<Item = Pubkey> + '_ {
96 self.tokens
97 .entries()
98 .map(|(key, _)| Pubkey::new_from_array(*key))
99 }
100 }
101}