5 min read
Solana Name Service has upgraded .sol domains to .sns. Domains managed by the SNS program now use the .sns extension, and the .sol extension has moved to the Solana Foundation's Solana Record Service (SRS). SNS released new SDKs for this change, and this guide uses the SNS Kit SDK v1 with Solana Kit. See What Changed with the .sol Upgrade for the details.
Overview
In a previous guide, we covered How to Create a .sns Domain using Solana Name Service. Solana Name Service (SNS) is a Solana program that lets users register a human-readable domain name that can be used in place of a public key.
In this guide, you will learn how to query SNS domains using TypeScript, Solana Kit, and the SNS Kit 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
- TypeScript experience
- A Solana Mainnet RPC endpoint (we cover setting one up below)
This guide uses the following dependencies:
| Package | Version | Used for |
|---|---|---|
node.js | >=24.0.0 | Runtime. The SNS Kit SDK requires Node.js 24 or newer |
@solana/kit | ^6.10.0 | Solana RPC client (createSolanaRpc) and the address helper |
@solana-name-service/sns-sdk-kit | ^1.0.1 | SNS Kit SDK: resolve and getSnsDomainsForAddress |
tsx | ^4.20.0 | Runs TypeScript files directly without a build step |
What Changed with the .sol Upgrade
If you have integrated SNS before the upgrade, three things are different in the current SDKs.
Domain Inputs
High-level read functions such as resolve expect the full name, for example rajgokal.sns. Earlier versions accepted a bare name or a .sol name.
Renamed Functions
The SNS Kit SDK (@solana-name-service/sns-sdk-kit) renamed several of its exports in v1 so that its function names match the SNS JavaScript SDK. Update both your imports and your call sites:
| SNS Kit SDK v0.10 | SNS Kit SDK v1 |
|---|---|
resolveDomain | resolve |
getAllDomains | getAllSnsDomains |
getDomainsForAddress | getSnsDomainsForAddress |
getNftsForAddress | getSnsNftsForAddress |
getNftMint | getSnsNftMint |
getNftOwner | getSnsNftOwner |
registerWithNft | registerDomainWithNft |
validateRoa | validateRecordRoa |
validateRoaEthereum | validateRecordRoaEthereum |
writeRoa | setRecordRoaVerifier |
Record reads changed too: verified.rightOfAssociation is now verified.roa. See the SNS Kit SDK migration guide for the rest.
.sol Resolution Ending
resolve still accepts a legacy .sol name today, but at finalized slot 452,825,395 the SDK starts rejecting .sol inputs. SRS-backed .sol resolution will arrive in a later SDK release. Use .sns names in your code now, and display existing domains as .sns in your UI.
If your project still uses @solana/web3.js v1, SNS maintains the original SDK as @bonfida/spl-name-service (v4). It exposes the same operations with web3.js types. See the JavaScript SDK migration guide for its renamed functions.
Set Up Your Environment
To run our onchain queries, we're going to use Node.js. Open your code editor of choice and create a new project directory in your terminal with:
mkdir sns-example
cd sns-example
Initialize your project with the "yes" flag to use default values for your new package:
npm init --y
Install Dependencies
Install Solana Kit, the SNS Kit SDK, and tsx for running TypeScript directly:
npm install @solana/kit@6 @solana-name-service/sns-sdk-kit@1 && npm install -D tsx@4
We will build two standalone scripts, one for each direction of the lookup:
touch name-search.ts wallet-search.ts
Set Up Your Quicknode Endpoint
You'll need to use a Mainnet endpoint to query users' SNS domains. Sign up for a Quicknode Account and copy the HTTPS endpoint link. You can also use a public Solana mainnet endpoint.

Keep that URL handy. Both scripts below start with it, so each one runs on its own.
Lookup SNS Domain Owner
Open name-search.ts and add the following, replacing QUICKNODE_ENDPOINT with your own endpoint URL:
import { createSolanaRpc } from "@solana/kit";
import { resolve } from "@solana-name-service/sns-sdk-kit";
const QUICKNODE_ENDPOINT = 'https://example.solana-mainnet.quiknode.pro/000000/';//replace with your own endpoint from https://www.quicknode.com/endpoints
const rpc = createSolanaRpc(QUICKNODE_ENDPOINT);
const DOMAIN_TO_SEARCH = 'rajgokal.sns';
async function getAddressFromSnsDomain(domain: string): Promise<string> {
const owner = await resolve({ rpc, domain });
console.log(`The owner of SNS domain ${domain} is:`, owner);
return owner;
}
getAddressFromSnsDomain(DOMAIN_TO_SEARCH);
createSolanaRpc returns a typed RPC client. Every SNS Kit SDK function takes this client as its rpc argument, so you pass it explicitly rather than relying on a global connection.
Our function accepts a string as a parameter, domain, which is the full domain name we want to look up, including the .sns extension.
The SDK's resolve function handles everything for us:
- Derives the domain's name account
- Reads the registry from the chain
- Returns the effective owner as a Kit
Address(a branded base58 string).
"Effective" matters here because a domain can be tokenized as an NFT or can point at a different wallet through a SOL record, and resolve follows those rules so you get the address funds should actually go to.
The SDK also exports safeResolve, which behaves exactly like resolve today. Once SRS-backed .sol resolution launches, safeResolve will additionally check that a .sol name and its .sns counterpart resolve to the same wallet and throw if they disagree.
Run the script:
npx tsx name-search.ts
You should see the domain's owner printed to your terminal:
The owner of SNS domain rajgokal.sns is: E645TckHQnDcavVv92Etc6xSWQaq8zzPtPRGBheviRAk
Now let's go the other direction and find every domain a wallet owns.
Find Domains Owned by a Wallet
Create wallet-search.ts and add the following, again replacing QUICKNODE_ENDPOINT with your own endpoint URL:
import { createSolanaRpc, address } from "@solana/kit";
import { getSnsDomainsForAddress } from "@solana-name-service/sns-sdk-kit";
const QUICKNODE_ENDPOINT = 'https://example.solana-mainnet.quiknode.pro/000000/';//replace with your own endpoint from https://www.quicknode.com/endpoints
const rpc = createSolanaRpc(QUICKNODE_ENDPOINT);
const WALLET_TO_SEARCH = 'E645TckHQnDcavVv92Etc6xSWQaq8zzPtPRGBheviRAk';
async function getSnsDomainsFromAddress(wallet: string): Promise<string[]> {
const domains = await getSnsDomainsForAddress({ rpc, address: address(wallet) });
const domainNames = domains.map(({ domain }) => `${domain}.sns`);
console.log(`${wallet} owns the following SNS domains:`);
domainNames.forEach((domain, i) => console.log(` ${i + 1}.`, domain));
return domainNames;
}
getSnsDomainsFromAddress(WALLET_TO_SEARCH);
This function returns an array of strings, to account for users who hold multiple domains.
First, we run the wallet string through Kit's address helper, which validates it and brands it as an Address. Then we use the SDK's getSnsDomainsForAddress function to fetch every top-level domain the wallet owns directly.
Each entry in the result includes the domain's name account (domainAddress) and its reverse-lookup name (domain). The names come back without an extension, so we append .sns for display. Domains without a valid reverse-lookup record are omitted from the result.
Domains that have been tokenized as NFTs are held by a token account rather than the wallet itself, so they do not appear here. Use getSnsNftsForAddress to list those. To fetch only a wallet's primary domain, use getPrimaryDomain.
Run the script:
npx tsx wallet-search.ts
Expected results:
E645TckHQnDcavVv92Etc6xSWQaq8zzPtPRGBheviRAk owns the following SNS domains:
1. raj.sns
2. rajgokal.sns
3. gokal.sns
4. 🖤.sns
Wrap Up
You now have the tools to run onchain queries to find domain owners or domains held by a wallet, and you know how the .sol Upgrade changes the SNS SDKs. You can apply these same concepts to your own Solana dApp to improve your users' experience.
