iota_names/
config.rs

1// Copyright (c) 2025 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use std::str::FromStr;
5
6use iota_types::{
7    TypeTag,
8    base_types::{IotaAddress, ObjectID},
9    supported_protocol_versions::Chain,
10};
11use serde::{Deserialize, Serialize};
12
13use crate::Name;
14
15#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
16#[serde(rename_all = "kebab-case")]
17pub struct IotaNamesConfig {
18    /// Address of the `iota_names` package.
19    pub package_address: IotaAddress,
20    /// ID of the `IotaNames` object.
21    pub object_id: ObjectID,
22    /// Address of the `payments` package.
23    pub payments_package_address: IotaAddress,
24    /// ID of the registry table.
25    pub registry_id: ObjectID,
26    /// ID of the reverse registry table.
27    pub reverse_registry_id: ObjectID,
28}
29
30impl Default for IotaNamesConfig {
31    fn default() -> Self {
32        Self::mainnet()
33    }
34}
35
36impl IotaNamesConfig {
37    pub fn new(
38        package_address: IotaAddress,
39        object_id: ObjectID,
40        payments_package_address: IotaAddress,
41        registry_id: ObjectID,
42        reverse_registry_id: ObjectID,
43    ) -> Self {
44        Self {
45            package_address,
46            object_id,
47            payments_package_address,
48            registry_id,
49            reverse_registry_id,
50        }
51    }
52
53    pub fn from_env() -> anyhow::Result<Self> {
54        Ok(Self::new(
55            std::env::var("IOTA_NAMES_PACKAGE_ADDRESS")?.parse()?,
56            std::env::var("IOTA_NAMES_OBJECT_ID")?.parse()?,
57            std::env::var("IOTA_NAMES_PAYMENTS_PACKAGE_ADDRESS")?.parse()?,
58            std::env::var("IOTA_NAMES_REGISTRY_ID")?.parse()?,
59            std::env::var("IOTA_NAMES_REVERSE_REGISTRY_ID")?.parse()?,
60        ))
61    }
62
63    pub fn from_chain(chain: &Chain) -> Self {
64        match chain {
65            Chain::Mainnet => IotaNamesConfig::mainnet(),
66            Chain::Testnet => IotaNamesConfig::testnet(),
67            Chain::Unknown => IotaNamesConfig::devnet(),
68        }
69    }
70
71    pub fn record_field_id(&self, name: &Name) -> ObjectID {
72        let name_type_tag = Name::type_(self.package_address);
73        let name_bytes = bcs::to_bytes(name).unwrap();
74
75        iota_types::dynamic_field::derive_dynamic_field_id(
76            self.registry_id,
77            &TypeTag::Struct(Box::new(name_type_tag)),
78            &name_bytes,
79        )
80        .unwrap()
81    }
82
83    pub fn reverse_record_field_id(&self, address: &IotaAddress) -> ObjectID {
84        iota_types::dynamic_field::derive_dynamic_field_id(
85            self.reverse_registry_id,
86            &TypeTag::Address,
87            address.as_ref(),
88        )
89        .unwrap()
90    }
91
92    // Create a config based on the package and object ids published on mainnet.
93    pub fn mainnet() -> Self {
94        const PACKAGE_ADDRESS: &str =
95            "0x6d2c743607ef275bd6934fe5c2a7e5179cca6fbd2049cfa79de2310b74f3cf83";
96        const OBJECT_ID: &str =
97            "0xa14e5d0481a7aa346157078e6facba3cd895d97038cd87b9f2cc24b0c6102d75";
98        const PAYMENTS_PACKAGE_ADDRESS: &str =
99            "0x53d3d37f00949a1baad95fa4fca0b3d0d70ff6121be316f9e46d37c2d29c71eb";
100        const REGISTRY_ID: &str =
101            "0xa773cef7d762871354f6ae19ad174dfb1153d2d247c4886ada0b5330b9543b57";
102        const REVERSE_REGISTRY_ID: &str =
103            "0x18fa62ab8b0ab95ae61088082bd5db796863016fda8f3205b1ea7d13b1792317";
104
105        let package_address = IotaAddress::from_str(PACKAGE_ADDRESS).unwrap();
106        let object_id = ObjectID::from_str(OBJECT_ID).unwrap();
107        let payments_package_address = IotaAddress::from_str(PAYMENTS_PACKAGE_ADDRESS).unwrap();
108        let registry_id = ObjectID::from_str(REGISTRY_ID).unwrap();
109        let reverse_registry_id = ObjectID::from_str(REVERSE_REGISTRY_ID).unwrap();
110
111        Self::new(
112            package_address,
113            object_id,
114            payments_package_address,
115            registry_id,
116            reverse_registry_id,
117        )
118    }
119
120    // Create a config based on the package and object ids published on testnet.
121    pub fn testnet() -> Self {
122        const PACKAGE_ADDRESS: &str =
123            "0x7fff6e95f385349bec98d17121ab2bfa3e134f2f0b1ccefc270313415f7835ea";
124        const OBJECT_ID: &str =
125            "0x7cab491740d51e0d75b26bf9984e49ba2e32a2d0694cabcee605543ed13c7dec";
126        const PAYMENTS_PACKAGE_ADDRESS: &str =
127            "0x6b1b01f4c72786a893191d5c6e73d3012f7529f86fdee3bc8c163323cee08441";
128        const REGISTRY_ID: &str =
129            "0x2dfc6f6d46ba55217425643a59dc85fe4d8ed273a9f74077bd0ee280dbb4f590";
130        const REVERSE_REGISTRY_ID: &str =
131            "0x3550bcacb793ef8b776264665e7c99fa3d897695ed664656aac693cf9cf9b76b";
132
133        let package_address = IotaAddress::from_str(PACKAGE_ADDRESS).unwrap();
134        let object_id = ObjectID::from_str(OBJECT_ID).unwrap();
135        let payments_package_address = IotaAddress::from_str(PAYMENTS_PACKAGE_ADDRESS).unwrap();
136        let registry_id = ObjectID::from_str(REGISTRY_ID).unwrap();
137        let reverse_registry_id = ObjectID::from_str(REVERSE_REGISTRY_ID).unwrap();
138
139        Self::new(
140            package_address,
141            object_id,
142            payments_package_address,
143            registry_id,
144            reverse_registry_id,
145        )
146    }
147
148    // Create a config based on the package and object ids published on devnet.
149    pub fn devnet() -> Self {
150        const PACKAGE_ADDRESS: &str =
151            "0x742d00d422294ca697c53662f571f8dc328296d62db2211e2bd05a1857c13e06";
152        const OBJECT_ID: &str =
153            "0x49ec1d51f532ba32f1b14d1794fdcd7727664587bde3fb65be31bd4eb7f32f21";
154        const PAYMENTS_PACKAGE_ADDRESS: &str =
155            "0xe14ccc7c77add03bb9b6ad902a9f92a470c6a25bf8a9793927b2678510bfbb31";
156        const REGISTRY_ID: &str =
157            "0x2e86c49747003e46be1691604e6c1fbf902b967e22452532de405647bff7af95";
158        const REVERSE_REGISTRY_ID: &str =
159            "0xad03947f9e0648b7cb85f8c8325ee95c58898cda5d21925184ed1e5f70a75cfb";
160
161        let package_address = IotaAddress::from_str(PACKAGE_ADDRESS).unwrap();
162        let object_id = ObjectID::from_str(OBJECT_ID).unwrap();
163        let payments_package_address = IotaAddress::from_str(PAYMENTS_PACKAGE_ADDRESS).unwrap();
164        let registry_id = ObjectID::from_str(REGISTRY_ID).unwrap();
165        let reverse_registry_id = ObjectID::from_str(REVERSE_REGISTRY_ID).unwrap();
166
167        Self::new(
168            package_address,
169            object_id,
170            payments_package_address,
171            registry_id,
172            reverse_registry_id,
173        )
174    }
175}