use std::sync::LazyLock;
use r402_core::chain::NetworkInfo;
use crate::chain::{Address, TronChainReference, TronTokenDeployment};
pub static TRON_NETWORKS: &[NetworkInfo] = &[
NetworkInfo {
name: "tron",
namespace: "tron",
reference: "0x2b6653dc",
},
NetworkInfo {
name: "tron-nile",
namespace: "tron",
reference: "0xcd8690dc",
},
];
#[allow(
clippy::expect_used,
reason = "hardcoded constant is infallible; validated by tests"
)]
fn well_known(s: &str) -> Address {
Address::from_base58check(s).expect("well-known tron address must be valid base58check")
}
static SUN_PERMIT2: LazyLock<[(TronChainReference, Address); 2]> = LazyLock::new(|| {
[
(
TronChainReference::MAINNET,
well_known("TTJxU3P8rHycAyFY4kVtGNfmnMH4ezcuM9"),
),
(
TronChainReference::NILE,
well_known("TCJjTtzwRJYPapGTdyJdKcr7MqkngRRWQx"),
),
]
});
static X402_EXACT_PERMIT2_PROXY: LazyLock<[(TronChainReference, Address); 2]> =
LazyLock::new(|| {
[
(
TronChainReference::MAINNET,
well_known("TNtw4Wg6uQe4bqFywtcn5qagVZesSdYBSs"),
),
(
TronChainReference::NILE,
well_known("TTjbkCh8sC4gNTWG48iWNssrLBqZq2tiTy"),
),
]
});
impl TronChainReference {
#[must_use]
pub fn sun_permit2(self) -> Option<Address> {
SUN_PERMIT2
.iter()
.find(|(chain, _)| *chain == self)
.map(|(_, addr)| *addr)
}
#[must_use]
pub fn x402_exact_permit2_proxy(self) -> Option<Address> {
X402_EXACT_PERMIT2_PROXY
.iter()
.find(|(chain, _)| *chain == self)
.map(|(_, addr)| *addr)
}
}
static USDT_DEPLOYMENTS: LazyLock<Vec<TronTokenDeployment>> = LazyLock::new(|| {
vec![
TronTokenDeployment::new(
TronChainReference::MAINNET,
well_known("TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"),
6,
),
TronTokenDeployment::new(
TronChainReference::NILE,
well_known("TXLAQ63Xg1NAzckPwKHvzw7CSEmLMEqcdj"),
6,
),
]
});
#[must_use]
pub fn usdt_tron_deployments() -> &'static [TronTokenDeployment] {
&USDT_DEPLOYMENTS
}
#[must_use]
pub fn usdt_tron_deployment(chain: TronChainReference) -> Option<&'static TronTokenDeployment> {
USDT_DEPLOYMENTS.iter().find(|d| d.chain_reference == chain)
}
#[derive(Debug, Clone, Copy)]
#[allow(
clippy::upper_case_acronyms,
reason = "USDT is a well-known token ticker"
)]
pub struct USDT;
#[allow(
clippy::doc_markdown,
clippy::missing_panics_doc,
clippy::expect_used,
reason = "static deployment lookups are infallible for built-in data"
)]
impl USDT {
#[must_use]
pub fn on(chain: TronChainReference) -> Option<&'static TronTokenDeployment> {
usdt_tron_deployment(chain)
}
#[must_use]
pub fn all() -> &'static [TronTokenDeployment] {
usdt_tron_deployments()
}
#[must_use]
pub fn mainnet() -> &'static TronTokenDeployment {
usdt_tron_deployment(TronChainReference::MAINNET)
.expect("built-in USDT deployment for tron mainnet missing")
}
#[must_use]
pub fn nile() -> &'static TronTokenDeployment {
usdt_tron_deployment(TronChainReference::NILE)
.expect("built-in USDT deployment for tron nile testnet missing")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn usdt_deployments_resolve() {
assert_eq!(USDT::mainnet().decimals, 6);
assert_eq!(USDT::nile().decimals, 6);
assert_eq!(USDT::all().len(), 2);
}
#[test]
fn permit2_addresses_resolve_for_known_networks() {
assert!(TronChainReference::MAINNET.sun_permit2().is_some());
assert!(
TronChainReference::MAINNET
.x402_exact_permit2_proxy()
.is_some()
);
assert!(TronChainReference::NILE.sun_permit2().is_some());
assert!(
TronChainReference::NILE
.x402_exact_permit2_proxy()
.is_some()
);
}
#[test]
fn permit2_addresses_absent_for_unknown_network() {
let unknown = TronChainReference::new(0xdead_beef);
assert!(unknown.sun_permit2().is_none());
assert!(unknown.x402_exact_permit2_proxy().is_none());
}
}