📖
Pulse Domains
  • 👋Introduction
  • đŸŸĸRegistration FAQ
  • 📒Terminology
  • Guides
    • đŸĒ„Domain Registration
    • đŸ§â€â™€ī¸Updating Your Profile
    • đŸĨˇPreserving Your Privacy
    • đŸ‘ĨCreating Subdomains
    • đŸ›Šī¸Domain Transfer
    • 🤝DNS Domain Setup
    • 🍭Brand Guidelines
    • 💸Referrals
    • 📜Whitelist & Claims
    • 🌟Registration Widget
    • đŸĒ…CCIP & PNS
    • đŸĒ…Name Renewal
  • Deep Dives
    • đŸŦName Wrapper
      • đŸ”ĨFuses
      • âŗExpiry
      • ✅Approved Operators
    • 👨‍🔧Managing a Name
    • 🔤Homoglyphs
  • pls.fyi Profile
    • ✨Your Web3 Profile
  • PLS.TO dWeb
    • đŸĒInterPlanetary FileSystem (IPFS)
    • 🌐Your Decentralized Website
    • đŸ’ģIPFS & PLS.TO Guide
  • Partner Sites
    • 📈PulseCoinList.com
    • 💱PulseSwap.io: The Aggregator of Aggregators
      • 📈 Integration for Developers and Projects
  • Dapp Developer Guide
    • đŸ› ī¸Getting Started
      • PNS Enabling your DApp
      • PNS Libraries
      • Working with PNS
      • Resolving Names
      • Managing Names
      • Registering & Renewing Names
      • PNS Front-End Design Guidelines
      • PNS as NFT
      • PNS Data guide
    • 🐛Bug Bounty Program & Audit
  • âš™ī¸Contract Api Reference
    • 📜Deployed Contracts
    • Name Processing
    • Registry
    • ReverseRegistrar
    • TestRegistrar
    • PublicResolver
    • .pls Permanent Registrar
      • Registrar
      • Controller
    • DNS Registrar
    • Name Wrapper
      • Expiry
      • Fuses
      • Wrapped States
    • Subgraph
      • Entities
      • Queries
  • 📙Contract Developer Guide
    • Resolving Names On-chain
    • Writing a Resolver
    • Writing a Registrar
  • đŸĻ¸â€â™‚ī¸Community
    • Community Dev Resources
  • Links
    • đŸ•šī¸PNS App
    • đŸĻTwitter
    • âœˆī¸Telegram
    • 💡PNS Name Ideas (Community Site)
Powered by GitBook
On this page
  • Deriving tokenId from PNS name
  • Deriving PNS name from tokenId
  • Turning subdomain into NFT
  • Metadata

Was this helpful?

  1. Dapp Developer Guide
  2. Getting Started

PNS as NFT

PreviousPNS Front-End Design GuidelinesNextPNS Data guide

Last updated 1 year ago

Was this helpful?

When PNS .pls registrar became an compliant non-fungible token contract, meaning that .pls registrations can be transferred in the same fashion as other NFTs.

Deriving tokenId from PNS name

The tokenId of PNS name is simply the uint256 representation of the hash of the label (pns for pns.pls).

const ethers = require('ethers')
const BigNumber = ethers.BigNumber
const utils = ethers.utils
const name = 'richard'
const labelHash = utils.keccak256(utils.toUtf8Bytes(name))
const tokenId = BigNumber.from(labelHash).toString()

In the example above, is the tokenId of pns.pls

Deriving PNS name from tokenId

Unlike deriving tokenId, deriving PNS name from tokenId is not as easy. This is because all PNS names are stored as fixed-length hash to allow registering infinite length of names. The downside of this architecture is that you cannot directly query PNS smart contracts to return PNS name using tokenId.

Our recommended way is to query via . The graph decodes the hash to name as it indexes. The example code to query is as follows.

const ethers = require('ethers')
const BigNumber = ethers.BigNumber
const gr = require('graphql-request')
const { request, gql } = gr
const tokenId = '26004363047961302715841817009868885426915362095607813844703532662233080456292'
// Should return 0x397df2a99f3fd3359a10190be2c38dd5cdea514e3c660c0ecad715815c22e464
const labelHash = BigNumber.from(tokenId).toHexString()

const url = 'https://graph.pulse.domains/subgraphs/name/graphprotocol/pns'
const GET_LABEL_NAME = gql`
query{
  domains(first:1, where:{labelhash:"${labelHash}"}){
    labelName
  }
}`

request(url, GET_LABEL_NAME).then((data) => console.log(data))
// { domains: [ { labelName: 'pns' } ] }

Turning subdomain into NFT

Currently, all the subdomains nor non .pls domains are not NFT. If you want to turn all subdomains which you own, you have to create a registrar

  1. Create a registrar contract as ERC721 compliant

  2. Set PNS registry address (mostly when you deploy the registrar)

  3. Create register function which calls registry.setSubnodeOwner then mint the token making the subdomain label hash as tokenId

contract DCLRegistrar is ERC721Full, Ownable {
    constructor(
        IPNSRegistry _registry,
    ) public ERC721Full("DCL Registrar", "DCLPNS") {
        // PNS registry
        updateRegistry(_registry);
    }

    function register(
        string memory _subdomain,
        bytes32 subdomainLabelHash,
        address _beneficiary,
        uint256 _createdDate
    ) internal {
        // Create new subdomain and assign the _beneficiary as the owner
        registry.setSubnodeOwner(domainNameHash, subdomainLabelHash, _beneficiary);
        // Mint an ERC721 token with the subdomain label hash as its id
        _mint(_beneficiary, uint256(subdomainLabelHash));
    }
}

Once deployed, then you have to transfer the controller address to the contract.

For non-technical users, we are currently working on upgrading our SubdomainRegistrar which allows you to turn your subdomain into NFT without any coding.

Metadata

.pls does not have .tokenURI . However, we created a separate metadata service which NFT marketplaces like OpenSea can fetch metadata for PNS such as registration data, expiration date, name length, etc. For more detail, please refer to the site.

đŸ› ī¸
ERC721
26004363047961302715841817009868885426915362095607813844703532662233080456292
PNS subgraph
metadata documentation