List Name Services
To list all registered name services, you can call the listServices
method. Here's an example:
index.ts
import nameMatcha from '@leapwallet/name-matcha'
const services = nameMatcha.listServices()
// ['icns', 'ibcDomains', 'stargazeNames', 'archIds', 'spaceIds', 'sns', 'nibId', 'degeNS', 'bidds']
Custom Name Services
This library allows you to define and register your own name services.
Defining a Name Service
A name service is a class that implements the NameService
interface. Here's an example of ICNS2 name service:
icns2.ts
import { decode } from 'bech32'
import {
AllowedTopLevelDomains,
MatchaError,
MatchaErrorType,
NameService,
Network,
RpcURLs
} from '@leapwallet/name-matcha'
const rpcUrls = {
mainnet: 'https://rpc.cosmos.directory/osmosis',
testnet: 'https://rpc-test.osmosis.zone'
}
// make sure this is unique
export const serviceID = 'icns2'
export class ICNS2 extends NameService {
serviceID = serviceID
chain = 'osmosis'
contractAddress = {
mainnet: 'osmo1xk0s8xgktn9x5vwcgtjdxqzadg88fgn33p8u9cnpdxwemvxscvast52cdd',
testnet: 'osmo1q2qpencrnnlamwalxt6tac2ytl35z5jejn0v4frnp6jff7gwp37sjcnhu5'
}
async resolve(
name: string,
network: Network,
options?: {
allowedTopLevelDomains?: AllowedTopLevelDomains
rpcUrls?: RpcURLs
}
): Promise<string> {
const client = await this.getCosmWasmClient(
options?.rpcUrls?.[serviceID]?.[network] ?? rpcUrls[network]
)
const [username, prefix] = name.split('.')
// place your logic here
try {
const res = await client?.queryContractSmart(
this.contractAddress[network],
{
address: {
name: username,
bech32_prefix: prefix
}
}
)
if (
!res?.address ||
allowedTopLevelDomains?.icns?.indexOf(prefix) === -1
) {
throw new MatchaError('', MatchaErrorType.NOT_FOUND)
}
return res.address
} catch (e) {
throw new MatchaError('', MatchaErrorType.NOT_FOUND)
}
}
async lookup(address: string, network: Network, options?: {
rpcUrls?: RpcURLs
}): Promise<string> {
const client = await this.getCosmWasmClient(
options?.rpcUrls?.[serviceID]?.[network] ?? rpcUrls[network]
)
const { prefix } = decode(address)
// place your logic here
try {
const res = await client?.queryContractSmart(
this.contractAddress[network],
{
primary_name: {
address
}
}
)
if (!res?.name) {
throw new MatchaError('', MatchaErrorType.NOT_FOUND)
}
return `${res.name}.${prefix}`
} catch (e) {
throw new MatchaError('', MatchaErrorType.NOT_FOUND)
}
}
}
The this.getCosmWasmClient
method is a helper method that returns a CosmWasmClient
instance. It is built into the NameService abstract class so you can use it in your own name service. Everything is taken care of for you.
Registering a Name Service
To register a name service, you need to call the registerNameService
method. Here's an example:
index.ts
import nameMatcha, { services } from '@leapwallet/name-matcha'
import { ICNS2, serviceID as icns2Id } from './icns2'
// add the service ID to the services object
const allServices = {
// built-in services
...services,
// your custom icns2 service
[icns2Id]: icns2Id
}
nameMatcha.registerNameService(new ICNS2())