Sanko Name Service

Integration Guide

This guide demonstrates how to integrate Sanko Name Service (SNS) into your application using Viem, a TypeScript interface for Ethereum.

Since SNS is essentially ENS, you can utilize the built-in utilities for ENS provided by Viem.

Prerequisites

  • Familiarity with JavaScript/TypeScript and Ethereum concepts
  • Node.js (or equivalent) environment
  • Viem library installed (npm install viem)

Setting up Viem

First, initialize Viem client connected to Sanko chain.

Find the sanko chain definition here

// https://viem.sh/docs/clients/custom#usage
const client = createClient({
	chain: sanko,
  transport: http(sanko.rpcUrls.default.http[0])
})

Interacting with SNS

Resolving SNS Names

To resolve an SNS name to an address:

...
const resolvedAddress = await getEnsAddress(client, {
	name: normalize("sanko.dmt"),
	// !IMPORTANT! modify with one deployed on Sanko as follow: 
	universalResolverAddress: "0xE6948912778506bf20896632c35163b1fACD5464",
})
// 0x123456689
...

Resolving Address to Name

Using Viem

Important Note: Reverse resolution is not enabled by default. Some users may not have set their primary address, which can result in null when resolving an address to a name using the method above.

For this reason, it is recommended to use the subgraph instead.

To perform reverse resolution (address to name):

...
const resolvedName = await getEnsName(client, {
	name: "0x123456689",
	// !IMPORTANT! modify with one deployed on Sanko as follow: 
	universalResolverAddress: "0xE6948912778506bf20896632c35163b1fACD5464",
})
// sanko.dmt
...

Through Subgraph

For comprehensive reverse resolution, it's recommended to query the SNS subgraph. Here's how you can do that using TypeScript:

async function resolveEnsName(address: string): Promise<string | null> {
  const query = `
    query GetDomainByAddress($address: String!) {
      domains(where: { resolvedAddress: $address }, first: 1) {
        name
      }
    }
  `
 
  const variables = {
    address: address.toLowerCase(),
  }
 
  try {
    const response = await fetch(
      'https://subgraph.fanko.tech/subgraphs/name/graphprotocol/ens',
      {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          query,
          variables,
        }),
      },
    )
 
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }
 
    const result = (await response.json()) as {
      data: {
        domains: Array<{ name: string }>
      }
    }
    const domain = result.data.domains.at(0)
    return domain?.name ?? null
  } catch (error) {
    console.error('Error querying SNS subgraph:', error)
    return null
  }
}
 
const name = await resolveEnsName('0x1234567890123456789012345678901234567890')
// sanko.dmt

Common Pitfalls

  • Incorrect Contract Addresses: Ensure you're using the correct SNS contract addresses for the Sanko chain.
  • Name Normalization: SNS names should be normalized before querying or registering.
  • Transaction Underpricing: Make sure to use the rentPrice function to get the total price for registration. This ensures you're sending enough value with the transaction.
  • CommitmentTooNew Error: This error occurs when trying to register a name too soon after making a commitment.

References

Sanko Chain Definition

Since Viem does not include Sanko by default, you will need to define it yourself.

export const sanko = defineChain({
    id: 1996,
    name: "Sanko",
    nativeCurrency: { name: "DMT", symbol: "DMT", decimals: 18 },
    rpcUrls: {
        default: { http: ["https://mainnet.sanko.xyz"] },
    },
    blockExplorers: {
        default: {
            name: "Sanko Explorer",
            url: "https://tools.sanko.xyz",
        },
    },
    testnet: false,
    contracts: {
        multicall3: {
            address: "0xcA11bde05977b3631167028862bE2a173976CA11",
            blockCreated: 37,
        },
    },
});

On this page