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::Domain;
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        // TODO change to testnet https://github.com/iotaledger/iota/issues/6531
34        Self::devnet()
35    }
36}
37
38impl IotaNamesConfig {
39    pub fn new(
40        package_address: IotaAddress,
41        object_id: ObjectID,
42        payments_package_address: IotaAddress,
43        registry_id: ObjectID,
44        reverse_registry_id: ObjectID,
45    ) -> Self {
46        Self {
47            package_address,
48            object_id,
49            payments_package_address,
50            registry_id,
51            reverse_registry_id,
52        }
53    }
54
55    pub fn from_env() -> anyhow::Result<Self> {
56        Ok(Self::new(
57            std::env::var("IOTA_NAMES_PACKAGE_ADDRESS")?.parse()?,
58            std::env::var("IOTA_NAMES_OBJECT_ID")?.parse()?,
59            std::env::var("IOTA_NAMES_PAYMENTS_PACKAGE_ADDRESS")?.parse()?,
60            std::env::var("IOTA_NAMES_REGISTRY_ID")?.parse()?,
61            std::env::var("IOTA_NAMES_REVERSE_REGISTRY_ID")?.parse()?,
62        ))
63    }
64
65    pub fn from_chain(chain: &Chain) -> Self {
66        match chain {
67            Chain::Mainnet => todo!("https://github.com/iotaledger/iota/issues/6532"),
68            Chain::Testnet => todo!("https://github.com/iotaledger/iota/issues/6531"),
69            Chain::Unknown => IotaNamesConfig::devnet(),
70        }
71    }
72
73    pub fn record_field_id(&self, domain: &Domain) -> ObjectID {
74        let domain_type_tag = Domain::type_(self.package_address);
75        let domain_bytes = bcs::to_bytes(domain).unwrap();
76
77        iota_types::dynamic_field::derive_dynamic_field_id(
78            self.registry_id,
79            &TypeTag::Struct(Box::new(domain_type_tag)),
80            &domain_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    // TODO add testnet https://github.com/iotaledger/iota/issues/6531
97
98    // Create a config based on the package and object ids published on devnet.
99    pub fn devnet() -> Self {
100        const PACKAGE_ADDRESS: &str =
101            "0x3ec4826f1d6e0d9f00680b2e9a7a41f03788ee610b3d11c24f41ab0ae71da39f";
102        const OBJECT_ID: &str =
103            "0x54a8a67fad7aa279429e08824e03481dd8b268779353d299d7f8edaa8b8c13b7";
104        const PAYMENTS_PACKAGE_ADDRESS: &str =
105            "0x882f88d252a650649f490e96e32e53979758fdda645863ca856d83c72d5e0e72";
106        const REGISTRY_ID: &str =
107            "0xef24c78e8c085e29760d37b287fc16647f0f578e8d22f18dd65f655285afad3e";
108        const REVERSE_REGISTRY_ID: &str =
109            "0x566dc13eafceaf8c3487ee2c41464553839ef4d50937c63741e359c98080c7b6";
110
111        let package_address = IotaAddress::from_str(PACKAGE_ADDRESS).unwrap();
112        let object_id = ObjectID::from_str(OBJECT_ID).unwrap();
113        let payments_package_address = IotaAddress::from_str(PAYMENTS_PACKAGE_ADDRESS).unwrap();
114        let registry_id = ObjectID::from_str(REGISTRY_ID).unwrap();
115        let reverse_registry_id = ObjectID::from_str(REVERSE_REGISTRY_ID).unwrap();
116
117        Self::new(
118            package_address,
119            object_id,
120            payments_package_address,
121            registry_id,
122            reverse_registry_id,
123        )
124    }
125}