npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@1001-digital/ethereum-names

v0.3.0

Published

One clean API to resolve Ethereum names across ENS, the Gwei Name Service (GNS), and the Wei Name Service (WNS), powered by viem.

Readme

@1001-digital/ethereum-names

One clean, viem-powered API to resolve Ethereum names across ENS, the Gwei Name Service (GNS), and the Wei Name Service (WNS).

Point it at a name — vitalik.eth, alice.gwei, or alice.wei — and it figures out which system to ask. Point it at an address and it gives you back the primary name. No branching in your app code.

Install

npm install @1001-digital/ethereum-names viem

viem is a peer dependency.

Usage

import { createEthereumNames } from '@1001-digital/ethereum-names'

const names = createEthereumNames()

// Forward: name → address (the system is detected from the name)
await names.resolve('vitalik.eth')    // ENS → '0xd8dA...' | null
await names.resolve('alice.gwei')     // GNS → '0x...'    | null
await names.resolve('alice.wei')      // WNS → '0x...'    | null
await names.resolve('alice')          // bare label → ENS by default (see bareLabel)
await names.resolve('0xd8dA...')      // address → returned checksummed

// Reverse: address → primary name (tries ENS, then GNS, then WNS)
await names.reverse('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045')
// => 'vitalik.eth' | 'alice.gwei' | 'alice.wei' | null

// Reverse across ALL systems at once (when an address has names in each)
await names.reverseAll('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045')
// => { ens: 'vitalik.eth', gns: 'vitalik.gwei', wns: 'vitalik.wei' }

// Rich lookup: resolve or reverse, and learn which system answered
await names.lookup('alice.wei')
// => { input: 'alice.wei', name: 'alice.wei', address: '0x...', system: 'wns' }

// Records work across all systems
await names.getAvatar('vitalik.eth')
await names.getText('alice.wei', 'url')

// Pure, offline system detection
names.system('alice.gwei') // 'gns'
names.system('alice.wei')  // 'wns'
names.system('foo.eth')    // 'ens'

How resolution is routed

| Input | System | | --------------------------- | ------ | | *.wei | WNS | | *.gwei | GNS | | any other dotted name *.eth, *.box, … | ENS | | bare label (no dot) | bareLabel option (default ENS) | | 0x… address | passed through (checksummed) |

A bare label like alice is ambiguous — GNS (.gwei) and WNS (.wei) both accept bare labels, and they can point to different owners. Rather than guess, it resolves against the bareLabel system, which defaults to ens. Since ENS has no bare-label namespace, bare labels resolve to null by default; set bareLabel: 'gns' or 'wns' to opt a label like alice into that registry.

Reverse lookups try each system in order (ENS first by default) and return the first match. Configure the order with reversePriority, or use reverseAll to get the primary name from all systems at once.

By default, reverse lookups are forward-verified: after reading an address's primary name, the library resolves that name back and confirms it points to the same address before trusting it. This guards against spoofed reverse records (ENS reverse records are not self-validating). Disable with verify: false to save a round-trip.

Configuration

import { createEthereumNames } from '@1001-digital/ethereum-names'
import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'

// Bring your own viem client (recommended for production)
const client = createPublicClient({ chain: mainnet, transport: http('https://my-rpc') })
const names = createEthereumNames({ client })

// …or let the library create a mainnet client for you
const quick = createEthereumNames({ rpcUrl: 'https://my-rpc' })

// Prefer GNS names on reverse lookups
const gnsFirst = createEthereumNames({ reversePriority: ['gns', 'ens', 'wns'] })

// Treat bare labels (e.g. `alice`) as `.gwei` names
const gwei = createEthereumNames({ bareLabel: 'gns' })
await gwei.resolve('alice') // → resolves alice.gwei

| Option | Type | Description | | ----------------- | --------------------- | -------------------------------------------------------------------- | | client | PublicClient | A viem client to read from. Its chain must have ENS contracts. | | rpcUrl | string | RPC endpoint used when no client is given. | | chain | Chain | Chain used when no client is given. Defaults to mainnet. | | gnsContract | Address | Override the GNS contract address. | | wnsContract | Address | Override the WNS contract address. | | bareLabel | 'ens' \| 'gns' \| 'wns' | System a bare label (no dot) resolves against. Defaults to 'ens'. | | reversePriority | ('ens' \| 'gns' \| 'wns')[] | Order reverse lookups try each system. Defaults to ['ens', 'gns', 'wns']. | | verify | boolean | Forward-verify reverse lookups before trusting them. Defaults to true. |

Note: ENS resolution relies on viem's ENS actions, which require a chain with ENS contracts configured (such as mainnet). GNS and WNS are live on Ethereum mainnet.

API

createEthereumNames(config?) → EthereumNames

| Method | Returns | Description | | ----------------------- | ----------------------------- | ------------------------------------------------------- | | resolve(nameOrAddress)| Promise<Address \| null> | Name → address. Addresses pass through, checksummed. | | reverse(address) | Promise<string \| null> | Address → primary name across systems. | | reverseAll(address) | Promise<ReverseNames> | Address → { ens, gns, wns } primary names from every system.| | lookup(input) | Promise<ResolvedName> | Resolve or reverse, with the answering system. | | getAvatar(name) | Promise<string \| null> | Avatar record (ENS avatar, or GNS/WNS avatar text). | | getText(name, key) | Promise<string \| null> | Arbitrary text record. | | system(name) | 'ens' \| 'gns' \| 'wns' \| null | Offline system detection. | | client | PublicClient | The underlying viem client. |

Also exported: detectSystem(name), DEFAULT_GNS_CONTRACT, DEFAULT_WNS_CONTRACT, and the types EthereumNames, EthereumNamesConfig, NameSystem, ResolvedName, ReverseNames.

Credits

GNS and WNS resolve against immutable mainnet registries; this library talks to them directly with a minimal ABI, so it ships with zero runtime dependencies (viem is a peer dependency). The registry interfaces come from @donnoh/gns-utils by lucadonnoh and wns-utils by NaniDAO.

License

MIT © 1001.digital