Developer Guide
Node.js

Node.js

The simplest interaction with the registry is with ethers (opens in a new tab) and using fetch directly on a vechain node.

Resolve Utility Contract

const { Interface, isAddress } = require('ethers')
 
const VET_UTILITY_ADDRESS = "0xA11413086e163e41901bb81fdc5617c975Fa5a1A";
const NODE_URL = "https://node-mainnet.vechain.energy"
 
const utilityInterface = new Interface([
    'function getAddresses(string[] memory names) external view returns (address[] memory addresses)',
    'function getNamehashes(string[] memory names) external pure returns (bytes32[] memory nodes)',
    'function getNames(address[] memory addresses) external view returns (string[] memory names)'
])
 
 
async function getRecord(name) {
    const [{ data: addressData }] = await fetch(`${NODE_URL}/accounts/*`, {
        method: 'POST',
        headers: {
            'content-type': 'application/json'
        },
        body: JSON.stringify({
            clauses: [
                {
                    to: VET_UTILITY_ADDRESS,
                    data: utilityInterface.encodeFunctionData('getAddresses', [[name]])
                }
            ]
        })
    }).then(res => res.json());
 
    const { addresses } = utilityInterface.decodeFunctionResult('getAddresses', addressData);
 
    return addresses[0];
}
 
async function getName(address) {
    const [{ data: nameData }] = await fetch(`${NODE_URL}/accounts/*`, {
        method: 'POST',
        headers: {
            'content-type': 'application/json'
        },
        body: JSON.stringify({
            clauses: [
                {
                    to: VET_UTILITY_ADDRESS,
                    data: utilityInterface.encodeFunctionData('getNames', [[address]])
                }
            ]
        })
    }).then(res => res.json());
 
    const { names } = utilityInterface.decodeFunctionResult('getNames', nameData);
    return names[0];
}
 
async function getAddress(addressOrName) {
    return isAddress(addressOrName) ? addressOrName : getRecord(addressOrName)
}
 
async function main() {
    const testName = 'hello.vet'
 
    const address = await getRecord(testName)
    console.log(testName, 'resolves to', address)
 
    const name = await getName(address)
    console.log('primary name of', address, 'is', name)
 
    const addressTest1 = await getAddress(address)
    const addressTest2 = await getAddress(name)
 
    console.log('getAddress(address) replies with', addressTest1)
    console.log('getAddress(name) replies with', addressTest2)
}
 
main()
    .then(() => process.exit(0))
    .catch(error => {
        console.error(error);
        process.exit(1);
    });

Pure Registry

const { namehash, Interface, ZeroAddress, isAddress } = require('ethers')
 
const VET_REGISTRY_ADDRESS = "0xa9231da8BF8D10e2df3f6E03Dd5449caD600129b";
const NODE_URL = "https://node-mainnet.vechain.energy"
 
const nameInterface = new Interface([
    'function resolver(bytes32 node) returns (address resolverAddress)',
    'function addr(bytes32 node) returns (address resolvedAddress)',
    'function name(bytes32 node) returns (string memory name)'
])
 
 
async function getRecord(name) {
    const node = namehash(name);
 
    const [{ data: resolverData, reverted: noResolver }] = await fetch(`${NODE_URL}/accounts/*`, {
        method: 'POST',
        headers: {
            'content-type': 'application/json'
        },
        body: JSON.stringify({
            clauses: [
                {
                    to: VET_REGISTRY_ADDRESS,
                    data: nameInterface.encodeFunctionData('resolver', [node])
                }
            ]
        })
    }).then(res => res.json());
 
    // return zero address if no resolver has been set
    if (noResolver) { return ZeroAddress; }
    const { resolverAddress } = nameInterface.decodeFunctionResult('resolver', resolverData);
 
    const [{ data: lookupData, reverted: noLookup }] = await fetch(`${NODE_URL}/accounts/*`, {
        method: 'POST',
        headers: {
            'content-type': 'application/json'
        },
        body: JSON.stringify({
            clauses: [
                {
                    to: resolverAddress,
                    data: nameInterface.encodeFunctionData('addr', [node])
                }
            ]
        })
    }).then(res => res.json());
 
    // return zero address if resolver does respond with error
    if (noLookup) { return ZeroAddress; }
    const { resolvedAddress } = nameInterface.decodeFunctionResult('addr', lookupData);
 
    return resolvedAddress;
}
 
async function getName(address) {
    const reverseLookup = `${address.slice(2).toLowerCase()}.addr.reverse`;
    const node = namehash(reverseLookup);
 
 
    const [{ data: resolverData, reverted: noResolver }] = await fetch(`${NODE_URL}/accounts/*`, {
        method: 'POST',
        headers: {
            'content-type': 'application/json'
        },
        body: JSON.stringify({
            clauses: [
                {
                    to: VET_REGISTRY_ADDRESS,
                    data: nameInterface.encodeFunctionData('resolver', [node])
                }
            ]
        })
    }).then(res => res.json());
 
    // return empty string if no resolver has been set
    if (noResolver) { return ''; }
    const { resolverAddress } = nameInterface.decodeFunctionResult('resolver', resolverData);
 
    const [{ data: lookupData, reverted: noLookup }] = await fetch(`${NODE_URL}/accounts/*`, {
        method: 'POST',
        headers: {
            'content-type': 'application/json'
        },
        body: JSON.stringify({
            clauses: [
                {
                    to: resolverAddress,
                    data: nameInterface.encodeFunctionData('name', [node])
                }
            ]
        })
    }).then(res => res.json());
 
    // return empty string if resolver does respond with error
    if (noLookup) { return ''; }
    const { name } = nameInterface.decodeFunctionResult('name', lookupData);
 
    return name;
}
 
async function getAddress(addressOrName) {
    return isAddress(addressOrName) ? addressOrName : getRecord(addressOrName)
}
 
async function main() {
    const testName = 'hello.vet'
 
    const address = await getRecord(testName)
    console.log(testName, 'resolves to', address)
 
    const name = await getName(address)
    console.log('primary name of', address, 'is', name)
 
    const addressTest1 = await getAddress(address)
    const addressTest2 = await getAddress(name)
 
    console.log('getAddress(address) replies with', addressTest1)
    console.log('getAddress(name) replies with', addressTest2)
}
 
main()
    .then(() => process.exit(0))
    .catch(error => {
        console.error(error);
        process.exit(1);
    });