Ir al contenido principal
Time to read: 1 min

RIF Name Service (RNS) Javascript SDK

The @rsksmart/rns-sdk package helps you interact with the Rootstock Name Service (RNS). It lets you:

  • Register .rsk domains
  • Check domain and subdomain availability
  • Query and set domain ownership
  • Resolve domains to addresses
  • Manage subdomains
  • Work with partner registrars

Installation

Install the package using npm:

npm install @rsksmart/rns-sdk ethers

Contract Addresses

You will need these addresses to initialize the SDK:

ContractMainnetRootstock Testnet
RNS Registry0xcb868aeabd31e2b66f74e9a55cf064abb31a4ad50x7d284aaac6e925aad802a53c0c69efe3764597b8
RIF Token0x2acc95758f8b5f583470ba265eb685a8f45fc9d50x19f64674d8a5b4e652319f5e239efd3bc969a1fe
RSK Owner0x45d3e4fb311982a06ba52359d44cb4f5980e0ef10xca0a477e19bac7e0e172ccfd2e3c28a7200bdb71
FIFS Addr Registrar0xd9c79ced86ecf49f5e4a973594634c83197c35ab0x90734bd6bf96250a7b262e2bc34284b0d47c1e8d
Partner Registrar-0x8104d97f6d82a7d3afbf45f72118fad51f190c42

Initialization

After obtaining the contract addresses from the table above, initialize the SDK by creating instances of the desired classes, passing the relevant addresses as constructor parameters. You'll also need a signer (e.g., from ethers.js) connected to the Rootstock network.

For example, to initialize the RNS class for mainnet:

import { ethers } from 'ethers';
import { RNS } from '@rsksmart/rns-sdk';

const provider = new ethers.providers.JsonRpcProvider('https://public-node.rsk.co');
const signer = new ethers.Wallet('your-private-key', provider);
const registryAddress = '0xcb868aeabd31e2b66f74e9a55cf064abb31a4ad5' // RNS Registry Mainnet address

const rns = new RNS(registryAddress, signer);

See the individual class sections below for more details on constructors and required addresses.

SDK Classes

The SDK provides five main classes:

ClassPurpose
RNSDomain management (owner, resolver, subdomains)
AddrResolverAddress resolution
RSKRegistrarStandard .rsk domain registration
PartnerRegistrarPartner-based domain registration
PartnerConfigurationPartner contract configuration

1. RNS Class

The RNS class handles domain management operations.

Constructor

import { Signer } from 'ethers'
import { RNS } from '@rsksmart/rns-sdk'

let signer: Signer
const rns = new RNS(registryAddress, signer)

Methods

1. getOwner(domain)

Gets the controller/owner of a domain.

const owner = await rns.getOwner('mydomain.rsk')
console.log('Owner:', owner)

2. setOwner(domain, newController)

Transfers domain ownership to a new controller.

const domain = 'mydomain.rsk'
const newController = '0xb774...d771'

const tx = await rns.setOwner(domain, newController)
await tx.wait()
console.log('Ownership transferred!')

3. resolver(domain)

Gets the resolver contract address for a domain.

const resolverAddress = await rns.resolver('mydomain.rsk')
console.log('Resolver:', resolverAddress)

4. setResolver(domain, resolverAddress)

Sets a new resolver contract for the domain.

const domain = 'mydomain.rsk'
const resolverAddr = '0xb774...d771'

const tx = await rns.setResolver(domain, resolverAddr)
await tx.wait()
console.log('Resolver updated!')

5. getSubdomainAvailability(domain, label)

Checks if a subdomain is available under a parent domain.

const isAvailable = await rns.getSubdomainAvailability('mydomain.rsk', 'blog')
console.log(isAvailable ? 'Subdomain available!' : 'Subdomain taken')

6. setSubdomainOwner(domain, label, ownerAddress)

Creates a subdomain and assigns ownership.

const domain = 'mydomain.rsk'
const subdomainLabel = 'blog'
const ownerAddress = '0x8c0f...1264'

const tx = await rns.setSubdomainOwner(domain, subdomainLabel, ownerAddress)
await tx.wait()
console.log('Subdomain created: blog.mydomain.rsk')
nota

You must own the parent domain to create subdomains.


2. AddrResolver Class

The AddrResolver class handles address resolution for domains.

Constructor

import { Signer } from 'ethers'
import { AddrResolver } from '@rsksmart/rns-sdk'

let signer: Signer
const addrResolver = new AddrResolver(registryAddress, signer)

Methods

1. addr(domain)

Resolves a domain to its linked address.

const address = await addrResolver.addr('mydomain.rsk')
console.log('Address:', address)

2. setAddr(domain, address)

Sets or updates the address a domain points to.

const domain = 'mydomain.rsk'
const newAddress = '0xABCD...7890'

const tx = await addrResolver.setAddr(domain, newAddress)
await tx.wait()
console.log('Address updated!')
nota

You must own the domain to set its address.


3. RSKRegistrar Class

The RSKRegistrar class handles standard .rsk domain registration using RIF tokens.

Constructor

import { Signer } from 'ethers'
import { RSKRegistrar } from '@rsksmart/rns-sdk'

let signer: Signer
const rskRegistrar = new RSKRegistrar(
rskOwnerAddress,
fifsAddrRegistrarAddress,
rifTokenAddress,
signer
)

Methods

1. available(label)

Checks if a domain label is available for registration.

const label = 'mynewdomain'
const isAvailable = await rskRegistrar.available(label)
console.log(isAvailable ? 'Available!' : 'Already registered')
nota

Pass only the label without .rsk suffix.

2. price(label, duration)

Gets the registration price in RIF tokens.

import { BigNumber } from 'ethers'

const label = 'mynewdomain'
const duration = BigNumber.from('1') // 1 year

const price = await rskRegistrar.price(label, duration)
console.log('Price:', ethers.utils.formatEther(price), 'RIF')

3. commitToRegister(label, ownerAddress)

Step 1 of registration: Makes a commitment to register a domain.

const label = 'mynewdomain'
const ownerAddress = '0x1234...5678'

const { makeCommitmentTransaction, secret, canReveal } =
await rskRegistrar.commitToRegister(label, ownerAddress)

await makeCommitmentTransaction.wait()
console.log('Commitment made! Wait ~1 minute before registering.')

// Save the secret - you'll need it for step 2

Returns:

PropertyDescription
makeCommitmentTransactionThe commitment transaction object
secretSecret needed for registration (save this!)
canReveal()Function to check if ready to register

4. register(label, owner, secret, duration, price)

Step 2 of registration: Completes the domain registration.

// Wait for commitment to be ready (at least 1 minute)
const isReady = await canReveal()
if (!isReady) {
console.log('Please wait, commitment not ready yet')
return
}

const registerTx = await rskRegistrar.register(
label,
ownerAddress,
secret, // from commitToRegister()
duration,
price
)

await registerTx.wait()
console.log('Domain registered successfully!')

Complete Registration Example

import { BigNumber, ethers } from 'ethers'
import { RSKRegistrar } from '@rsksmart/rns-sdk'

async function registerDomain(label, ownerAddress, signer) {
const rskRegistrar = new RSKRegistrar(
rskOwnerAddress,
fifsAddrRegistrarAddress,
rifTokenAddress,
signer
)

// Check availability
const available = await rskRegistrar.available(label)
if (!available) {
throw new Error('Domain not available')
}

// Get price
const duration = BigNumber.from('1')
const price = await rskRegistrar.price(label, duration)
console.log('Price:', ethers.utils.formatEther(price), 'RIF')

// Step 1: Commit
const { makeCommitmentTransaction, secret, canReveal } =
await rskRegistrar.commitToRegister(label, ownerAddress)
await makeCommitmentTransaction.wait()
console.log('Commitment made!')

// Wait for commitment to mature (poll canReveal)
while (!(await canReveal())) {
console.log('Waiting for commitment...')
await new Promise(r => setTimeout(r, 10000)) // Wait 10 seconds
}

// Step 2: Register
const registerTx = await rskRegistrar.register(
label,
ownerAddress,
secret,
duration,
price
)
await registerTx.wait()

console.log(`Successfully registered ${label}.rsk!`)
}

4. PartnerRegistrar Class

The PartnerRegistrar class provides partner-based registration with one-click registration support.

Constructor

import { Signer } from 'ethers'
import { PartnerRegistrar } from '@rsksmart/rns-sdk'

let signer: Signer

// Option 1: Use network presets (recommended)
const partnerRegistrar = new PartnerRegistrar(signer, 'testnet')

// Option 2: Custom addresses (for localhost or custom setup)
const partnerRegistrar = new PartnerRegistrar(signer, 'localhost', {
rskOwnerAddress: '0x...',
rifTokenAddress: '0x...',
partnerRegistrarAddress: '0x...',
partnerRenewerAddress: '0x...',
partnerAddress: '0x...'
})

Network Options:

ValueDescription
'mainnet'RSK Mainnet (uses default addresses)
'testnet'RSK Testnet (uses default addresses)
'localhost'Local network (requires custom addresses)

Methods

1. available(label)

Checks if a domain is available.

const available = await partnerRegistrar.available('mynewdomain')
console.log(available ? 'Available!' : 'Taken')

2. price(label, duration)

Gets the price with partner pricing applied.

import { BigNumber } from 'ethers'

const duration = BigNumber.from('1')
const price = await partnerRegistrar.price('mynewdomain', duration)
console.log('Partner price:', ethers.utils.formatEther(price), 'RIF')

3. commitAndRegister(label, owner, duration, price)

One-click registration - handles both commit and register in one call.

import { BigNumber } from 'ethers'

const label = 'mynewdomain'
const ownerAddress = '0x1234...5678'
const duration = BigNumber.from('1')
const price = await partnerRegistrar.price(label, duration)

const { commitHash, commitSecret, registerTxHash } =
await partnerRegistrar.commitAndRegister(label, ownerAddress, duration, price)

console.log('Domain registered!')
console.log('Commit hash:', commitHash)
console.log('Register TX:', registerTxHash)

4. transfer(label, toAddress)

Transfers domain ownership to another address.

const label = 'mydomain'
const toAddress = '0xABCD...7890'

const txHash = await partnerRegistrar.transfer(label, toAddress)
console.log('Domain transferred! TX:', txHash)

5. renew(label, duration, price)

Renews a domain registration.

import { BigNumber } from 'ethers'

const label = 'mydomain'
const duration = BigNumber.from('1')
const price = await partnerRegistrar.price(label, duration)

const txHash = await partnerRegistrar.renew(label, duration, price)
console.log('Domain renewed! TX:', txHash)

5. PartnerConfiguration Class

The PartnerConfiguration class queries partner contract settings.

Constructor

import { Signer } from 'ethers'
import { PartnerConfiguration } from '@rsksmart/rns-sdk'

let signer: Signer
const partnerConfig = new PartnerConfiguration(partnerConfigurationAddress, signer)

Methods

1. getMinLength()

Gets the minimum allowed domain label length.

const minLength = await partnerConfig.getMinLength()
console.log('Min length:', minLength.toString())

2. getMaxLength()

Gets the maximum allowed domain label length.

const maxLength = await partnerConfig.getMaxLength()
console.log('Max length:', maxLength.toString())

3. getMinDuration()

Gets the minimum registration duration (in years).

const minDuration = await partnerConfig.getMinDuration()
console.log('Min duration:', minDuration.toString(), 'years')

getMaxDuration()

Gets the maximum registration duration (in years).

const maxDuration = await partnerConfig.getMaxDuration()
console.log('Max duration:', maxDuration.toString(), 'years')

4. getMinCommitmentAge()

Gets the minimum time (in seconds) before a commitment can be revealed.

const minAge = await partnerConfig.getMinCommitmentAge()
console.log('Min commitment age:', minAge.toString(), 'seconds')

5. getFeePercentage()

Gets the partner fee percentage.

const fee = await partnerConfig.getFeePercentage()
console.log('Fee percentage:', fee.toString(), '%')

6. getDiscount()

Gets the partner discount percentage.

const discount = await partnerConfig.getDiscount()
console.log('Discount:', discount.toString(), '%')

7. getPrice(label, duration)

Gets the price for a domain with partner pricing.

import { BigNumber } from 'ethers'

const price = await partnerConfig.getPrice('mydomain', BigNumber.from('1'))
console.log('Price:', ethers.utils.formatEther(price), 'RIF')

8. validateName(label, duration)

Validates if a name meets partner requirements. Throws an error if invalid.

import { BigNumber } from 'ethers'

try {
await partnerConfig.validateName('mydomain', BigNumber.from('1'))
console.log('Name is valid!')
} catch (error) {
console.log('Invalid name:', error.message)
}

Name Validation

The SDK automatically validates and normalizes domain names:

Validation Rules:

  • Names can only contain letters (a-z), digits (0-9), and hyphens (-)
  • Names must start and end with a letter or digit

Normalization:

  • All letters are converted to lowercase
  • Punycode-encoded internationalized domain names (IDNs) are expanded to Unicode

Troubleshooting

Browser Environment

The SDK requires Buffer to be globally available. Add this to your webpack config:

const webpack = require('webpack')

module.exports = {
resolve: {
fallback: {
buffer: require.resolve('buffer/'),
},
},
plugins: [
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
}),
],
}

Or add this to your app's entry point:

window.Buffer = window.Buffer || require('buffer/').Buffer

React Native

Use the rn-nodeify package:

rn-nodeify --install buffer --hack --yarn && patch-package

Additional Resources

Última actualización en por Ileolami