Skip to main content

Contract Addresses

All contracts are deployed to the same addresses on both Base and BSC:
ContractAddress
ENSRegistry0xce3830A628674C67e35294128F638dDC9c69d8f8
MakxRegistrar0x62b26B7e71127AF8bD26b44FB3BF2f17D845A530
MakxTokenResolver0xEcB18a27D37a289AA5A9721f8F28c879E894E2F3
MakxUniversalResolver0x535aeD7b7Cd80Ed9A0835E1Ed29a99d038B8B777

Registering Tokens (Factory Integration)

Only approved factories can register .makx domains. Your factory contract must be added by the Makx team before you can register names.

Registration Flow

import {MakxRegistrar} from "./MakxRegistrar.sol";

contract MyFactory {
    MakxRegistrar public immutable registrar;

    constructor(MakxRegistrar _registrar) {
        registrar = _registrar;
    }

    function launchToken(
        string calldata label,
        address tokenAddress
    ) external {
        // Deploy your token first...

        // Build the registration request
        string[] memory keys = new string[](2);
        string[] memory values = new string[](2);
        keys[0] = "description";
        values[0] = "A token launched on Makx";
        keys[1] = "url";
        values[1] = "https://makx.app";

        MakxRegistrar.RegistrationRequest memory req = MakxRegistrar
            .RegistrationRequest({
                label: label,           // e.g. "uniswap" -> uniswap.makx
                owner: msg.sender,      // who can edit metadata later
                tokenAddress: tokenAddress,
                name: "Uniswap",
                symbol: "UNI",
                keys: keys,
                values: values
            });

        bytes32 node = registrar.register(req);
        // node = namehash("uniswap.makx")
    }
}

What Happens During Registration

A single register() call atomically:
  1. Creates the ENS subnode <label>.makx in the ENS registry
  2. Sets the resolver to MakxTokenResolver
  3. Stores immutable token data (address, name, symbol)
  4. Sets the ETH address record (coin type 60)
  5. Stores initial text records from keys/values
  6. Creates the reverse record (<address>.addr.reverse -> label.makx)
The registrar retains ENS ownership of the node. The owner in the request becomes the metadata editor — they can update mutable text records and contenthash, but cannot change the token address, name, or symbol.

Label Rules

Labels are used as-is (no normalization). The resulting domain is <label>.makx. Choose labels carefully — they cannot be changed or re-registered.

Managing Token Metadata

After registration, the metadata owner can update mutable fields by calling the MakxTokenResolver directly.

Setting Text Records

import {MakxTokenResolver} from "./MakxTokenResolver.sol";

// The metadata owner calls setText directly on the resolver
resolver.setText(node, "description", "Updated description");
resolver.setText(node, "url", "https://new-website.com");
resolver.setText(node, "com.twitter", "@newhandle");
Immutable keys (name, symbol) will revert with ImmutableField(key).

Setting Content Hash

resolver.setContenthash(node, ipfsContentHash);

Transferring Metadata Ownership

resolver.transferOwnership(node, newOwnerAddress);
After transfer, only the new owner can call setText, setContenthash, and transferOwnership.

Reading Token Data On-Chain

Single Call for Core Info

(address tokenAddress, string memory name_, string memory symbol_) =
    resolver.tokenInfo(node);

Individual Lookups

address token = resolver.addr(node);               // Token address
string memory desc = resolver.text(node, "description");  // Text record
bytes memory hash = resolver.contenthash(node);     // Content hash
bool registered = resolver.exists(node);            // Existence check
address owner = resolver.ownerOf(node);             // Metadata owner

Reverse Lookup

To find the .makx name for a token address on-chain, compute the reverse node:
bytes32 reverseNode = keccak256(
    abi.encodePacked(
        addrReverseNode,    // namehash("addr.reverse")
        keccak256(abi.encodePacked(_addressToHex(tokenAddress)))
    )
);
string memory name = resolver.name(reverseNode);

Verifying a Makx Token On-Chain

function isMakxToken(bytes32 node) external view returns (bool) {
    return resolver.exists(node);
}
Since only approved factories can create records through the registrar, the existence of a record is proof the token was launched through Makx.

Computing Node Hashes

The node for <label>.makx is:
bytes32 makxNode = /* namehash("makx") -- set at deployment */;
bytes32 node = keccak256(abi.encodePacked(makxNode, keccak256(bytes(label))));
This matches the ENS namehash specification.

Deployment Order

Contracts must be deployed in this order due to circular references:
1. Deploy ENSRegistry
2. Deploy MakxRegistrar(owner, registry, makxNode, addrReverseNode)
3. Deploy MakxTokenResolver(registrar.address)
4. Call registrar.setResolver(resolver.address)
5. Set up ENS hierarchy:
   a. Grant registrar ownership of the "makx" node in ENS
   b. Grant registrar ownership of "addr.reverse" node in ENS
6. Call registrar.addFactory(factoryAddress) for each approved factory