@thenamespace/offchain-manager
v1.0.12
Published
TypeScript SDK for creating and managing ENS subnames off-chain with the Namespace API.
Maintainers
Readme

Namespace SDK - Offchain Manager
Overview
The @thenamespace/offchain-manager provides an easy-to-use client for managing ENS subnames off-chain. With this SDK, developers can create, update, delete, and query subnames, as well as manage associated records like addresses, text records, and data records.
Getting Started
Installation
npm install @thenamespace/offchain-managerImport the SDK
import { createOffchainClient } from "@thenamespace/offchain-manager";Initialize the Client
To use the SDK, create an instance using the createOffchainClient factory function and set your API key, which you can obtain from https://dev.namespace.ninja.
// 1) No-arg initialization (defaults to mainnet)
const client = createOffchainClient();
// 2) Configure network and API keys inline
const client = createOffchainClient({
mode: "sepolia", // or "mainnet"
// Address-based API key (works with all ENS domains registered to your address)
defaultApiKey: "your-address-based-api-key",
// Domain-based API keys for specific ENS parent names
domainApiKeys: {
"your-ens-name.eth": "your-domain-based-api-key",
// add more domains if needed
},
});
// You can also set API Keys after initialization as well
// Approach 1: Address-based API key (recommended for most use cases)
// Works with all ENS domains registered to your address
client.setDefaultApiKey("your-address-based-api-key");
// Approach 2: Domain-based API key
// Works with a specific ENS domain only
client.setApiKey("your-ens-name.eth", "your-domain-based-api-key");Supported Chains
The SDK supports multiple blockchain networks for address records:
import { ChainName } from "@thenamespace/offchain-manager";
// Available chains: Ethereum, Solana, Arbitrum, Optimism, Base, Polygon,
// BSC, Avalanche, Gnosis, zkSync, Cosmos, NEAR, Linea, Scroll, Bitcoin,
// Starknet, SuiSubname Management
Create a Subname
import { ChainName } from "@thenamespace/offchain-manager";
// Creates a subname named sub.example.eth resolvable to "0x123.."
await client.createSubname({
parentName: "example.eth",
label: "sub",
addresses: [
{
chain: ChainName.Ethereum,
value: "0x123...",
},
],
texts: [
{
key: "avatar",
value: "https://my_avatar_url",
},
],
});Update a Subname
await client.updateSubname("sub.example.eth", {
addresses: [
{
chain: ChainName.Ethereum,
value: "0x123...",
},
],
texts: [
{
key: "avatar",
value: "https://my_avatar_url",
},
],
});Delete a Subname
await client.deleteSubname("sub.example.eth");Check if a Subname is Available
const response = await client.isSubnameAvailable("sub.example.eth");
console.log(response.available);Get a Subname
const subname = await client.getSingleSubname("sub.example.eth");
console.log(subname);Query Subnames
const subnames = await client.getFilteredSubnames({
parentName: "example.eth",
});
console.log(subnames);Record Management
Add an Address Record
import { ChainName } from "@thenamespace/offchain-manager";
await client.addAddressRecord(
"sub.example.eth",
ChainName.Ethereum,
"0xYourEthereumAddress"
);Delete an Address Record
await client.deleteAddressRecord("sub.example.eth", ChainName.Base);Set Default EVM Address
// Sets the same EVM address for all EVM-compatible chains (Ethereum, Arbitrum, Optimism, Base, Polygon, BSC, Avalanche, Gnosis, zkSync, Linea, Scroll, Unichain, Berachain, WorldChain, Zora, Celo, and Monad)
await client.setDefaultEvmAddress("sub.example.eth", "0xYourEthereumAddress");Add a Text Record
await client.addTextRecord("sub.example.eth", "twitter", "@yourhandle");Delete a Text Record
await client.deleteTextRecord("sub.example.eth", "twitter");Retrieve All Text Records
const records = await client.getTextRecords("sub.example.eth");
console.log(records);Retrieve a Specific Text Record
const record = await client.getTextRecord("sub.example.eth", "twitter");
console.log(record);Add a Data Record
await client.addDataRecord("sub.example.eth", "customData", { key: "value" });Delete a Data Record
await client.deleteDataRecord("sub.example.eth", "customData");Retrieve All Data Records
const dataRecords = await client.getDataRecords("sub.example.eth");
console.log(dataRecords);Retrieve a Specific Data Record
const dataRecord = await client.getDataRecord("sub.example.eth", "customData");
console.log(dataRecord);Error Handling
The SDK provides specific error classes for different scenarios:
import {
SubnameAlreadyExistsError,
AuthenticationError,
SubnameNotFoundError
} from "@thenamespace/offchain-manager";
try {
await client.createSubname({...});
} catch (error) {
if (error instanceof SubnameAlreadyExistsError) {
console.log("Subname already exists");
} else if (error instanceof AuthenticationError) {
console.log("Invalid API key");
} else if (error instanceof SubnameNotFoundError) {
console.log("Subname not found");
}
}Advanced Configuration
const client = createOffchainClient({
mode: "sepolia", // or "mainnet"
backendUri: "https://custom-backend.com", // Optional custom backend
defaultApiKey: "your-address-based-api-key", // Optional inline key
domainApiKeys: { "example.eth": "your-domain-based-api-key" },
});Documentation
For detailed documentation, API reference, and advanced usage examples, visit our documentation site.
License
This project is licensed under the MIT License.
Support
For any issues or feature requests, please open an issue on GitHub.
Contributing
Contributions are welcome! Please read our contributing guidelines before submitting a pull request.
Questions? Join our Builders Group chat
Consider joining the Namespace Builders group chat on Telegram if you have any questions, suggestions, feedback, or anything you want to talk about.
