### Configure and Use NNS Adapters with Viem Source: https://docs.nad.domains/developers/integrating-into-your-dapps/using-nns-adapter This example demonstrates how to configure Viem with NNS Adapters by defining a custom chain with specific contract addresses for ENS registry and universal resolver. It then shows how to use the client to fetch ENS-related data like address, avatar, name, and text records. ```typescript import { defineChain, createPublicClient, http } from 'viem' import { normalize } from 'viem/ens' export const monadDevnet = defineChain({ id: 41454, name: 'Monad Devnet', nativeCurrency: { decimals: 18, name: 'Monad', symbol: 'MON', }, rpcUrls: { default: { http: [...], }, }, contracts: { ensRegistry: { // NNS Adapter address: '0x...', }, ensUniversalResolver: { // NNS Universal Resolver Adapter address: '0x...', }, }, }) const client = createPublicClient({ chain: monadDevnet, transport: http(), }) async function main() { const ensAddress = await client.getEnsAddress({ name: normalize('test.nad'), }) const avatar = await client.getEnsAvatar({ name: normalize('test.nad'), }) const ensName = await client.getEnsName({ address: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', }) const resolver = await client.getEnsResolver({ name: normalize('test.nad'), }) const avatarStr = await client.getEnsText({ name: normalize('test.nad'), key: 'avatar', }) console.log(ensAddress) console.log(avatar) console.log(ensName) console.log(avatarStr) console.log(resolver) } ``` -------------------------------- ### Query NAD Contract for Resolved Address (Ethers.js) Source: https://docs.nad.domains/developers/integrating-into-your-dapps/query-contract-directly Provides an example of querying the NAD contract for a resolved address using Ethers.js. It involves setting up a provider, signer, and contract instance, then calling the `getResolvedAddress` method with the domain's namehash. ```typescript // Setup provider and signer const provider = new ethers.providers.JsonRpcProvider('YOUR_RPC_URL'); const signer = new ethers.Wallet('YOUR_PRIVATE_KEY', provider); const abi = [...] // Replace with your ABI // Contract setup const nnsContractAddress = 'YOUR_CONTRACT_ADDRESS'; const contract = new ethers.Contract(nnsContractAddress, abi, provider); const contractWithSigner = contract.connect(signer); try { // Example values const domain = 'example.nad'; const node = namehash(domain); // Read queries // 1. Get resolved address const resolvedAddress = await contract.getResolvedAddress(node); console.log(`Resolved address for ${domain}:`, resolvedAddress); } catch (error) { console.error('Error:', error); } ``` -------------------------------- ### Normalize Names for Nad Name Service (viem, ethers.js) Source: https://docs.nad.domains/developers/integrating-into-your-dapps/name-processing Normalize names to a consistent format before hashing. This process is crucial as variations in casing can lead to different namehashes. Examples are provided for both viem and ethers.js. ```typescript import { normalize } from 'viem/ens' const normalizedName = normalize('Salmo.Nad') // => salmo.nad ``` ```typescript import { ensNormalize, namehash } from "ethers/hash"; const normalizedName = ensNormalize('Salmo.Nad') // => salmo.nad ``` -------------------------------- ### Query NAD Contract for Name Attributes (Viem) Source: https://docs.nad.domains/developers/integrating-into-your-dapps/query-contract-directly Illustrates how to retrieve attributes associated with a NAD domain name using Viem. This includes fetching a single attribute by key or multiple attributes using an array of keys. The `getNameAttribute` and `getNameAttributes` functions are used, requiring the namehash and attribute key(s). ```typescript // Replace with your contract address const nnsContractAddress = '0x...' // Replace with your contract address // Create contract instance const contract = getContract({ address: nnsContractAddress, abi: contractAbi, publicClient, walletClient }) try { // Example domain and attribute keys const normalizedName = normalize('salmo.nad'); const node = namehash(normalizedName); const attributeKey = 'avatar' const attributeKeys = ['avatar', 'email', 'url'] // 3. Get single name attribute const attributeValue = await contract.read.getNameAttribute([node, attributeKey]) console.log(`Attribute ${attributeKey}:`, attributeValue) // 4. Get multiple name attributes const attributes = await contract.read.getNameAttributes([node, attributeKeys]) console.log('Multiple attributes:', attributes) } catch (error) { console.error('Error:', error) } ``` -------------------------------- ### Generate Namehash for Nad Name Service (viem, ethers.js) Source: https://docs.nad.domains/developers/integrating-into-your-dapps/name-processing Generate a namehash for a normalized name, which is used by NNS core smart contracts for optimization. The namehash is a hex-encoded 32-byte value derived using the ENS namehash algorithm. Examples are provided for both viem and ethers.js. ```typescript import { namehash, normalize } from "viem/ens"; const normalizedName = normalize('salmo.nad'); const node = namehash(normalizedName); ``` ```typescript import { ensNormalize, namehash } from "ethers/hash"; const normalizedName = ensNormalize('salmo.nad') const node = namehash(normalizedName) ``` -------------------------------- ### Query NAD Contract for Primary Name (Viem) Source: https://docs.nad.domains/developers/integrating-into-your-dapps/query-contract-directly Shows how to query the NAD contract using Viem to find the primary domain name associated with a specific wallet address. This involves creating a contract instance and calling the `getPrimaryNameForAddress` function with the address. ```typescript // Replace with your contract address const nnsContractAddress = '0x...' // Replace with your contract address // Create contract instance const contract = getContract({ address: nnsContractAddress, abi: contractAbi, publicClient, walletClient }) try { // Example values const address = '0x1234567890123456789012345678901234567890' // 2. Get primary name for an address const primaryName = await contract.read.getPrimaryNameForAddress([address]) console.log('Primary name for address:', primaryName) } catch (error) { console.error('Error:', error) } ``` -------------------------------- ### Query NAD Contract for Resolved Address (Viem) Source: https://docs.nad.domains/developers/integrating-into-your-dapps/query-contract-directly Demonstrates how to use Viem to query the NAD contract for a resolved address associated with a given domain name. It requires the contract address, ABI, and a public/wallet client. The function `getResolvedAddress` takes a namehash as input and returns the resolved address. ```typescript // Replace with your contract address const nnsContractAddress = '0x...' // Replace with your contract address // Create contract instance const contract = getContract({ address: nnsContractAddress, abi: contractAbi, publicClient, walletClient }) try { // Example domain const normalizedName = normalize('salmo.nad'); const node = namehash(normalizedName); // 1. Get resolved address for a name const resolvedAddress = await contract.read.getResolvedAddress([node]) console.log(`Resolved address for ${domain}:`, resolvedAddress) } catch (error) { console.error('Error:', error) } ``` -------------------------------- ### Query NAD Contract for Primary Name (Ethers.js) Source: https://docs.nad.domains/developers/integrating-into-your-dapps/query-contract-directly Demonstrates how to retrieve the primary domain name for a given wallet address using Ethers.js. This requires initializing the contract and calling the `getPrimaryNameForAddress` function with the target address. ```typescript // Setup provider and signer const provider = new ethers.providers.JsonRpcProvider('YOUR_RPC_URL'); const signer = new ethers.Wallet('YOUR_PRIVATE_KEY', provider); const abi = [...] // Replace with your ABI // Contract setup const nnsContractAddress = 'YOUR_CONTRACT_ADDRESS'; const contract = new ethers.Contract(nnsContractAddress, abi, provider); const contractWithSigner = contract.connect(signer); try { // Example values const address = '0x1234567890123456789012345678901234567890'; // Read queries // 2. Get primary name for address const primaryName = await contract.getPrimaryNameForAddress(address); console.log('Primary name for address:', primaryName); } catch (error) { console.error('Error:', error); } ``` -------------------------------- ### Profile API Source: https://docs.nad.domains/developers/contracts Endpoints for retrieving profile information for addresses, including primary name and avatar. ```APIDOC ## GET /getProfileForAddress ### Description Retrieves the profile information for a given address. ### Method GET ### Endpoint `/getProfileForAddress` ### Query Parameters - **addr** (address) - Required - The address to get the profile for. ### Response #### Success Response (200) - **profile** (Profile) - The profile object containing primary name and avatar. - **addr** (address) - The address. - **primaryName** (string) - The primary name for the address. - **avatar** (string) - The avatar associated with the address. #### Response Example ```json { "profile": { "addr": "0x1234567890abcdef1234567890abcdef12345678", "primaryName": "myprofile.domain", "avatar": "QmXoZfKj9Xz7UfJg9gLzZpWpVfTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXzTpVgYfXz ``` -------------------------------- ### NadNameService.sol Interface - Core Functionality Source: https://docs.nad.domains/developers/contracts This Solidity interface defines the core functionalities of the Nad Name Service, including name resolution, primary name retrieval, and attribute management. It specifies the data structures and function signatures for interacting with the protocol. ```solidity interface INadNameService { struct Attribute { string key; string value; } struct ResolvedAddressItem { bytes32 node; address addr; } struct PrimaryNameItem { address addr; string primaryName; } struct Profile { address addr; string primaryName; string avatar; } /** * @notice Emitted when a name's attribute is set. * @param node the hash of the name that attribute was set for * @param key the key of the attribute that was set * @param value the value of the attribute that was set */ event AttributeSet(bytes32 indexed node, string key, string value); /** * @notice Emitted when multiple attributes for a name are set. * @param node the hash of the name that attributes were set for * @param attributes an array of attributes with the keys and values */ event AttributesSet(bytes32 indexed node, Attribute[] attributes); /** * @notice Get the resolved address for a name. * @param node the hash of the name to get the resolved address for * @return the resolved address */ function getResolvedAddress( bytes32 node ) external view returns (address); /** * @notice Get the resolved addresses for a list of names. * @param nodes the hashes of the names to get the resolved addresses for * @return an array of ResolvedAddressItem structs containing the node and address */ function getResolvedAddresses( bytes32[] calldata nodes ) external view returns (ResolvedAddressItem[] memory); /** * @notice Get the primary name for a node. * @param node The node address to get the primary name for * @return The primary name for the address */ function getPrimaryNameForNode( bytes32 node ) external view returns (string memory); /** * @notice Get the primary name for an address. * @param addr The address to get the primary name for * @return The primary name for the address */ function getPrimaryNameForAddress( address addr ) external view returns (string memory); /** * @notice Get the primary names for a list of addresses. * @param addr The addresses to get the primary names for * @return An array of PrimaryNameItem structs containing the address and primary name */ function getPrimaryNameForAddresses( address[] calldata addr ) external view returns (PrimaryNameItem[] memory); /** * @notice Set an attribute for a name. * @param node the hash of the name to set the attribute for * @param key the key of the attribute to set * @param value the value of the attribute to set */ function setNameAttribute( bytes32 node, string calldata key, string calldata value ) external; /** * @notice Set multiple attributes for a name. * @param node the hash of the name to set the attributes for * @param attributes an array of attributes with the keys and values */ function setNameAttributes( bytes32 node, Attribute[] calldata attributes ) external; /** * @notice Get an attribute for a name. * @param node the hash of the name to get the attribute for * @param key the key of the attribute to get * @return result value of the attribute */ function getNameAttribute( bytes32 node, string calldata key ) external view returns (string memory); /** * @notice Get multiple attributes for a name * @param node the hash of the name to get the attributes for * @param keys the keys of the attributes to get * @return result an array of attributes with the keys and values */ function getNameAttributes( bytes32 node, string[] calldata keys ) external view returns (Attribute[] memory); /** * @notice Get a profile for an address, containing primary name and avatar * @param addr the address to get the profile * @return profile the profile of the address, including primary name and avatar */ function getProfileForAddress( address addr ) external view returns (Profile memory); /** * @notice Get a list of profiles for a list of addresses * @param addrs the addresses to get the profiles for * @return profiles the profiles of the addresses, including primary name and avatar */ function getProfilesForAddresses( address[] calldata addrs ) external view returns (Profile[] memory); } ``` -------------------------------- ### Query NAD Contract for Name Attributes (Ethers.js) Source: https://docs.nad.domains/developers/integrating-into-your-dapps/query-contract-directly Shows how to fetch attributes for a NAD domain name using Ethers.js, including single and multiple attributes. The `getNameAttribute` and `getNameAttributes` methods are called with the namehash and the relevant attribute key(s). ```typescript // Setup provider and signer const provider = new ethers.providers.JsonRpcProvider('YOUR_RPC_URL'); const signer = new ethers.Wallet('YOUR_PRIVATE_KEY', provider); const abi = [...] // Replace with your ABI // Contract setup const nnsContractAddress = 'YOUR_CONTRACT_ADDRESS'; const contract = new ethers.Contract(nnsContractAddress, abi, provider); const contractWithSigner = contract.connect(signer); try { // Example values const domain = 'example.nad'; const node = namehash(domain); const attributeKeys = ['avatar', 'email', 'url']; // Read queries // 3. Get single attribute const avatarValue = await contract.getNameAttribute(node, 'avatar'); console.log('Avatar value:', avatarValue); // 4. Get multiple attributes const attributes = await contract.getNameAttributes(node, attributeKeys); console.log('Multiple attributes:', attributes); } catch (error) { console.error('Error:', error); } ```