5 min read
Before you get started
We have partnered with Bonfida to make working with SNS data significantly easier. Check out the new Bonfida API on the QuickNode Marketplace! This Bonfida-powered API leverages QuickNode endpoints to query Solana Name Service:
- seamless .sol resolution
- fetching registration transactions
- listing subdomain names
- retrieving wallet-owned domains
Free for all QuickNode users at QuickNode Marketplace.
Overview
In a recent guide, we covered How to Create Solana Naming Service Domains. Solana Naming Service ("SNS") is a handy Solana Solana Program that allows users to create a readable domain name that can be used in place of a Public Key.
What You Will Do
In this guide, you will learn how to query Solana domain names using Typescript and Bonfida's SPL Name Service SDK. This will enable you to:
- look up a user's wallet by their domain name and
- look up a user's domain name(s) by their wallet
What You Will Need
- Nodejs (version 16.15 or higher) installed
- Typescript experience and ts-node installed
- Solana Web3
- Bonfida SPL Name Service
Set Up Your Environment
To run our on-chain queries, we're going to use Nodejs. Open your code editor of choice and create a new project directory in your terminal with:
mkdir sns-example
cd sns-example
Create name-search.ts. We will use this as our primary app for running our scripts.
echo > name-search.ts
Initialize your project with the "yes" flag to use default values for your new package:
yarn init --yes
#or
npm init --y
Install Solana Web3 dependencies:
yarn add @solana/web3.js @bonfida/spl-name-service
#or
npm install @solana/web3.js @bonfida/spl-name-service
Your environment should look something like this:
Let's set up your app with all the dependencies you'll need. Open name-search.ts and on lines 1-2, import the following dependencies:
import { Connection, PublicKey } from "@solana/web3.js";
import { getDomainKey, NameRegistryState, getAllDomains, performReverseLookup } from "@bonfida/spl-name-service";
The @solana/web3.js dependencies will allow us to create a connection to the Solana network and get the Public Key of a wallet address.
The @bonfida/spl-name-service imports will help us query .sol domains (we will explain these in the subsequent section).
Alright, you're ready to go.
Set Up Your QuickNode Endpoint
To build on Solana, you'll need an API endpoint to connect with the network. You're welcome to use public nodes or deploy and manage your own infrastructure. However, if you'd like 8x faster response times, you can leave the heavy lifting to us.
You can now pay for a QuickNode plan using USDC on Solana. As the first multi-chain provider to accept Solana payments, we're streamlining the process for developers — whether you're creating a new account or managing an existing one. Learn more about paying with Solana here.
See why over 50% of projects on Solana choose QuickNode and sign up for a free account here. You'll need to use a Mainnet endpoint to query users' Solana domain names. Copy the HTTP Provider link:
line 4 of name-search.ts, add the following code replacing QUICKNODE_RPC with your HTTP Provider Link:
const QUICKNODE_RPC = 'https://example.solana-mainnet.quiknode.pro/000000/';//replace with your HTTP Provider from https://www.quicknode.com/endpoints
const SOLANA_CONNECTION = new Connection(QUICKNODE_RPC);
Lookup .SOL Domain Owner
Let's start by creating a new async function, getPublicKeyFromSolDomain, that we will use to find the wallet owner of a given .sol domain. On line 7 of name-search.ts, add:
async function getPublicKeyFromSolDomain(domain: string):Promise<string>{
const { pubkey } = await getDomainKey(domain);
const owner = (await NameRegistryState.retrieve(SOLANA_CONNECTION, pubkey)).registry.owner.toBase58();
console.log(`The owner of SNS Domain: ${domain} is: `,owner);
return owner;
}
Our function accepts a string as a parameter, domain, which will be the domain name we want to look up (with or without the ".sol" extension). Finding the owner of the domain is a two-part process:
- Identify the public key associated with the domain (this is kind of like the mint address of an NFT). We do this above using the getDomainKey function and passing our domain parameter. We're looking specifically for the pubkey key from the returned object.
- Retrieve the owner's address from the name registry. We do this by invoking the retrieve method on the NameRegistryState class. The Name Registry stores information about the domain name on chain. The retrieve method will return an object that includes the registry, which holds the owner's public key (fetched by calling .registry.owner.toBase58()).
After fetching the owner's address, we log and return the results.
Reverse Lookup: Find All Domains Owned by a Wallet
Create a new function below getPublicKeyFromSolDomain (line 14 for us) that accepts a wallet address string and returns an array of strings (to account for users who hold multiple Solana Domains).
async function getSolDomainsFromPublicKey(wallet: string):Promise<string[]>{
const ownerWallet = new PublicKey(wallet);
const allDomainKeys = await getAllDomains(SOLANA_CONNECTION, ownerWallet);
const allDomainNames = await Promise.all(allDomainKeys.map(key=>{return performReverseLookup(SOLANA_CONNECTION,key)}));
console.log(`${wallet} owns the following SNS domains:`)
allDomainNames.forEach((domain,i) => console.log(` ${i+1}.`,domain));
return allDomainNames;
}
First, we get the PublicKey of the wallet we passed as our parameter, and then we use Bonfida's getAllDomains function to fetch the Public Key of all domains owned by that wallet and store the values in allDomainKeys. Next, we use Promise.all to run performReverseLookup for each key stored in allDomainKeys. The performReverseLookup function will resolve the .sol domain for the associated public key we pass into it. Because we used Promise.all, our formula will return an array of each domain name owned by the wallet.
After fetching the wallet's domains, we loop through the array and log each domain name.
Almost done. Nice work!
Run Your Code
Let's declare our search queries and call our functions. On line 23 of name-search.ts, paste:
//Examples for our search. You can replace these with your own wallet or Solana Naming Service queries.
const DOMAIN_TO_SEARCH = 'bonfida';
const WALLET_TO_SEARCH = 'E645TckHQnDcavVv92Etc6xSWQaq8zzPtPRGBheviRAk';
getPublicKeyFromSolDomain(DOMAIN_TO_SEARCH);
getSolDomainsFromPublicKey(WALLET_TO_SEARCH);
We have included a couple of sample queries in the DOMAIN_TO_SEARCH and WALLET_TO_SEARCH variables, but feel free to replace them with any wallet or domain that you would rather search.
Finally, we call both functions we created and pass our search variables as parameters. We have included our entire code sample on Github here.
Now, let's run it! Head back to the terminal and type:
ts-node name-search.ts
Do you see something like this?
Nice work!
Apply Your Skills
You now have the tools to run on-chain queries to find domain owners or domains held by a wallet. You can apply these same concepts to your own Solana dApp to improve your users' experience. Haven't built a dApp? Check out our Guide: How to Connect Users to Your dApp with the Solana Wallet Adapter and Scaffold.
If you don't already have a .sol domain and want to get one, check out our Guide: How to Create Solana Naming Service Domains.
Want some help with this guide? Find us on Discord or reach out to us via Twitter.
We <3 Feedback! If you have any feedback or questions on this guide, let us know. We’d love to hear from you!