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        // 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, 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    // 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            "0xe1284870018484a7a12255aebb737b6b98b47d652b842ea2f324499ff163a648";
102        const OBJECT_ID: &str =
103            "0xa92a67ae8a8c644acfa6dd5a4d8098a20b07b6061cbf36aff8daef3ba892913f";
104        const PAYMENTS_PACKAGE_ADDRESS: &str =
105            "0x1efac8bf200acca64b62ce75557cd7232310fc8c4ea90960487d2908055fc94f";
106        const REGISTRY_ID: &str =
107            "0x88fa01b1f2462f2f33b593eb205b88158e1f51594102b9748b73f134388a3f2d";
108        const REVERSE_REGISTRY_ID: &str =
109            "0x1b3840a267efdc30d11b2b7ad2e574cf8483cd4e06bdf7b39c61ee5717ac3fe6";
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}