1use std::sync::LazyLock;
7
8use r402_core::chain::NetworkInfo;
9
10use crate::DEFAULT_TOKEN_DECIMALS;
11use crate::chain::{StellarAddress, StellarChainReference, StellarTokenDeployment};
12
13pub static STELLAR_NETWORKS: &[NetworkInfo] = &[
15 NetworkInfo {
16 name: "stellar",
17 namespace: "stellar",
18 reference: "pubnet",
19 },
20 NetworkInfo {
21 name: "stellar-testnet",
22 namespace: "stellar",
23 reference: "testnet",
24 },
25];
26
27pub const USDC_PUBNET_ADDRESS: &str = "CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75";
29
30pub const USDC_TESTNET_ADDRESS: &str = "CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA";
32
33#[allow(
38 clippy::expect_used,
39 reason = "hardcoded constant is infallible; validated by tests"
40)]
41fn well_known(s: &str) -> StellarAddress {
42 s.parse().expect("well-known stellar address must be valid")
43}
44
45static USDC_DEPLOYMENTS: LazyLock<Vec<StellarTokenDeployment>> = LazyLock::new(|| {
47 vec![
48 StellarTokenDeployment::new(
49 StellarChainReference::PUBNET,
50 well_known(USDC_PUBNET_ADDRESS),
51 DEFAULT_TOKEN_DECIMALS,
52 ),
53 StellarTokenDeployment::new(
54 StellarChainReference::TESTNET,
55 well_known(USDC_TESTNET_ADDRESS),
56 DEFAULT_TOKEN_DECIMALS,
57 ),
58 ]
59});
60
61#[must_use]
63pub fn usdc_stellar_deployments() -> &'static [StellarTokenDeployment] {
64 &USDC_DEPLOYMENTS
65}
66
67#[must_use]
69pub fn usdc_stellar_deployment(
70 chain: StellarChainReference,
71) -> Option<&'static StellarTokenDeployment> {
72 USDC_DEPLOYMENTS.iter().find(|d| d.chain_reference == chain)
73}
74
75#[derive(Debug, Clone, Copy)]
85#[allow(
86 clippy::upper_case_acronyms,
87 reason = "USDC is a well-known token ticker"
88)]
89pub struct USDC;
90
91#[allow(
92 clippy::doc_markdown,
93 clippy::missing_panics_doc,
94 clippy::expect_used,
95 reason = "static deployment lookups are infallible for built-in data"
96)]
97impl USDC {
98 #[must_use]
100 pub fn on(chain: StellarChainReference) -> Option<&'static StellarTokenDeployment> {
101 usdc_stellar_deployment(chain)
102 }
103
104 #[must_use]
106 pub fn all() -> &'static [StellarTokenDeployment] {
107 usdc_stellar_deployments()
108 }
109
110 #[must_use]
112 pub fn stellar() -> &'static StellarTokenDeployment {
113 usdc_stellar_deployment(StellarChainReference::PUBNET)
114 .expect("built-in USDC deployment for stellar pubnet missing")
115 }
116
117 #[must_use]
119 pub fn stellar_testnet() -> &'static StellarTokenDeployment {
120 usdc_stellar_deployment(StellarChainReference::TESTNET)
121 .expect("built-in USDC deployment for stellar testnet missing")
122 }
123}
124
125#[cfg(test)]
126#[allow(clippy::unwrap_used, reason = "test assertions")]
127mod tests {
128 use super::*;
129
130 #[test]
131 fn usdc_deployments_resolve() {
132 assert_eq!(USDC::stellar().decimals, DEFAULT_TOKEN_DECIMALS);
133 assert_eq!(USDC::stellar_testnet().decimals, DEFAULT_TOKEN_DECIMALS);
134 assert_eq!(USDC::stellar().address.as_str(), USDC_PUBNET_ADDRESS);
135 assert_eq!(
136 USDC::stellar_testnet().address.as_str(),
137 USDC_TESTNET_ADDRESS
138 );
139 assert!(USDC::stellar().address.is_contract());
140 assert_eq!(USDC::all().len(), 2);
141 assert_eq!(STELLAR_NETWORKS.len(), 2);
142 }
143}