πŸ“–
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
  • Overview
  • Target audience
  • How to access PNS data
  • The Graph
  • Contract structures
  • PNSRegistry
  • Resolver
  • BaseRegistrar
  • ETHRegistrarController
  • NameWrapper
  • FAQ
  • Listing all primary names
  • Listing all registered names
  • Listing all records (PLS address/contenthash/text record)
  • Listing Offchain names
  • Why are some subdomain names not decoded?
  • How do I find sub categories such as 10k club, 100k club, emoji, etc?

Was this helpful?

  1. Dapp Developer Guide
  2. Getting Started

PNS Data guide

PreviousPNS as NFTNextBug Bounty Program & Audit

Last updated 1 year ago

Was this helpful?

Overview

Even though adding basic functionalities such as a single name lookup is just adding a few lines of code, analysing overall stats or integrating with historical info can be challenging due to the following reasons.

  • The data is stored in storage efficient way to save gas costs, which requires decoding

  • Some of the contracts can be extensible by end users leading to inconsistent interface

  • Some names (.pls, wrapped names) expire without emitting events

  • Smart contract structures have changed over time

  • Some names are not available on the chain (eg: CCIP-read integrated names such as)\

In this section, I will go through the overall structure of PNS contracts and events to help you guide through the PNS data space.\

Target audience

The target audience of this article is developers and data analysts who are interested in labelling PNS names into the PulseChain transaction data such as NFT owners, Defi users, and PNS name trading history. It assumes that you have a basic understanding of how smart contracts work (such as function calls and events). Some tools also require query language knowledge such as GraphQL and SQL.\

How to access PNS data

Just like many other PulseChain-based projects, PNS consists of a set of smart contracts. You can use tools of your choice to interact directly with PNS smart contracts (which we will explain in depth). If you want extra data about a single name, please refer to the PNS library section which explains how to interact with PNS via popular libraries such as ethers.js.

Extracting multiple entities tends to be slow and time-consuming because you have to make a function call to extract each record. call function to save some call time. If you are interested in extracting more than dozens of name records or want to access event-related information. There are currently two popular services, , and .

The Graph

The Graph is a decentralized indexing service that allows developers to turn smart contract events (and function calls) into GraphQL schema called subgraph. The PNS team maintains the subgraph that encapsulates multiple events data into a single entity such as Domain, Account, Registration and Resolver. \

The following sample query lists all names

account{
  domains {
    labelName
    labelhash
    name
  }
}

It is suitable to extract information such as the list of subdomains a name created, a list of names the address registered, and text keys (eg: Twitter, email, avatar). You can also use it to extract analytics information such as registered names though you need to traverse the data multiple times. \

Contract structures

PNSRegistry

  • "Transfer(node, owner)"

  • "NewOwner(node, label, owner)"

  • "NewResolver(node,resolver)"

NewOwner event is logged when the owner of a node assigns a new owner to a sub node. Transfer event is logged when the owner of a node transfers ownership to a new account. NewResolver event is logged when the resolver for a node changes.

Resolver

  • AddressChanged(node,coinType,address)

  • ContenthashChanged(node, name)

  • NameChanged(node, value)

  • TextChanged(node, key, key, value)

The majority of the contracts use a default resolver which is set at the time of registration. However, the default resolver has changed a few times to add new functionalities (eg: coin type). To find out all the resolver addresses, you have to get the resolver address through PNSRegistry. NewResolver event (note: Users in the past have put their own PLS address by mistake hence there are 100s of addresses that are set as new resolver which don’t contain any record).

BaseRegistrar

  • NameRegistered(id, owner, expires)

  • NameRenewed(id, expires)

  • Transfer(from,to,tokenId)\

ETHRegistrarController

  • NameRegistered(name, label, owner, baseCost, premium, expires)

  • NameRenewed(name, label, cost, expires)

The ETHRegistrarController contract contains the actual registration logic. The contract is upgradable via DAO vote and has been changed a few times in the past. The Registered/Renewed events contain the registration logic as well as domain names in plain text. The Graph uses this information to decode .pls id and lablehash into human readable names.

NameWrapper

  • NameWrapped(node, name, owner, fuses, expiry)

  • NameUnwrapped(node, owner)

  • FusesSet(node, fuses)

  • TransferSingle(operator, from, to, ids, value)

  • TransferBatch(operator, from, to, ids, value)

NameWrapper is the new feature that turns any subdomains into NFT (with extra access control to prevent parent domain owners from reverting the NFT ownership). TransferSingle and TransferBatch are ERC1155 defined events.

FAQ

Listing all primary names

Listing all registered names

  • JS & SmartContract = There is no function to list all registered names.

  • TheGraph = Querying Domains object will give you the list of names.

If you want to exclude released names, you need to join the registration table and exclude where the expiration date is less than the current date - 90 days (90 days is the grace period where the name is expired but no one can register).

Listing all records (PLS address/contenthash/text record)

  • JS & SmartContract = There is no function to list all registered names.

  • TheGraph = Querying `Domains.resolver` object will give you all the records.

Example

{
  domains {
    name
      resolver{
      contentHash
      texts
      addr {
        id
      }
      coinTypes
    }
  }

NOTE: texts and coinTypes only return the keys so you still have to call smart contracts to get the value.

Listing Offchain names

The offchain names cannot be tracked because they do not exist on the chain.

Why are some subdomain names not decoded?

PNS names are stored as a hash on-chain so we have to decode the name using a list of possible names, and it shows in the hashed format if we don't have it on our list. You can still access and manage the name if you search for the name directly in the search bar.

How do I find sub categories such as 10k club, 100k club, emoji, etc?

PNS Protocol itself does not have any mechanism to categorise names.

The full detail of each smart contract is covered in . This section lists function names and events which are often used to access the data.

The contract contains the name owner (aka β€œcontroller”) and resolver contract addresses that hold the actual record (such as PLS address, IPFS content hash) . The name is stored in format so that it can store an infinite length of the name. The name owner has the privilege to change the resolver contract and can create subdomains under the name you own.

BaseRegistrar is the owner of .pls and is a ERC721 NFT contract. id is the hash of the label (eg: for β€œmatoken.pls”, the keccak256 of β€œmatoken” becomes the id. For more information, read β€œ section”).

SmartContract = smart contract allows you to resolve primary names for multiple addresses.

TheGraph = subgraph currently does not index primary name info ()

πŸ› οΈ
cb.id
pns-sdk has a batch
The Graph
Dune Analytics
Google Big Query
Mainnet
Testnet
the contract api reference section
namehash
ENS as NFT
reverse-records
github issue