Skip to content

Add ENSv2 migration command - #8

Merged
gskril merged 5 commits into
ensdomains:mainfrom
gregsbot:codex/add-ens-v2-migration
Jul 22, 2026
Merged

Add ENSv2 migration command#8
gskril merged 5 commits into
ensdomains:mainfrom
gregsbot:codex/add-ens-v2-migration

Conversation

@gregsbot

@gregsbot gregsbot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add ens migrate <name> for one-way ENSv1-to-ENSv2 migration of reserved .eth 2LDs.
  • Detect unwrapped, wrapped-unlocked, and wrapped-locked names from ENSv1 registry ownership and NameWrapper fuses.
  • Validate ENSv2 reservation status, ENSv1 expiry, required nonzero addresses, and fuse conditions that would prevent migration.
  • Use an explicitly provided resolver or the ENSv2 owner’s deployed canonical OwnedResolver. If neither is available, preserve the current ENSv1 resolver and return an actionable recommendation.
  • Encode the appropriate ERC-721 or ERC-1155 safeTransferFrom call and migration payload for the selected controller.
  • Return concise flags for assumptions and conditions users should review, omitting flags when there are none.
  • Add the Sepolia migration controller addresses and migration documentation.

Why

Existing ENSv1 names claim their pre-migrated ENSv2 reservations through different controllers depending on whether the name is unwrapped, wrapped but unlocked, or wrapped and locked. The CLI previously had no way to inspect this state and generate the correct unsigned migration transaction.

The command follows the ENSv2 migration controller flow and uses a direct token transfer for a single-name CLI operation, avoiding the approval-for-all requirement of the batch-oriented MigrationHelper.

ENSv1 Public Resolver authorization is tied to the ENSv1 registry, so reusing it after migration can leave the ENSv2 owner unable to update records. The CLI now discovers and uses the target owner’s canonical OwnedResolver when it is already deployed.

Behavior

Running:

ens migrate myname.eth --chain sepolia --json

now:

  1. Confirms the name is a reserved .eth 2LD in ENSv2.
  2. Rejects expired names, including names in the ENSv1 grace period, with instructions to renew through ETHRenewerV1.
  3. Reads the ENSv1 owner, resolver, wrapping state, approvals, and relevant fuses.
  4. Selects the unlocked or locked migration controller.
  5. Uses --resolver when provided; otherwise uses the new owner’s deployed canonical OwnedResolver when available.
  6. Falls back to the current ENSv1 resolver when no OwnedResolver is deployed and recommends deploying one before regenerating the transaction.
  7. Returns the unsigned migration transaction for the current ENSv1 owner or an approved operator to broadcast.

For wrapped-locked names with CANNOT_SET_RESOLVER, resolver discovery is skipped because the migration controller ignores the resolver payload. The returned flags explain this and other relevant fuse-dependent behavior.

Names with CANNOT_TRANSFER fail early because NameWrapper cannot perform the transfer required for migration. A locked name with CANNOT_APPROVE and an existing frozen token approval also returns an actionable warning before broadcast.

Validation

  • bun run typecheck
  • bun run build
  • bun run src/index.ts migrate --help
  • bun run src/index.ts resolver deploy --help
  • git diff --check

References

@gskril

gskril commented Jul 22, 2026

Copy link
Copy Markdown
Member

Successfully migrated cosmic-zebra.eth to v2 using the CLI https://sepolia.etherscan.io/tx/0x4adc5e6d0eaf8eee05975cd63dc90b00456568cd1e262f623732d49814271e74

@pkg-pr-new

pkg-pr-new Bot commented Jul 22, 2026

Copy link
Copy Markdown

Open in StackBlitz

npx https://pkg.pr.new/ensdomains/ens-cli/@ensdomains/cli@8

commit: 85a121d

@gskril
gskril marked this pull request as ready for review July 22, 2026 05:54

@gskril gskril left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably can clean up code and can definitely test further, but migration is working at least for unwrapped names so i'm merging for now. This repo is meant to be fast pace.

@gskril
gskril merged commit 30a5b43 into ensdomains:main Jul 22, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants