use std::sync::LazyLock;
use compact_str::CompactString;
use r402_core::chain::NetworkInfo;
use crate::chain::{
XrplAsset, XrplChainReference, XrplClassicAddress, XrplIssuedCurrency, XrplTokenDeployment,
};
use crate::{
RLUSD_CURRENCY, RLUSD_DECIMALS, RLUSD_MAINNET_ISSUER, RLUSD_TESTNET_ISSUER, XRP_DECIMALS,
};
pub static XRPL_NETWORKS: &[NetworkInfo] = &[
NetworkInfo {
name: "xrpl",
namespace: "xrpl",
reference: "0",
},
NetworkInfo {
name: "xrpl-testnet",
namespace: "xrpl",
reference: "1",
},
NetworkInfo {
name: "xrpl-devnet",
namespace: "xrpl",
reference: "2",
},
];
#[allow(
clippy::expect_used,
reason = "hardcoded constant is infallible; validated by tests"
)]
fn well_known(s: &str) -> XrplClassicAddress {
s.parse()
.expect("well-known xrpl classic address must be valid")
}
fn rlusd(chain: XrplChainReference, issuer: &str) -> XrplTokenDeployment {
XrplTokenDeployment::new(
chain,
XrplAsset::Iou(XrplIssuedCurrency {
currency: CompactString::from(RLUSD_CURRENCY),
issuer: well_known(issuer),
}),
RLUSD_DECIMALS,
)
}
static XRP_DEPLOYMENTS: LazyLock<Vec<XrplTokenDeployment>> = LazyLock::new(|| {
vec![
XrplTokenDeployment::new(XrplChainReference::MAINNET, XrplAsset::Xrp, XRP_DECIMALS),
XrplTokenDeployment::new(XrplChainReference::TESTNET, XrplAsset::Xrp, XRP_DECIMALS),
XrplTokenDeployment::new(XrplChainReference::DEVNET, XrplAsset::Xrp, XRP_DECIMALS),
]
});
static RLUSD_DEPLOYMENTS: LazyLock<Vec<XrplTokenDeployment>> = LazyLock::new(|| {
vec![
rlusd(XrplChainReference::MAINNET, RLUSD_MAINNET_ISSUER),
rlusd(XrplChainReference::TESTNET, RLUSD_TESTNET_ISSUER),
]
});
#[must_use]
pub fn xrp_deployments() -> &'static [XrplTokenDeployment] {
&XRP_DEPLOYMENTS
}
#[must_use]
pub fn xrp_deployment(chain: XrplChainReference) -> Option<&'static XrplTokenDeployment> {
XRP_DEPLOYMENTS.iter().find(|d| d.chain_reference == chain)
}
#[must_use]
pub fn rlusd_deployments() -> &'static [XrplTokenDeployment] {
&RLUSD_DEPLOYMENTS
}
#[must_use]
pub fn rlusd_deployment(chain: XrplChainReference) -> Option<&'static XrplTokenDeployment> {
RLUSD_DEPLOYMENTS
.iter()
.find(|d| d.chain_reference == chain)
}
#[derive(Debug, Clone, Copy)]
#[allow(
clippy::upper_case_acronyms,
reason = "XRP is a well-known token ticker"
)]
pub struct XRP;
#[allow(
clippy::missing_panics_doc,
clippy::expect_used,
reason = "static deployment lookups are infallible for built-in data"
)]
impl XRP {
#[must_use]
pub fn mainnet() -> &'static XrplTokenDeployment {
xrp_deployment(XrplChainReference::MAINNET)
.expect("built-in XRP deployment for xrpl mainnet missing")
}
#[must_use]
pub fn testnet() -> &'static XrplTokenDeployment {
xrp_deployment(XrplChainReference::TESTNET)
.expect("built-in XRP deployment for xrpl testnet missing")
}
#[must_use]
pub fn devnet() -> &'static XrplTokenDeployment {
xrp_deployment(XrplChainReference::DEVNET)
.expect("built-in XRP deployment for xrpl devnet missing")
}
}
#[derive(Debug, Clone, Copy)]
#[allow(
clippy::upper_case_acronyms,
reason = "RLUSD is a well-known token ticker"
)]
pub struct RLUSD;
#[allow(
clippy::missing_panics_doc,
clippy::expect_used,
reason = "static deployment lookups are infallible for built-in data"
)]
impl RLUSD {
#[must_use]
pub fn mainnet() -> &'static XrplTokenDeployment {
rlusd_deployment(XrplChainReference::MAINNET)
.expect("built-in RLUSD deployment for xrpl mainnet missing")
}
#[must_use]
pub fn testnet() -> &'static XrplTokenDeployment {
rlusd_deployment(XrplChainReference::TESTNET)
.expect("built-in RLUSD deployment for xrpl testnet missing")
}
}
#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::panic, reason = "test assertions")]
mod tests {
use super::*;
#[test]
fn deployments_resolve() {
assert_eq!(XRP::mainnet().decimals, XRP_DECIMALS);
assert_eq!(RLUSD::mainnet().decimals, RLUSD_DECIMALS);
assert_eq!(RLUSD::testnet().decimals, RLUSD_DECIMALS);
assert_eq!(XRPL_NETWORKS.len(), 3);
match &RLUSD::mainnet().asset {
XrplAsset::Iou(iou) => {
assert_eq!(iou.currency, RLUSD_CURRENCY);
assert_eq!(iou.issuer.as_str(), RLUSD_MAINNET_ISSUER);
}
XrplAsset::Xrp => panic!("expected IOU"),
}
}
}