Skip to content

Getting Namespace Information⚓︎

This tutorial shows how to retrieve a namespace's properties and the mosaic or account it points to.

Prerequisites⚓︎

This tutorial only reads data from the network. No account is required.

Before you start, make sure to set up your development environment.

Full Code⚓︎

import json
import os
import urllib.request

from symbolchain.symbol.IdGenerator import generate_namespace_path
from symbolchain.symbol.Network import Address

NODE_URL = os.getenv(
    'NODE_URL', 'https://reference.symboltest.net:3001')
print(f'Using node {NODE_URL}')

NAMESPACE_NAME = os.getenv('NAMESPACE_NAME', 'symbol.xym')
print(f'Namespace name: {NAMESPACE_NAME}')

try:
    # Generate namespace ID from name
    path = generate_namespace_path(NAMESPACE_NAME)
    namespace_id = path[-1]
    namespace_id_hex = f'{namespace_id:x}'
    print(f'Namespace ID: {namespace_id} (0x{namespace_id_hex})')

    # Fetch namespace information
    namespace_path = f'/namespaces/{namespace_id_hex}'
    print(f'Fetching namespace information from {namespace_path}')
    with urllib.request.urlopen(
            f'{NODE_URL}{namespace_path}') as response:
        response_json = json.loads(response.read().decode())
        ns = response_json['namespace']
        print('Namespace information:')
        reg_type = ns['registrationType']
        print(f'  Registration type: {reg_type}')
        owner_address = Address.from_decoded_address_hex_string(
            ns['ownerAddress'])
        print(f'  Owner address: {owner_address}')
        depth = int(ns['depth'])
        print(f'  Depth: {depth}')
        print(f'  Level 0 ID: {ns["level0"]}')
        if depth >= 2:
            print(f'  Level 1 ID: {ns["level1"]}')
        if depth == 3 and 'level2' in ns:
            print(f'  Level 2 ID: {ns["level2"]}')
        print(f'  Start height: {ns["startHeight"]}')
        end_height = int(ns['endHeight'])
        print(f'  End height: {end_height} (0x{end_height:X})')

        # Display alias information
        alias = ns['alias']
        alias_type = alias['type']
        print(f'  Alias type: {alias_type}')
        if alias_type == 1:
            print(f'  Linked mosaic ID: {alias["mosaicId"]}')
        elif alias_type == 2:
            linked_address = (
                Address.from_decoded_address_hex_string(
                    alias['address']))
            print(f'  Linked address: {linked_address}')
        else:
            print('  No alias linked')

except Exception as e:
    print(e)

Download source

import { Address, generateNamespacePath } from 'symbol-sdk/symbol';

const NODE_URL = process.env.NODE_URL
|| 'https://reference.symboltest.net:3001';
console.log('Using node', NODE_URL);

const NAMESPACE_NAME = process.env.NAMESPACE_NAME || 'symbol.xym';
console.log('Namespace name:', NAMESPACE_NAME);

try {
    // Generate namespace ID from name
    const path = generateNamespacePath(NAMESPACE_NAME);
    const namespaceId = path[path.length - 1];
    const namespaceIdHex = namespaceId.toString(16);
    console.log('Namespace ID:', `${namespaceId} (0x${namespaceIdHex})`);

    // Fetch namespace information
    const namespacePath = `/namespaces/${namespaceIdHex}`;
    console.log(
        'Fetching namespace information from', namespacePath);
    const namespaceResponse =
        await fetch(`${NODE_URL}${namespacePath}`);
    if (!namespaceResponse.ok) {
        throw new Error(
            `HTTP error! status: ${namespaceResponse.status}`);
    }
    const namespaceJSON = await namespaceResponse.json();
    const ns = namespaceJSON.namespace;
    console.log('Namespace information:');
    console.log('  Registration type:', ns.registrationType);
    const ownerAddress = Address.fromDecodedAddressHexString(
        ns.ownerAddress);
    console.log('  Owner address:', ownerAddress.toString());
    const depth = ns.depth;
    console.log('  Depth:', depth);
    console.log('  Level 0 ID:', ns.level0);
    if (depth >= 2) {
        console.log('  Level 1 ID:', ns.level1);
    }
    if (depth === 3 && ns.level2) {
        console.log('  Level 2 ID:', ns.level2);
    }
    console.log('  Start height:', ns.startHeight);
    const endHeight = BigInt(ns.endHeight);
    console.log('  End height:',
        `${endHeight} (0x${endHeight.toString(16).toUpperCase()})`);

    // Display alias information
    const alias = ns.alias;
    console.log('  Alias type:', alias.type);
    if (alias.type === 1) {
        console.log('  Linked mosaic ID:', alias.mosaicId);
    } else if (alias.type === 2) {
        const linkedAddress = Address.fromDecodedAddressHexString(
            alias.address);
        console.log('  Linked address:', linkedAddress.toString());
    } else {
        console.log('  No alias linked');
    }
} catch (e) {
    console.error(e.message);
}

Download source

The snippet uses the NODE_URL environment variable to set the Symbol API node. If no value is provided, a default testnet node is used.

The NAMESPACE_NAME environment variable specifies which namespace to query. If not set, it defaults to symbol.xym, the namespace linked to the network's native currency XYM.

Code Explanation⚓︎

Generating the Namespace ID⚓︎

    # Generate namespace ID from name
    path = generate_namespace_path(NAMESPACE_NAME)
    namespace_id = path[-1]
    namespace_id_hex = f'{namespace_id:x}'
    print(f'Namespace ID: {namespace_id} (0x{namespace_id_hex})')
    // Generate namespace ID from name
    const path = generateNamespacePath(NAMESPACE_NAME);
    const namespaceId = path[path.length - 1];
    const namespaceIdHex = namespaceId.toString(16);
    console.log('Namespace ID:', `${namespaceId} (0x${namespaceIdHex})`);

Namespace IDs are computed locally from the namespace name using . This function takes a fully qualified name like symbol.xym, splits it by ., and returns an array of namespace IDs for each level in the hierarchy. The last element is the ID of the deepest namespace.

Fetching Namespace Information⚓︎

    # Fetch namespace information
    namespace_path = f'/namespaces/{namespace_id_hex}'
    print(f'Fetching namespace information from {namespace_path}')
    with urllib.request.urlopen(
            f'{NODE_URL}{namespace_path}') as response:
        response_json = json.loads(response.read().decode())
        ns = response_json['namespace']
        print('Namespace information:')
        reg_type = ns['registrationType']
        print(f'  Registration type: {reg_type}')
        owner_address = Address.from_decoded_address_hex_string(
            ns['ownerAddress'])
        print(f'  Owner address: {owner_address}')
        depth = int(ns['depth'])
        print(f'  Depth: {depth}')
        print(f'  Level 0 ID: {ns["level0"]}')
        if depth >= 2:
            print(f'  Level 1 ID: {ns["level1"]}')
        if depth == 3 and 'level2' in ns:
            print(f'  Level 2 ID: {ns["level2"]}')
        print(f'  Start height: {ns["startHeight"]}')
        end_height = int(ns['endHeight'])
        print(f'  End height: {end_height} (0x{end_height:X})')
    // Fetch namespace information
    const namespacePath = `/namespaces/${namespaceIdHex}`;
    console.log(
        'Fetching namespace information from', namespacePath);
    const namespaceResponse =
        await fetch(`${NODE_URL}${namespacePath}`);
    if (!namespaceResponse.ok) {
        throw new Error(
            `HTTP error! status: ${namespaceResponse.status}`);
    }
    const namespaceJSON = await namespaceResponse.json();
    const ns = namespaceJSON.namespace;
    console.log('Namespace information:');
    console.log('  Registration type:', ns.registrationType);
    const ownerAddress = Address.fromDecodedAddressHexString(
        ns.ownerAddress);
    console.log('  Owner address:', ownerAddress.toString());
    const depth = ns.depth;
    console.log('  Depth:', depth);
    console.log('  Level 0 ID:', ns.level0);
    if (depth >= 2) {
        console.log('  Level 1 ID:', ns.level1);
    }
    if (depth === 3 && ns.level2) {
        console.log('  Level 2 ID:', ns.level2);
    }
    console.log('  Start height:', ns.startHeight);
    const endHeight = BigInt(ns.endHeight);
    console.log('  End height:',
        `${endHeight} (0x${endHeight.toString(16).toUpperCase()})`);

The /namespaces/{namespaceId} GET endpoint retrieves the current properties of a namespace, including:

  • Registration type: The value 0 indicates a root namespace and 1 indicates a subnamespace.

  • Owner address: The account that registered the namespace.

  • Depth: The number of levels in the namespace hierarchy. For example, foo has a depth of 1, foo.bar has a depth of 2, and foo.bar.baz has a depth of 3.

  • Levels: The namespace IDs for each level in the hierarchy. level0 is always the root namespace ID. level1 and level2 appear for deeper hierarchies.

  • Start and end heights: The block range during which the namespace is active.

Checking the Alias⚓︎

        # Display alias information
        alias = ns['alias']
        alias_type = alias['type']
        print(f'  Alias type: {alias_type}')
        if alias_type == 1:
            print(f'  Linked mosaic ID: {alias["mosaicId"]}')
        elif alias_type == 2:
            linked_address = (
                Address.from_decoded_address_hex_string(
                    alias['address']))
            print(f'  Linked address: {linked_address}')
        else:
            print('  No alias linked')
    // Display alias information
    const alias = ns.alias;
    console.log('  Alias type:', alias.type);
    if (alias.type === 1) {
        console.log('  Linked mosaic ID:', alias.mosaicId);
    } else if (alias.type === 2) {
        const linkedAddress = Address.fromDecodedAddressHexString(
            alias.address);
        console.log('  Linked address:', linkedAddress.toString());
    } else {
        console.log('  No alias linked');
    }

Each level in a namespace hierarchy is an independent namespace that can have its own alias. The response includes alias information for the queried level, indicating whether it is linked to a mosaic or an account:

  • Alias type 0: No alias is linked.
  • Alias type 1: The namespace is linked to a mosaic. The response includes the linked mosaic ID.
  • Alias type 2: The namespace is linked to an account. The response includes the linked address.

Output⚓︎

The output shown below corresponds to a typical run of the program, querying the symbol.xym namespace on testnet.

Using node https://reference.symboltest.net:3001
Namespace name: symbol.xym
Namespace ID: 16666583871264174062 (0xe74b99ba41f4afee)
Fetching namespace information from /namespaces/e74b99ba41f4afee
Namespace information:
  Registration type: 1
  Owner address: TCEUGLPCMO5Y72EEISSNUKGTMCN5RO4PVYMK5FI
  Depth: 2
  Level 0 ID: A95F1F8A96159516
  Level 1 ID: E74B99BA41F4AFEE
  Start height: 1
  End height: 18446744073709551615 (0xFFFFFFFFFFFFFFFF)
  Alias type: 1
  Linked mosaic ID: 72C0212E67A08BCE

Some highlights from the output:

  • Namespace ID (line 3): The computed ID for symbol.xym is 0xe74b99ba41f4afee.

  • Registration type (line 6): The value 1 confirms this is a subnamespace (child of symbol).

  • Owner address (line 7): The account that registered the symbol namespace hierarchy.

  • Depth (line 8): The value 2 indicates a two-level hierarchy: symbol (level 0) and xym (level 1).

  • Level IDs (lines 9-10): level0 is the root symbol namespace ID (A95F1F8A96159516), and level1 is the xym subnamespace ID (E74B99BA41F4AFEE). The last level ID matches the namespace ID on line 3, confirming it is the namespace being queried.

  • End height (line 12): The value 18446744073709551615 (0xFFFFFFFFFFFFFFFF) means this namespace never expires.

  • Alias (lines 13-14): The alias type 1 confirms the namespace is linked to the XYM mosaic (72C0212E67A08BCE).

Conclusion⚓︎

This tutorial showed how to:

Step Related documentation
Generate namespace ID
Fetch namespace properties /namespaces/{namespaceId} GET
Check namespace alias /namespaces/{namespaceId} GET