All pages
Powered by GitBook
1 of 7

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Resolver Contract

The dotHYPEResolver brings your .hype name to life across Web3. It makes your name functionally usable as an identity layer readable by dApps, wallets, bots, and dashboards.

Fully ENS-compatible, the Resolver contract supports multiple record types, reverse resolution, and metadata customization. It follows the standard ENS interface structure but is tightly integrated with the dotHYPE Registry to enforce domain status and expiration.

This contract does not handle ownership—it simply reflects what the Registry allows, and enables you to associate rich identity data with your name.

🔍 What It Does

The Resolver supports:

  • Address resolution (EVM and multi-chain)

  • Text records (socials, avatar, website, etc.)

  • Content hash linking (IPFS, Swarm)

  • Reverse resolution (address → name)

  • Record versioning and batch updates

If your name is expired or inactive, all resolution queries return blank results. The Resolver only returns records for active .hype names.

🔗 Address Resolution

You can link your .hype name to wallet addresses using either:

  • A simple EVM address (default Ethereum-style resolution)

  • A multi-coin address using SLIP-0044 standards

function addr(bytes32 node) external view returns (address);
function addr(bytes32 node, uint256 coinType) external view returns (bytes memory);

Set via:

function setAddr(bytes32 node, address addr) external;
function setAddr(bytes32 node, uint256 coinType, bytes calldata addr) external;

If no address is set, most systems default to the current domain owner.

📝 Text Records

Text records allow you to embed human-readable metadata into your .hype name.

Common uses include:

  • Socials: com.twitter, com.github

  • Profile: avatar, description

  • Contact: email, url, website

function text(bytes32 node, string calldata key) external view returns (string memory);
function setText(bytes32 node, string calldata key, string calldata value) external;

Text records power UI display, social graphing, and indexing.

🧬 Content Hash

Use a .hype name to link to decentralized content like:

  • IPFS files or websites

  • Swarm hashes

  • Other content-addressed systems

function contenthash(bytes32 node) external view returns (bytes memory);
function setContenthash(bytes32 node, bytes calldata hash) external;

This is ideal for user profiles, dApp frontends, or media hubs.

🔄 Versioning System

Rather than deleting records one by one, dotHYPE enables full record resets via versioning.

function recordVersions(bytes32 node) external view returns (uint256);
function clearRecords(bytes32 node) external;

Each record is linked to a version counter:

  • clearRecords() bumps the version

  • All previous records become invalid

Useful for refreshing a stale or incorrect profile in one transaction.

🔁 Reverse Resolution

Reverse records map wallet addresses back to .hype names. This is what makes UIs (wallets, explorers, dApps) show your name instead of a 0x address.

Key functions:

function setReverseRecord(string calldata name) external returns (bytes32);
function clearReverseRecord() external;
function reverseLookup(address addr) external view returns (string memory);
function getName(address addr) external view returns (string memory);

You can also:

  • Query a text record via reverse: getValue(address, key)

  • Check if an address has a reverse record: hasRecord(address)

🚫 Domain Expiration Enforcement

The Resolver enforces expiration checks. If a domain is expired:

  • All resolution returns are blank

  • Records cannot be set or updated

function isAuthorized(bytes32 node) internal view returns (bool);

This ensures that only active .hype names can display metadata or resolve onchain.

🧩 Multi-call Support

To keep things gas-efficient, the resolver supports batch operations:

  • Set multiple records in a single call

  • Commonly used when updating profiles or migrating data

This feature inherits from the Multicallable interface standard.

🔐 Access & Authorization

Only the current name owner can set or update records.

  • Ownership is checked against the Registry

  • If your name is expired, you temporarily lose write access

All write functions include internal isAuthorized() checks.

📡 Interface Discovery

Applications can check whether this resolver supports a given record type using:

function supportsInterface(bytes4 interfaceID) public view override returns (bool);

dotHYPE Resolver supports:

  • IAddrResolver

  • IAddressResolver

  • ITextResolver

  • IContentHashResolver

  • IReverseResolver

This ensures compatibility with ENS-resolving dApps and multi-chain interfaces.

🧠 For Developers

If you're building with .hype names:

  • Use addr() to resolve to a wallet or contract

  • Use text() to display social or profile metadata

  • Use reverseLookup() to show names for addresses

The Resolver does not store ownership—it’s a read/write utility that enhances what the Registry tracks.

Registry Contract

The dotHYPERegistry is the foundational contract that tracks ownership of .hype names, manages expirations, and defines how names behave onchain.

Every .hype name is an NFT—minted and stored using this registry. It’s compliant with ERC-721, but also includes extensions to manage lifecycle events like renewal, expiration, and status tracking in a way that fits naming infrastructure.

This page explains how the registry works and what matters for developers or curious users.

📘 What It Does

The Registry contract is responsible for:

  • Minting .hype names as NFTs

  • Assigning expiration timestamps

  • Enforcing availability logic (e.g. what counts as expired)

  • Preventing transfers of expired names

  • Handling metadata for display

All minting and renewing must come through the Controller contract, which acts as a gatekeeper. That ensures pricing and access logic can be upgraded independently.

You can think of the Registry as the final source of truth for who owns what and for how long.

⏳ Expiration & Renewal Rules

Each name is registered for a fixed period, starting from the time of mint. Once that period ends, the name enters a 30-day grace period. During this window:

  • The owner can still renew the name

  • But it can’t be transferred or sold

After the grace period ends:

  • The name becomes available to others

  • It can be re-registered by anyone

To ensure meaningful durations, all registrations must last at least 28 days.

🔐 Availability Logic

A name is considered available if:

  • It has never been registered

  • OR its expiration + grace period has passed

This logic ensures names can’t be accidentally or maliciously re-claimed too early. Builders can use the available() function to check status.

function available(string calldata name) external view returns (bool);

🔁 Minting & Renewal Process (Simplified)

Names are minted and renewed through the Controller. The Registry handles the actual recording.

When a name is registered:

  1. A token ID is created using the namehash algorithm

  2. An expiration time is assigned

  3. An NFT is minted to the user

When renewed:

  • The expiration is extended based on the original expiry (not the current time)

  • If the name is expired but within the grace period, it can still be renewed

function register(string calldata name, address owner, uint256 duration) external onlyController returns (uint256 expiresAt);
function renew(string calldata name, uint256 duration) external onlyController returns (uint256 expiresAt);

🧠 Token ID Generation

Each .hype name is converted into a token ID using a standard namehash algorithm—similar to ENS. This ensures uniqueness and predictability.

function nameToTokenId(string calldata name) public pure returns (uint256);

The algorithm:

  • Hashes the domain label using keccak256

  • Combines it with a root .hype identifier

  • Outputs a 256-bit integer as the token ID

This process ensures all names are deterministically derived and collision-resistant.

🖼 Metadata & Status Queries

Each name has a metadata URI, which can be customized using an external metadata provider. This lets you:

  • Display profile cards, avatars, or status in apps

  • Serve dynamic visuals for first 1K mints or milestone names

The Registry also exposes read-only status functions:

function expiresAt(uint256 tokenId) external view returns (uint256);
function expiry(string calldata name) external view returns (uint256);
function isExpired(uint256 tokenId) external view returns (bool);

🚫 Transfer Restrictions

Expired names (outside the grace period) cannot be transferred. This is enforced at the contract level no UI trickery.

The Registry overrides the _update() function to block transfers of expired tokens unless they are first renewed.

This protects users and prevents accidental loss of names post-expiration.

🛠 Admin Controls

Some functions are reserved for the protocol owner or multisig governance:

function setController(address _controller) external onlyOwner;
function setMetadataProvider(address _metadataProvider) external onlyOwner;

These allow future upgrades or metadata format changes without touching the core Registry logic.

🔎 For Developers

If you’re building an integration and want to:

  • Check if a name is expired

  • Query expiration time

  • Display metadata or avatars

...the Registry is your go-to source.

It’s not where minting logic lives—that happens in the Controller. But it’s where final ownership, expiration, and display logic is confirmed.

See the Controller Contract → to understand how minting works upstream.

Still have questions? Reach out in our dev community →

How It all Works

A high-level overview of the smart contract architecture and design philosophy that powers dotHYPE.

🔧 The Modular Backbone of dotHYPE

dotHYPE is built for a modular blockchain future. Instead of one giant smart contract, we designed a clean, composable system split across four core contracts—each responsible for a specific piece of functionality.

This modularity gives us:

  • 🚀 Flexibility to iterate without hardcoding everything into one place

  • 🔐 Better security through limited scopes and cleaner audits

  • 🤝 Easier integrations for developers and protocols

These components are designed to work independently, but connect seamlessly through permissioned interfaces and shared standards.

🧱 Core Contracts at a Glance

Contract

Role

What it Controls

Registry

NFT ownership

Tracks who owns each name, when it expires, and when it can be renewed

Controller

Minting logic

Sets pricing, duration, access, and routes requests to the registry

Resolver

Name functionality

Allows your name to resolve to addresses, text records, content hashes, and more

🔄 How They Work Together

Here’s the typical mint flow for a .hype name:

  1. You search for a name on the frontend.

  2. The frontend checks the name’s status via the Registry.

  3. If available, you sign a minting intent via EIP-712 (handled by the Controller).

  4. The Controller processes the request, confirms allowlist or auction state, and passes it to the Registry to mint.

  5. Once minted, your name can be personalized and resolved using the Resolver.

one is described in detail in the sections that follow.

🔍 Why This Design Matters

Other systems often bundle all logic into one contract or rely on legacy ENS-style routers. We didn’t do that.

Our approach:

  • ✅ Separates business logic from storage and resolution

  • ✅ Respects ENS standards where they matter (like resolution)

  • ✅ Enables protocol-level upgrades and partner modules without rewrites

This structure allows dotHYPE to evolve from a minting system into a programmable identity layer.

📚 What’s Next

Explore the core contracts:

  • Registry Contract → Tracks ownership and expirations

  • Controller Contract → Handles minting access and pricing

  • Resolver Contract → Makes your name usable across Web3

Minting Flow

All dotHYPE registrations follow a shared lifecycle—from name search to NFT minting. This page breaks down that flow so developers and users alike can understand what happens under the hood.

Regardless of whether you're minting via whitelist, reserved access, or public signature, the registration process moves through the same stages.

High-Level Flow

  1. Search a name → Check availability and pricing

  2. Validate eligibility → Based on mint phase (whitelist, reserved, or public)

  3. Submit transaction → Confirm duration and pay with $HYPE

  4. Mint NFT → Registry issues the .hype name as an ERC-721 token

  5. Record expiration → Expiry timestamp is stored in the Registry

The Controller contract orchestrates all of this and ensures only valid requests make it through.

UX Flow Example

Let’s walk through what happens when a user mints a name:

  1. User connects wallet to the mint UI

  2. User types a name (e.g. artist.hype)

  3. UI checks name availability via available(name)

  4. UI fetches price for 1-year term via getPrice(name, duration)

  5. Depending on the phase:

    • If whitelisted: user submits a Merkle proof

    • If reserved: contract verifies the address matches

    • If public: user signs an EIP-712 message and submits it

  6. Controller processes payment in $HYPE

  7. Registry mints the name and logs expiration

  8. UI shows confirmation, name dashboard becomes active

On-chain Processing Summary

Behind the scenes:

  • All logic is routed through the dotHYPEController

  • The Controller ensures:

    • The name meets eligibility criteria

    • Duration and price are valid

    • Payment is processed and refunded if overpaid

  • Once verified, the Controller:

    • Calls the Registry to mint the NFT

    • Sets expiration timestamp (now + duration)

Duration and Pricing

All names:

  • Must be registered for at least 365 days

  • Can be extended in 1-year increments

  • Are priced according to character length:

    • 3 characters → higher tier

    • 4 characters → mid tier

    • 5+ characters → base tier

Pricing is in USD and converted to $HYPE using an oracle at time of mint.

Payment Details

  • All mint payments are made in $HYPE

  • Overpayments are refunded automatically

  • A designated recipient receives mint funds (e.g. treasury multisig)

No approvals or token swaps needed—users only need $HYPE in their wallet.

Mint Result

Once minting is complete:

  • The user owns a .hype name NFT

  • It appears in their wallet

  • It can be resolved across Web3 using the Resolver

  • Expiration is stored and can be extended via renewal

dotHYPE Smart Contracts

Function
Address
View on Explorer

Controller

0xCd0A58e078c57B69A3Da6703213aa69085E2AC65

Registry

0xBf7cE65e6E920052C11690a80EAa3ed2fE752Dd8

Resolver

0x4d5e4ed4D5e4A160Fa136853597cDc2eBBe66494

Price Oracle

0x09fAB7D96dB646a0f164E3EA84782B45F650Fb51

Mainnet

🌐 Network Information

  • Current Network: HyperEVM Mainnet

  • Chain ID: 999

  • Block Explorer: HyperEVM Scan

🧾 Protocol Information

  • Protocol Name: DotHYPE

  • Top-Level Domain: .hype

  • Total Contracts: 4 of 4 configured

Testnet

🌐 Network Information

  • Current Network: Hyperliquid Testnet

  • Chain ID: 998

  • Block Explorer: HyperEVM Scan

🧾 Protocol Information

  • Protocol Name: DotHYPE

  • Top-Level Domain: .hype

  • Total Contracts: 4 of 4 configured

Link
Link
Link
Link

Registration Mechanics

dotHYPE supports multiple minting methods, each designed for different access phases—from community whitelists to partner allocations to public minting.

All registration pathways ultimately result in the same outcome: a .hype name minted as an NFT, owned by the registrant, and governed by an expiration timestamp.

This page introduces the shared rules and eligibility requirements that apply to all minting methods.

For deeper implementation details, see the following subpages:

  • Minting Flow

  • Signature Validation (EIP-712)

  • Merkle-Based Whitelisting

Key Principles of Registration

Across all registration types:

  • Names are minted as ERC-721 NFTs

  • Each name has a minimum 1-year registration period (365 days)

  • Pricing is based on name length (shorter = more expensive)

  • All payments are made in $HYPE (priced in USD via oracle)

  • Registrations are recorded with expiration timestamps

Your name is yours for the full term—but must be renewed to avoid expiration.

Name Requirements

To be eligible for registration, a name must:

  • Be at least 1 character in length

  • Be available (never registered, or expired + grace period passed)

  • Match an assigned reservation if it’s reserved

  • Be registered for at least 365 days

Names that don’t meet these criteria will be rejected at the contract level.

Where to Go Next

To dive deeper into the specific mechanics and smart contract patterns behind each registration method:

  • Minting Flow →

  • Signature Validation (EIP-712) →

  • Merkle-Based Whitelisting →

Or continue exploring Registry Contract → and Controller Contract → for the underlying infrastructure.

Controller Contract

The dotHYPEController is the logic layer for domain registration. It manages who can mint, how much they pay, and how names are allocated across phases.

All domain registrations and renewals are routed through the controller; it’s the decision-making contract that sits between users and the registry.

This is where pricing, access rules, signature verification, and allowlist enforcement live.

🔍 What It Does

The Controller handles:

  • Enforcing registration pricing (based on name length and duration)

  • Processing payments in $HYPE (based on USD-pegged prices)

  • Verifying signed requests to prevent front-running (via EIP-712)

  • Checking Merkle proofs for allowlisted mints

  • Managing name reservations (for pre-approved addresses)

Think of it as the programmable access layer for the dotHYPE registry.

💸 Pricing Model

dotHYPE uses a simple but powerful pricing structure:

  • Price is based on name length (e.g., 3-char names cost more than 5+)

  • All prices are denominated in USD

  • Payment is made in $HYPE, converted using an onchain oracle

  • Registration and renewal are priced separately

Example (public mint):

  • 3 characters: $100/year

  • 4 characters: $40/year

  • 5+ characters: $15/year

Pricing can be updated over time by the protocol owner, but logic is hardcoded for length-based tiers.

To fetch the price:

function getPrice(string calldata name, uint256 duration) public view returns (uint256);

✍️ Signature-Based Registration

Most mints use EIP-712 structured data to ensure fair access. This prevents bots from front-running open registrations.

function registerWithSignature(...) external payable returns (uint256);

This flow:

  1. Verifies a signed message from an authorized backend signer

  2. Confirms the nonce hasn't been used

  3. Calculates price and duration

  4. Registers the name through the Registry

Signatures are used in public mint, premium auction, and certain reserved phases.


🌿 Merkle-Based Allowlists

For whitelist and partner-only phases, we use Merkle trees to verify whether a user can register a name:

function registerWithMerkleProof(...) external payable returns (uint256);

Each address on the allowlist can register one name. Proofs are verified onchain. The Merkle root is updated periodically by the owner.


🪪 Reserved Name Access

Some names are explicitly reserved for specific addresses—partners, integrations, or founders.

function registerReservedName(...) external payable returns (uint256);

Only the address that a name is reserved for can register it. No one else can front-run or bypass this.

Admin can assign or remove reservations:

function reserveName(...) external onlyOwner;
function removeReservation(...) external onlyOwner;

🔁 Renewal

Renewals are permissionless. Anyone can renew any name by paying the correct amount.

function renew(string calldata name, uint256 duration) external payable returns (uint256);
  • Duration is in seconds

  • Pricing uses the renewal tier (not the first-year price)


🔐 Payment Handling

The Controller:

  • Calculates price in $USD

  • Converts it to $HYPE using a live price oracle

  • Verifies the user paid enough

  • Refunds any overpayment

  • Sends funds to the treasury or designated recipient

All payments are native token compatible—no need for approval flows.


🛠 Admin Functions

The Controller can be configured by the protocol owner (via multisig):

setAnnualPrice()
setAnnualRenewalPrice()
setRegistry()
setSigner()
setPaymentRecipient()
setPriceOracle()

These functions adjust pricing, set key addresses, and manage access without changing the contract itself.


📡 Events for Tracking

Events emitted for downstream analytics:

  • DomainRegistered

  • DomainRenewed

  • ReservedNameRegistered

  • MerkleProofRegistration

  • SignerUpdated, PaymentRecipientUpdated, PriceOracleUpdated

These can be tracked via Subgraph or block explorer for indexers and dashboards.


🔎 For Developers

If you’re building a dApp or CLI for minting:

  • Use getPrice() to fetch cost before submitting

  • Use registerWithSignature() for standard public minting

  • Use registerWithMerkleProof() for allowlisted flows

You don’t need to interact with the Registry directly—the Controller routes all writes.

Want to mint for users via backend signature? Check our SDK guide or integration examples.

To see how a registered name becomes usable across dApps, dashboards, and wallets, continue to the Resolver Contract →