diff --git a/STYLE_GUIDE.md b/STYLE_GUIDE.md
index b72d8bb..a7ea1e1 100644
--- a/STYLE_GUIDE.md
+++ b/STYLE_GUIDE.md
@@ -24,6 +24,7 @@ Use these forms consistently:
| npm | Npm |
| mainnet, testnet | Mainnet, Testnet unless part of a proper name |
| API key | API Key in body copy |
+| ENSv2, ENSv1 | ENS v2, ENS V2, ENSV2, or a bare v2 in headings |
Keep official product names capitalized: Namespace App, Offchain Manager, Mint Manager, Indexer Manager, ENS Components, ENS Widget, and Resolvio.
diff --git a/api-reference/introduction.mdx b/api-reference/introduction.mdx
index 1da5977..09b6b5e 100644
--- a/api-reference/introduction.mdx
+++ b/api-reference/introduction.mdx
@@ -5,6 +5,8 @@ sidebarTitle: "Overview"
icon: "book-bookmark"
---
+import MintApiDeprecated from '/snippets/mint-api-deprecated.mdx';
+
## Offchain Manager API
The Offchain Manager API allows you to create, update, delete, and retrieve offchain ENS subnames and their associated records by using the Namespace.
@@ -52,27 +54,6 @@ x-auth-token: YOUR_API_KEY
-## Mint Manager API
-
-
-
- Get estimated price, fee, and validation status for a requested subname.
-
-
- Generate signed mint parameters ready to be used on-chain.
-
-
-
## Resolvio API
Base URL: `https://api.resolvio.xyz/`
@@ -161,3 +142,26 @@ Base URL: `https://api.resolvio.xyz/`
Invalidate cached resolver data before your next read.
+
+## Mint API (deprecated)
+
+
+
+
+
+ Get estimated price, fee, and validation status for a requested subname.
+
+
+ Generate signed mint parameters ready to use onchain.
+
+
diff --git a/api-reference/mint-manager/estimate-mint-params.mdx b/api-reference/mint-manager/estimate-mint-params.mdx
index 708090d..00bdffe 100644
--- a/api-reference/mint-manager/estimate-mint-params.mdx
+++ b/api-reference/mint-manager/estimate-mint-params.mdx
@@ -3,3 +3,7 @@ title: "Estimate mint params"
description: "Estimate the price, fee, and eligibility for an ENS subname mint."
openapi: "/openapi/mint-openapi.json GET /api/v1/mint/estimate"
---
+
+import MintApiDeprecated from '/snippets/mint-api-deprecated.mdx';
+
+
diff --git a/api-reference/mint-manager/generate-mint-params.mdx b/api-reference/mint-manager/generate-mint-params.mdx
index 52bb4cb..e5ec73d 100644
--- a/api-reference/mint-manager/generate-mint-params.mdx
+++ b/api-reference/mint-manager/generate-mint-params.mdx
@@ -3,3 +3,7 @@ title: "Generate mint params"
description: "Generate signed parameters for an ENS subname mint transaction."
openapi: "/openapi/mint-openapi.json POST /api/v1/mint"
---
+
+import MintApiDeprecated from '/snippets/mint-api-deprecated.mdx';
+
+
diff --git a/assets/activate-ens-name-10.png b/assets/activate-ens-name-10.png
deleted file mode 100644
index 70a7a07..0000000
Binary files a/assets/activate-ens-name-10.png and /dev/null differ
diff --git a/assets/activate-ens-name-9.png b/assets/activate-ens-name-9.png
deleted file mode 100644
index 3d2fd75..0000000
Binary files a/assets/activate-ens-name-9.png and /dev/null differ
diff --git a/assets/onchain/activate-choose-mainnet.png b/assets/onchain/activate-choose-mainnet.png
new file mode 100644
index 0000000..a758319
Binary files /dev/null and b/assets/onchain/activate-choose-mainnet.png differ
diff --git a/assets/onchain/activate-confirm-steps.png b/assets/onchain/activate-confirm-steps.png
new file mode 100644
index 0000000..cda4412
Binary files /dev/null and b/assets/onchain/activate-confirm-steps.png differ
diff --git a/assets/onchain/activate-name-not-activated.png b/assets/onchain/activate-name-not-activated.png
new file mode 100644
index 0000000..721c019
Binary files /dev/null and b/assets/onchain/activate-name-not-activated.png differ
diff --git a/assets/onchain/activate-review.png b/assets/onchain/activate-review.png
new file mode 100644
index 0000000..7ffcd85
Binary files /dev/null and b/assets/onchain/activate-review.png differ
diff --git a/assets/onchain/activate-select-name.png b/assets/onchain/activate-select-name.png
new file mode 100644
index 0000000..f7e8db6
Binary files /dev/null and b/assets/onchain/activate-select-name.png differ
diff --git a/assets/onchain/activate-success.png b/assets/onchain/activate-success.png
new file mode 100644
index 0000000..b59562c
Binary files /dev/null and b/assets/onchain/activate-success.png differ
diff --git a/assets/onchain/configure-mint-window.png b/assets/onchain/configure-mint-window.png
new file mode 100644
index 0000000..3989137
Binary files /dev/null and b/assets/onchain/configure-mint-window.png differ
diff --git a/assets/onchain/configure-other-settings.png b/assets/onchain/configure-other-settings.png
new file mode 100644
index 0000000..2aa531c
Binary files /dev/null and b/assets/onchain/configure-other-settings.png differ
diff --git a/assets/onchain/configure-prices.png b/assets/onchain/configure-prices.png
new file mode 100644
index 0000000..cc7bc22
Binary files /dev/null and b/assets/onchain/configure-prices.png differ
diff --git a/assets/onchain/configure-reservations.png b/assets/onchain/configure-reservations.png
new file mode 100644
index 0000000..7fcb9b5
Binary files /dev/null and b/assets/onchain/configure-reservations.png differ
diff --git a/assets/onchain/configure-setup.png b/assets/onchain/configure-setup.png
new file mode 100644
index 0000000..3e99d2e
Binary files /dev/null and b/assets/onchain/configure-setup.png differ
diff --git a/assets/onchain/configure-token-gated.png b/assets/onchain/configure-token-gated.png
new file mode 100644
index 0000000..9ccef7a
Binary files /dev/null and b/assets/onchain/configure-token-gated.png differ
diff --git a/assets/onchain/configure-whitelist.png b/assets/onchain/configure-whitelist.png
new file mode 100644
index 0000000..232a221
Binary files /dev/null and b/assets/onchain/configure-whitelist.png differ
diff --git a/assets/onchain/manage-subnames-list.png b/assets/onchain/manage-subnames-list.png
new file mode 100644
index 0000000..817d657
Binary files /dev/null and b/assets/onchain/manage-subnames-list.png differ
diff --git a/assets/onchain/mint-complete-profile.png b/assets/onchain/mint-complete-profile.png
new file mode 100644
index 0000000..aaf0b02
Binary files /dev/null and b/assets/onchain/mint-complete-profile.png differ
diff --git a/assets/onchain/mint-search-subname.png b/assets/onchain/mint-search-subname.png
new file mode 100644
index 0000000..23f9fef
Binary files /dev/null and b/assets/onchain/mint-search-subname.png differ
diff --git a/assets/onchain/mint-subname-dialog.png b/assets/onchain/mint-subname-dialog.png
new file mode 100644
index 0000000..d6ff041
Binary files /dev/null and b/assets/onchain/mint-subname-dialog.png differ
diff --git a/assets/onchain/mint-success.png b/assets/onchain/mint-success.png
new file mode 100644
index 0000000..ed40433
Binary files /dev/null and b/assets/onchain/mint-success.png differ
diff --git a/assets/onchain/verify-ens-app.png b/assets/onchain/verify-ens-app.png
new file mode 100644
index 0000000..1bf30af
Binary files /dev/null and b/assets/onchain/verify-ens-app.png differ
diff --git a/assets/register-name.png b/assets/register-name.png
deleted file mode 100644
index 95132a1..0000000
Binary files a/assets/register-name.png and /dev/null differ
diff --git a/assets/register/commit-transaction.png b/assets/register/commit-transaction.png
new file mode 100644
index 0000000..6ac9f14
Binary files /dev/null and b/assets/register/commit-transaction.png differ
diff --git a/assets/register/complete-profile.png b/assets/register/complete-profile.png
new file mode 100644
index 0000000..1406379
Binary files /dev/null and b/assets/register/complete-profile.png differ
diff --git a/assets/register/complete-registration.png b/assets/register/complete-registration.png
new file mode 100644
index 0000000..e246a6f
Binary files /dev/null and b/assets/register/complete-registration.png differ
diff --git a/assets/register/registered.png b/assets/register/registered.png
new file mode 100644
index 0000000..011f3f6
Binary files /dev/null and b/assets/register/registered.png differ
diff --git a/assets/register/registration-details.png b/assets/register/registration-details.png
new file mode 100644
index 0000000..a6c2319
Binary files /dev/null and b/assets/register/registration-details.png differ
diff --git a/assets/register/search-name.png b/assets/register/search-name.png
new file mode 100644
index 0000000..bc09c57
Binary files /dev/null and b/assets/register/search-name.png differ
diff --git a/assets/register/search-results.png b/assets/register/search-results.png
new file mode 100644
index 0000000..1d3e827
Binary files /dev/null and b/assets/register/search-results.png differ
diff --git a/assets/register/wait-timer.png b/assets/register/wait-timer.png
new file mode 100644
index 0000000..1ea1657
Binary files /dev/null and b/assets/register/wait-timer.png differ
diff --git a/assets/search-results.png b/assets/search-results.png
deleted file mode 100644
index 2426705..0000000
Binary files a/assets/search-results.png and /dev/null differ
diff --git a/changelog/ens-components.mdx b/changelog/ens-components.mdx
index fb6bd97..616e67b 100644
--- a/changelog/ens-components.mdx
+++ b/changelog/ens-components.mdx
@@ -5,29 +5,195 @@ sidebarTitle: "ENS Components"
icon: "puzzle-piece"
---
+Release notes for [`@thenamespace/ens-components`](https://www.npmjs.com/package/@thenamespace/ens-components). Dates are npm publish dates. Prereleases on the `alpha` tag aren't listed separately; their changes are listed under the stable release that shipped them.
+
+To move from 2.x to 3.x, follow [Upgrade to the latest version](/developer-guide/sdks/ens-components/upgrade).
+
+
+ - Breaking:
+ - **Onchain flows default to ENSv2.** `version` on `EnsNameRegistrationForm`, `NameRenewForm`, `EnsRecordsForm`, `SubnameMintForm`, and the `useENSResolver` hook defaults to `2`. Pass `version={1}` to `SubnameMintForm` for parents on an old Namespace listing. ENSv1 registration and renewal are retired.
+ - **`.eth` registration is paid in USDC or DAI.** In `onRegistrationSuccess`, `registrationCost` is the token amount, and `transactionFees` and `total` are both the ETH network fees.
+ - **`TransactionPendingScreen` no longer takes a `message` prop.** `hash` is now optional, and a new `details` prop takes label and value rows.
+ - Added:
+ - **`NameRenewForm`**: renews a `.eth` name in one step, paid in USDC or DAI. Anyone can renew any name, and the owner keeps it.
+ - **`SubnameRenewForm`**: renews a subname at the price set by the parent's owner, and warns when the subname would outlive its parent.
+ - **`TransactionProgress` and `TransactionModal`**: the progress screen every form uses, exported for your own transactions.
+ - **ENSv2 subname minting** in `SubnameMintForm`, through Namespace's ENSv2 activation contracts. The user pays in USDC or DAI.
+ - **`resolver` prop** on `SubnameMintForm` for activations that don't set a resolver.
+ - **`priceCurrency`** on the `SubnameMintForm` `onSuccess` payload.
+ - ENSv2 helpers: `getEnsV2RegistrationDeployment`, `isEnsV2NameAvailable`, `getEnsV2Deployment`, `quoteEnsV2Mint`, `quoteEnsV2Payment`, `getEnsV2RenewalDeployment`, `getEnsV2RenewalTarget`, `getEnsV2RenewPrice`, and `quoteEnsV2Renewal`.
+ - Changed:
+ - ENSv2 runs on mainnet and Sepolia. Contract addresses come from `@thenamespace/addresses` 1.2.0.
+ - ENSv2 registration gives each owner a PermissionedResolver, deployed with the name's records. Commitments resume after a page reload.
+ - `EnsRecordsForm` finds the resolver through the ENSv2 Universal Resolver and writes to standard resolvers, PermissionedResolvers, and Namespace's SimplifiedResolver.
+ - Registration and renewal send the `referrer` prop, falling back to Namespace's referrer address.
+ - Wallets with EIP-5792 atomic batching confirm each step in one prompt. Other wallets get one transaction per call.
+ - Forms show "Insufficient funds" and block the transaction when the wallet can't cover the token price or gas.
+ - The subname mint fee estimate uses the effective gas price.
+ - The package ships CommonJS bundles for `require` entries.
+
+
+
+ - Added:
+ - A **Custom** section in the records editor for arbitrary key and value text records.
+ - Changed:
+ - Every top-level form card is 500 px wide, set by `--ns-frame-width`.
+ - Registration, subname minting, and offchain subname forms share one layout and no longer depend on host Bootstrap margins.
+ - Visible hover states on buttons, and alerts without the left accent bar.
+
+
+
+ - Fixed:
+ - `SubnameMintForm` estimates the network fee when the wallet can't cover price and fee, then shows "Insufficient funds" and disables **Mint** instead of showing N/A.
+ - `EnsNameRegistrationForm` checks `.eth` availability with the registrar instead of the registry, so expired names past their grace period show as available.
+
+
+
+ - Breaking:
+ - **New visual design.** Components adopt the Namespace Flows design system: a near-black accent derived from `--ns-ink` instead of blue, 10 px corners from `--ns-radius` instead of square ones, and DM Sans and DM Mono instead of Satoshi. Props, hooks, and exports are unchanged.
+ - Added:
+ - A token layer (`--ns-` variables). Older `--ns-color-*`, `--ns-blue-*`, and `--ns-alert-*` names still resolve as aliases.
+ - `Tag` and `Identicon` atoms.
+ - One availability status line for every name state in registration, subname minting, and offchain subname forms.
+ - A "No records found" state with a clear-filter action in the records editor search.
+ - Changed:
+ - The stylesheet no longer forces a background on the host page's `html` element.
+ - Forms use container queries, so they adapt inside narrow modals on desktop screens.
+ - The records editor is 600 px wide.
+
+
+
+ - Changed:
+ - Updated `@thenamespace/avatar` to 2.0.2.
+
+
+
+ - Changed:
+ - Documented DNS names imported into ENS as supported parents in `SubnameMintForm` and `OffchainSubnameForm`, and as names in `EnsRecordsForm`.
+ - Updated `@thenamespace/avatar` to 2.0.1.
+
+
- Changed:
- - Updated avatar and header record support to use `@thenamespace/avatar` v2.
- - Externalized the Avatar SDK from the browser bundle.
+ - Avatar and header uploads use `@thenamespace/avatar` v2.
+ - The Avatar SDK is no longer bundled into the package, which keeps the build browser-safe.
+ - Changed:
+ - Amounts below the display threshold read `<0.0001`.
- Fixed:
- - Populated ENS registration fees when the registration form opens.
- - Preserved the displayed registration fees when no wallet is connected.
+ - Registration fees load when the registration form opens.
+ - Registration fees stay visible when no wallet is connected.
- Fixed:
- - Stabilized ENS registration fee estimation.
- - Added an RPC fallback for fee estimation.
- - Displayed estimated fees with consistent precision.
+ - Registration shows a real network fee estimate for the commit and register transactions instead of a fixed placeholder.
+ - Fee estimation falls back to a heuristic when the RPC can't simulate the registration, and marks the value with `~`.
+ - Network fees and totals display with four decimals.
+ - Breaking:
+ - **`onRegistrationSuccess` returns `durationLabel` instead of `expiryInYears`.**
+ - Added:
+ - A duration picker for registration and subname minting that switches between years and a calendar date.
+ - Changed:
+ - Registration and minting track duration in seconds.
+
+
+
+ - Fixed:
+ - `EnsNameRegistrationForm` passes the `referrer` prop to the commit and register transactions. Before, both used Namespace's default referrer.
+
+
+
+ - Added:
+ - USD estimates next to ETH totals, using `useEthDollarValue`.
+ - Changed:
+ - The mint client uses the RPC URLs from your wagmi config for mainnet, Sepolia, Base, Base Sepolia, and Optimism.
+ - Fixed:
+ - Subname mint fee estimation.
+
+
+
+ - Fixed:
+ - Chain switching to Sepolia, and other testnet issues.
+
+
+
+ - Fixed:
+ - The email text record.
+
+
+
+ - Changed:
+ - Maintenance release with no changes to the components.
+
+
+
- Added:
- - Calendar-based duration selection for ENS registration and onchain subname minting.
- - Agent instructions and quick-start resources for ENS Components integrations.
+ - Custom text records in the records editor.
+ - `title` and `subtitle` props on `SubnameMintForm`.
+
+
+
+ - Breaking:
+ - **`OffchainSubnameForm` no longer writes subnames.** It takes an `offchainManager` client instead of `apiKeyOrToken`, and replaces `onSuccess` with `onSubnameCreated` and `onSubnameUpdated`. Your callbacks save the subname.
+ - **Peer dependencies raised** to `viem` ^2.46.3 and `wagmi` ^2.19.5.
+ - Added:
+ - `title` and `subtitle` props on `OffchainSubnameForm`.
+
+
+
+ - Added:
+ - `avatarUploadDomain` prop on `EnsNameRegistrationForm` and `SubnameMintForm`, used as the domain in the avatar upload sign-in message.
+
+
+
+ - Added:
+ - First 1.x release. Version 1.0.0 was never published.
+ - Avatar and header image upload in the records editor, with cropping. GIF and SVG files skip the crop step.
+ - A drawer presentation for modals on small screens.
+
+
+
+ - Added:
+ - `SubnameMintForm` for onchain subnames under a Namespace listing (0.27.0).
+ - `OffchainSubnameForm` for gasless subnames (0.29.0), with Sepolia support (0.30.0).
+ - `txConfirmations` option (0.33.0), also on `EnsRecordsForm` (0.34.0).
- Changed:
- - Updated duration handling to use seconds across registration and minting flows.
+ - `EnsRecordsForm` callbacks (0.26.0) and transaction wait handling (0.32.0).
+ - Fixed:
+ - Removing text records (0.31.0).
+ - Minting on Sepolia, including L2 listings (0.35.0, 0.36.0).
+ - `SubnameMintForm` passes `isTestnet` to the mint client (0.37.0).
+
+
+
+ - Breaking:
+ - **Reworked component set.** `ENSNameCard`, `ProfileCard`, `NavbarProfileCard`, `SubnameOnChainRegistrarModal`, `SubnameOffChainRegistrarModal`, and `ENSNamesRegistrarComponent` were removed (0.20.0), and `PendingTransaction` followed (0.25.0).
+ - **React 19 required.** Peer dependencies are `react` and `react-dom` 19 or later, `viem`, and `wagmi` (0.20.0).
+ - Added:
+ - `EnsNameRegistrationForm` with the commit, wait, and register flow and a progress bar (0.20.0).
+ - `EnsRecordsForm` with a summary of record changes (0.25.0).
+ - Fixed:
+ - Registration with records (0.21.0), form styles (0.22.0, 0.23.0), and registration fixes (0.24.0).
+
+
+
+ - Added:
+ - ENS name registration and onchain registration integration (0.10.0, 0.11.0).
+ - Profile and ENS records components (0.13.0, 0.14.0).
+ - Fixed:
+ - Build and bundling issues, including the viem export and a `process is not defined` error (0.15.0 to 0.19.0).
+
+
+
+ - Added:
+ - First releases: `SelectRecordsForm`, ENS name and profile cards, and first versions of the ENS registration and onchain and offchain subname modals.
+ - Contenthash record support and record selector improvements (0.3.0, 0.4.0).
+ - Fixed:
+ - The avatar record button (0.5.0).
diff --git a/changelog/indexer-sdk.mdx b/changelog/indexer-sdk.mdx
index 578fd23..637bfbb 100644
--- a/changelog/indexer-sdk.mdx
+++ b/changelog/indexer-sdk.mdx
@@ -3,8 +3,13 @@ title: "Indexer SDK"
description: "Changelog for the Indexer SDK with version updates and changes."
sidebarTitle: "Indexer SDK"
icon: "bars-progress"
+tag: "Deprecated"
---
+
+ - The Indexer Manager SDK is deprecated. It keeps working for onchain listings on ENSv1 names. For new integrations, use [offchain subnames](/developer-guide/guide/create-offchain-subnames), or issue onchain subnames from the [Namespace App](/user-guide/app). See [ENSv2 and Namespace](/overview/ensv2).
+
+
- Changed:
- **BREAKING**: SDK renamed to `@thenamespace/indexer` from `@namespacesdk/indexer`.
diff --git a/changelog/mint-sdk.mdx b/changelog/mint-sdk.mdx
index 7596f16..9292c94 100644
--- a/changelog/mint-sdk.mdx
+++ b/changelog/mint-sdk.mdx
@@ -3,8 +3,13 @@ title: "Mint SDK"
description: "Changelog for the Mint SDK with version updates and changes."
sidebarTitle: "Mint SDK"
icon: "gauge"
+tag: "Deprecated"
---
+
+ - The Mint Manager SDK is deprecated. It keeps working for onchain listings on ENSv1 names. For new integrations, use [offchain subnames](/developer-guide/guide/create-offchain-subnames), or issue onchain subnames from the [Namespace App](/user-guide/app). See [ENSv2 and Namespace](/overview/ensv2).
+
+
- Added:
- **`checkName`**: Returns whether a name is free and whether an address may mint it, with the chain taken from the listing. Compares the API result with the ENS registry. The previous methods could not do that on a gated listing.
diff --git a/changelog/offchain-sdk.mdx b/changelog/offchain-sdk.mdx
index 4ae7cd6..290269d 100644
--- a/changelog/offchain-sdk.mdx
+++ b/changelog/offchain-sdk.mdx
@@ -6,6 +6,14 @@ icon: "cloud"
---
+
+ - Changed:
+ - **API key links**: The JSDoc for `setApiKey` and `setDefaultApiKey` now points to the API keys tab in the [Namespace App](https://app.namespace.ninja/offchain?activeTab=apiKeys) instead of `dev.namespace.ninja`.
+ - Documentation:
+ - Updated the README with the official Namespace logo, the new API key link, and working links for GitHub issues and the contributing guide.
+ - No changes to the public API. Code written for v1.0.13 works without changes.
+
+
- Added:
- **New Blockchain Support**: Added support for two Substrate L1 chains:
diff --git a/developer-guide/ai-development.mdx b/developer-guide/ai-development.mdx
index 2640996..37f02a1 100644
--- a/developer-guide/ai-development.mdx
+++ b/developer-guide/ai-development.mdx
@@ -39,7 +39,13 @@ Get AI-optimized plain text for any page or the entire corpus.
## Skills
-See the [Skills](/developer-guide/skills) page for more information on how to install skills to give your AI agent deep knowledge of a specific SDK. Skills are available for the [Offchain ENS Subname SDK](/developer-guide/skills#offchain-ens-subname-sdk-skill), [ENS Components](/developer-guide/skills#ens-components-skill), and [Resolvio](/developer-guide/skills#resolvio-ens-resolution-skill).
+Skills give your AI agent detailed instructions for one Namespace SDK, API, or ENS task. Install all of them with:
+
+```bash
+npx skills add thenamespace/skills --yes
+```
+
+Skills are available for the [ENS protocol](/developer-guide/skills#ens-skill), the [Offchain ENS subname SDK](/developer-guide/skills#offchain-ens-subname-sdk-skill), [Celo Names](/developer-guide/skills#celo-names-skill), [Resolvio](/developer-guide/skills#resolvio-ens-resolution-skill), [ENS Components](/developer-guide/skills#ens-components-skill), and the [Avatar SDK](/developer-guide/skills#avatar-sdk-skill). See [Skills](/developer-guide/skills) to install one at a time.
---
## MCP Server
diff --git a/developer-guide/guide/create-offchain-subnames.mdx b/developer-guide/guide/create-offchain-subnames.mdx
index 79fe9e3..a253e15 100644
--- a/developer-guide/guide/create-offchain-subnames.mdx
+++ b/developer-guide/guide/create-offchain-subnames.mdx
@@ -22,6 +22,10 @@ Create a gasless offchain subname, attach ENS records, and query the result with
Follow this guide to create and copy your API key from the Namespace App.
+
+ **Coming from ENSv1?** If you upgrade your parent name to ENSv2, [set the Namespace resolver again](/user-guide/dev-portal#configure-the-resolver). Existing subnames and your SDK code keep working without changes. See [What happens if I upgrade my name to ENSv2?](/overview/ensv2#what-happens-if-i-upgrade-my-name-to-ensv2)
+
+
diff --git a/developer-guide/guide/mint-l1-l2-subnames.mdx b/developer-guide/guide/mint-l1-l2-subnames.mdx
index b47c6ba..1c4fdcc 100644
--- a/developer-guide/guide/mint-l1-l2-subnames.mdx
+++ b/developer-guide/guide/mint-l1-l2-subnames.mdx
@@ -1,11 +1,16 @@
---
-title: "Mint Onchain Subnames on Ethereum or L2"
-description: "Mint ENS subnames on Ethereum or L2 chains."
-sidebarTitle: "Mint Onchain Subnames"
+title: "Mint onchain subnames with Mint Manager"
+description: "Mint subnames from an existing onchain listing."
+sidebarTitle: "Mint onchain subnames"
icon: "coins"
+tag: "Deprecated"
---
-This guide shows how to mint an onchain subname under an ENS name activated in the Namespace App. The Mint Manager SDK selects the correct mint contract for Ethereum or the parent listing's L2 chain; your Viem clients submit the resulting transaction on that chain.
+import MintManagerDeprecated from '/snippets/mint-manager-deprecated.mdx';
+
+
+
+This guide shows how to mint an onchain subname under an ENSv1 name that already has an onchain listing in the Namespace App. The Mint Manager SDK selects the correct mint contract for Ethereum or the parent listing's L2 chain; your Viem clients submit the resulting transaction on that chain.
The complete example uses Base. The SDK derives the chain from the parent listing, so the same code mints an Ethereum listing without change.
@@ -13,7 +18,7 @@ The complete example uses Base. The SDK derives the chain from the parent listin
- Node.js 22 and npm
- TypeScript experience
-- An ENS name activated and listed in the [Namespace App](/user-guide/app#activate-your-ens-name)
+- An ENSv1 name with an existing onchain listing in the [Namespace App](/user-guide/app)
- A wallet with enough native currency for the mint price and gas
- An RPC endpoint for the chain on which you will mint
diff --git a/developer-guide/guide/subpages.mdx b/developer-guide/guide/subpages.mdx
index b4ad1ed..b060a3d 100644
--- a/developer-guide/guide/subpages.mdx
+++ b/developer-guide/guide/subpages.mdx
@@ -3,8 +3,13 @@ title: "Subname Developer Guide"
description: "A flexible starting point for branded minting sites."
sidebarTitle: "Create your own Subpage"
icon: "folder-open"
+tag: "Deprecated"
---
+
+ The Subpages starter is deprecated. It works only with onchain listings on ENSv1 names. See [ENSv2 and Namespace](/overview/ensv2) for what works with ENSv2 names.
+
+
The Subname Developer Guide helps you build and customize your own ENS subname minting website using our white label starter kit. This template provides a fully functional subname-minting website that you can deploy in minutes and customize to match your brand.
## Prerequisites
@@ -19,8 +24,8 @@ The Subname Developer Guide helps you build and customize your own ENS subname m
To enable subname registrations through your custom website, you first need to **activate your ENS name(s)**. Once activated, others will be able to mint subnames from them.
-
- See the step-by-step guide on how to activate an ENS Name.
+
+ Subpages work only with a name that already has an ENSv1 listing.
diff --git a/developer-guide/quickstart.mdx b/developer-guide/quickstart.mdx
index 088703c..34ecad0 100644
--- a/developer-guide/quickstart.mdx
+++ b/developer-guide/quickstart.mdx
@@ -9,15 +9,19 @@ icon: "rocket"
Pick the outcome you need. Each path leads to one focused, end-to-end guide.
+
+ Your offchain subnames and onchain listings keep working. See what changes.
+
+
Issue gasless ENS subnames via API.
-
- Mint ENS subnames on Ethereum or L2 chains.
+
+ Activate your name and issue L1 subnames in the Namespace App.
-
- Customize and deploy a subname storefront.
+
+ Look up addresses, profiles, and records with Resolvio.
@@ -34,7 +38,7 @@ Pick the outcome you need. Each path leads to one focused, end-to-end guide.
Browse hosted API endpoints, parameters, and request schemas.
- Review Offchain, Mint, and Indexer Manager methods.
+ Review Offchain Manager, Avatar, and ENS Components methods.
Ask any ENS-related technical or integration questions.
diff --git a/developer-guide/sdks/ens-components.mdx b/developer-guide/sdks/ens-components.mdx
index 9d511d0..a511080 100644
--- a/developer-guide/sdks/ens-components.mdx
+++ b/developer-guide/sdks/ens-components.mdx
@@ -1,65 +1,64 @@
---
title: "Overview"
-description: "Add ENS workflows to React applications."
+description: "React forms for ENS names, records, and subnames."
sidebarTitle: "Overview"
icon: "puzzle-piece"
---
-`@thenamespace/ens-components` provides React components for `.eth` registration, ENS record editing, and onchain or offchain subname issuance. The components use wagmi and Viem for wallet and chain interactions.
+`@thenamespace/ens-components` is a React library of complete ENS flows. Each form handles input, validation, pricing, wallet prompts, and the success screen, so you add a flow by rendering one component. The forms read the wallet from wagmi and send transactions with viem.
-## Install
+The current major version is 3. Onchain flows run on ENSv2 by default, on Ethereum mainnet or Sepolia.
-Install the package and its peer dependencies:
+## Choose a component
-```bash
-npm install @thenamespace/ens-components react react-dom wagmi viem @tanstack/react-query
-```
-
-Import the component styles once in your application:
-
-```tsx
-import '@thenamespace/ens-components/styles';
-```
+| You want to | Use | Page |
+| --- | --- | --- |
+| Register a `.eth` name | `EnsNameRegistrationForm` | [Register names](/developer-guide/sdks/ens-components/register-names) |
+| Renew a `.eth` name | `NameRenewForm` | [Renew names](/developer-guide/sdks/ens-components/renew-names) |
+| Edit records on a name the user owns | `EnsRecordsForm` | [Edit records](/developer-guide/sdks/ens-components/edit-records) |
+| Collect records in your own flow, without a transaction | `SelectRecordsForm` | [Edit records](/developer-guide/sdks/ens-components/edit-records#collect-records-without-a-transaction) |
+| Mint an onchain subname | `SubnameMintForm` | [Mint subnames](/developer-guide/sdks/ens-components/mint-subnames) |
+| Renew an onchain subname | `SubnameRenewForm` | [Renew subnames](/developer-guide/sdks/ens-components/renew-subnames) |
+| Create or update a gasless offchain subname | `OffchainSubnameForm` | [Offchain subnames](/developer-guide/sdks/ens-components/offchain-subnames) |
+| Show progress for your own transaction | `TransactionProgress`, `TransactionModal` | [Transaction progress](/developer-guide/sdks/ens-components/transaction-progress) |
-Your application must provide `WagmiProvider` and `QueryClientProvider`.
+The package also exports hooks and ENSv2 helpers for custom flows. See [Hooks and helpers](/developer-guide/sdks/ens-components/hooks).
-## Use a component
+## Quick example
-Import the form that matches your ENS workflow:
+After you [install the package and set up providers](/developer-guide/sdks/ens-components/installation), render a form:
```tsx
+'use client';
+
import { EnsNameRegistrationForm } from '@thenamespace/ens-components';
export function RegisterName() {
- return ;
+ return (
+ {
+ console.log(`Registered until ${result.expiryDate}`);
+ }}
+ />
+ );
}
```
-Set `isTestnet` to `true` to use Sepolia instead of Ethereum mainnet.
-
-## Available components
-
-
-
- `EnsNameRegistrationForm` handles the search, commit, wait, and register flow for `.eth` names.
-
-
- `EnsRecordsForm` edits addresses, text records, contenthash, avatar, and header records.
-
-
- `SelectRecordsForm` collects ENS records without requiring a wallet or transaction.
-
-
- `SubnameMintForm` handles price lookup, record selection, and onchain minting from a Namespace listing.
-
-
- `OffchainSubnameForm` creates and updates gasless subnames through the Namespace API.
-
-
+## How ENSv2 works in the forms
+
+These rules apply to registration, renewal, subname minting, and subname renewal.
+
+- **Networks:** Ethereum mainnet by default, or Sepolia when you pass `isTestnet`.
+- **Payment:** `.eth` registration and renewal, and subname mints and renewals, are paid in USDC or DAI. The user picks the token inside the form. Network fees are always paid in ETH.
+- **Wallet prompts:** Wallets that support EIP-5792 atomic batching confirm each step in one prompt. Other wallets get one prompt per call, for example a token approval before the payment. The forms handle approvals, so don't add your own.
+- **Balances:** When the wallet holds too little of the chosen token, or too little ETH for gas, the form shows "Insufficient funds" and blocks the transaction.
+
+The one ENSv1 flow still in use is minting under a parent on an old Namespace listing. Pass `version={1}` to `SubnameMintForm` for those parents. See [Mint under an old Namespace listing](/developer-guide/sdks/ens-components/mint-subnames#mint-under-an-old-namespace-listing).
## Resources
-- Explore the components and their props in the [interactive documentation](https://enscomponents.com/).
-- View the source on [GitHub](https://github.com/thenamespace/ens-components).
-- Install the [ENS Components skill](/developer-guide/skills#ens-components-skill) for agent-assisted integration.
-- Review release changes in the [ENS Components changelog](/changelog/ens-components).
+- Try every component live on [enscomponents.com](https://enscomponents.com/).
+- Read the source on [GitHub](https://github.com/thenamespace/ens-components).
+- Give an AI agent the [ENS Components skill](/developer-guide/skills#ens-components-skill), or point it at [Skill.md](https://enscomponents.com/Skill.md).
+- Upgrading from 2.x? Follow [Upgrade to the latest version](/developer-guide/sdks/ens-components/upgrade).
+- Review every release in the [ENS Components changelog](/changelog/ens-components).
diff --git a/developer-guide/sdks/ens-components/edit-records.mdx b/developer-guide/sdks/ens-components/edit-records.mdx
new file mode 100644
index 0000000..a78dd13
--- /dev/null
+++ b/developer-guide/sdks/ens-components/edit-records.mdx
@@ -0,0 +1,158 @@
+---
+title: "Edit ENS records"
+description: "Update records with EnsRecordsForm and SelectRecordsForm."
+sidebarTitle: "Edit records"
+icon: "list"
+---
+
+`EnsRecordsForm` edits the records of a name the user already controls: addresses, text records, contenthash, avatar, and header image. It compares the user's edits with the records you pass in and writes only what changed, in one transaction.
+
+`SelectRecordsForm` is the same records editor without a wallet or transaction. Use it when your own screen saves the records.
+
+## Edit records on a name
+
+Fetch the name's current records before you render the form, and pass them as `existingRecords`. An empty placeholder for a name that has records hides those records from the user.
+
+```tsx
+'use client';
+
+import { EnsRecordsForm, type EnsRecords } from '@thenamespace/ens-components';
+import { useEffect, useState } from 'react';
+import { usePublicClient } from 'wagmi';
+import { mainnet } from 'wagmi/chains';
+import { normalize } from 'viem/ens';
+
+const TEXT_KEYS = ['avatar', 'description', 'url', 'com.twitter'];
+
+export function EditRecords({ name }: { name: string }) {
+ const client = usePublicClient({ chainId: mainnet.id });
+ const [records, setRecords] = useState(null);
+
+ useEffect(() => {
+ if (!client) return;
+
+ const loadRecords = async () => {
+ const ensName = normalize(name);
+ const texts = await Promise.all(
+ TEXT_KEYS.map(async (key) => ({
+ key,
+ value: (await client.getEnsText({ name: ensName, key })) ?? '',
+ })),
+ );
+ const ethAddress = await client.getEnsAddress({ name: ensName });
+
+ setRecords({
+ texts: texts.filter((text) => text.value),
+ addresses: ethAddress ? [{ coinType: 60, value: ethAddress }] : [],
+ });
+ };
+
+ loadRecords().catch((error) => console.error('Failed to load records', error));
+ }, [client, name]);
+
+ if (!records) return
Loading records…
;
+
+ return (
+ console.log('Updated records', diff)}
+ />
+ );
+}
+```
+
+This example reads a few records with viem. Any source works, such as [Resolvio](/user-guide/resolvio), as long as you pass the result in the `EnsRecords` shape.
+
+### Resolvers
+
+By default the form finds the name's resolver through the ENSv2 Universal Resolver. It writes to standard ENS resolvers, ENSv2 PermissionedResolvers, and Namespace's SimplifiedResolver, and encodes records to match each one. Pass `resolverAddress` or `resolverChainId` only to override the lookup.
+
+### Props
+
+| Prop | Type | Description |
+| --- | --- | --- |
+| `name` | `string` | Required. The full name, such as `alice.eth`. DNS names imported into ENS also work. |
+| `existingRecords` | `EnsRecords` | Required. The name's current records. |
+| `isTestnet` | `boolean` | Uses Sepolia instead of Ethereum mainnet. |
+| `resolverAddress` | `Address` | Skips the resolver lookup and uses this resolver. |
+| `resolverChainId` | `number` | Chain of the resolver. Defaults to mainnet, or Sepolia with `isTestnet`. |
+| `txConfirmations` | `number` | Confirmations to wait for before the update counts as done. |
+| `avatarUploadDomain` | `string` | Hostname used in the avatar upload sign-in message. |
+| `noBorder` | `boolean` | Removes the card border. |
+| `className` | `string` | Class added to the form container. |
+| `version` | `1 \| 2` | Defaults to `2`, which finds the resolver through the ENSv2 Universal Resolver. `1` reads it from the ENSv1 registry. |
+| `onTransactionSent` | `(hash: Hash) => void` | Called when the update transaction is sent. |
+| `onRecordsUpdated` | `(diff: EnsRecordsDiff) => void` | Called after the records are saved, with what changed. |
+| `onGreat` | `() => void` | Called when the user closes the success screen. |
+| `onCancel` | `() => void` | Called when the user cancels. |
+
+## Collect records without a transaction
+
+Use `SelectRecordsForm` when the surrounding screen owns the records, such as a records step inside a larger flow or a custom save button. It doesn't need a connected wallet and sends no transactions.
+
+```tsx
+'use client';
+
+import { SelectRecordsForm, type EnsRecords } from '@thenamespace/ens-components';
+import { useState } from 'react';
+
+export function ProfileStep({ onSave }: { onSave: (records: EnsRecords) => void }) {
+ const [records, setRecords] = useState({ addresses: [], texts: [] });
+
+ return (
+ onSave(records)}>Save}
+ />
+ );
+}
+```
+
+| Prop | Type | Description |
+| --- | --- | --- |
+| `records` | `EnsRecords` | Required. The starting records. |
+| `onRecordsUpdated` | `(records: EnsRecords) => void` | Required. Called with the full record set on every change. |
+| `actionButtons` | `ReactNode` | Buttons rendered at the bottom of the form. |
+| `avatarUpload` | `{ ensName: string; isTestnet?: boolean; siweDomain?: string }` | Turns on avatar and header upload for `ensName`. Without it, users can only paste image URLs. |
+| `noBorder` | `boolean` | Removes the card border. |
+
+## Avatar and header images
+
+Every form with a records step can upload images. The user signs a Sign-In with Ethereum message for `avatarUploadDomain`, or `avatarUpload.siweDomain` on `SelectRecordsForm`. EOAs and deployed smart contract wallets can both sign.
+
+- **Avatar:** square crop, up to 2 MB.
+- **Header:** rectangular crop, up to 5 MB.
+- **Formats:** JPEG, PNG, GIF, WebP, and SVG. GIF and SVG files skip the crop step.
+
+To upload images from your own UI, use the [Avatar SDK](/developer-guide/sdks/avatar) or the `useAvatarClient` hook.
+
+## Record types
+
+```ts
+interface EnsRecords {
+ addresses: { coinType: number; value: string }[];
+ texts: { key: string; value: string }[];
+ contenthash?: { protocol: ContenthashProtocol; value: string };
+}
+
+// ContenthashProtocol: 'ipfs' | 'onion3' | 'arweave' | 'skynet' | 'swarm'
+
+interface EnsRecordsDiff {
+ textsAdded: EnsTextRecord[];
+ textsModified: EnsTextRecord[];
+ textsRemoved: EnsTextRecord[];
+ addressesAdded: EnsAddressRecord[];
+ addressesModified: EnsAddressRecord[];
+ addressesRemoved: EnsAddressRecord[];
+ contenthashAdded?: EnsContenthashRecord;
+ contenthashModified?: EnsContenthashRecord;
+ contenthashRemoved: boolean;
+ isDifferent: boolean;
+}
+```
+
+Address records use [SLIP-44 coin types](https://github.com/satoshilabs/slips/blob/master/slip-0044.md), for example `60` for Ethereum. `convertEVMChainIdToCoinType(chainId)` returns the ENSIP-11 coin type for an EVM chain.
diff --git a/developer-guide/sdks/ens-components/hooks.mdx b/developer-guide/sdks/ens-components/hooks.mdx
new file mode 100644
index 0000000..801304b
--- /dev/null
+++ b/developer-guide/sdks/ens-components/hooks.mdx
@@ -0,0 +1,106 @@
+---
+title: "Hooks and helpers"
+description: "Lower-level building blocks behind the forms."
+sidebarTitle: "Hooks and helpers"
+icon: "code"
+---
+
+The forms are built from hooks and helpers that the package also exports. Use them when you build a custom UI and a form doesn't fit. Start with the forms when you can, because they handle pricing, approvals, batching, and errors for you.
+
+## Check ENSv2 availability
+
+ENSv2 helpers take a viem `PublicClient` and a deployment object that holds the contract addresses for mainnet or Sepolia.
+
+```tsx
+'use client';
+
+import {
+ getEnsV2RegistrationDeployment,
+ isEnsV2NameAvailable,
+} from '@thenamespace/ens-components';
+import { usePublicClient } from 'wagmi';
+import { mainnet } from 'wagmi/chains';
+
+export function useNameAvailability() {
+ const client = usePublicClient({ chainId: mainnet.id });
+
+ return async (label: string) => {
+ if (!client) throw new Error('No public client for mainnet');
+ const deployment = getEnsV2RegistrationDeployment(false);
+ return isEnsV2NameAvailable(client, deployment, label);
+ };
+}
+```
+
+Pass `true` to the deployment getters for Sepolia, and use a Sepolia public client.
+
+## ENSv2 helpers
+
+| Helper | Returns |
+| --- | --- |
+| `getEnsV2RegistrationDeployment(isTestnet)` | The registrar contracts and payment tokens for `.eth` registration. |
+| `isEnsV2NameAvailable(client, deployment, label)` | Whether `label.eth` can be registered. |
+| `getEnsV2RenewalDeployment(isTestnet)` | The contracts for `.eth` renewal. |
+| `getEnsV2RenewalTarget(client, deployment, label)` | The contract that renews the name, its expiry, owner, and whether it's in its grace period. |
+| `getEnsV2RenewPrice(client, renewer, label, duration, token)` | The renewal price in the given token. |
+| `getEnsV2Deployment(isTestnet)` | The Namespace activation contracts and payment tokens for subnames, or `null` when the network has none. |
+| `quoteEnsV2Mint(client, deployment, { parentName, label, minter, duration })` | Whether the address can mint the subname, the USD price, and why a mint is denied. |
+| `quoteEnsV2Payment(client, deployment, priceUsdRaw, token)` | The amount to pay in the given token. |
+| `quoteEnsV2Renewal(client, deployment, { parentName, label, renewer, duration })` | Whether the subname can be renewed, the price, and the parent's expiry. |
+
+Durations are `bigint` seconds.
+
+## Hooks
+
+| Hook | Use it to |
+| --- | --- |
+| `useENSResolver({ resolverChainId, isTestnet, version })` | Find a name's resolver, check it's supported, and send a records update from an `EnsRecordsDiff`. `version` defaults to `2`. |
+| `useAvatarClient({ isTestnet, domain })` | Upload an avatar or header image with `uploadAvatar` and `uploadHeader`, signed by the connected wallet. |
+| `useWaitTransaction({ isTestnet, chainId })` | Wait for a receipt with retries, a timeout, and a confirmation count, through `waitTx`. |
+| `useEthDollarValue()` | Read the current ETH to USD rate as `ethUsdRate`. |
+| `useOffchainManager(name, apiKeyOrToken, isTestnet)` | Create an Offchain Manager client for one parent name. |
+| `useRegisterENS({ isTestnet })` | Price, commit, and register through the ENSv1 registrar controller. |
+| `useMintManager({ isTestnet })` and `useMintSubname({ chainId })` | Read and mint old Namespace listings, the flow behind `SubnameMintForm version={1}`. |
+
+
+ `useOffchainManager` puts the API key in the browser. Use it only with keys you are comfortable exposing, such as in a local demo. In production, keep the key on your server, as shown in [Offchain subnames](/developer-guide/sdks/ens-components/offchain-subnames).
+
+
+`useRegisterENS` targets ENSv1, which is retired for registration. For ENSv2 registration, use `EnsNameRegistrationForm` or the ENSv2 helpers.
+
+## Upload an avatar
+
+```tsx
+'use client';
+
+import { useAvatarClient } from '@thenamespace/ens-components';
+
+export function AvatarInput({ ensName }: { ensName: string }) {
+ const { uploadAvatar, getErrorMessage } = useAvatarClient({ domain: 'app.example.com' });
+
+ const handleFile = async (file: File) => {
+ try {
+ await uploadAvatar({ ensName, file, onProgress: (percent) => console.log(percent) });
+ } catch (error) {
+ console.error(getErrorMessage(error, 'avatar'));
+ }
+ };
+
+ return (
+ {
+ const file = event.target.files?.[0];
+ if (file) void handleFile(file);
+ }}
+ />
+ );
+}
+```
+
+For the full upload API, see the [Avatar SDK](/developer-guide/sdks/avatar).
+
+## Other exports
+
+The package also exports the atoms and molecules the forms use, such as `Button`, `Input`, `Modal`, `Alert`, `TokenSelect`, and `DurationPicker`, plus record utilities such as `getEnsRecordsDiff`, `validateEnsRecords`, and `convertEVMChainIdToCoinType`. Their props are in the package's TypeScript types.
diff --git a/developer-guide/sdks/ens-components/installation.mdx b/developer-guide/sdks/ens-components/installation.mdx
new file mode 100644
index 0000000..eff90b8
--- /dev/null
+++ b/developer-guide/sdks/ens-components/installation.mdx
@@ -0,0 +1,134 @@
+---
+title: "Install ENS Components"
+description: "Install the package and set up its providers."
+sidebarTitle: "Installation"
+icon: "download"
+---
+
+Install the package, wrap your app in wagmi and React Query providers, and import the stylesheet once. Then any form can read the connected wallet.
+
+## Requirements
+
+- React 19 or later
+- wagmi `^2.19.5` and viem `^2.46.3`, which are peer dependencies
+- `@tanstack/react-query`, which wagmi needs
+
+The forms don't include a wallet connect UI. Use your own, or a library such as RainbowKit, and pass its connect action to the forms through `onConnectWallet`.
+
+## Install the package
+
+
+
+
+```bash
+npm install @thenamespace/ens-components@3 wagmi viem @tanstack/react-query
+```
+
+
+
+
+```bash
+pnpm add @thenamespace/ens-components@3 wagmi viem @tanstack/react-query
+```
+
+
+
+
+```bash
+yarn add @thenamespace/ens-components@3 wagmi viem @tanstack/react-query
+```
+
+
+
+
+## Set up providers
+
+Add every chain you use to the wagmi config. ENSv2 flows need `mainnet`, and `sepolia` if you use `isTestnet`. Minting under an old Namespace listing can also need Base or Optimism.
+
+```tsx providers.tsx
+'use client';
+
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
+import { useState, type ReactNode } from 'react';
+import { WagmiProvider, createConfig, http } from 'wagmi';
+import { mainnet, sepolia } from 'wagmi/chains';
+import { injected } from 'wagmi/connectors';
+
+const wagmiConfig = createConfig({
+ chains: [mainnet, sepolia],
+ connectors: [injected()],
+ transports: {
+ [mainnet.id]: http(),
+ [sepolia.id]: http(),
+ },
+});
+
+export function Providers({ children }: { children: ReactNode }) {
+ const [queryClient] = useState(() => new QueryClient());
+
+ return (
+
+ {children}
+
+ );
+}
+```
+
+`http()` with no URL uses the chain's public RPC, which is rate limited. Pass your own RPC URL in production.
+
+## Import the styles
+
+Import the stylesheet once, at the root of your app. Without it the forms render unstyled.
+
+```tsx
+import '@thenamespace/ens-components/styles.css';
+```
+
+`@thenamespace/ens-components/styles` imports the same CSS from a JavaScript module, if your bundler prefers that.
+
+The stylesheet loads DM Sans and DM Mono from Google Fonts. To change fonts, colors, or corners, see [Theming](/developer-guide/sdks/ens-components/theming).
+
+## Render a form
+
+Wrap your app in `Providers`, then render a form. This example also wires the connect button:
+
+```tsx app/register/page.tsx
+'use client';
+
+import { EnsNameRegistrationForm } from '@thenamespace/ens-components';
+import { useConnect } from 'wagmi';
+import { injected } from 'wagmi/connectors';
+
+export default function RegisterPage() {
+ const { connect } = useConnect();
+
+ return (
+ connect({ connector: injected() })}
+ />
+ );
+}
+```
+
+- **`onConnectWallet`:** Pass it to the registration, renewal, and subname forms. Without it, a disconnected user has no way to connect from inside the form.
+- **`avatarUploadDomain`:** The bare hostname your app is served from, such as `app.example.com`, with no protocol or path. It's the domain in the sign-in message the user signs to upload an avatar or header image. When you leave it out, the form uses `window.location.hostname`.
+
+## Use Next.js and other SSR frameworks
+
+The forms use wallet hooks and browser APIs such as `window` and `localStorage`. Render them only in client components (`'use client'`), and keep the providers in a client component too, as in the example above.
+
+## Use testnet
+
+Set `isTestnet` to use Sepolia instead of Ethereum mainnet. ENSv2 registration, renewal, subname minting, and subname renewal all work on Sepolia.
+
+```tsx
+
+```
+
+For offchain subnames, create the client with `mode: 'sepolia'`. See [Offchain subnames](/developer-guide/sdks/ens-components/offchain-subnames).
+
+## Next steps
+
+- Pick a form from the [component overview](/developer-guide/sdks/ens-components#choose-a-component).
+- Restyle the forms with [Theming](/developer-guide/sdks/ens-components/theming).
diff --git a/developer-guide/sdks/ens-components/mint-subnames.mdx b/developer-guide/sdks/ens-components/mint-subnames.mdx
new file mode 100644
index 0000000..7983abb
--- /dev/null
+++ b/developer-guide/sdks/ens-components/mint-subnames.mdx
@@ -0,0 +1,100 @@
+---
+title: "Mint onchain subnames"
+description: "Sell or give away subnames with SubnameMintForm."
+sidebarTitle: "Mint subnames"
+icon: "link"
+---
+
+`SubnameMintForm` mints an onchain subname under a parent name. The user picks a label, a duration, and a payment token, optionally sets records, and confirms the mint. By default it mints on ENSv2.
+
+## Before you start
+
+The parent must be a `.eth` name with a Namespace ENSv2 activation. The owner sets one up in the [Namespace App](/user-guide/app#activate-your-ens-name). The activation sets the price, the accepted payment tokens, the whitelist, and reserved labels. The form reads all of these and fetches whitelist and reservation proofs itself.
+
+## Example
+
+```tsx
+'use client';
+
+import { SubnameMintForm } from '@thenamespace/ens-components';
+
+export function MintSubname({ onConnect }: { onConnect: () => void }) {
+ return (
+ {
+ console.log(`Minted ${data.fullName} for ${data.price} ${data.priceCurrency ?? 'ETH'}`);
+ }}
+ />
+ );
+}
+```
+
+The user pays in USDC or DAI and picks the token in the form. Network fees are always in ETH.
+
+## Props
+
+| Prop | Type | Description |
+| --- | --- | --- |
+| `parentName` | `string` | Required. The activated parent, such as `yourname.eth`. |
+| `label` | `string` | Prefills the subname label. |
+| `isTestnet` | `boolean` | Uses Sepolia instead of Ethereum mainnet. |
+| `resolver` | `Address` | Resolver for the new subname when the activation doesn't set one. Defaults to Namespace's shared resolver. Ignored with `version={1}`. |
+| `version` | `1 \| 2` | Defaults to `2` (ENSv2). Pass `1` for a parent on an old Namespace listing. |
+| `avatarUploadDomain` | `string` | Hostname used in the avatar upload sign-in message. |
+| `title` | `string` | Replaces the form title. |
+| `subtitle` | `string` | Replaces the form subtitle. |
+| `txConfirmations` | `number` | Confirmations to wait for, on the `version={1}` flow. |
+| `noBorder` | `boolean` | Removes the card border. |
+| `onSuccess` | `(data: MintSuccessData) => void` | Called after the mint confirms. |
+| `onSubnameMinted` | `(data: SubnameMintedData) => void` | Also called after the mint confirms, with owner and chain details. |
+| `onConnectWallet` | `() => void` | Called when the user needs to connect a wallet. |
+| `onCancel` | `() => void` | Called when the user cancels. |
+
+## Success data
+
+```ts
+interface MintSuccessData {
+ fullName: string;
+ label: string;
+ parentName: string;
+ txHash: string;
+ price: string;
+ priceCurrency?: string; // 'USDC' or 'DAI'. Unset on version={1} mints, which are paid in ETH.
+ transactionFees: string; // ETH
+ records: EnsRecords;
+}
+
+interface SubnameMintedData {
+ label: string;
+ parentName: string;
+ fullSubname: string;
+ records: EnsRecords;
+ price: string;
+ transactionFees: string;
+ ownerAddress: string;
+ txHash: string;
+ chainId: number;
+}
+```
+
+## Mint under an old Namespace listing
+
+Parents listed in the Namespace App before ENSv2 have an ENSv1 listing. Onchain subnames don't migrate to ENSv2, so those listings keep minting on ENSv1. Pass `version={1}` for them:
+
+```tsx
+
+```
+
+- The parent can be a `.eth` name or a DNS name imported into ENS.
+- The mint is paid in ETH.
+- Some listings mint on Base or Optimism. Add those chains to your wagmi config. The form asks the user to switch chains.
+
+See [ENSv2 and Namespace](/overview/ensv2) for which names use which version.
+
+## Related
+
+- Let holders extend their subnames with [`SubnameRenewForm`](/developer-guide/sdks/ens-components/renew-subnames).
+- Issue gasless subnames instead with [`OffchainSubnameForm`](/developer-guide/sdks/ens-components/offchain-subnames).
diff --git a/developer-guide/sdks/ens-components/offchain-subnames.mdx b/developer-guide/sdks/ens-components/offchain-subnames.mdx
new file mode 100644
index 0000000..c617861
--- /dev/null
+++ b/developer-guide/sdks/ens-components/offchain-subnames.mdx
@@ -0,0 +1,131 @@
+---
+title: "Create offchain subnames"
+description: "Issue gasless subnames with OffchainSubnameForm."
+sidebarTitle: "Offchain subnames"
+icon: "cloud"
+---
+
+`OffchainSubnameForm` lets users claim or update a gasless offchain subname under your parent name. The form checks availability, collects records, and, if the subname already exists, switches to update mode with its records prefilled.
+
+The form only reads from Namespace. It never creates or updates a subname itself. The subname exists once your `onSubnameCreated` or `onSubnameUpdated` callback saves it through your server. Without those callbacks, the form shows success and nothing is created.
+
+## Before you start
+
+- The parent name, a `.eth` name or a DNS name imported into ENS, must use the Namespace resolver. See [Configure the resolver](/user-guide/dev-portal#configure-the-resolver).
+- Get an API key for the parent. See [Generate an API key](/developer-guide/sdks/offchain-manager/generate-api-key).
+- Install the Offchain Manager SDK: `npm install @thenamespace/offchain-manager`.
+
+
+ Keep the API key on your server. It grants write access to every subname under the parent, so it must not ship in client code.
+
+
+## Render the form
+
+In the browser, a client without an API key is enough for the form's reads. Each callback sends the subname to your server, and the form shows an error if the callback throws.
+
+```tsx
+'use client';
+
+import {
+ OffchainSubnameForm,
+ type OffchainSubnameCreatedData,
+} from '@thenamespace/ens-components';
+import { createOffchainClient } from '@thenamespace/offchain-manager';
+
+// Use mode: 'sepolia' for testnet.
+const offchainManager = createOffchainClient({ mode: 'mainnet' });
+
+async function saveSubname(subname: OffchainSubnameCreatedData) {
+ const response = await fetch('/api/subnames', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(subname),
+ });
+ if (!response.ok) throw new Error(await response.text());
+}
+
+export function ClaimSubname() {
+ return (
+
+ );
+}
+```
+
+## Save the subname on your server
+
+Check that the request is allowed, such as who may claim or edit which label, then write with a client that holds the API key:
+
+```ts app/api/subnames/route.ts
+import { createOffchainClient } from '@thenamespace/offchain-manager';
+
+const apiKey = process.env.NAMESPACE_API_KEY;
+if (!apiKey) throw new Error('NAMESPACE_API_KEY is not set');
+
+const offchain = createOffchainClient({
+ mode: 'mainnet',
+ domainApiKeys: { 'yourname.eth': apiKey },
+});
+
+export async function POST(request: Request) {
+ const subname = await request.json();
+ // Authorize the request here before writing.
+
+ const existing = await offchain.getSingleSubname(subname.fullSubname);
+ if (existing) {
+ await offchain.updateSubname(subname.fullSubname, {
+ addresses: subname.addresses,
+ texts: subname.texts,
+ });
+ } else {
+ await offchain.createSubname({
+ parentName: subname.parentName,
+ label: subname.label,
+ addresses: subname.addresses,
+ texts: subname.texts,
+ owner: subname.owner,
+ });
+ }
+
+ return Response.json({ ok: true });
+}
+```
+
+For the full SDK, see [Offchain Manager](/developer-guide/sdks/offchain-manager).
+
+## Props
+
+| Prop | Type | Description |
+| --- | --- | --- |
+| `name` | `string` | Required. The parent name. |
+| `offchainManager` | `OffchainClient` | Required. A client from `createOffchainClient()`. |
+| `label` | `string` | Prefills and locks the subname label. |
+| `isTestnet` | `boolean` | Uses Sepolia for avatar uploads. Set the client's `mode` to match. |
+| `avatarUploadDomain` | `string` | Hostname used in the avatar upload sign-in message. |
+| `title` | `string` | Replaces the form title. |
+| `subtitle` | `string` | Replaces the form subtitle. |
+| `hideTitle` | `boolean` | Hides the title and subtitle. |
+| `noBorder` | `boolean` | Removes the card border. |
+| `onSubnameCreated` | `(data: OffchainSubnameCreatedData) => Promise \| void` | Called when the user submits a new subname. Save it here. |
+| `onSubnameUpdated` | `(data: OffchainSubnameCreatedData) => Promise \| void` | Called when the user submits changes to an existing subname. Save them here. |
+| `onCancel` | `() => void` | Called when the user cancels. |
+
+## Callback data
+
+```ts
+interface OffchainSubnameCreatedData {
+ label: string;
+ parentName: string;
+ fullSubname: string;
+ addresses: { chain: ChainName; value: string }[];
+ texts: { key: string; value: string }[];
+ owner?: string;
+}
+```
+
+`ChainName` comes from `@thenamespace/offchain-manager`, so the data matches what `createSubname` and `updateSubname` expect.
diff --git a/developer-guide/sdks/ens-components/register-names.mdx b/developer-guide/sdks/ens-components/register-names.mdx
new file mode 100644
index 0000000..b5ed529
--- /dev/null
+++ b/developer-guide/sdks/ens-components/register-names.mdx
@@ -0,0 +1,78 @@
+---
+title: "Register .eth names"
+description: "Add .eth registration with EnsNameRegistrationForm."
+sidebarTitle: "Register names"
+icon: "signature"
+---
+
+`EnsNameRegistrationForm` registers a `.eth` name on ENSv2. The user searches for a name, picks a duration, optionally sets profile records, and confirms the commit and register transactions. Registration is paid in USDC or DAI.
+
+## Example
+
+```tsx
+'use client';
+
+import { EnsNameRegistrationForm } from '@thenamespace/ens-components';
+
+export function RegisterName({ onConnect }: { onConnect: () => void }) {
+ return (
+ {
+ // registrationCost is the USDC or DAI price. total covers only ETH network fees.
+ console.log(result.registrationCost, result.expiryDate);
+ }}
+ />
+ );
+}
+```
+
+## How the flow works
+
+1. The user types a label. The form checks availability with the ENSv2 registrar and shows the price.
+2. The user picks a duration in years or with a calendar date. The minimum is 28 days.
+3. The user can add records, an avatar, and a header image before registering.
+4. The form sends the commit transaction, waits the registrar's minimum commitment age, then sends the register transaction. If the page reloads during the wait, the commitment resumes.
+5. Each owner gets their own PermissionedResolver. On the owner's first registration it's deployed as an extra step in the same flow, and records set during registration are written to it.
+
+The `referrer` is part of the registration. It defaults to Namespace's referrer address.
+
+## Props
+
+| Prop | Type | Description |
+| --- | --- | --- |
+| `name` | `string` | Prefills the label. Accepts `alice` or `alice.eth`. |
+| `isTestnet` | `boolean` | Uses Sepolia instead of Ethereum mainnet. |
+| `referrer` | `Address` | Referrer recorded with the registration. Defaults to Namespace's referrer. |
+| `avatarUploadDomain` | `string` | Hostname used in the avatar upload sign-in message. Defaults to `window.location.hostname`. |
+| `title` | `string` | Replaces the form title. |
+| `subtitle` | `string` | Replaces the form subtitle. |
+| `bannerImage` | `string` | Image URL for the banner. |
+| `bannerWidth` | `number` | Banner width in pixels. |
+| `hideBanner` | `boolean` | Hides the banner. |
+| `noBorder` | `boolean` | Removes the card border. |
+| `className` | `string` | Class added to the form container. |
+| `version` | `1 \| 2` | Defaults to `2` (ENSv2). ENSv1 registration is retired, so leave this unset. |
+| `onRegistrationStart` | `(name: string) => void` | Called when the first transaction is sent, with the full name. |
+| `onRegistrationSuccess` | `(result: RegistrationSuccessData) => void` | Called after the register transaction confirms. |
+| `onClose` | `(isSuccess: boolean) => void` | Called when the user closes the success screen. |
+| `onConnectWallet` | `() => void` | Called when the user needs to connect a wallet. |
+
+## Success data
+
+`onRegistrationSuccess` receives an object with these string fields:
+
+| Field | Description |
+| --- | --- |
+| `durationLabel` | The registration length, for example `1 year`. |
+| `expiryDate` | The formatted expiry date. |
+| `registrationCost` | The price paid, in USDC or DAI. |
+| `transactionFees` | Network fees paid, in ETH. |
+| `total` | The same ETH network fees as `transactionFees`. Don't show it as the price. |
+
+## Related
+
+- Let users extend a name with [`NameRenewForm`](/developer-guide/sdks/ens-components/renew-names).
+- Edit records after registration with [`EnsRecordsForm`](/developer-guide/sdks/ens-components/edit-records).
diff --git a/developer-guide/sdks/ens-components/renew-names.mdx b/developer-guide/sdks/ens-components/renew-names.mdx
new file mode 100644
index 0000000..5df077d
--- /dev/null
+++ b/developer-guide/sdks/ens-components/renew-names.mdx
@@ -0,0 +1,63 @@
+---
+title: "Renew .eth names"
+description: "Extend a .eth name with NameRenewForm."
+sidebarTitle: "Renew names"
+icon: "rotate"
+---
+
+`NameRenewForm` renews a `.eth` name in one step on ENSv2, paid in USDC or DAI. Anyone can renew any name, and the owner keeps it, so don't limit the form to the name's owner.
+
+## Example
+
+```tsx
+'use client';
+
+import { NameRenewForm, type RenewalSuccessData } from '@thenamespace/ens-components';
+
+export function RenewName({ onConnect }: { onConnect: () => void }) {
+ const handleSuccess = (data: RenewalSuccessData) => {
+ console.log(`${data.fullName} now expires ${data.newExpiry}`);
+ };
+
+ return (
+
+ );
+}
+```
+
+Leave out `name` to let the user type the name to renew.
+
+## Props
+
+| Prop | Type | Description |
+| --- | --- | --- |
+| `name` | `string` | The name to renew, as `alice` or `alice.eth`. Leave empty to let the user type one. |
+| `isTestnet` | `boolean` | Uses Sepolia instead of Ethereum mainnet. |
+| `referrer` | `Address` | Referrer recorded with the renewal. Defaults to Namespace's referrer. |
+| `title` | `string` | Replaces the form title. |
+| `subtitle` | `string` | Replaces the form subtitle. |
+| `noBorder` | `boolean` | Removes the card border. |
+| `className` | `string` | Class added to the form container. |
+| `version` | `1 \| 2` | Defaults to `2` (ENSv2). ENSv1 renewal is retired, so leave this unset. |
+| `onRenewalSuccess` | `(data: RenewalSuccessData) => void` | Called after the renewal confirms. |
+| `onConnectWallet` | `() => void` | Called when the user needs to connect a wallet. |
+| `onCancel` | `() => void` | Called when the user cancels. |
+
+## Success data
+
+`RenewalSuccessData` is shared with [`SubnameRenewForm`](/developer-guide/sdks/ens-components/renew-subnames).
+
+```ts
+interface RenewalSuccessData {
+ fullName: string;
+ txHash: string;
+ price: string;
+ priceCurrency: string; // 'USDC' or 'DAI'
+ transactionFees: string; // ETH
+ newExpiry: string;
+}
+```
diff --git a/developer-guide/sdks/ens-components/renew-subnames.mdx b/developer-guide/sdks/ens-components/renew-subnames.mdx
new file mode 100644
index 0000000..00772e1
--- /dev/null
+++ b/developer-guide/sdks/ens-components/renew-subnames.mdx
@@ -0,0 +1,58 @@
+---
+title: "Renew onchain subnames"
+description: "Extend ENSv2 subnames with SubnameRenewForm."
+sidebarTitle: "Renew subnames"
+icon: "clock-rotate-left"
+---
+
+`SubnameRenewForm` renews a subname minted under an ENSv2-activated parent, at the price the parent's owner set. Anyone can renew any subname, and the owner keeps it.
+
+A subname stops resolving when its parent expires, whatever its own expiry. When the new expiry would outlive the parent, the form warns the user. Pass `onRenewParent` to add a link in that warning, and open a [`NameRenewForm`](/developer-guide/sdks/ens-components/renew-names) for the parent from it.
+
+## Example
+
+```tsx
+'use client';
+
+import { NameRenewForm, SubnameRenewForm } from '@thenamespace/ens-components';
+import { useState } from 'react';
+
+export function RenewSubname() {
+ const [renewParent, setRenewParent] = useState(false);
+
+ if (renewParent) {
+ return setRenewParent(false)} />;
+ }
+
+ return (
+ setRenewParent(true)}
+ onRenewalSuccess={(data) => console.log(`${data.fullName} now expires ${data.newExpiry}`)}
+ />
+ );
+}
+```
+
+Leave out `label` to let the user type the subname.
+
+## Props
+
+| Prop | Type | Description |
+| --- | --- | --- |
+| `parentName` | `string` | Required. The ENSv2-activated parent, such as `yourname.eth`. |
+| `label` | `string` | The subname label. Leave empty to let the user type one. |
+| `isTestnet` | `boolean` | Uses Sepolia instead of Ethereum mainnet. |
+| `title` | `string` | Replaces the form title. |
+| `subtitle` | `string` | Replaces the form subtitle. |
+| `noBorder` | `boolean` | Removes the card border. |
+| `className` | `string` | Class added to the form container. |
+| `onRenewalSuccess` | `(data: RenewalSuccessData) => void` | Called after the renewal confirms. |
+| `onRenewParent` | `() => void` | Adds a link to renew the parent when the subname would outlive it. |
+| `onConnectWallet` | `() => void` | Called when the user needs to connect a wallet. |
+| `onCancel` | `() => void` | Called when the user cancels. |
+
+`SubnameRenewForm` has no `version` prop. It renews ENSv2 subnames only.
+
+`onRenewalSuccess` receives the same [`RenewalSuccessData`](/developer-guide/sdks/ens-components/renew-names#success-data) as `NameRenewForm`.
diff --git a/developer-guide/sdks/ens-components/theming.mdx b/developer-guide/sdks/ens-components/theming.mdx
new file mode 100644
index 0000000..c627bf6
--- /dev/null
+++ b/developer-guide/sdks/ens-components/theming.mdx
@@ -0,0 +1,50 @@
+---
+title: "Theme ENS Components"
+description: "Match the forms to your brand with CSS variables."
+sidebarTitle: "Theming"
+icon: "palette"
+---
+
+The forms are styled with CSS variables prefixed with `--ns-`. Override them in your own CSS, after the package stylesheet, to change the accent color, corners, fonts, and surfaces.
+
+## Override tokens
+
+```css globals.css
+:root {
+ --ns-ink: #212121; /* accent; buttons and highlights derive from it */
+ --ns-radius: 10px; /* every corner */
+ --ns-bg: #fbfaf9; /* page background */
+ --ns-surface: #ffffff; /* card background */
+ --ns-text: #1b1d1e;
+ --ns-link: #0080bc;
+ --ns-font-family: 'DM Sans', system-ui, sans-serif;
+ --ns-font-mono: 'DM Mono', ui-monospace, monospace; /* names, amounts, dates, hashes */
+ --ns-frame-width: 500px; /* width of every form card */
+}
+```
+
+The values above are the defaults.
+
+- Change the accent with `--ns-ink`. The rest of the accent scale is derived from it.
+- Change every corner at once with `--ns-radius`. Set it to `0` for square corners.
+- Older names such as `--ns-color-*` and `--ns-blue-*` still resolve, but they derive from the tokens above. Override the tokens, not the older names.
+
+## Match the page background
+
+The stylesheet doesn't set your page background. To match the forms, add it yourself:
+
+```css
+body {
+ background: var(--ns-bg);
+}
+```
+
+## Adjust a single form
+
+- `noBorder` removes the card border on every form.
+- `className` adds a class to the registration, renewal, records, subname renewal, and transaction progress components.
+- `title` and `subtitle` replace the default copy on most forms.
+
+## Dark mode
+
+The design ships light only. The package exports `ThemeProvider` and `useTheme`, and `ThemeProvider initialTheme="dark"` sets `data-theme="dark"`, but the dark palette hasn't been updated for the current design. Test it carefully before you offer dark mode to users.
diff --git a/developer-guide/sdks/ens-components/transaction-progress.mdx b/developer-guide/sdks/ens-components/transaction-progress.mdx
new file mode 100644
index 0000000..2d1378c
--- /dev/null
+++ b/developer-guide/sdks/ens-components/transaction-progress.mdx
@@ -0,0 +1,71 @@
+---
+title: "Show transaction progress"
+description: "Reuse the forms' progress screen for your own transactions."
+sidebarTitle: "Transaction progress"
+icon: "hourglass"
+---
+
+Every form shows the same progress screen while a transaction confirms: a progress bar, optional detail rows, and a block explorer link. `TransactionProgress` and `TransactionModal` export that screen for transactions your own code sends, so your flows match the forms.
+
+You don't need these components with the forms. Each form already shows its own progress.
+
+## Example
+
+```tsx
+'use client';
+
+import { TransactionModal, type TransactionProgressStatus } from '@thenamespace/ens-components';
+import type { Hash } from 'viem';
+
+interface Props {
+ isOpen: boolean;
+ status: TransactionProgressStatus;
+ hash?: Hash;
+ onClose: () => void;
+}
+
+export function SetPrimaryNameProgress({ isOpen, status, hash, onClose }: Props) {
+ return (
+
+ );
+}
+```
+
+Render `TransactionProgress` with the same props, minus `isOpen`, `onClose`, and `footer`, to show the screen inline instead of in a modal.
+
+## TransactionProgress props
+
+| Prop | Type | Description |
+| --- | --- | --- |
+| `status` | `'pending' \| 'success' \| 'failed'` | Required. The transaction state. |
+| `hash` | `Hash` | Transaction hash, used for the explorer link. |
+| `chainId` | `number` | Chain for the explorer link. |
+| `isTestnet` | `boolean` | Uses the Sepolia explorer when `chainId` isn't set. |
+| `title` | `ReactNode` | Replaces the default title for the current status. |
+| `description` | `ReactNode` | Replaces the default description for the current status. |
+| `details` | `{ label: ReactNode; value: ReactNode }[]` | Rows shown in a card under the progress bar. |
+| `duration` | `number` | Milliseconds the bar takes to reach 90% while pending. Defaults to `10000`. |
+| `className` | `string` | Class added to the container. |
+
+## TransactionModal props
+
+`TransactionModal` takes every `TransactionProgress` prop, plus:
+
+| Prop | Type | Description |
+| --- | --- | --- |
+| `isOpen` | `boolean` | Required. Shows the modal. |
+| `onClose` | `() => void` | Required. Called when the user closes the modal. |
+| `footer` | `ReactNode` | Replaces the default **Close** button. |
+
+## TransactionPendingScreen
+
+`TransactionPendingScreen` is still exported for existing code. It wraps `TransactionProgress` and takes `hash`, `isCompleted`, `isTestnet`, `chainId`, and `details`. Since 3.0 it no longer accepts `message`. For new code, use `TransactionProgress`.
diff --git a/developer-guide/sdks/ens-components/upgrade.mdx b/developer-guide/sdks/ens-components/upgrade.mdx
new file mode 100644
index 0000000..3545395
--- /dev/null
+++ b/developer-guide/sdks/ens-components/upgrade.mdx
@@ -0,0 +1,109 @@
+---
+title: "Upgrade to the latest version"
+description: "Move from ENS Components 2.x to 3.x."
+sidebarTitle: "Upgrade guide"
+icon: "arrow-up"
+---
+
+Version 3 moves every onchain flow to ENSv2. Most apps only need to bump the package, but three cases need code changes: minting under an old Namespace listing, showing the registration price from the success callback, and passing `message` to `TransactionPendingScreen`.
+
+## What changed from 2.x to 3.x
+
+| Flow | 2.x | 3.x |
+| --- | --- | --- |
+| `.eth` registration | ENSv1 registrar controller, paid in ETH. Records go to the ENS public resolver. | ENSv2 registrar, paid in USDC or DAI. Each owner gets a PermissionedResolver, deployed on their first registration. |
+| `.eth` renewal | No component. | New `NameRenewForm`, paid in USDC or DAI. |
+| Record editing | Resolver read from the ENSv1 registry. | Resolver found through the ENSv2 Universal Resolver. Writes to standard resolvers, PermissionedResolvers, and Namespace's SimplifiedResolver. |
+| Onchain subname minting | Namespace listings through the Mint Manager, on Ethereum, Base, or Optimism, paid in ETH. | Namespace ENSv2 activations on Ethereum, paid in USDC or DAI. Old listings need `version={1}`. |
+| Onchain subname renewal | No component. | New `SubnameRenewForm`, for ENSv2 subnames. |
+| Offchain subnames | `OffchainSubnameForm` with your save callbacks. | No change. |
+| Transaction screens | `TransactionPendingScreen`, with a `message` prop and a required `hash`. | One shared screen in every form, exported as `TransactionProgress` and `TransactionModal`. `TransactionPendingScreen` no longer takes `message`. |
+| Wallet prompts | One transaction per step. | One prompt per step for wallets with EIP-5792 batching. Others get one prompt per call. |
+
+The new `version` prop on `EnsNameRegistrationForm`, `NameRenewForm`, `EnsRecordsForm`, and `SubnameMintForm`, and on the `useENSResolver` hook, defaults to `2`. ENSv1 registration and renewal are retired, so the only reason to pass `version={1}` is to mint under an old Namespace listing.
+
+Peer dependencies are unchanged: React 19 or later, wagmi `^2.19.5`, and viem `^2.46.3`.
+
+## Upgrade checklist
+
+
+
+ ```bash
+ npm install @thenamespace/ens-components@3
+ ```
+
+
+
+ In 3.x, `SubnameMintForm` looks for an ENSv2 activation on the parent. If the parent has a listing created before ENSv2, keep it on ENSv1:
+
+ ```tsx
+ // 2.x
+
+
+ // 3.x
+
+ ```
+
+ Parents that the owner activates on ENSv2 in the [Namespace App](/user-guide/app#activate-your-ens-name) need no `version` prop. If a listing mints on Base or Optimism, keep those chains in your wagmi config.
+
+
+
+ Registration is now paid in USDC or DAI. In `onRegistrationSuccess`, `registrationCost` is the token amount. `transactionFees` and `total` are both the ETH network fees, so `total` no longer includes the price.
+
+ ```tsx
+ // 2.x: total was the ETH price plus fees
+ onRegistrationSuccess={(result) => showReceipt(`${result.total} ETH`)}
+
+ // 3.x: registrationCost is the stablecoin price, total is the ETH fee
+ onRegistrationSuccess={(result) =>
+ showReceipt(`${result.registrationCost} + ${result.transactionFees} ETH in fees`)
+ }
+ ```
+
+ Update copy that tells users they'll pay in ETH. Users need USDC or DAI to register, and ETH for gas.
+
+
+
+ ```tsx
+ // 2.x
+
+
+ // 3.x
+
+ ```
+
+ `TransactionPendingScreen` still works without `message`, and its `hash` is now optional. `TransactionProgress` replaces it. See [Transaction progress](/developer-guide/sdks/ens-components/transaction-progress).
+
+
+
+ The forms now approve the payment token, batch calls when the wallet supports it, and block the transaction with "Insufficient funds" when the wallet can't pay. Remove any approval or balance check you added around the forms.
+
+
+
+ ENSv2 runs on Ethereum mainnet, and on Sepolia with `isTestnet`. Make sure your wagmi config includes the chains you use.
+
+
+
+ `NameRenewForm` and `SubnameRenewForm` are new and optional. See [Renew names](/developer-guide/sdks/ens-components/renew-names) and [Renew subnames](/developer-guide/sdks/ens-components/renew-subnames).
+
+
+
+## Upgrade from 1.x to 2.x
+
+Version 2.0.0 was a visual redesign. Props, hooks, and exports didn't change.
+
+- The accent changed from blue to near-black, set by `--ns-ink`, and corners changed from square to 10 px, set by `--ns-radius`.
+- Fonts changed from Satoshi to DM Sans and DM Mono.
+- The stylesheet no longer sets a background on your page's `html` element. Add `background: var(--ns-bg)` to your page if you relied on it.
+- Older `--ns-color-*` and `--ns-blue-*` variables still resolve. Move overrides to the new tokens. See [Theming](/developer-guide/sdks/ens-components/theming).
+
+If you are on 1.1.0 or 1.1.1, two later 1.x releases also changed the API:
+
+- **1.1.2:** `OffchainSubnameForm` takes an `offchainManager` client instead of `apiKeyOrToken`, and `onSubnameCreated` and `onSubnameUpdated` replace `onSuccess`. The form no longer saves subnames, so your callbacks must. See [Offchain subnames](/developer-guide/sdks/ens-components/offchain-subnames).
+- **1.3.0:** `onRegistrationSuccess` returns `durationLabel` instead of `expiryInYears`.
+
+See the [changelog](/changelog/ens-components) for every release.
diff --git a/developer-guide/sdks/indexer-manager.mdx b/developer-guide/sdks/indexer-manager.mdx
index 5cd0c71..729da5e 100644
--- a/developer-guide/sdks/indexer-manager.mdx
+++ b/developer-guide/sdks/indexer-manager.mdx
@@ -4,6 +4,10 @@ description: "Typed access to indexed registry and subname data from L2 chains."
icon: "eye"
---
+import IndexerManagerDeprecated from '/snippets/indexer-manager-deprecated.mdx';
+
+
+
## Introduction
The Indexer Manager SDK is a lightweight TypeScript client for reading indexed data produced by Namespace smart contracts on Layer 2 networks. It provides simple, typed methods to read individual subnames, search and paginate subnames, and retrieve registry metadata.
diff --git a/developer-guide/sdks/indexer-manager/fetch-l2-registries.mdx b/developer-guide/sdks/indexer-manager/fetch-l2-registries.mdx
index eb1d1fc..950783c 100644
--- a/developer-guide/sdks/indexer-manager/fetch-l2-registries.mdx
+++ b/developer-guide/sdks/indexer-manager/fetch-l2-registries.mdx
@@ -5,6 +5,10 @@ sidebarTitle: "Fetch L2 Registries"
icon: "notebook"
---
+import IndexerManagerDeprecated from '/snippets/indexer-manager-deprecated.mdx';
+
+
+
## getL2Registry
Fetches the information about the deployed NFT registry for an ENS name on a specific L2 network using its `chainId` and either the name or namehash.
diff --git a/developer-guide/sdks/indexer-manager/fetch-l2-subnames.mdx b/developer-guide/sdks/indexer-manager/fetch-l2-subnames.mdx
index 18bb3a8..606312c 100644
--- a/developer-guide/sdks/indexer-manager/fetch-l2-subnames.mdx
+++ b/developer-guide/sdks/indexer-manager/fetch-l2-subnames.mdx
@@ -5,6 +5,10 @@ sidebarTitle: "Fetch L2 Subnames"
icon: "square-user"
---
+import IndexerManagerDeprecated from '/snippets/indexer-manager-deprecated.mdx';
+
+
+
Indexer has methods for fetching single or multiple L2 subnames.
## Get one L2 subname
diff --git a/developer-guide/sdks/indexer-manager/installation.mdx b/developer-guide/sdks/indexer-manager/installation.mdx
index ffc659e..a18d76c 100644
--- a/developer-guide/sdks/indexer-manager/installation.mdx
+++ b/developer-guide/sdks/indexer-manager/installation.mdx
@@ -5,6 +5,10 @@ sidebarTitle: "Installation"
icon: "download"
---
+import IndexerManagerDeprecated from '/snippets/indexer-manager-deprecated.mdx';
+
+
+
You can install the library:
diff --git a/developer-guide/sdks/introduction.mdx b/developer-guide/sdks/introduction.mdx
index 8b614cf..f3ac79d 100644
--- a/developer-guide/sdks/introduction.mdx
+++ b/developer-guide/sdks/introduction.mdx
@@ -4,20 +4,14 @@ description: "Pick the SDK for the operation your app performs."
icon: "code"
---
-Namespace publishes focused TypeScript SDKs for offchain management, mint preparation, and indexed onchain data. Choose the client that matches the operation your application performs.
+Namespace publishes focused TypeScript SDKs for offchain subnames, avatar uploads, and ENS interfaces in React. Choose the client that matches the operation your application performs.
SDK packages include:
-
+
Create, update, delete, and query gasless offchain subnames and records.
-
- Check eligibility and generate mint transaction parameters for Ethereum or L2 chains.
-
-
- Query indexed subnames and registry deployments from L2 chains.
-
Upload and delete ENS avatar and header images with SIWE authentication.
@@ -25,3 +19,16 @@ SDK packages include:
Add React interfaces for ENS registration, record editing, and subname issuance.
+
+## Deprecated SDKs
+
+Mint Manager and Indexer Manager are deprecated. They keep working for onchain listings created on ENSv1 names.
+
+
+
+ Check eligibility and generate mint transactions for existing ENSv1 listings.
+
+
+ Query indexed L2 subnames and registries for existing listings.
+
+
diff --git a/developer-guide/sdks/mint-manager.mdx b/developer-guide/sdks/mint-manager.mdx
index e8c9a35..8d38c45 100644
--- a/developer-guide/sdks/mint-manager.mdx
+++ b/developer-guide/sdks/mint-manager.mdx
@@ -4,6 +4,10 @@ description: "Generate contract calls to mint onchain subnames on Ethereum or L2
icon: "eye"
---
+import MintManagerDeprecated from '/snippets/mint-manager-deprecated.mdx';
+
+
+
`@thenamespace/mint-manager` checks mint eligibility and returns the contract call required to mint under a name activated in the Namespace App. It supports Ethereum mainnet and configured L2 networks such as Base and Optimism. Use viem or another compatible client to simulate and submit the returned transaction.
The SDK never holds a private key and never sends a transaction.
diff --git a/developer-guide/sdks/mint-manager/check-name.mdx b/developer-guide/sdks/mint-manager/check-name.mdx
index 7640c8d..e853256 100644
--- a/developer-guide/sdks/mint-manager/check-name.mdx
+++ b/developer-guide/sdks/mint-manager/check-name.mdx
@@ -5,6 +5,10 @@ sidebarTitle: "Check a name"
icon: "circle-check"
---
+import MintManagerDeprecated from '/snippets/mint-manager-deprecated.mdx';
+
+
+
`checkName` reports whether this address can mint this name. If it cannot, the result says why. Pass the whole subname. The SDK normalizes it, splits it, resolves the listing, and picks the chain.
### Usage
diff --git a/developer-guide/sdks/mint-manager/errors.mdx b/developer-guide/sdks/mint-manager/errors.mdx
index 4b21943..5952e50 100644
--- a/developer-guide/sdks/mint-manager/errors.mdx
+++ b/developer-guide/sdks/mint-manager/errors.mdx
@@ -5,6 +5,10 @@ sidebarTitle: "Error handling"
icon: "circle-alert"
---
+import MintManagerDeprecated from '/snippets/mint-manager-deprecated.mdx';
+
+
+
Every failure the SDK raises is a `MintManagerError` carrying a stable `code`. Branch on `code`; the `message` is written for a human reading a log and may change between releases.
```typescript
diff --git a/developer-guide/sdks/mint-manager/get-mint-details.mdx b/developer-guide/sdks/mint-manager/get-mint-details.mdx
index e114dad..aa9def6 100644
--- a/developer-guide/sdks/mint-manager/get-mint-details.mdx
+++ b/developer-guide/sdks/mint-manager/get-mint-details.mdx
@@ -5,6 +5,10 @@ sidebarTitle: "Get mint details"
icon: "file-circle-info"
---
+import MintManagerDeprecated from '/snippets/mint-manager-deprecated.mdx';
+
+
+
Use `getMintDetails` to check whether a wallet can mint a subname and to retrieve the estimated price and fee.
diff --git a/developer-guide/sdks/mint-manager/get-mint-transaction-parameters.mdx b/developer-guide/sdks/mint-manager/get-mint-transaction-parameters.mdx
index c06fe21..d0c9dda 100644
--- a/developer-guide/sdks/mint-manager/get-mint-transaction-parameters.mdx
+++ b/developer-guide/sdks/mint-manager/get-mint-transaction-parameters.mdx
@@ -5,6 +5,10 @@ sidebarTitle: "Transaction parameters"
icon: "list-check"
---
+import MintManagerDeprecated from '/snippets/mint-manager-deprecated.mdx';
+
+
+
`prepareMint` returns the contract address, ABI, arguments, and value required to mint a subname. Submit the result with viem, ethers, or wagmi; the SDK never holds a key and never sends a transaction.
### Usage
diff --git a/developer-guide/sdks/mint-manager/installation.mdx b/developer-guide/sdks/mint-manager/installation.mdx
index 43fde77..5003c97 100644
--- a/developer-guide/sdks/mint-manager/installation.mdx
+++ b/developer-guide/sdks/mint-manager/installation.mdx
@@ -5,6 +5,10 @@ sidebarTitle: "Installation"
icon: "download"
---
+import MintManagerDeprecated from '/snippets/mint-manager-deprecated.mdx';
+
+
+
Install the required packages, depending on your package manager:
diff --git a/developer-guide/sdks/mint-manager/is-subname-available.mdx b/developer-guide/sdks/mint-manager/is-subname-available.mdx
index 2129861..44d8f2f 100644
--- a/developer-guide/sdks/mint-manager/is-subname-available.mdx
+++ b/developer-guide/sdks/mint-manager/is-subname-available.mdx
@@ -5,6 +5,10 @@ sidebarTitle: "Subname availability"
icon: "magnifying-glass"
---
+import MintManagerDeprecated from '/snippets/mint-manager-deprecated.mdx';
+
+
+
`isL1SubnameAvailable` and `isL2SubnameAvailable` report raw registry ownership. Use the method that matches the parent name's listing: `isL1SubnameAvailable` for Ethereum, or `isL2SubnameAvailable` for an L2 chain.
diff --git a/developer-guide/sdks/mint-manager/normalization.mdx b/developer-guide/sdks/mint-manager/normalization.mdx
index 70ccc85..fac5f76 100644
--- a/developer-guide/sdks/mint-manager/normalization.mdx
+++ b/developer-guide/sdks/mint-manager/normalization.mdx
@@ -5,6 +5,10 @@ sidebarTitle: "Normalization"
icon: "text-cursor-input"
---
+import MintManagerDeprecated from '/snippets/mint-manager-deprecated.mdx';
+
+
+
Every name and label you pass to the SDK is normalized per [ENSIP-15](https://docs.ens.domains/ensip/15) before it is hashed, sent to the API, or compared.
Viem's `namehash()` does not normalize. Skip this step and `Alice.eth` and `alice.eth` hash to different nodes, so an availability check can report a registered name as free.
diff --git a/developer-guide/sdks/offchain-manager.mdx b/developer-guide/sdks/offchain-manager.mdx
index ed811e0..395d602 100644
--- a/developer-guide/sdks/offchain-manager.mdx
+++ b/developer-guide/sdks/offchain-manager.mdx
@@ -6,6 +6,8 @@ icon: "eye"
The Offchain Manager SDK is a TypeScript library for managing offchain subnames, text records, and data records in an ENS system with gasless operations.
+Namespace stores the subnames you create with the SDK. ENS clients resolve them through [CCIP Read](https://docs.ens.domains/resolvers/ccip-read), and creating or updating them needs no onchain transaction.
+
Install the offchain ENS subname skill to give your AI coding agent full SDK context automatically.
diff --git a/developer-guide/sdks/offchain-manager/installation.mdx b/developer-guide/sdks/offchain-manager/installation.mdx
index 50a5fed..1706e5a 100644
--- a/developer-guide/sdks/offchain-manager/installation.mdx
+++ b/developer-guide/sdks/offchain-manager/installation.mdx
@@ -5,7 +5,7 @@ sidebarTitle: "Installation"
icon: "download"
---
-Install the Offchain SDK using your preferred package manager:
+Install the Offchain SDK using your preferred package manager. This page covers `@thenamespace/offchain-manager` 1.1.3, the latest release. See the [Offchain SDK changelog](/changelog/offchain-sdk) for earlier versions.
@@ -88,3 +88,7 @@ const client = createOffchainClient({
- `timeout`: Request timeout in milliseconds (optional)
- `defaultApiKey`: Address-based API key for all domains registered to your address
- `domainApiKeys`: Object mapping specific ENS domains to their API keys
+- `customHeaders`: HTTP headers sent with every request, such as a trace ID (optional). You can also set them later with `client.setCustomHeaders(headers)`. The API key travels in the `x-auth-token` header, so an `x-auth-token` value here replaces it.
+- `backendUri`: Custom backend URL (optional). Defaults to the Namespace API for the selected `mode`.
+
+The config also accepts [Axios request options](https://axios-http.com/docs/req_config), which is where `timeout` comes from.
diff --git a/developer-guide/skills.mdx b/developer-guide/skills.mdx
index 250d81e..1064a53 100644
--- a/developer-guide/skills.mdx
+++ b/developer-guide/skills.mdx
@@ -5,86 +5,101 @@ sidebarTitle: "Skills"
icon: "scroll"
---
-Skills are installable context packages for AI coding tools. They give tools like Cursor, Claude Code, and GitHub Copilot the details they need about a specific Namespace SDK or UI library, including APIs, common patterns, and examples. Once a skill is installed, you do not need to keep re-explaining the same integration in every chat.
+Skills are instruction packages for AI coding agents. Each one gives your agent the APIs, patterns, and examples for one Namespace SDK, API, or ENS task, so you do not have to explain the same integration in every chat.
-### Offchain ENS Subname SDK skill
+The skills live in the [thenamespace/skills](https://github.com/thenamespace/skills) repository and follow the [Agent Skills specification](https://agentskills.io/specification). Check your coding tool's documentation to confirm that it loads Agent Skills.
-The `offchain-ens-subname-sdk` skill gives your agent the context it needs to work with the Namespace Offchain Manager SDK. It includes examples and common workflows for creating, managing, and resolving offchain ENS subnames.
+## Install skills
-**Install in your project:**
+Install every skill at once:
+
+```bash
+npx skills add thenamespace/skills --yes
+```
+
+Or install one skill with the `-s` flag:
```bash
npx skills add thenamespace/skills -s offchain-ens-subname-sdk
```
-Once installed, your AI agent can:
-- Generate code for creating offchain subnames from a prompt
-- Suggest the right SDK methods, types, and parameters
-- Answer SDK questions without digging through the docs
+## Which skill to use
-### ENS components skill
+| Scenario | Skill |
+| --- | --- |
+| Integrate, debug, or audit ENS in your app | `ens` |
+| Issue gasless offchain subnames to your users | `offchain-ens-subname-sdk` |
+| Register a `*.celo.eth` name onchain from an agent | `celonames` |
+| Resolve ENS profiles and addresses over HTTP | `resolvio` |
+| Add React components for ENS registration, records, or subnames | `ens-components` |
+| Upload, update, or delete ENS avatar and header images | `avatar-sdk` |
-The `ens-components` skill helps your agent build ENS flows in React with `@thenamespace/ens-components`. It covers name registration, record management, subname minting, avatar uploads, and theming.
+### ENS skill
-**Install in your project:**
+The `ens` skill is a vendor-neutral guide to the ENS protocol for app developers, auditors, and AI agent builders. It covers ENSIP-15 normalization, forward and reverse resolution, CCIP Read, multichain coin types, L2 primary names (ENSIP-19), records, subnames, smart contract naming, subgraph queries, ENSv2 readiness, and AI agent identity.
```bash
-npx skills add thenamespace/skills -s ens-components
+npx skills add thenamespace/skills -s ens
```
-Once installed, your AI agent can:
-- Scaffold React flows for name registration, record management, and subname minting
-- Choose the right component for the job, including `EnsNameRegistrationForm`, `EnsRecordsForm`, `SelectRecordsForm`, `SubnameMintForm`, and `OffchainSubnameForm`
+The repository recommends viem 2.35 or later with wagmi. ethers v6 is also supported. No API key is needed.
-### Resolvio ENS resolution skill
+### Offchain ENS subname SDK skill
+
+The `offchain-ens-subname-sdk` skill covers the [Offchain Manager SDK](/developer-guide/sdks/offchain-manager) (`@thenamespace/offchain-manager`). Your agent can use it to create and manage gasless subnames under `.eth` names, imported web2 domains, and alternative TLDs.
+
+```bash
+npx skills add thenamespace/skills -s offchain-ens-subname-sdk
+```
+
+You need an [API key](/developer-guide/sdks/offchain-manager/generate-api-key) for write operations.
+
+### Celo Names skill
+
+The `celonames` skill covers registering, renewing, and managing Celo Names (`*.celo.eth`) through the L2Registrar contract on Celo mainnet. Names are ERC-721 NFTs on Celo and resolve from Ethereum through CCIP Read.
-The `resolvio` skill gives your agent the context it needs to use the Resolvio ENS Resolution API for forward lookups, reverse lookups, profile reads, text records, and contenthash retrieval.
+```bash
+npx skills add thenamespace/skills -s celonames
+```
+
+The agent needs a wallet with CELO or stablecoins and access to a Celo RPC such as `https://forno.celo.org`.
+
+### Resolvio ENS resolution skill
-**Install in your project:**
+The `resolvio` skill covers the [Resolvio](/user-guide/resolvio) ENS Resolution API: forward and reverse lookups, full profile reads (texts, addresses, and contenthash), and batch reverse resolution for tables and leaderboards.
```bash
npx skills add thenamespace/skills -s resolvio
```
-Once installed, your AI agent can:
-- Resolve ENS names to addresses on supported chains
-- Reverse resolve wallet addresses to ENS names
-- Fetch full ENS profiles, including texts, addresses, and contenthash, in one request
-- Use bulk endpoints for tables, leaderboards, and multi-row UI data
+No API key is needed. The examples use `curl`.
-### Avatar SDK skill
+### ENS components skill
-The `avatar-sdk` skill gives your agent the context it needs to manage ENS avatar and header images with the `@thenamespace/avatar` SDK. It covers SIWE v4 authentication, automatic and manual signing flows, and the Metadata Service profile media routes.
+The `ens-components` skill helps your agent build ENS flows in React with [`@thenamespace/ens-components`](/developer-guide/sdks/ens-components). It covers name registration and renewal, record editing, onchain and offchain subname minting, avatar and header uploads, theming, and callback-driven customization. Every form runs on ENSv2 by default. The skill passes `version={1}` to `SubnameMintForm` only when the parent has an existing Namespace listing.
-**Install in your project:**
+```bash
+npx skills add thenamespace/skills -s ens-components
+```
+
+### Avatar SDK skill
+
+The `avatar-sdk` skill covers uploading, updating, and deleting ENS avatar and header images with the [Avatar SDK](/developer-guide/sdks/avatar) (`@thenamespace/avatar`). It includes SIWE v4 authentication, automatic and manual signing flows, network enforcement, and direct use of a Viem, Ethers, wagmi, or custom `WalletProvider`. It works with EOAs and deployed smart contract wallets.
```bash
npx skills add thenamespace/skills -s avatar-sdk
```
-Once installed, your AI agent can:
-- Upload and delete avatar and header images for ENS subnames
-- Wire up a Viem, Ethers, or wagmi wallet as the signing provider with no adapters
-- Use the manual SIWE flow for server-side or custom signing
-- Enforce the correct network and handle SDK error codes
+## Legacy skills
### Mint Manager SDK skill
-The `mint-manager-sdk` skill is the agent instructions for minting onchain ENS subnames with `@thenamespace/mint-manager`. It includes the check-then-mint flow, setting records at mint time, and the `MintManagerError` codes.
+
+ The [Mint Manager SDK](/developer-guide/sdks/mint-manager) is deprecated. Install this skill only to mint under an existing onchain listing on an ENSv1 name.
+
-**Install in your project:**
+The `mint-manager-sdk` skill covers minting onchain subnames on Ethereum, Base, and Optimism with `@thenamespace/mint-manager`, including `checkName`, records at mint time, `maxValue` price caps, and `MintManagerError` codes.
```bash
npx skills add thenamespace/skills -s mint-manager-sdk
```
-
-Once installed, your AI agent can:
-- Check availability, price, and mint eligibility in a single `checkName` call
-- Build, simulate, and submit the mint transaction on Ethereum, Base, or Optimism
-- Apply text, address, and contenthash records in the same transaction as the mint
-- Tell a name obstacle from a minter obstacle, so a gated wallet is not sent back to the name field
-- Cap the price with `maxValue` and handle `MintManagerError` codes
-
-
- Skills work with any AI coding tool that supports agent context, including Cursor, Claude Code, and GitHub Copilot.
-
diff --git a/developer-guide/troubleshooting.mdx b/developer-guide/troubleshooting.mdx
index 3cb93a5..b1e754a 100644
--- a/developer-guide/troubleshooting.mdx
+++ b/developer-guide/troubleshooting.mdx
@@ -5,118 +5,193 @@ sidebarTitle: "Troubleshooting"
icon: "screwdriver-wrench"
---
-Use this page when a Namespace integration fails during setup, subname creation, minting, or resolution. Start with the error category below, then confirm your environment and request parameters.
+Find the symptom you're seeing below. Each entry gives the likely cause, a short fix, and the page with the full details.
-## Before you troubleshoot
+Before you dig in, rule out the usual suspects:
-Check these basics first:
+- The client's network matches the parent name. Use `mode: 'sepolia'` or `isTestnet` for testnet names, and mainnet settings for mainnet names.
+- The package version in your project matches the version these docs use.
+- API keys and private keys are loaded from server-side environment variables.
-- Use a supported Node.js version. The documentation examples and repository use Node.js 22.
-- Confirm the package version in your project matches the version documented in `package.json`.
-- Use Sepolia or another supported testnet while developing.
-- Keep API keys and wallet private keys in server-side environment variables.
-- Confirm the parent ENS name is configured for the operation you are attempting.
+## Offchain subnames
-## Authentication errors
+### An offchain subname doesn't resolve
-### `401` or `403` from the Offchain API
+**Likely cause:** the parent name isn't using the Namespace resolver, or the app reading the name doesn't support CCIP Read.
-The API key is missing, expired, or does not authorize the parent name.
+1. In the [Namespace App](https://app.namespace.ninja/offchain), open **Offchain**, select the parent name, and open **Resolution**. Click **Update resolver**, then **Configure**, until the status reads **Configured**.
+2. Look the name up with [Resolvio](/user-guide/resolvio). If it resolves there, the problem is in the consuming app.
+3. Confirm the consuming wallet or library supports CCIP Read. Offchain subnames don't support reverse resolution, so looking up a name from an address won't return them.
-1. Generate or copy the key in the [Namespace App](/user-guide/dev-portal#create-an-api-key).
-2. Confirm your server loaded `NAMESPACE_API_KEY`.
-3. Use an address-based key as `defaultApiKey`, or map a domain-based key to the exact parent name.
-4. Do not expose the key in browser code or commit it to source control.
+See [Configure the resolver](/user-guide/dev-portal#configure-the-resolver).
-```typescript
-import { createOffchainClient } from '@thenamespace/offchain-manager';
+### Subnames stopped resolving after an ENSv2 upgrade
-const apiKey = process.env.NAMESPACE_API_KEY;
-if (!apiKey) throw new Error('Missing NAMESPACE_API_KEY');
+**Likely cause:** upgrading a name to ENSv2 resets its resolver.
-const client = createOffchainClient({
- mode: 'sepolia',
- defaultApiKey: apiKey,
-});
-```
+1. Open the name in the Namespace App, go to **Offchain** > **Resolution**, and set the Namespace resolver again with **Update resolver** and **Configure**.
+2. Check that the status reads **Configured**.
-## Subname creation errors
+Your existing subnames and SDK code don't need to change. See [Namespace ENSv2 migration](/overview/ensv2#upgrade-to-ensv2-in-the-namespace-app).
-### The subname already exists
+### `401` from the Offchain API
-Call `isSubnameAvailable` and await the result before creating a subname:
+**Likely cause:** the API key is missing, expired, revoked, or scoped to a different parent name. The API returns `401` with "Missing or invalid API key".
-```typescript
-const { isAvailable } = await client.isSubnameAvailable(
- 'alice.example.eth',
-);
+1. Check that your server loads the key and sends it. The REST API expects it in the `x-auth-token` header. The SDK takes it as `defaultApiKey` or in `domainApiKeys`.
+2. Check the key's scope. A domain-based key only works for the parent name it was created for. An address-based key works for every name the creating wallet owns.
+3. If the key has expired or you've lost it, [create a new key](/user-guide/dev-portal#create-an-api-key).
+
+See [API key setup](/developer-guide/sdks/offchain-manager/generate-api-key) and the [API overview](/api-reference/introduction).
+
+### Subname already exists or is unavailable
+
+**Likely cause:** the label is already registered under the parent. Creating it again returns `409` "Subname already exists" from the API.
-if (!isAvailable) {
- throw new Error('alice.example.eth is already registered');
+1. Call `isSubnameAvailable` before `createSubname`.
+2. To change an existing subname, call `updateSubname` instead of creating it again.
+
+```typescript
+const { isAvailable } = await client.isSubnameAvailable('alice.example.eth');
+
+if (isAvailable) {
+ await client.createSubname({ parentName: 'example.eth', label: 'alice' });
+} else {
+ await client.updateSubname('alice.example.eth', {
+ texts: [{ key: 'name', value: 'Alice' }],
+ });
}
```
-If your product intentionally updates existing subnames, call `updateSubname` explicitly instead of relying on create behavior.
+See [Check subname availability](/developer-guide/sdks/offchain-manager/is-subname-available).
-### Records fail validation
+### Can't create more subnames under a parent
-- Use a complete, valid address for the selected `ChainName`.
-- Use the label only in `label`; do not pass the full subname.
-- Pass the parent separately in `parentName`.
-- Follow [ENSIP-15](https://docs.ens.domains/ensip/15/) normalization rules for labels.
+**Likely cause:** you've reached the limit of 2,000 subnames per parent name.
-## Minting errors
+1. Ask for a higher limit in the [Namespace Builders group](https://t.me/+5FAwyiKOTeswNTIy).
-### `canMint` is false
+See [Offchain subnames](/user-guide/dev-portal).
-Inspect `validationErrors` from `getMintDetails`. Common causes include an unavailable label, a missing whitelist entry, a reserved name, or a wallet that does not meet the listing rules.
+## Records
-```typescript
-const details = await mintClient.getMintDetails({
- parentName: 'example.eth',
- label: 'alice',
- minterAddress: account.address,
-});
-
-if (!details.canMint) {
- throw new Error(details.validationErrors.join(', '));
-}
-```
+### Records don't show in wallets or apps
+
+**Likely cause:** the record was saved under a different chain or key than the app reads, or the app shows cached data.
+
+1. Fetch the subname with `getSingleSubname` and check the stored records.
+2. Check address records use the right [`ChainName`](/developer-guide/sdks/offchain-manager/chainname). To set one EVM address on every supported EVM chain, use [`setDefaultEvmAddress`](/developer-guide/sdks/offchain-manager/set-default-evm-address).
+3. Check text record keys match what the app reads, such as `description`. Keys are case-sensitive.
+
+If you read through Resolvio, [clear the name's cache](/api-reference/resolvio/clear-ens-cache) before reading again.
+
+### Creating a subname fails validation
+
+**Likely cause:** the label or address is malformed.
+
+1. Pass only the label in `label` and the parent in `parentName`, not the full subname.
+2. Use a complete, valid address for each `ChainName`.
+3. Follow [ENSIP-15](https://docs.ens.domains/ensip/15/) normalization for labels.
+
+See [Create or update a subname](/developer-guide/sdks/offchain-manager/create-update-subname).
+
+## Onchain subnames (ENSv2)
+
+### An onchain mint fails or the label can't be minted
+
+**Likely cause:** one of the listing's rules blocks this label or wallet. Onchain subnames are minted on Ethereum (L1) under a name activated in the Namespace App.
+
+Check the listing in [Configure pricing and rules](/user-guide/app#configure-pricing-and-rules):
+
+1. **Price**: type the label into **Price check** to see what it costs. A [reservation](/user-guide/app#reservations) can block the label or give it a custom price.
+2. **Who can mint**: with a [whitelist](/user-guide/app#whitelist) in **Gate** mode, only listed wallets can mint. With [token gating](/user-guide/app#token-gated), the wallet must hold the minimum balance of the listed tokens.
+3. **When**: minting only works inside the [mint window](/user-guide/app#mint-window), if one is set.
+
+Labels that are already minted show as taken. Pick another label.
+
+### Mint is blocked with "Insufficient funds"
+
+**Likely cause:** the wallet doesn't hold enough of the payment token or ETH. Onchain subnames are paid in USDC or DAI, and network fees are paid in ETH. The ENS Components forms block the transaction with "Insufficient funds" when the wallet can't pay.
+
+1. Add USDC or DAI to cover the price, and pick that token in the mint form.
+2. Add ETH to cover network fees.
+
+See [Mint onchain subnames](/developer-guide/sdks/ens-components/mint-subnames).
+
+## ENS Components
+
+### Forms render unstyled
+
+**Likely cause:** the stylesheet isn't imported.
+
+1. Import it once at the root of your app: `import '@thenamespace/ens-components/styles.css';`
+
+See [Import the styles](/developer-guide/sdks/ens-components/installation#import-the-styles).
+
+### Forms throw provider or wallet errors
+
+**Likely cause:** the forms aren't wrapped in the wagmi and React Query providers, a chain is missing from the wagmi config, or the forms render on the server.
+
+1. Wrap your app in `WagmiProvider` and `QueryClientProvider`.
+2. Add every chain you use to the wagmi config: `mainnet`, plus `sepolia` if you use `isTestnet`. Minting under an ENSv1 listing can also need Base or Optimism.
+3. In Next.js and other SSR frameworks, render the forms and providers in client components (`'use client'`).
+
+Pass `onConnectWallet` to the forms so a disconnected user can connect. See [Install ENS Components](/developer-guide/sdks/ens-components/installation).
+
+### `SubnameMintForm` doesn't work for your parent name
+
+**Likely cause:** the parent has no ENSv2 activation, or it's an ENSv1 listing.
+
+1. [Activate the name](/user-guide/app#activate-your-ens-name) in the Namespace App.
+2. For a parent listed before ENSv2, pass `version={1}`.
+
+See [Mint under an old Namespace listing](/developer-guide/sdks/ens-components/mint-subnames#mint-under-an-old-namespace-listing).
+
+### `OffchainSubnameForm` shows success but no subname is created
+
+**Likely cause:** the form only reads from Namespace. It never writes the subname itself.
+
+1. Pass `onSubnameCreated` and `onSubnameUpdated` callbacks that send the subname to your server.
+2. On your server, write it with an Offchain Manager client that holds the API key.
+
+See [Create offchain subnames](/developer-guide/sdks/ens-components/offchain-subnames).
+
+## Rate limits
+
+### Requests fail intermittently or get rate limited
+
+**Likely cause:** you're using a shared public RPC endpoint. `http()` with no URL in wagmi uses the chain's public RPC, which is rate limited.
-### The transaction simulation fails
+1. Pass your own RPC URL for each chain in production.
+2. Retry transient failures, such as `5xx` responses, with bounded exponential backoff.
-Confirm all of the following:
+See [Set up providers](/developer-guide/sdks/ens-components/installation#set-up-providers).
-- The wallet client and public client use the same chain.
-- The parent name is activated and listed for that chain.
-- The wallet has enough native currency for the mint price and gas.
-- You pass the `value` returned by `getMintTransactionParameters` unchanged.
-- You generated the transaction parameters immediately before simulation so price and signature data are current.
+## ENSv1 listings (deprecated)
-## Resolution errors
+
+ Mint Manager, Indexer Manager, and the Mint API are deprecated. They only work with onchain listings on ENSv1 names. For new names, use [ENSv2 onchain subnames](/user-guide/app) and [`SubnameMintForm`](/developer-guide/sdks/ens-components/mint-subnames).
+
-### An offchain subname does not resolve
+### `checkName` returns `taken` or `blocked`
-1. Confirm the subname exists in the Namespace App.
-2. Confirm the parent name uses the Namespace Hybrid resolver.
-3. Check that the consuming wallet or app supports CCIP Read.
-4. Test the name through [Resolvio](/user-guide/resolvio) to separate resolver issues from client integration issues.
+`taken` means the label is registered, so offer a different one. `blocked` means the label is free but this wallet can't mint it. Read `reasons`, such as `MINTER_NOT_WHITELISTED`, `MINTER_NOT_TOKEN_OWNER`, or `LISTING_EXPIRED`. See [Check a name before you mint](/developer-guide/sdks/mint-manager/check-name).
-### An address or text record is missing
+### Mint Manager throws `MintManagerError`
-Fetch the subname directly and inspect its stored records. Make sure you used the correct chain and text-record key. Record keys are case-sensitive.
+Branch on `error.code`:
-## Network and RPC errors
+- `RPC_ERROR`: a registry read failed, so the name's status is unknown. Retry, and pass your own endpoints in `customRpcUrls`.
+- `LISTING_NOT_FOUND`: no listing exists for the parent on this network. Check `isTestnet` and the spelling.
+- `PRICE_EXCEEDS_MAX`: the quote went over your `maxValue` and nothing was submitted. Re-quote, then raise the cap or show the new price.
+- `SIGNATURE_EXPIRED`: the mint authorization expired. Call `prepareMint` again and submit promptly.
-- Confirm the RPC endpoint supports the chain used by the wallet and public clients.
-- Check the provider dashboard for rate limiting or an invalid token.
-- Avoid mixing mainnet parent names with testnet configuration.
-- Retry transient `429` and `5xx` errors with bounded exponential backoff.
+See [Error handling](/developer-guide/sdks/mint-manager/errors) for every code.
## Get more help
-When asking for support, include the SDK package and version, network, parent name, method name, and complete error message. Remove API keys, RPC tokens, wallet private keys, and other secrets.
+When you ask for support, include the package and version, network, parent name, method name, and the full error message. Remove API keys, RPC tokens, private keys, and other secrets first.
- Ask an integration question and include the non-sensitive diagnostic details listed above.
+ Ask an integration question and include the details listed above.
diff --git a/docs.json b/docs.json
index b50817c..b6e2eb5 100644
--- a/docs.json
+++ b/docs.json
@@ -17,6 +17,10 @@
}
},
"favicon": "/favicon.ico",
+ "banner": {
+ "content": "ENSv2 is live. [Read the migration guide](/overview/ensv2)",
+ "dismissible": true
+ },
"integrations": {
"posthog": {
"apiKey": "phc_m34ZAW7cLSFC3o4eipnrMG3GONeV40GXARnD3bJCap7"
@@ -34,6 +38,7 @@
"group": "Start here",
"pages": [
"getting-started",
+ "overview/ensv2",
"learn-more",
"overview/subnames"
]
@@ -143,30 +148,6 @@
"developer-guide/sdks/offchain-manager/data-records"
]
},
- {
- "group": "Mint Manager",
- "icon": "gauge",
- "pages": [
- "developer-guide/sdks/mint-manager",
- "developer-guide/sdks/mint-manager/installation",
- "developer-guide/sdks/mint-manager/check-name",
- "developer-guide/sdks/mint-manager/get-mint-transaction-parameters",
- "developer-guide/sdks/mint-manager/normalization",
- "developer-guide/sdks/mint-manager/errors",
- "developer-guide/sdks/mint-manager/is-subname-available",
- "developer-guide/sdks/mint-manager/get-mint-details"
- ]
- },
- {
- "group": "Indexer Manager",
- "icon": "database",
- "pages": [
- "developer-guide/sdks/indexer-manager",
- "developer-guide/sdks/indexer-manager/installation",
- "developer-guide/sdks/indexer-manager/fetch-l2-subnames",
- "developer-guide/sdks/indexer-manager/fetch-l2-registries"
- ]
- },
{
"group": "Avatar",
"icon": "image",
@@ -183,7 +164,50 @@
"group": "ENS Components",
"icon": "puzzle-piece",
"pages": [
- "developer-guide/sdks/ens-components"
+ "developer-guide/sdks/ens-components",
+ "developer-guide/sdks/ens-components/installation",
+ "developer-guide/sdks/ens-components/register-names",
+ "developer-guide/sdks/ens-components/renew-names",
+ "developer-guide/sdks/ens-components/edit-records",
+ "developer-guide/sdks/ens-components/mint-subnames",
+ "developer-guide/sdks/ens-components/renew-subnames",
+ "developer-guide/sdks/ens-components/offchain-subnames",
+ "developer-guide/sdks/ens-components/transaction-progress",
+ "developer-guide/sdks/ens-components/hooks",
+ "developer-guide/sdks/ens-components/theming",
+ "developer-guide/sdks/ens-components/upgrade"
+ ]
+ },
+ {
+ "group": "Legacy (ENSv1)",
+ "icon": "box-archive",
+ "pages": [
+ {
+ "group": "Mint Manager",
+ "tag": "Deprecated",
+ "icon": "gauge",
+ "pages": [
+ "developer-guide/sdks/mint-manager",
+ "developer-guide/sdks/mint-manager/installation",
+ "developer-guide/sdks/mint-manager/check-name",
+ "developer-guide/sdks/mint-manager/get-mint-transaction-parameters",
+ "developer-guide/sdks/mint-manager/normalization",
+ "developer-guide/sdks/mint-manager/errors",
+ "developer-guide/sdks/mint-manager/is-subname-available",
+ "developer-guide/sdks/mint-manager/get-mint-details"
+ ]
+ },
+ {
+ "group": "Indexer Manager",
+ "tag": "Deprecated",
+ "icon": "database",
+ "pages": [
+ "developer-guide/sdks/indexer-manager",
+ "developer-guide/sdks/indexer-manager/installation",
+ "developer-guide/sdks/indexer-manager/fetch-l2-subnames",
+ "developer-guide/sdks/indexer-manager/fetch-l2-registries"
+ ]
+ }
]
}
]
@@ -203,14 +227,6 @@
"api-reference/offchain-manager/delete-a-subname"
]
},
- {
- "group": "Mint API",
- "icon": "gauge",
- "pages": [
- "api-reference/mint-manager/estimate-mint-params",
- "api-reference/mint-manager/generate-mint-params"
- ]
- },
{
"group": "Resolvio API",
"icon": "magnifying-glass",
@@ -226,6 +242,21 @@
"api-reference/resolvio/get-ens-contenthash",
"api-reference/resolvio/clear-ens-cache"
]
+ },
+ {
+ "group": "Legacy (ENSv1)",
+ "icon": "box-archive",
+ "pages": [
+ {
+ "group": "Mint API",
+ "tag": "Deprecated",
+ "icon": "gauge",
+ "pages": [
+ "api-reference/mint-manager/estimate-mint-params",
+ "api-reference/mint-manager/generate-mint-params"
+ ]
+ }
+ ]
}
]
}
@@ -243,11 +274,11 @@
"tab": "Changelog",
"pages": [
"changelog/offchain-sdk",
+ "changelog/avatar-sdk",
+ "changelog/ens-components",
"changelog/address-sdk",
- "changelog/indexer-sdk",
"changelog/mint-sdk",
- "changelog/avatar-sdk",
- "changelog/ens-components"
+ "changelog/indexer-sdk"
]
}
],
@@ -532,6 +563,10 @@
"source": "/user-guide/overview",
"destination": "/getting-started"
},
+ {
+ "source": "/user-guide/app/ensv1",
+ "destination": "/user-guide/app"
+ },
{
"source": "/user-guide/app/wizard",
"destination": "/user-guide/app"
diff --git a/getting-started.mdx b/getting-started.mdx
index 2fb9021..5d95560 100644
--- a/getting-started.mdx
+++ b/getting-started.mdx
@@ -8,18 +8,21 @@ icon: "hand-wave"
[Namespace](https://namespace.ninja/) is the infrastructure for issuing ENS subnames. We provide no-code apps, APIs, and SDKs for issuing and managing ENS subnames, so developers can give every user, agent, or resource a name of its own.
+
+ ENSv2 is live on Ethereum mainnet. See [ENSv2 and Namespace](/overview/ensv2) for what works with your name.
+
+
### Choose where subnames live
-Subnames can be issued on Ethereum, on an L2 chain, or through an offchain service. All 3 work the same, but they differ in cost, control, and ownership.
+You can issue subnames onchain on Ethereum or offchain, where Namespace stores them. Both work the same in ENS apps, but they differ in cost, control, and ownership.
| Model | Best for | Cost to issue | Ownership model |
| --- | --- | --- | --- |
-| Offchain | High-volume onboarding and application-managed identities | No blockchain transaction | The parent-name operator manages records |
-| L2 (Base, Optimism) | Lower-cost NFT ownership on a supported L2 | L2 transaction and mint price | The minted subname is held by its owner |
+| Offchain | High-volume onboarding and application-managed identities | No blockchain transaction | Namespace stores the subname; the parent-name owner manages its records |
| Ethereum (L1) | Lower-volume, Ethereum-native ownership | Ethereum transaction and mint price | The minted subname is held by its owner |
- Start with offchain subnames when you need gasless, high-volume issuance. Choose Ethereum or an L2 chain when holding the subname as an onchain asset is a product requirement.
+ Start with offchain subnames when you need gasless, high-volume issuance. Choose onchain subnames on Ethereum when holding the subname as an onchain asset is a product requirement.
## Choose your path
@@ -40,7 +43,7 @@ Subnames can be issued on Ethereum, on an L2 chain, or through an offchain servi
- Compare Ethereum, L2, and offchain subnames in more detail.
+ Compare onchain and offchain subnames in more detail.
Learn how Namespace products fit into the ENS ecosystem.
diff --git a/learn-more.mdx b/learn-more.mdx
index d79427d..a1078bb 100644
--- a/learn-more.mdx
+++ b/learn-more.mdx
@@ -11,12 +11,12 @@ Funded by the ENS DAO to put ENS names in the hands of millions of users. Namesp
Namespace helps product teams and ENS name owners issue and manage subnames through:
- The [Namespace App](/user-guide/app) for issuing and managing subnames without coding.
- - [Onchain subnames](https://app.namespace.ninja/onchain): mint subnames as NFTs on Ethereum or an L2.
+ - [Onchain subnames](https://app.namespace.ninja/onchain): mint subnames as NFTs on Ethereum.
- [Offchain subnames](https://app.namespace.ninja/offchain): issue gasless subnames.
- [Offchain tools](/user-guide/dev-portal) for resolver configuration, API keys, and gasless subname records.
-- [TypeScript SDKs](/developer-guide/sdks/introduction) for offchain management, mint preparation, and indexed data.
+- [TypeScript SDKs](/developer-guide/sdks/introduction) for offchain subnames, avatar uploads, and ENS interfaces in React.
- [REST APIs](/api-reference/introduction) for hosted subname and ENS-resolution workflows.
-- [ENS Components](/user-guide/ens-components) and [ENS Widget](/user-guide/ens-widget) for ready-made user interfaces.
+- [ENS Components](/user-guide/ens-components) for ready-made user interfaces.
- [Resolvio](https://www.resolvio.xyz/), a universal ENS resolution API with one endpoint for forward, reverse, and offchain lookups.
- [ENS Diamonds](https://ens.diamonds), an app to pool ETH with others and co-own premium `.eth` names during their expiry auction.
@@ -42,7 +42,7 @@ If you are interested in partnering, [contact the Namespace team](https://t.me/+
## Current usage
- View current subname, registry, widget, and resolution activity.
+ View current subname, registry, and resolution activity.
## Official links
diff --git a/openapi/mint-openapi.json b/openapi/mint-openapi.json
index c79b724..38a0037 100644
--- a/openapi/mint-openapi.json
+++ b/openapi/mint-openapi.json
@@ -103,7 +103,8 @@
}
},
"summary": "Estimate mint params",
- "tags": ["Mint Manager"]
+ "tags": ["Mint Manager"],
+ "deprecated": true
}
},
"/api/v1/mint": {
@@ -175,7 +176,8 @@
}
},
"summary": "Generate mint params",
- "tags": ["Mint Manager"]
+ "tags": ["Mint Manager"],
+ "deprecated": true
}
}
},
diff --git a/overview/ensv2.mdx b/overview/ensv2.mdx
new file mode 100644
index 0000000..35bf81b
--- /dev/null
+++ b/overview/ensv2.mdx
@@ -0,0 +1,62 @@
+---
+title: "Namespace ENSv2 migration"
+description: "What ENSv2 changes for your names and subnames."
+sidebarTitle: "ENSv2 migration"
+icon: "bolt"
+tag: "New"
+---
+
+## What is ENSv2?
+
+[ENSv2](https://ens.domains/blog/post/ensv2-live-on-mainnet) is the new version of ENS, now live on Ethereum mainnet. New `.eth` names are registered on ENSv2. Names registered before it are ENSv1 names, and they keep resolving. See the [ENSv2 overview](https://docs.ens.domains/ensv2/overview) in the ENS docs.
+
+## Do I need to do anything for my existing offchain subnames?
+
+No. Offchain subnames work with ENSv1 and ENSv2 names. Namespace stores them and their records, and ENS clients resolve them through CCIP Read.
+
+## What happens if I upgrade my name to ENSv2?
+
+Upgrading resets the name's resolver. If the name has offchain subnames, [set the Namespace resolver again](/user-guide/dev-portal#configure-the-resolver) so they keep resolving. Your subnames, API keys, and SDK code don't change.
+
+## Do my onchain listings move to ENSv2?
+
+No. Listings on ENSv1 names stay on ENSv1, keep working, and can still be edited. See [ENSv1 listings](/user-guide/app#ensv1-deprecated) in the Namespace App guide.
+
+## I'm using Mint Manager, Indexer Manager, or the Mint API. What now?
+
+They're deprecated. They keep working for existing ENSv1 listings but don't support ENSv2 names. See [Mint Manager](/developer-guide/sdks/mint-manager), [Indexer Manager](/developer-guide/sdks/indexer-manager), and the [Mint API reference](/api-reference/mint-manager/estimate-mint-params).
+
+## Which products work with ENSv2?
+
+| Product | ENSv1 names | ENSv2 names |
+| --- | --- | --- |
+| [Offchain subnames](/user-guide/dev-portal) in the App, SDK, and API | Yes | Yes |
+| [Onchain subnames](/user-guide/app) in the Namespace App | Existing listings only | Yes, on Ethereum (L1) |
+| [Resolvio](/user-guide/resolvio) | Yes | Yes |
+| [ENS Widget](/user-guide/ens-widget) and [Subpages](/user-guide/subpages) | Existing listings only | No |
+| Mint Manager, Indexer Manager, and the Mint API | Existing listings only | No |
+
+## What about L2 subnames?
+
+New L2 subnames are coming soon. Subnames already minted on Base and Optimism keep resolving, and their owners don't need to do anything.
+
+## Where do I start with a new name?
+
+Pick offchain subnames for gasless, high-volume issuance: use the [Namespace App](/user-guide/dev-portal), the [SDK](/developer-guide/guide/create-offchain-subnames), or the [API](/api-reference/introduction). Pick onchain subnames on Ethereum when users should own them: [activate your name](/user-guide/app#activate-your-ens-name) in the Namespace App.
+
+## Continue where you left off
+
+
+
+ Pick your first Namespace integration.
+
+
+ Go from API key to a resolved name with the SDK.
+
+
+ Configure the resolver and manage subnames in the Namespace App.
+
+
+ Activate your name and issue onchain subnames.
+
+
diff --git a/overview/for-fintechs-neobanks.mdx b/overview/for-fintechs-neobanks.mdx
index 07b79cf..00a1683 100644
--- a/overview/for-fintechs-neobanks.mdx
+++ b/overview/for-fintechs-neobanks.mdx
@@ -50,7 +50,7 @@ Give each customer a readable ENS name they can recognize and share instead of r
Resolve the entered name, then show the destination address and network before the customer confirms the transaction.
- Add onchain minting on Ethereum or an L2 chain when customers need to hold and transfer the subname as an onchain asset.
+ Add onchain minting on Ethereum when customers need to hold and transfer the subname as an onchain asset.
@@ -63,8 +63,8 @@ Give each customer a readable ENS name they can recognize and share instead of r
Add forward, reverse, profile, bulk, and multichain resolution.
-
- Prepare and submit onchain mint transactions on Ethereum or L2 chains.
+
+ Activate your name and issue onchain subnames on Ethereum.
Choose the integration surface that fits your backend.
diff --git a/overview/for-name-owners.mdx b/overview/for-name-owners.mdx
index a5ace6f..9dbb2b8 100644
--- a/overview/for-name-owners.mdx
+++ b/overview/for-name-owners.mdx
@@ -20,7 +20,7 @@ Buy `yourcommunity.eth` and issue a subname to every member, holder, or follower
## What you can do
-- Activate your ENS name and issue subnames on Ethereum Mainnet or an L2 chain
+- Activate your ENS name and issue onchain subnames on Ethereum Mainnet
- Set pricing, reservations, allowlists, or token gating
- Sell or gift subnames
- Reserve premium names or blocklist words
diff --git a/overview/for-product-teams.mdx b/overview/for-product-teams.mdx
index 7fd3a63..d933678 100644
--- a/overview/for-product-teams.mdx
+++ b/overview/for-product-teams.mdx
@@ -20,9 +20,8 @@ See [Use cases](/overview/use-cases) for more examples.
| Model | Choose it when | Main tradeoff |
| --- | --- | --- |
-| Offchain | You need gasless, high-volume issuance and application-managed records | The parent-name operator retains administrative control |
-| L2 | Users should hold subname NFTs and lower transaction cost matters | Requires a supported L2 transaction |
-| L1 | Ethereum-native ownership is required for a lower-volume flow | Higher transaction cost than L2 |
+| Offchain | You need gasless, high-volume issuance and application-managed records | Namespace stores the subnames, and the parent-name owner keeps control of them |
+| L1 | Users should hold their subnames as onchain assets | Each subname requires an Ethereum transaction |
Read [Learn about Subnames](/overview/subnames) for the architecture and ownership differences.
@@ -32,11 +31,11 @@ Read [Learn about Subnames](/overview/subnames) for the architecture and ownersh
Create gasless subnames and manage their records with TypeScript.
-
- Prepare and submit onchain mint transactions.
+
+ Activate your name and issue L1 subnames without code.
- Integrate the hosted Offchain, Mint, or Resolvio APIs.
+ Integrate the hosted Offchain or Resolvio APIs.
Start from RainbowKit, Privy, or Openfort examples.
diff --git a/overview/subnames.mdx b/overview/subnames.mdx
index aed6276..28cdf2e 100644
--- a/overview/subnames.mdx
+++ b/overview/subnames.mdx
@@ -1,6 +1,6 @@
---
title: "Learn about Subnames"
-description: "Learn more about Subnames and how to choose between offchain, L1, and L2."
+description: "Learn more about subnames and how to choose offchain or onchain."
sidebarTitle: "Learn about Subnames"
icon: "question"
---
@@ -41,45 +41,25 @@ See [Use cases](/overview/use-cases) for examples across wallets, payments, AI a
- **Stronger security:** Showing a name and avatar helps users verify a recipient, which can reduce address-poisoning and lookalike-address scams.
- **Brand distribution:** Users carry your brand into every app they touch, and every transaction becomes a brand impression.
-## L1 subnames
+## Offchain or onchain
-L1 subnames are created through ENS contracts on Ethereum. Their guarantees depend on the parent name's fuse configuration and the minting contract used.
+Namespace issues subnames in two ways. Both resolve in ENS apps, and both work under the same parent name.
+| | Offchain | Onchain (Ethereum L1) |
+| --- | --- | --- |
+| Where it lives | Namespace stores the subname and its records | The ENSv2 registry on Ethereum |
+| Who controls it | The parent-name owner, through the Namespace App or API | The wallet that minted it |
+| Cost to issue | No transaction or gas | Ethereum gas, plus the mint price you set |
+| Parent name | ENSv1 or ENSv2 | ENSv2 |
+| Best for | Gasless, high-volume onboarding and frequently changing records | Lower-volume flows where users should own their subname |
-When a name is activated through the [Namespace App](/user-guide/app#activate-your-ens-name), the activation flow configures the parent and its minting rules before users register subnames. Review the confirmation transaction carefully because fuse changes may be irreversible.
-
-Fuses are permission bits that restrict what can be done with a name. Once burned (enabled), a fuse cannot be reverted until the name expires.
-L1 issuance usually has the highest transaction cost, so it best fits lower-volume flows where Ethereum-native ownership is a requirement.
-
-
-
- Activate your ENS name, configure L1 minting rules, and let users register through Namespace.
-
-
- Deploy and customize a branded website where users can mint your L1 subnames.
-
-
-
-## L2 subnames
-
-L2 subnames are minted through registry contracts on a supported Layer 2. They offer onchain ownership with lower transaction costs than Ethereum mainnet, although the exact cost and trust assumptions depend on the selected L2.
-
-The Namespace App supports configured L2 listings, including Base and Optimism. Developers can use the [Mint Manager guide](/developer-guide/guide/mint-l1-l2-subnames) to prepare and submit a transaction for the chain specified by the parent listing.
-
-
-
- Activate your ENS name, configure an L2 listing, and let users mint through Namespace.
-
-
- Use the Mint Manager SDK to add L2 availability checks and mint transactions to your app.
-
-
+Start with offchain subnames unless users need to hold the subname themselves.
## Offchain subnames
-Offchain subnames are stored by an operator and resolved through [CCIP Read](https://eips.ethereum.org/EIPS/eip-3668). Creating or updating one does not require a blockchain transaction, which makes this model useful for high-volume onboarding and frequently changing records.
+Namespace stores offchain subnames and their records, and ENS clients resolve them through [CCIP Read](https://eips.ethereum.org/EIPS/eip-3668). Creating or updating one needs no blockchain transaction.
-Offchain subnames are not minted as NFTs. The parent-name operator controls issuance and updates through its API-key and application rules. Compatible ENS clients can still read their address, text, and content-hash records through the configured resolver.
+Offchain subnames aren't NFTs. The parent-name owner controls issuance and updates through the Namespace App or with an API key. Compatible ENS clients read their address, text, and content-hash records through the Namespace resolver.
@@ -90,10 +70,18 @@ Offchain subnames are not minted as NFTs. The parent-name operator controls issu
-## Choose a model
+## Onchain subnames on Ethereum
+
+Onchain subnames are minted in the ENSv2 registry on Ethereum (L1). The wallet that mints a subname owns it as an onchain asset and can transfer it.
+
+You set the rules when you activate your name: a one-time or yearly price in dollars, paid in USDC or DAI, plus optional pricing tiers, reservations, a mint window, a whitelist, or token gating. Minters pay your price plus Ethereum gas. Activation needs an ENSv2 name.
+
+
+ Activate your ENS name, set prices and rules, and let people mint subnames through Namespace.
+
+
+## L2 subnames
-- Choose **offchain** for gasless issuance, high volume, and application-managed identities.
-- Choose **L2** for lower-cost onchain ownership on a supported L2.
-- Choose **L1** when Ethereum-native ownership outweighs transaction cost.
+New L2 subnames are coming soon. Subnames already minted on Base and Optimism keep resolving, and their owners don't need to do anything.
See [Getting started](/getting-started) for the no-code and developer paths for each model.
diff --git a/scripts/check-docs.mjs b/scripts/check-docs.mjs
index ce79f5b..f4fd19a 100644
--- a/scripts/check-docs.mjs
+++ b/scripts/check-docs.mjs
@@ -3,7 +3,8 @@ import { existsSync, readFileSync, readdirSync } from 'node:fs';
import { dirname, join, relative, resolve } from 'node:path';
const root = process.cwd();
-const ignoredDirectories = new Set(['.git', 'node_modules']);
+// Snippets are partials imported into pages, not pages themselves.
+const ignoredDirectories = new Set(['.git', 'node_modules', 'snippets']);
const mintignorePath = join(root, '.mintignore');
const ignoredRoutes = new Set(
diff --git a/snippets/indexer-manager-deprecated.mdx b/snippets/indexer-manager-deprecated.mdx
new file mode 100644
index 0000000..1cf7ac8
--- /dev/null
+++ b/snippets/indexer-manager-deprecated.mdx
@@ -0,0 +1,3 @@
+
+ Indexer Manager is deprecated. It keeps working for onchain listings on ENSv1 names. For new integrations, use [offchain subnames](/developer-guide/guide/create-offchain-subnames), or issue onchain subnames from the [Namespace App](/user-guide/app). See [ENSv2 and Namespace](/overview/ensv2).
+
diff --git a/snippets/mint-api-deprecated.mdx b/snippets/mint-api-deprecated.mdx
new file mode 100644
index 0000000..4bcfaf2
--- /dev/null
+++ b/snippets/mint-api-deprecated.mdx
@@ -0,0 +1,3 @@
+
+ The Mint API is deprecated. It keeps working for onchain listings on ENSv1 names. For new integrations, use [offchain subnames](/developer-guide/guide/create-offchain-subnames), or issue onchain subnames from the [Namespace App](/user-guide/app). See [ENSv2 and Namespace](/overview/ensv2).
+
diff --git a/snippets/mint-manager-deprecated.mdx b/snippets/mint-manager-deprecated.mdx
new file mode 100644
index 0000000..fe84b3d
--- /dev/null
+++ b/snippets/mint-manager-deprecated.mdx
@@ -0,0 +1,3 @@
+
+ Mint Manager is deprecated. It keeps working for onchain listings on ENSv1 names. For new integrations, use [offchain subnames](/developer-guide/guide/create-offchain-subnames), or issue onchain subnames from the [Namespace App](/user-guide/app). See [ENSv2 and Namespace](/overview/ensv2).
+
diff --git a/user-guide/app.mdx b/user-guide/app.mdx
index b7a83cc..767adc4 100644
--- a/user-guide/app.mdx
+++ b/user-guide/app.mdx
@@ -1,92 +1,362 @@
---
title: "Onchain subnames"
-description: "No-code onchain subname issuance on Ethereum and L2 chains."
+description: "Activate an ENS name and issue onchain subnames on Ethereum."
sidebarTitle: "Onchain subnames"
icon: "coins"
---
-Use the [Onchain section of the Namespace App](https://app.namespace.ninja/onchain) to activate an ENS name, configure its minting rules, and issue onchain subnames on Ethereum or a supported L2.
+Activate your ENS name in the [Namespace App](https://app.namespace.ninja) to let people mint subnames under it on Ethereum (L1). Each subname is minted onchain and owned by the wallet that mints it. You set the price, the rules, and who can mint, then confirm in your wallet.
-## Choose L1 or L2
+New activations need an ENSv2 name. Listings on ENSv1 names keep working and can still be edited, but they stay on ENSv1. Pick the tab that matches your name.
-| Model | Best for | Issuance cost | Ownership |
-| --- | --- | --- | --- |
-| L1 | Ethereum-native ownership | Ethereum transaction and mint price | The minted subname is held by its owner |
-| L2 | Lower-cost onchain ownership | L2 transaction and mint price | The minted subname is held by its owner |
+
+
+ ## Before you begin
-
- Names activated on Ethereum Mainnet cannot be migrated to Namechain (ENS v2). If you plan to use Namechain, activate on a supported L2 such as Base or Optimism instead.
-
+ - Connect the wallet that owns the parent ENS name.
+ - Pick a name tagged `v2`. The name picker greys out ENSv1 names.
+ - Keep some ETH in the wallet to pay network fees for the activation transaction.
+ - Decide on a base price and how payouts should be split.
-## Before you begin
+ ## Activate your ENS name
-- Connect the wallet that owns the parent ENS name.
-- Decide whether you want to issue subnames on Ethereum Mainnet or a supported L2.
-- Choose your pricing, treasury address, and any minting restrictions.
+
+
+ In the sidebar, open **Onchain subnames** and then **ENSv2**. Pick the name from **Search your names**.
-## Activate your ENS name
+
+
+
+
-
-
- Visit [app.namespace.ninja/onchain](https://app.namespace.ninja/onchain), connect the owner wallet, select the ENS name, and click **Activate Name**.
+
+ The page shows **Name not activated** for a name without a listing. Click **Activate**.
-
-
+
+
+
+
-
- Select **L1 ENS Subnames** for Ethereum mainnet or **L2 ENS Subnames** for a supported L2. For L2, select the network from the dropdown, then click **Next**.
+
+ Select **Mainnet subnames**, which places subnames on Ethereum in the ENSv2 registry. Click **Next**.
-
-
+
+
+
+
-
- Set the currency, treasury address, collection name and symbol, and whether subnames can be burned or rented. Then configure the base mint price and any length-based or special-name pricing.
+
+ On the **Setup** tab, choose an expiration mode:
-
-
+ - **Permanent**: subnames are paid for once.
+ - **Expirable**: subnames are rented for a chosen duration and renewed to keep. The base price is charged per year.
-
- Use reservations to block or specially price names. You can also add a deadline, restrict minting with an allowlist, or require ownership of an ERC-20 or ERC-721 token.
+ Enter the **Base price** in dollars. It applies when no other price rule matches. Minters pay in USDC or DAI. Under **Payout**, keep **100% to owner** or choose **Split payment**.
-
-
+ Type a label into **Price check** on the right to see what it would cost under your current rules.
-
- Review the configuration, click **Activate**, and confirm the transaction in your wallet.
+
+
+
+
-
- Activation on Ethereum Mainnet may require wrapping the ENS name. For activation on an L2 chain, the app may also prompt you to deploy the registry contract and configure the Namespace Hybrid Resolver.
-
-
+
+ Add pricing tiers and minting restrictions on the other tabs, or skip them. See [Configure pricing and rules](#configure-pricing-and-rules).
+
-
- Complete any remaining registry or resolver transactions, then click **Finish Activation**. The ENS name now shows an **Activated** badge and is ready for subname minting.
+
+ Click **Review**. The summary lists each section with its settings. Click a section to change it, then click **Deploy**.
-
-
-
+
+
+
+
-
- Use **Edit Activation** to update pricing, reservations, deadlines, allowlists, or token-gating rules later. Review every transaction carefully because some ENS fuse changes may be irreversible.
-
+
+ The app lists the activation steps:
-## Choose how users mint
+ 1. **Set up subname registry** deploys the registry that holds your name's subnames. You own it.
+ 2. **Allow Namespace to mint subnames** lets Namespace's subname issuer register and renew subnames in that registry.
+ 3. **Save activation** saves your pricing, rules, and payment settings.
-After activation, users can mint through:
+ Click **Activate** and confirm in your wallet.
-- The dedicated name page at `app.namespace.ninja/.eth`.
-- [Namespace search](/user-guide/app/search-register) for registering an ENS name or an available onchain subname.
-- The [ENS Widget](/user-guide/ens-widget) embedded on your website without building a registration interface.
-- A [custom minting website](/developer-guide/guide/subpages) based on the white-label Subpages starter.
-- A custom app using the [mint onchain subnames workflow](/developer-guide/guide/mint-l1-l2-subnames).
+
+
+
+
+
+
+ When all three steps show **Confirmed**, the app shows that your name is activated. Click **Done**. People can now mint subnames of your name.
+
+
+
+
+
+
+
+ ## Configure pricing and rules
+
+ Every tab after **Setup** is optional. Turn a rule on with the toggle at the top of its tab. Tabs you skip stay marked **OFF**. Use **Price check** to see what a label costs as you change the rules.
+
+ ### Prices
+
+ A label's price comes from up to three rules that work together. Only the base price is required:
+
+ - **Base price**: set on **Setup**. Applies when no other rule matches the label.
+ - **Label length pricing**: a price per year for labels of an exact length. Click **Add length tier**, then enter the number of characters and the price, such as $50 for 1 character, $20 for 2, and $10 for 3.
+ - **Character-class pricing**: one price for labels made only of letters (**Letters only**) and one for labels made only of numbers (**Numbers only**). Labels that mix letters and numbers match neither.
+
+ Length and character-class pricing each have their own toggle. A [reservation](#reservations) overrides all of them.
+
+ {/* TODO: confirm precedence. State which price applies when a label matches both a length tier and a character class (for example, "abc" with a 3-character tier and a Letters only price). */}
+
+
+
+
+
+ ### Reservations
+
+ Block specific labels or give them a custom price. Reservations override every other rule.
+
+ - Click **Add reserved label** and enter the label.
+ - **Blocked**: nobody can mint it.
+ - **Priced**: it can be minted at the price you enter.
+
+
+
+
+
+ ### Mint window
+
+ Allow minting only between two dates.
+
+ - **Opens at**: when minting starts.
+ - **Closes at**: when minting stops.
+ - Leave either one empty for an open start or end.
+
+
+
+
+
+ ### Whitelist
+
+ Limit minting to listed wallets, or let them mint for free.
+
+ - **Allowed addresses**: click **Add address** for each wallet.
+ - **Gate**: only listed wallets can mint.
+ - **Free mint**: anyone can mint, and listed wallets pay nothing.
+
+
+
+
+
+ ### Token gated
+
+ Let only wallets that hold specific tokens mint.
+
+ - **Standard**: ERC721, ERC1155, or ERC20.
+ - **Contract** and **Min. held**: the token's contract address and the minimum balance a minter needs. Click **Add token** to add another.
+ - **Combine with**: **All of them** requires every listed token. **Any one** requires just one.
+
+
+
+
+
+ ### Other settings
+
+ Set the resolver for new subnames and what their owners can do after minting.
+
+ - **Use a custom resolver**: registers every subname with your resolver, whatever resolver the minting app asks for.
+ - **Owner permissions**, **Default**: owners can set a resolver, create subnames under their subname, and transfer it. **Renew** and **Unregister** stay off.
+ - **Owner permissions**, **Custom**: change any of these. Unregister permanently destroys the subname and frees the label for anyone to mint, so it's usually left off.
+
+
+
+
+
+ ## Mint a subname
+
+ After activation, anyone can mint a subname from your name's page in the Namespace App or through [Namespace search](/user-guide/app/search-register). Minting one yourself is a quick way to check the listing.
+
+
+
+ On the name's page, type a label under **Find your perfect subname**. The app shows whether the subname is available and its price. Click **Mint**.
+
+
+
+
+
+
+
+ For an expirable listing, set the duration in years. The dialog shows the price, estimated network fees, and the total.
+
+
+
+
+
+
+
+ Optionally, open **Complete your profile** to add an avatar, nickname, short bio, social accounts, addresses, a website, or custom records. Click **Save**, then click **Mint** and confirm in your wallet.
+
+
+
+
+
+
+
+ When the transaction confirms, the dialog shows the minted subname, mint price, and transaction fees, with a link to Etherscan.
+
+
+
+
+
+
+
+ The subname resolves like any other ENS name, with the owner, expiry, and records you set.
+
+
+
+
+
+ ## Manage onchain subnames
+
+ The name's page lists every minted subname with its expiry date. Search the list or switch between grid and list views. Labels that are already minted show as taken in the search.
+
+
+
+
+
+
+
+ The ENSv1 onchain flow is deprecated. Use this tab only to manage an existing ENSv1 listing. To activate a new name, use the **ENSv2** tab.
+
+
+ ## How ENSv1 listings work
+
+ ENSv1 listings issue subnames on Ethereum (L1) or on an L2 network such as Base or Optimism. Subnames already minted on Base and Optimism keep resolving.
+
+ | Model | Issuance cost | Ownership |
+ | --- | --- | --- |
+ | L1 | Ethereum transaction and mint price | The minted subname is held by its owner |
+ | L2 | L2 transaction and mint price | The minted subname is held by its owner |
+
+ ## Edit an ENSv1 listing
+
+
+
+ Open **Onchain subnames** > **ENSv1**, connect the owner wallet, and select the activated name.
+
+
+
+ Click **Edit Activation** to change pricing, reservations, deadlines, allowlists, or token-gating rules. Each tab has an **Update** button that saves that tab's changes.
+
+
+
+
+
+
+
+ Confirm the update in your wallet.
+
+
+
+
+ Review every transaction carefully. Some ENS fuse changes on wrapped names can't be undone.
+
+
+ ### Listing settings
+
+ - **Setup**: currency, treasury address, collection name and symbol, and whether subnames can be burned or rented.
+ - **Prices**: the base mint price, prices by label length, and special-name pricing.
+ - **Reservations**: block names or give them a custom price.
+ - **Deadline**: stop minting after a date.
+ - **Whitelist**: let only listed wallets mint, or let them mint for free.
+ - **Token Gated**: require minters to hold an ERC-20 or ERC-721 token.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ## How ENSv1 listings were activated
+
+ For reference, these are the steps owners followed to activate an ENSv1 name.
+
+
+
+ The owner connected their wallet, selected the ENS name, and clicked **Activate Name**.
+
+
+
+
+
+
+
+ **L1 ENS Subnames** issued subnames on Ethereum Mainnet. **L2 ENS Subnames** issued them on a supported L2 picked from a dropdown.
+
+
+
+
+
+
+
+ The owner set the currency, treasury address, collection name and symbol, and whether subnames could be burned or rented. Then they set the base mint price and any length-based or special-name pricing.
+
+
+
+
+
+
+
+ Reservations blocked names or gave them a custom price. Owners could also add a deadline, restrict minting with an allowlist, or require an ERC-20 or ERC-721 token.
+
+
+
+
+
+
+
+ The owner reviewed the configuration, clicked **Activate**, and confirmed the transaction. On Ethereum Mainnet this could require wrapping the ENS name. L2 listings also needed a registry contract and the Namespace Hybrid Resolver.
+
+
+
+ After any remaining registry or resolver transactions, the owner clicked **Finish Activation**. The name then showed an **Activated** badge.
+
+
+
+
+
+
+
+ ## How users mint
+
+ Users mint subnames of an ENSv1 listing through:
+
+ - The name's page at `app.namespace.ninja/.eth`.
+ - [Namespace search](/user-guide/app/search-register).
+
+ ENSv1 listings also work with the deprecated [ENS Widget](/user-guide/ens-widget), [Subpages](/user-guide/subpages), and [Mint Manager](/developer-guide/guide/mint-l1-l2-subnames).
+
+
## Next steps
-
- Embed onchain subname registration on your website.
+
+ Let users mint subnames of your activated name with ENS Components.
+
+
+ Create gasless subnames under the same name.
-
- Add availability checks and mint transactions for Ethereum Mainnet or supported L2 chains to your app.
+
+ Check what works with your ENSv1 or ENSv2 name.
diff --git a/user-guide/app/search-register.mdx b/user-guide/app/search-register.mdx
index b0bcff1..951316e 100644
--- a/user-guide/app/search-register.mdx
+++ b/user-guide/app/search-register.mdx
@@ -1,11 +1,18 @@
---
title: "Register name or subname"
-description: "Discover names available through Namespace."
+description: "Find and register a name in the Namespace App."
sidebarTitle: "Register name or subname"
icon: "user-magnifying-glass"
---
-Use [Namespace search](https://app.namespace.ninja/search) to find and register an ENS name such as `example.eth` or an available onchain subname such as `alice.brand.eth`.
+Use [Namespace search](https://app.namespace.ninja/search) to register an ENS name such as `example.eth` or an available onchain subname such as `alice.brand.eth`. A `.eth` name takes two wallet transactions with a short wait between them. You can set up the name's profile during registration.
+
+New `.eth` names you register through Namespace are ENSv2 names.
+
+## Before you start
+
+- A wallet connected to the [Namespace App](https://app.namespace.ninja).
+- Enough of the payment token for the registration fee, plus ETH for network fees.
## What you can register
@@ -14,49 +21,99 @@ Use [Namespace search](https://app.namespace.ninja/search) to find and register
| ENS name | A second-level `.eth` name | Registration period and price follow ENS rules |
| Onchain subname | A name beneath an activated parent ENS name | Price, network, ownership, and expiry follow the parent's listing rules |
-## Search for a name
+## Register an ENS name
-
- Visit [app.namespace.ninja/search](https://app.namespace.ninja/search), connect your wallet, and enter the name you want.
+
+ Open **Search and register** in the sidebar, or go to [app.namespace.ninja/search](https://app.namespace.ninja/search). Type the name you want in the search box.
+
+
+
+
-
- Search results can include the exact `.eth` name and matching subnames from parent names activated on Namespace. Each subname shows its price or a **Free Mint** label.
+
+ The results list the `.eth` name first. An **AVAILABLE** status means you can register it. Below it, the list shows matching subnames from parent names activated on Namespace, each with its price and a **MINT** button.
+
+ Select the `.eth` name to start registering it.
-
+
+
+
-
- Select the result you want and check the full name, owner, network, registration or mint price, estimated network fee, and total before continuing.
+
+ The **Claim your Web3 identity** dialog shows the name and its expiry date. To change how long you register the name, pick a date with the calendar button or select **PICK BY YEARS**.
+
+ Check the **Registration Fee**, **Est. network fees**, and **Total**. Use the token menu next to the total to choose what you pay with. The dialog also shows the approximate USD value.
+
+
+
+
-
- Continue from the registration dialog and approve the required wallet transaction. Wait for the transaction to confirm before using the name.
+
+ To add profile records to the name as part of registration, select **Complete your profile** before you continue. You can skip this and edit records after the name is registered.
+
+
+
+
+
+ When you're ready, select **Next**.
-
-## Register an onchain subname
+
+ The **ENS Registration Process** dialog lists three steps: **Commitment**, **Timer Started**, and **Complete Registration**. Under **Commitment**, select **Open Wallet** and approve the transaction in your wallet.
-The registration dialog shows the parent name's configured mint price, estimated network fee, and total. Free listings show a **Free Mint** label.
+ After you approve it, the dialog shows **Transaction Sent** with a **View on Etherscan** link. Wait for the transaction to confirm.
-
+
+
+
+
-Onchain subname ownership and expiry on Ethereum Mainnet depend on the parent name's ENS fuse and listing configuration. On L2 chains, subnames can also use a registration period when the parent-name owner enables renting.
+
+ Once the commitment confirms, a countdown starts. The wait helps protect your registration from front-running. Keep the dialog open until the timer finishes.
-## Register an ENS name
+
+
+
+
+
+
+ Under **Complete Registration**, select **Open Wallet** and approve the second transaction. The name isn't registered until this transaction confirms. The dialog shows how many hours you have left to complete it.
+
+
+
+
+
+
+
+ When the transaction confirms, the dialog marks the name **REGISTERED**. It shows the registration length and fee, the transaction fees, and when the name expires.
+
+ Select **View Name** to open the name, **Register another** to search again, or **Great!** to close the dialog.
-For an available `.eth` name, choose the registration period and review the registration fee, estimated network fee, and total. Continue through the wallet prompts shown by the app.
+
+
+
+
+
+
+## Register an onchain subname
+
+Select **MINT** next to a subname in the search results. The registration dialog shows the parent name's configured mint price, estimated network fee, and total. Free listings show **Free** instead of a price.
+
+
-
+The wallet that mints an onchain subname owns it. Whether it expires depends on the parent name's listing: permanent subnames are paid for once, and expirable ones are renewed to keep.
## Next steps
- Activate a parent ENS name and configure its listing rules on Ethereum Mainnet or an L2 chain.
+ Activate a parent ENS name and configure its listing rules on Ethereum Mainnet.
-
- Create and embed a no-code ENS Widget.
+
+ Create gasless subnames under your new name.
diff --git a/user-guide/dev-portal.mdx b/user-guide/dev-portal.mdx
index 9bf8496..1acbdeb 100644
--- a/user-guide/dev-portal.mdx
+++ b/user-guide/dev-portal.mdx
@@ -22,6 +22,10 @@ Creating, editing, and deleting offchain subnames and their records is free. The
Set the parent ENS name to use the Namespace Hybrid Resolver. This initial setup requires an onchain transaction and gas fees. Skip this section if resolution is already configured.
+
+ If you upgrade an ENSv1 name to ENSv2, the upgrade resets its resolver. Run these steps again afterwards. See [Namespace ENSv2 migration](/overview/ensv2#what-happens-if-i-upgrade-my-name-to-ensv2).
+
+
Connect the wallet that owns the ENS name. In **Offchain**, select the name and open **Resolution**.
diff --git a/user-guide/ens-components.mdx b/user-guide/ens-components.mdx
index 0a5e427..8708fa6 100644
--- a/user-guide/ens-components.mdx
+++ b/user-guide/ens-components.mdx
@@ -5,38 +5,53 @@ sidebarTitle: "ENS Components"
icon: "puzzle-piece"
---
-[ENS Components](https://enscomponents.com/) is an open-source React UI library for ENS name registration, record editing, and subname issuance, including Namespace onchain and offchain subnames.
+[ENS Components](https://enscomponents.com/) is an open-source React library from Namespace with complete ENS flows you can put in your own app. Your users can register names, claim subnames, and edit their profiles inside your product, and your team skips building the ENS contract calls and pricing.
+
+Each flow is one component. A developer renders it, and it handles the screens, validation, pricing, wallet prompts, and confirmation.
- enscomponents.com
+ Try every component live
thenamespace/ens-components
-
- Agent-ready component instructions
+
+ Install and integrate
-## Core components
+## Flows it covers
+
+| Flow | What your users can do |
+| --- | --- |
+| Name registration | Search for a `.eth` name and register it. |
+| Name renewal | Extend any `.eth` name. Anyone can pay, and the owner keeps the name. |
+| Profile records | Edit addresses, social and text records, website contenthash, avatar, and header image. |
+| Onchain subnames | Mint a subname under your name, at the price and rules you set in the Namespace App. |
+| Subname renewal | Extend an onchain subname at your price. |
+| Offchain subnames | Claim a gasless subname under your name, such as `alice.yourbrand.eth`, saved through your server. |
+
+The library also includes a transaction progress screen your team can reuse in its own flows, so everything looks consistent.
+
+## ENSv2 by default
+
+The onchain flows run on [ENSv2](/overview/ensv2), on Ethereum mainnet or the Sepolia testnet.
+
+- `.eth` registration and renewal are paid in USDC or DAI.
+- Onchain subnames under an [activated name](/user-guide/app#activate-your-ens-name) are paid in USDC or DAI.
+- Network fees are paid in ETH.
+
+If you created an onchain listing in the Namespace App before ENSv2, it keeps working. Your developers add one setting to the subname form to mint under it. Offchain subnames work with both ENSv1 and ENSv2 names.
-- **`EnsNameRegistrationForm`:** full commit/register flow for `.eth` names
-- **`EnsRecordsForm`:** edit text records, addresses, avatar, and contenthash
-- **`SelectRecordsForm`:** standalone record composer, no wallet required
-- **`OffchainSubnameForm`:** gasless subnames via the Namespace API
-- **`SubnameMintForm`:** onchain subname minting with L2 resolver support
+## When to use it
-## Features
+Use it when you want ENS names or subnames in your product without building the flows yourself. It fits well if you issue subnames to a community or customers: pair the subname forms with an onchain activation or offchain subnames from the [Namespace App](/user-guide/app). You can change colors, corners, fonts, and copy to match your brand. See [Theming](/developer-guide/sdks/ens-components/theming).
-- Drop-in ENS UX
-- `.eth` name registration
-- Onchain or offchain subname registration
-- Customizable templates
-- Open-source, MIT-licensed
+ENS Components is for React apps that use wagmi for wallet connections. It's open source, so your team can read and audit the code.
-## Use it
+## Get started
-- **Source and install:** [github.com/thenamespace/ens-components](https://github.com/thenamespace/ens-components)
-- **Skill.md:** Give an AI agent the official [ENS Components instructions](https://enscomponents.com/Skill.md) directly.
-- **Installable skill:** Add the [ENS components skill](/developer-guide/skills#ens-components-skill) to your project.
+- **Developers:** Start with the [ENS Components developer guide](/developer-guide/sdks/ens-components).
+- **AI agents:** Install the [ENS Components skill](/developer-guide/skills#ens-components-skill), or give your agent [Skill.md](https://enscomponents.com/Skill.md).
+- **Release notes:** See the [ENS Components changelog](/changelog/ens-components).
diff --git a/user-guide/ens-widget.mdx b/user-guide/ens-widget.mdx
index 2c690b3..9208581 100644
--- a/user-guide/ens-widget.mdx
+++ b/user-guide/ens-widget.mdx
@@ -3,14 +3,19 @@ title: "ENS Widget"
description: "Embed ENS registration without rebuilding the interface."
sidebarTitle: "ENS Widget"
icon: "puzzle-piece"
+tag: "Deprecated"
---
+
+ ENS Widget is deprecated. It works only with onchain listings on ENSv1 names. See [ENSv2 and Namespace](/overview/ensv2) for what works with ENSv2 names.
+
+
Use ENS Widget to add ENS name and onchain subname registration to your website without building the registration interface yourself.
## Before you begin
- Connect the wallet that owns the parent ENS name.
-- [Activate the parent ENS name](/user-guide/app#activate-your-ens-name) before offering its subnames through the widget.
+- [Activate the parent ENS name on ENSv1](/user-guide/app#ensv1-deprecated) before offering its subnames through the widget.
- Decide which names and subnames visitors should be able to search and mint.
## Choose the widget type
diff --git a/user-guide/sdk-and-api.mdx b/user-guide/sdk-and-api.mdx
index 4a6a6f1..456e796 100644
--- a/user-guide/sdk-and-api.mdx
+++ b/user-guide/sdk-and-api.mdx
@@ -4,7 +4,7 @@ description: "Build with Namespace SDKs and APIs."
icon: "code"
---
-Namespace provides TypeScript SDKs and hosted APIs for creating, minting, querying, and resolving ENS subnames. Choose the interface that fits your runtime and how much infrastructure you want to manage.
+Namespace provides TypeScript SDKs and hosted APIs for creating, querying, and resolving ENS subnames. Choose the interface that fits your runtime and how much infrastructure you want to manage.
## Choose an interface
@@ -22,16 +22,25 @@ Namespace provides TypeScript SDKs and hosted APIs for creating, minting, queryi
| Tool | Use it to |
| --- | --- |
| Offchain Manager | Create, update, delete, and query gasless offchain subnames and records |
-| Mint Manager | Check eligibility and generate mint transaction parameters for Ethereum Mainnet or L2 chains |
-| Indexer Manager | Query indexed registries and subnames from L2 chains |
+| [Avatar SDK](/developer-guide/sdks/avatar) | Upload avatar and header images for ENS names and subnames |
+| [ENS Components](/developer-guide/sdks/ens-components) | Add ready-made React interfaces for registration, minting, and record editing |
| Offchain API | Manage offchain subnames over HTTP |
-| Mint API | Estimate and generate mint parameters over HTTP |
| Resolvio API | Resolve ENS names, profiles, addresses, text records, and content hashes |
+## Deprecated tools
+
+These tools still work for onchain listings on ENSv1 names. Don't use them for new integrations.
+
+| Tool | Reference |
+| --- | --- |
+| Mint Manager SDK | [Mint Manager](/developer-guide/sdks/mint-manager) |
+| Indexer Manager SDK | [Indexer Manager](/developer-guide/sdks/indexer-manager) |
+| Mint API | [Mint API reference](/api-reference/mint-manager/estimate-mint-params) |
+
## Before you integrate
- Keep Namespace API keys in server-side environment variables.
-- Decide whether your product needs operator-managed offchain records or onchain subnames on Ethereum or L2 chains.
+- Decide whether your product needs offchain subnames, which Namespace stores, or onchain subnames on Ethereum.
- Use a testnet configuration during development.
- Handle unavailable labels, authentication failures, rate limiting, and resolver errors explicitly.
- Pin supported package versions and review the changelog before upgrading.
diff --git a/user-guide/subpages.mdx b/user-guide/subpages.mdx
index 70dd666..c327ba1 100644
--- a/user-guide/subpages.mdx
+++ b/user-guide/subpages.mdx
@@ -2,8 +2,13 @@
title: "Subpages"
description: "Launch a branded subname minting site."
icon: "page"
+tag: "Deprecated"
---
+
+ Subpages is deprecated. It works only with onchain listings on ENSv1 names. See [ENSv2 and Namespace](/overview/ensv2) for what works with ENSv2 names.
+
+
Subpages is a customizable white-label subname minting template that enables ENS name owners (companies, communities, DAOs, and others) to issue subnames from a custom-built website in record time. For example, if an organization owns _awesome.eth_, using Subpages, they can quickly spin up a custom website to allow members to mint personalized subnames like **alice**.awesome.eth.
## Features