Skip to main content

miden_usdcx/xreserve/encoding/
domain.rs

1//! Circle's domain identifier: the `u32` Circle assigns each chain it attests for.
2
3use core::fmt;
4use core::num::ParseIntError;
5use core::str::FromStr;
6
7use miden_protocol::Felt;
8use serde::{Deserialize, Serialize};
9
10/// A Circle domain identifier — the number Circle assigns a chain.
11///
12/// It names Miden as the `remoteDomain` a deposit is addressed to and the faucet is configured
13/// with, and the source chains a withdrawal can be sent to as its destination domain. Every `u32`
14/// is a well-formed identifier.
15#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
16#[serde(transparent)]
17pub struct CircleDomain(u32);
18
19impl CircleDomain {
20    /// Miden's domain identifier.
21    pub const MIDEN: Self = Self(10_007);
22
23    /// Wraps a Circle domain identifier.
24    pub const fn new(value: u32) -> Self {
25        Self(value)
26    }
27
28    /// The identifier as the `u32` Circle's wire forms carry.
29    pub const fn as_u32(&self) -> u32 {
30        self.0
31    }
32}
33
34impl Default for CircleDomain {
35    /// Defaults to [`Self::MIDEN`], the domain this deployment runs on.
36    fn default() -> Self {
37        Self::MIDEN
38    }
39}
40
41impl From<u32> for CircleDomain {
42    fn from(value: u32) -> Self {
43        Self::new(value)
44    }
45}
46
47impl From<CircleDomain> for u32 {
48    fn from(domain: CircleDomain) -> Self {
49        domain.0
50    }
51}
52
53impl From<CircleDomain> for Felt {
54    fn from(domain: CircleDomain) -> Self {
55        Felt::from(domain.0)
56    }
57}
58
59impl FromStr for CircleDomain {
60    type Err = ParseIntError;
61
62    fn from_str(value: &str) -> Result<Self, Self::Err> {
63        value.parse().map(Self::new)
64    }
65}
66
67impl fmt::Display for CircleDomain {
68    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69        self.0.fmt(f)
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use super::CircleDomain;
76
77    #[test]
78    fn a_domain_parses_from_a_32_bit_number() {
79        assert_eq!("7".parse::<CircleDomain>().unwrap(), CircleDomain::new(7));
80        assert!("".parse::<CircleDomain>().is_err());
81        assert!("abc".parse::<CircleDomain>().is_err());
82        assert!("-1".parse::<CircleDomain>().is_err());
83        assert!("4294967296".parse::<CircleDomain>().is_err());
84    }
85
86    #[test]
87    fn a_domain_deserializes_from_a_bare_number() {
88        let domain: CircleDomain = serde_json::from_str("10007").unwrap();
89        assert_eq!(domain, CircleDomain::new(10007));
90        assert_eq!(serde_json::to_string(&domain).unwrap(), "10007");
91    }
92}