Skip to main content

Integration Guide

Sui Name Service (SuiNS) is a decentralized naming service on the Sui blockchain that enables users to replace complex wallet addresses with human-readable names. You can integrate SuiNS into your application using either onchain or offchain resolution.

Active constants

The following list shows the current active objects for interacting with SuiNS.

info

Look here for the latest state, as some active constants might change. These changes come from secondary packages responsible for registering a name, renewing a name, and associated utilities. The core package cannot change, nor can the core SuiNS object.

SuiNS deploys, authorizes, and maintains the following packages on Mainnet.

KindPackage ID
SuiNS Core (latest)0x71af035413ed499710980ed8adb010bbf2cc5cacf4ab37c7710a4bb87eb58ba5
SuiNS Core V10xd22b24490e0bae52676651b4f56660a5ff8022a2576e0089f79b3c88d44e08f0
Subnames0xe177697e191327901637f8d2c5ffbbde8b1aaac27ec1024c4b62d1ebd1cd7430
Subnames Proxy0xf335dfbcb2020fc996250c0d6fd4655c5e2036b0606cac7408aa163f51340886
Discounts0x03f625d805339b1b0235ba8c503fa6ea62c88c02ddf14cd9d246d9e1febc0c76
Coupons0xb162340524e0697461c307b9dc530c17e837b0f2c6d7f787da40d29d29681e5e
Payments0xdd0a4a34152a80d7841710e916a407b2a62961eee5b2188dcfdaa24194f66286

Integration

You can integrate SuiNS in multiple ways depending on your use case. For apps, you typically integrate SuiNS through offchain resolution using remote procedural calls (RPCs). The calls enable you to interact with the Sui network or display names instead of addresses. For example, your RPCs might create transactions that send assets to names, or show names instead of addresses on a leaderboard.

Resolution types

SuiNS supports 2 types of resolution:

  • Lookup: A name can point to an address or an object (target address). This allows you to resolve a name like example.sui to its target address.

  • Reverse lookup: An address can have a default name. This allows you to find the name associated with a particular address.

Address types

Lookups work with different types of addresses:

  • Target address: The address that a SuiNS name resolves to. For example, example.sui might point to 0x2, making 0x2 the target address for example.sui. Lookup resolution retrieves this information.

  • Default address: The SuiNS name that the owner of a particular address has selected to represent that address. For example, if you own 0x2 you can make example.sui its default address. The owner must sign and execute a set default transaction to establish this connection. The default address resets anytime the target address changes. Reverse lookup resolution retrieves this name.

SuiNS NFT ownership

Do not use ownership of a SuiNS NFT as a resolution method. An NFT is used as the key (capability) to change the target address, but should not be used to identify any name with an address.

SuiNS NFT ownership allows any address to be set as the target address. So, the example.sui address used in the previous section can point to any address, not just 0x2. Consequently, when you want to display default addresses, you should trust the default address over target address because it is guaranteed onchain.

Offchain resolution

For offchain resolution, use the available Sui API endpoints:

info

For GraphQL's default name resolution, use the defaultSuinsName field.

Onchain resolution

Use the SuiNS core package for onchain resolution. Add the following dependency in your Move.toml file depending on which network you are targeting:

[dependencies]
suins = { git = "https://github.com/mystenlabs/suins-contracts/", subdir = "packages/suins", rev = "releases/mainnet/core/v3" }

Example: transfer object to SuiNS name

The following demo module demonstrates how to transfer an object of any type to a SuiNS name. This is a basic example of how to interact with SuiNS onchain.

module demo::demo {
use std::string::String;
use sui::clock::Clock;

/// Import the SuiNS dependency.
use suins::{
suins::SuiNS,
registry::Registry,
domain
};

/// Different custom error messages.
const ENameNotFound: u64 = 0;
const ENameNotPointingToAddress: u64 = 1;
const ENameExpired: u64 = 2;

/// A function to transfer an object of any type T to a name (for instance `example.sui`)
public fun send_to_name<T: key + store>(suins: &SuiNS, obj: T, name: String, clock: &Clock) {
// Look up the name on the registry.
let mut optional = suins.registry<Registry>().lookup(domain::new(name));
// Check that the name indeed exists.
assert!(optional.is_some(), ENameNotFound);

let name_record = optional.extract();
// Check that name has not expired.
// This check is optional, but it's recommended you perform the verification.
assert!(!name_record.has_expired(clock), ENameExpired);
// Check that the name has a target address set.
assert!(name_record.target_address().is_some(), ENameNotPointingToAddress);

// Transfer the object to that name.
transfer::public_transfer(obj, name_record.target_address().extract())
}
}
caution

You should integrate SuiNS onchain using the core package only. The utility packages are likely to be replaced, rendering your logic non-functional unless you update your code with each change.

Indexing

The indexer enables more expressive queries about the active domain state when onchain resolution is not sufficient to power your interface.

This allows for complex queries such as:

  • Get all the subnames for a given parent: Retrieve every subdomain linked to a parent domain, enhancing the ability to manage and analyze domain structures.

  • Get all names pointing to a specified address: Identify all domain names associated with a specific wallet address to track ownership and usage.

You can find the indexer in the suins-indexer GitHub repository. Feel free to spin up your own service if you are looking to index data tailored to your needs.

For a deeper understanding of how the indexer works and how to integrate it into your projects, refer to Sui's custom indexer documentation.

Subnames

Subnames are nested names under a parent name. Unlike regular names, creating subnames has no cost.

The maximum nesting depth is 8 levels. The total depth, including the second-level domain (SLD) and top-level domain (TLD), means the maximum total depth is 10 levels.

Parent rules control whether you can create nested names or not and can also allow a subname to extend the expiration to match the parent's expiration. You can alter the parent rules at any time, but revoking or burning follows the same rules.

Subname types

Subnames can be one of 2 types:

  1. Node subnames: Similar to regular names, they have an NFT associated with them that gives access to all extra features (personalization, avatars, and so on).

  2. Leaf subnames: These subnames exist under a node subname. They do not have an NFT associated with them, so the parent controls their configuration. Consequently, the typical use case for leaf subnames is to use them programmatically.

The following table provides more details on the differences between the types of names:

Capabilities/CategoryNode subnamesLeaf subnames
Has NFT✅ Yes,
  • SuinsRegistration for SLD*
  • SubDomainRegistration for nested names
❌ No, parent's NFT acts as the capability
Can create children (node or leaf)✅ Yes, provided the name is an SLD or the parent allows it❌ No
Expiration✅ Yes, SuiNS determines expiration for SLDs, otherwise the parent determines❌ No, the parent's expiration determines the leaf expiration
Extend expiration✅ Yes, you can extend expiration if parent rules allow it (or you can pay for it for SLD)✅ Yes, leaf names do not expire
Target address✅ Yes, NFT holder can update the target address; address can be empty✅ Yes, active parent's NFT holder can update the target address; address cannot be empty
Reverse registry✅ Yes✅ Yes
Revoke❌ No, you cannot remove a node name (except when expired)✅ Yes, active parent holder can remove a leaf name
Burn✅ Yes, post-expiration only✅ Yes, burn and revoking is the same for leaf names
Transfer ownership✅ Yes, the NFT determines node name ownership❌ No, SuiNS preserves ownership for the active parent name holder

SLD - Second-level domain (for example, example in example.sui)