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        // TODO change to mainnet https://github.com/iotaledger/iota/issues/6532
33        Self::testnet()
34    }
35}
36
37impl IotaNamesConfig {
38    pub fn new(
39        package_address: IotaAddress,
40        object_id: ObjectID,
41        payments_package_address: IotaAddress,
42        registry_id: ObjectID,
43        reverse_registry_id: ObjectID,
44    ) -> Self {
45        Self {
46            package_address,
47            object_id,
48            payments_package_address,
49            registry_id,
50            reverse_registry_id,
51        }
52    }
53
54    pub fn from_env() -> anyhow::Result<Self> {
55        Ok(Self::new(
56            std::env::var("IOTA_NAMES_PACKAGE_ADDRESS")?.parse()?,
57            std::env::var("IOTA_NAMES_OBJECT_ID")?.parse()?,
58            std::env::var("IOTA_NAMES_PAYMENTS_PACKAGE_ADDRESS")?.parse()?,
59            std::env::var("IOTA_NAMES_REGISTRY_ID")?.parse()?,
60            std::env::var("IOTA_NAMES_REVERSE_REGISTRY_ID")?.parse()?,
61        ))
62    }
63
64    pub fn from_chain(chain: &Chain) -> Self {
65        match chain {
66            // TODO switch to mainnet https://github.com/iotaledger/iota/issues/6532
67            Chain::Mainnet => IotaNamesConfig::testnet(),
68            Chain::Testnet => IotaNamesConfig::testnet(),
69            Chain::Unknown => IotaNamesConfig::devnet(),
70        }
71    }
72
73    pub fn record_field_id(&self, name: &Name) -> ObjectID {
74        let name_type_tag = Name::type_(self.package_address);
75        let name_bytes = bcs::to_bytes(name).unwrap();
76
77        iota_types::dynamic_field::derive_dynamic_field_id(
78            self.registry_id,
79            &TypeTag::Struct(Box::new(name_type_tag)),
80            &name_bytes,
81        )
82        .unwrap()
83    }
84
85    pub fn reverse_record_field_id(&self, address: &IotaAddress) -> ObjectID {
86        iota_types::dynamic_field::derive_dynamic_field_id(
87            self.reverse_registry_id,
88            &TypeTag::Address,
89            address.as_ref(),
90        )
91        .unwrap()
92    }
93
94    // TODO add mainnet https://github.com/iotaledger/iota/issues/6532
95
96    // Create a config based on the package and object ids published on testnet.
97    pub fn testnet() -> Self {
98        const PACKAGE_ADDRESS: &str =
99            "0x7fff6e95f385349bec98d17121ab2bfa3e134f2f0b1ccefc270313415f7835ea";
100        const OBJECT_ID: &str =
101            "0x7cab491740d51e0d75b26bf9984e49ba2e32a2d0694cabcee605543ed13c7dec";
102        const PAYMENTS_PACKAGE_ADDRESS: &str =
103            "0x6b1b01f4c72786a893191d5c6e73d3012f7529f86fdee3bc8c163323cee08441";
104        const REGISTRY_ID: &str =
105            "0x2dfc6f6d46ba55217425643a59dc85fe4d8ed273a9f74077bd0ee280dbb4f590";
106        const REVERSE_REGISTRY_ID: &str =
107            "0x3550bcacb793ef8b776264665e7c99fa3d897695ed664656aac693cf9cf9b76b";
108
109        let package_address = IotaAddress::from_str(PACKAGE_ADDRESS).unwrap();
110        let object_id = ObjectID::from_str(OBJECT_ID).unwrap();
111        let payments_package_address = IotaAddress::from_str(PAYMENTS_PACKAGE_ADDRESS).unwrap();
112        let registry_id = ObjectID::from_str(REGISTRY_ID).unwrap();
113        let reverse_registry_id = ObjectID::from_str(REVERSE_REGISTRY_ID).unwrap();
114
115        Self::new(
116            package_address,
117            object_id,
118            payments_package_address,
119            registry_id,
120            reverse_registry_id,
121        )
122    }
123
124    // Create a config based on the package and object ids published on devnet.
125    pub fn devnet() -> Self {
126        const PACKAGE_ADDRESS: &str =
127            "0xb9d617f24c84826bf660a2f4031951678cc80c264aebc4413459fb2a95ada9ba";
128        const OBJECT_ID: &str =
129            "0x07c59b37bd7d036bf78fa30561a2ab9f7a970837487656ec29466e817f879342";
130        const PAYMENTS_PACKAGE_ADDRESS: &str =
131            "0x98b9b33b7c2347a8f4e8b8716fb4c7e6e1af846ec2ea063a47bba81ffe03b440";
132        const REGISTRY_ID: &str =
133            "0xe00b2f2400c33b4dbd3081c4dcf2e289d0544caba23a3d130b264bd756403c07";
134        const REVERSE_REGISTRY_ID: &str =
135            "0x1c1da17843cc453ad4079b05ce55e103b7a8cdd4db6ab42dc367b47ed6d8994d";
136
137        let package_address = IotaAddress::from_str(PACKAGE_ADDRESS).unwrap();
138        let object_id = ObjectID::from_str(OBJECT_ID).unwrap();
139        let payments_package_address = IotaAddress::from_str(PAYMENTS_PACKAGE_ADDRESS).unwrap();
140        let registry_id = ObjectID::from_str(REGISTRY_ID).unwrap();
141        let reverse_registry_id = ObjectID::from_str(REVERSE_REGISTRY_ID).unwrap();
142
143        Self::new(
144            package_address,
145            object_id,
146            payments_package_address,
147            registry_id,
148            reverse_registry_id,
149        )
150    }
151}