{"_id":"@1001-digital/ethereum-names","_rev":"6-8a1c13fdaabb052757c159fbc1f37733","name":"@1001-digital/ethereum-names","dist-tags":{"latest":"0.6.0"},"versions":{"0.1.0":{"name":"@1001-digital/ethereum-names","version":"0.1.0","keywords":["ethereum","ens","gns","gwei","gwei-name-service","name-service","resolver","viem","web3"],"author":{"name":"jalil.eth"},"license":"MIT","_id":"@1001-digital/ethereum-names@0.1.0","maintainers":[{"name":"jwahdatehagh","email":"jalil@1001.digital"}],"homepage":"https://github.com/1001-digital/ethereum-names#readme","bugs":{"url":"https://github.com/1001-digital/ethereum-names/issues"},"dist":{"shasum":"41f7adb7d5ed217ab21bb3f39bc861a2c35e05cf","tarball":"https://registry.npmjs.org/@1001-digital/ethereum-names/-/ethereum-names-0.1.0.tgz","fileCount":9,"integrity":"sha512-nR/CX0iPxhoeLz50QN4gDSaY+LbgA6PDGSq9bjXDJUiYvGqDWayCsI7gJ0P+OZn33W0tTFEYSe5ewNttq1sixQ==","signatures":[{"sig":"MEQCID93BhFo+yeseiySdBxAY86R/7TCbuHsBnV0vJEUB9fMAiBPbQGcoo+BOk5eDRQdIjmLK4UrVNvvg4GR6g6QFtNqKA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":62439},"main":"./dist/index.cjs","type":"module","_from":"file:1001-digital-ethereum-names-0.1.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"scripts":{"dev":"tsup --watch","lint":"biome check src","test":"tsx --test src/*.test.ts","build":"tsup","check":"biome check src && tsc --noEmit","clean":"rm -rf dist","format":"biome check --write src","release":"changeset publish","version":"changeset version","changeset":"changeset","typecheck":"tsc --noEmit"},"_npmUser":{"name":"jwahdatehagh","email":"jalil@1001.digital"},"_resolved":"/tmp/6d0272058c5ab206bcd850793edcdbf8/1001-digital-ethereum-names-0.1.0.tgz","_integrity":"sha512-nR/CX0iPxhoeLz50QN4gDSaY+LbgA6PDGSq9bjXDJUiYvGqDWayCsI7gJ0P+OZn33W0tTFEYSe5ewNttq1sixQ==","repository":{"url":"git+https://github.com/1001-digital/ethereum-names.git","type":"git"},"_npmVersion":"10.9.8","description":"One clean API to resolve Ethereum names across ENS and the Gwei Name Service (GNS), powered by viem.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.0","dependencies":{"@donnoh/gns-utils":"^0.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","tsup":"^8.5.0","viem":"^2.45.3","typescript":"~5.8.3","@types/node":"^22.19.11","@biomejs/biome":"^1.9.4","@changesets/cli":"^2.30.0","@changesets/changelog-github":"^0.5.1"},"peerDependencies":{"viem":"^2.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ethereum-names_0.1.0_1782863432014_0.6244370810807276","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@1001-digital/ethereum-names","version":"0.2.0","keywords":["ethereum","ens","gns","gwei","gwei-name-service","wns","wei","wei-name-service","name-service","resolver","viem","web3"],"author":{"name":"jalil.eth"},"license":"MIT","_id":"@1001-digital/ethereum-names@0.2.0","maintainers":[{"name":"jwahdatehagh","email":"jalil@1001.digital"}],"homepage":"https://github.com/1001-digital/ethereum-names#readme","bugs":{"url":"https://github.com/1001-digital/ethereum-names/issues"},"dist":{"shasum":"03fdd1e36402014ffe0b606b6ab566886bd61544","tarball":"https://registry.npmjs.org/@1001-digital/ethereum-names/-/ethereum-names-0.2.0.tgz","fileCount":9,"integrity":"sha512-OLZgFeYZqEX/l0+U8FpCyUxn7M8nG2ruL+iqWdwY31DHJwToS/8yygvgeonwLOb43oDDkysTrdKXEIIzWXHA0w==","signatures":[{"sig":"MEYCIQDs/3ysKSrBBmO877m8Ip5GZYtHF9HFPnh3l3iFn7mHzAIhAJ7U4u5VRHYi3jUfqW9kbgK0iZhI+McxjxH7tHQIgS9E","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":77157},"main":"./dist/index.cjs","type":"module","_from":"file:1001-digital-ethereum-names-0.2.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"scripts":{"dev":"tsup --watch","lint":"biome check src","test":"tsx --test src/*.test.ts","build":"tsup","check":"biome check src && tsc --noEmit","clean":"rm -rf dist","format":"biome check --write src","release":"changeset publish","version":"changeset version","changeset":"changeset","typecheck":"tsc --noEmit"},"_npmUser":{"name":"jwahdatehagh","email":"jalil@1001.digital"},"_resolved":"/tmp/6914c130e6d7ec4d7444e7876a96f758/1001-digital-ethereum-names-0.2.0.tgz","_integrity":"sha512-OLZgFeYZqEX/l0+U8FpCyUxn7M8nG2ruL+iqWdwY31DHJwToS/8yygvgeonwLOb43oDDkysTrdKXEIIzWXHA0w==","repository":{"url":"git+https://github.com/1001-digital/ethereum-names.git","type":"git"},"_npmVersion":"10.9.8","description":"One clean API to resolve Ethereum names across ENS, the Gwei Name Service (GNS), and the Wei Name Service (WNS), powered by viem.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","tsup":"^8.5.0","viem":"^2.45.3","typescript":"~5.8.3","@types/node":"^22.19.11","@biomejs/biome":"^1.9.4","@changesets/cli":"^2.30.0","@changesets/changelog-github":"^0.5.1"},"peerDependencies":{"viem":"^2.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ethereum-names_0.2.0_1783320941660_0.3701693670146047","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@1001-digital/ethereum-names","version":"0.3.0","keywords":["ethereum","ens","gns","gwei","gwei-name-service","wns","wei","wei-name-service","name-service","resolver","viem","web3"],"author":{"name":"jalil.eth"},"license":"MIT","_id":"@1001-digital/ethereum-names@0.3.0","maintainers":[{"name":"jwahdatehagh","email":"jalil@1001.digital"}],"homepage":"https://github.com/1001-digital/ethereum-names#readme","bugs":{"url":"https://github.com/1001-digital/ethereum-names/issues"},"dist":{"shasum":"f083829e5b81a6d071c71c6febe9de18dd48767b","tarball":"https://registry.npmjs.org/@1001-digital/ethereum-names/-/ethereum-names-0.3.0.tgz","fileCount":9,"integrity":"sha512-ANII971KETISXS3bqszjBKJ1wbmKr3ydyRJOlzn13V3VuM7wNl43MkbVrDXV9GzTAihW3574vhf5IHjZRGlxJw==","signatures":[{"sig":"MEUCIEB42AlfzLSvN/KzMtAqizyZghE8+LFoodIbjZaG5cL2AiEA1P/GmTqNWNAp91zxt4pSiDRHx6gGML0GttbEnb8vqns=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":80041},"main":"./dist/index.cjs","type":"module","_from":"file:1001-digital-ethereum-names-0.3.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"scripts":{"dev":"tsup --watch","lint":"biome check src","test":"tsx --test src/*.test.ts","build":"tsup","check":"biome check src && tsc --noEmit","clean":"rm -rf dist","format":"biome check --write src","release":"changeset publish","version":"changeset version","changeset":"changeset","typecheck":"tsc --noEmit"},"_npmUser":{"name":"jwahdatehagh","email":"jalil@1001.digital"},"_resolved":"/tmp/955ce006d24bc8fe2f7e79632e88601a/1001-digital-ethereum-names-0.3.0.tgz","_integrity":"sha512-ANII971KETISXS3bqszjBKJ1wbmKr3ydyRJOlzn13V3VuM7wNl43MkbVrDXV9GzTAihW3574vhf5IHjZRGlxJw==","repository":{"url":"git+https://github.com/1001-digital/ethereum-names.git","type":"git"},"_npmVersion":"10.9.8","description":"One clean API to resolve Ethereum names across ENS, the Gwei Name Service (GNS), and the Wei Name Service (WNS), powered by viem.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","tsup":"^8.5.0","viem":"^2.45.3","typescript":"~5.8.3","@types/node":"^22.19.11","@biomejs/biome":"^1.9.4","@changesets/cli":"^2.30.0","@changesets/changelog-github":"^0.5.1"},"peerDependencies":{"viem":"^2.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ethereum-names_0.3.0_1783321756556_0.25025560484189135","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@1001-digital/ethereum-names","version":"0.4.0","keywords":["ethereum","ens","gns","gwei","gwei-name-service","wns","wei","wei-name-service","name-service","resolver","viem","web3"],"author":{"name":"jalil.eth"},"license":"MIT","_id":"@1001-digital/ethereum-names@0.4.0","maintainers":[{"name":"jwahdatehagh","email":"jalil@1001.digital"}],"homepage":"https://github.com/1001-digital/ethereum-names#readme","bugs":{"url":"https://github.com/1001-digital/ethereum-names/issues"},"dist":{"shasum":"e4dfea9724ec5fb7d5bfe75c942e510fb408ca56","tarball":"https://registry.npmjs.org/@1001-digital/ethereum-names/-/ethereum-names-0.4.0.tgz","fileCount":9,"integrity":"sha512-4fVnLgkZ1PxF2TFZIR/dE3nGdd3C6a+zE5Bpn3usATflLUmaic2CWZHbpJaR16AbBBAOXuoT4PuBpfE7/WpjKg==","signatures":[{"sig":"MEUCIQCucz54bj24SMKg9Ts8e9Y50MdIi5MwSq4YWDtLBvf7nwIgC2NHOXy1l0bag2IRPk3CMmtLbYAYaQNdwXKZeWs4bb0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":192183},"main":"./dist/index.cjs","type":"module","_from":"file:1001-digital-ethereum-names-0.4.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"scripts":{"dev":"tsup --watch","lint":"biome check src","test":"tsx --test src/*.test.ts","build":"tsup","check":"biome check src && tsc --noEmit","clean":"rm -rf dist","format":"biome check --write src","release":"changeset publish","version":"changeset version","changeset":"changeset","typecheck":"tsc --noEmit"},"_npmUser":{"name":"jwahdatehagh","email":"jalil@1001.digital"},"_resolved":"/tmp/807843be247ef53a97a45fe1240b70ae/1001-digital-ethereum-names-0.4.0.tgz","_integrity":"sha512-4fVnLgkZ1PxF2TFZIR/dE3nGdd3C6a+zE5Bpn3usATflLUmaic2CWZHbpJaR16AbBBAOXuoT4PuBpfE7/WpjKg==","repository":{"url":"git+https://github.com/1001-digital/ethereum-names.git","type":"git"},"_npmVersion":"10.9.8","description":"One clean API to resolve Ethereum names across ENS, the Gwei Name Service (GNS), and the Wei Name Service (WNS), powered by viem.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","tsup":"^8.5.0","viem":"^2.45.3","typescript":"~5.8.3","@types/node":"^22.19.11","@biomejs/biome":"^1.9.4","@changesets/cli":"^2.30.0","@changesets/changelog-github":"^0.5.1"},"peerDependencies":{"viem":"^2.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ethereum-names_0.4.0_1788278360939_0.28442784734519333","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@1001-digital/ethereum-names","version":"0.5.0","keywords":["ethereum","ens","gns","gwei","gwei-name-service","wns","wei","wei-name-service","name-service","resolver","viem","web3"],"author":{"name":"jalil.eth"},"license":"MIT","_id":"@1001-digital/ethereum-names@0.5.0","maintainers":[{"name":"jwahdatehagh","email":"jalil@1001.digital"}],"homepage":"https://github.com/1001-digital/ethereum-names#readme","bugs":{"url":"https://github.com/1001-digital/ethereum-names/issues"},"dist":{"shasum":"5acda5135923f17c86aacf69a7d48e327f430006","tarball":"https://registry.npmjs.org/@1001-digital/ethereum-names/-/ethereum-names-0.5.0.tgz","fileCount":9,"integrity":"sha512-2HLjr+dRYQw3dmx6yiM1uDTBuAQXms08QYLQ0ea2akiQww7MQMfg4J9+9u3PS/kWGqJSBKh7lxlGSyOsXmTXCQ==","signatures":[{"sig":"MEUCIATK9QVmlAIWK+XBFSwH416xiQn4qcdZBxg83a5vJWPlAiEA4Hrhu561Z4+dqPrwGGs2Xwe+Nxyw56fBLdkLYu3dEjo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":196967},"main":"./dist/index.cjs","type":"module","_from":"file:1001-digital-ethereum-names-0.5.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"scripts":{"dev":"tsup --watch","lint":"biome check src","test":"tsx --test src/*.test.ts","build":"tsup","check":"biome check src && tsc --noEmit","clean":"rm -rf dist","format":"biome check --write src","release":"changeset publish","version":"changeset version","changeset":"changeset","typecheck":"tsc --noEmit"},"_npmUser":{"name":"jwahdatehagh","email":"jalil@1001.digital"},"_resolved":"/tmp/057e70814d3158390e888825f5125e88/1001-digital-ethereum-names-0.5.0.tgz","_integrity":"sha512-2HLjr+dRYQw3dmx6yiM1uDTBuAQXms08QYLQ0ea2akiQww7MQMfg4J9+9u3PS/kWGqJSBKh7lxlGSyOsXmTXCQ==","repository":{"url":"git+https://github.com/1001-digital/ethereum-names.git","type":"git"},"_npmVersion":"10.9.8","description":"One clean API to resolve Ethereum names across ENS, the Gwei Name Service (GNS), and the Wei Name Service (WNS), powered by viem.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","tsup":"^8.5.0","viem":"^2.45.3","typescript":"~5.8.3","@types/node":"^22.19.11","@biomejs/biome":"^1.9.4","@changesets/cli":"^2.30.0","@changesets/changelog-github":"^0.5.1"},"peerDependencies":{"viem":"^2.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ethereum-names_0.5.0_1788279723284_0.8317256983652448","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@1001-digital/ethereum-names","version":"0.6.0","description":"One clean API to resolve Ethereum names across ENS, the Gwei Name Service (GNS), and the Wei Name Service (WNS), powered by viem.","type":"module","publishConfig":{"access":"public"},"main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"sideEffects":false,"keywords":["ethereum","ens","gns","gwei","gwei-name-service","wns","wei","wei-name-service","name-service","resolver","viem","web3"],"author":{"name":"jalil.eth"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/1001-digital/ethereum-names.git"},"bugs":{"url":"https://github.com/1001-digital/ethereum-names/issues"},"homepage":"https://github.com/1001-digital/ethereum-names#readme","peerDependencies":{"viem":"^2.0.0"},"devDependencies":{"@biomejs/biome":"^1.9.4","@changesets/changelog-github":"^0.5.1","@changesets/cli":"^2.30.0","@types/node":"^22.19.11","tsup":"^8.5.0","tsx":"^4.21.0","typescript":"~5.8.3","viem":"^2.45.3"},"scripts":{"build":"tsup","dev":"tsup --watch","clean":"rm -rf dist","typecheck":"tsc --noEmit","test":"tsx --test src/*.test.ts","lint":"biome check src","format":"biome check --write src","check":"biome check src && tsc --noEmit","changeset":"changeset","version":"changeset version","release":"changeset publish"},"_id":"@1001-digital/ethereum-names@0.6.0","_integrity":"sha512-FUpnQTsQ1/tEKUmn+EEp2VLNfpifa5ui8biBSM8K5YdBdvliV7uy21GdB8BjWj27FWBkDaIex+fgf+lDl7RxSA==","_resolved":"/tmp/5d59906c427ee3faafa98fd5ef2784fe/1001-digital-ethereum-names-0.6.0.tgz","_from":"file:1001-digital-ethereum-names-0.6.0.tgz","_nodeVersion":"22.23.2","_npmVersion":"10.9.8","dist":{"integrity":"sha512-FUpnQTsQ1/tEKUmn+EEp2VLNfpifa5ui8biBSM8K5YdBdvliV7uy21GdB8BjWj27FWBkDaIex+fgf+lDl7RxSA==","shasum":"ff644e5bcc0e4f30284195c250c8e90cde49cd7e","tarball":"https://registry.npmjs.org/@1001-digital/ethereum-names/-/ethereum-names-0.6.0.tgz","fileCount":9,"unpackedSize":219418,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQC3ExKNNcYufCjXQnjPPvBqdPCa1KFIeBAUY4x4NJqgXQIgOqEYmlZ2aenZUHdy9U5694vKVYp2tTw8CbzKbEqtUHo="}]},"_npmUser":{"name":"jwahdatehagh","email":"jalil@1001.digital"},"directories":{},"maintainers":[{"name":"jwahdatehagh","email":"jalil@1001.digital"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ethereum-names_0.6.0_1788365442211_0.47563360542336164"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-30T23:50:31.819Z","modified":"2026-09-02T16:10:42.588Z","0.1.0":"2026-06-30T23:50:32.150Z","0.2.0":"2026-07-06T06:55:41.852Z","0.3.0":"2026-07-06T07:09:16.678Z","0.4.0":"2026-09-01T15:59:21.067Z","0.5.0":"2026-09-01T16:22:03.400Z","0.6.0":"2026-09-02T16:10:42.399Z"},"bugs":{"url":"https://github.com/1001-digital/ethereum-names/issues"},"author":{"name":"jalil.eth"},"license":"MIT","homepage":"https://github.com/1001-digital/ethereum-names#readme","keywords":["ethereum","ens","gns","gwei","gwei-name-service","wns","wei","wei-name-service","name-service","resolver","viem","web3"],"repository":{"type":"git","url":"git+https://github.com/1001-digital/ethereum-names.git"},"description":"One clean API to resolve Ethereum names across ENS, the Gwei Name Service (GNS), and the Wei Name Service (WNS), powered by viem.","maintainers":[{"name":"jwahdatehagh","email":"jalil@1001.digital"}],"readme":"# @1001-digital/ethereum-names\n\nOne clean, [viem](https://viem.sh)-powered API to resolve Ethereum names across\n[ENS](https://ens.domains), the [Gwei Name Service](https://gwei.domains) (GNS), and the\n[Wei Name Service](https://wei.domains) (WNS).\n\nPoint it at a name — `vitalik.eth`, `alice.gwei`, or `alice.wei` — and it figures out which\nsystem to ask. Point it at an address and it gives you back the primary name. No branching\nin your app code.\n\nIt also tells you **what resolved and why**: which system answered, whether the answer was\nverified, and whether anything else claimed the same name. Name systems increasingly\noverlap, and a wallet about to send funds needs to know when they do.\n\n## Install\n\n```bash\nnpm install @1001-digital/ethereum-names viem\n```\n\n`viem` is a peer dependency.\n\n## Usage\n\n```ts\nimport { createEthereumNames } from '@1001-digital/ethereum-names'\n\nconst names = createEthereumNames()\n\n// Forward: name → address (the system is detected from the name)\nawait names.resolve('vitalik.eth')    // ENS → '0xd8dA...' | null\nawait names.resolve('alice.gwei')     // GNS → '0x...'    | null\nawait names.resolve('alice.wei')      // WNS → '0x...'    | null\nawait names.resolve('alice')          // bare label → ENS by default (see bareLabel)\nawait names.resolve('0xd8dA...')      // address → returned checksummed\n\n// Reverse: address → primary name (tries ENS, then GNS, then WNS)\nawait names.reverse('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045')\n// => 'vitalik.eth' | 'alice.gwei' | 'alice.wei' | null\n\n// Reverse across ALL systems at once (when an address has names in each)\nawait names.reverseAll('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045')\n// => { ens: 'vitalik.eth', gns: 'vitalik.gwei', wns: 'vitalik.wei' }\n\n// Rich lookup: resolve or reverse, with the evidence behind the answer\nawait names.lookup('alice.wei')\n// => { input: 'alice.wei', name: 'alice.wei', address: '0x...', system: 'wns',\n//      status: 'resolved', verified: true, ambiguous: false, matches: [...] }\n\n// Records work across all systems\nawait names.getAvatar('vitalik.eth')\nawait names.getText('alice.wei', 'url')\n\n// Pure, offline system detection\nnames.system('alice.gwei')     // 'gns'\nnames.systemsFor('alice.gwei') // ['gns'] — every system claiming this name\n\n// Pure, offline profile links (\"view on ENS / GNS / WNS\")\nnames.profileUrl('vitalik.eth') // 'https://app.ens.domains/vitalik.eth'\nnames.profileUrl('alice.gwei')  // 'https://gwei.domains/#alice'\nnames.profileUrl('alice.wei')   // 'https://wei.domains/#alice'\n```\n\n## How resolution is routed\n\nEach system declares which names it claims. A name can be claimed by more than one — that\nis a **collision**, and it is handled explicitly rather than by first-match luck.\n\n| Input | Claimed by |\n| --- | --- |\n| `*.gwei` | GNS |\n| `*.wei` | WNS |\n| any suffix from a custom registry | that registry |\n| any other dotted name `*.eth`, `*.box`, … | ENS |\n| bare label (no dot) | every registry accepting bare labels — GNS and WNS |\n| `0x…` address | passed through (checksummed) |\n\nThe rules, in order:\n\n1. **Suffix claims win, longest first.** `.bar.foo` beats `.foo`, and `.gwei` is never\n   mistaken for `.wei`. Claiming a suffix takes it away from ENS — which is why `.eth` is\n   reserved and cannot be claimed by a registry.\n2. **Wildcard registries stack.** A registry with permissionless namespaces claims every\n   dotted name outside its `excludeSuffixes`, on top of any suffix claim. That is how a\n   name like `bob.gwei` ends up claimed by two systems.\n3. **ENS is the fallback** for any dotted name no registry claimed by suffix.\n\n`system(name)` returns the single preferred system, for UI that just wants a label.\n`systemsFor(name)` returns every claimant — more than one means a collision.\n\n### Bare labels\n\nA bare label like `alice` is ambiguous — GNS (`.gwei`) and WNS (`.wei`) both accept bare\nlabels, and they can point to different owners. Rather than guess, resolution follows the\n`bareLabel` option, which defaults to `ens`. Since ENS has no bare-label namespace, bare\nlabels resolve to `null` by default; set `bareLabel: 'gns'` or `'wns'` to opt a label like\n`alice` into that registry.\n\n### Collisions\n\nWhen several systems resolve one name to **different** addresses, the default is to refuse\nto guess:\n\n```ts\nconst result = await names.lookup('bob.gwei')\n\nif (result.status === 'ambiguous') {\n  // result.matches → [{ system: 'gns', address: '0x123…' },\n  //                   { system: 'xyz', address: '0xabc…' }]\n  // Ask the user which one they meant, then resolve it explicitly:\n  await names.resolveIn('gns', 'bob.gwei')\n}\n```\n\n`resolve()` returns `null` for an ambiguous name, so a payment flow fails closed instead of\nmisrouting. Change that with `collisions`:\n\n| `collisions` | Behavior |\n| --- | --- |\n| `'safe'` (default) | Never guess. `resolve()` → `null`, `lookup()` → `status: 'ambiguous'`. |\n| `'priority'` | Take the first match in `priority` order. |\n| `(candidates, input) => match` | Your own rule — e.g. `[...candidates].sort((a, b) => a.system.localeCompare(b.system))[0]` for a deterministic, explainable choice. |\n\n`ambiguous` stays `true` even when a rule picked a winner, so you can still warn.\n\n### Verification\n\nBy default, reverse lookups are **forward-verified**: after reading an address's primary\nname, the library resolves that name back and confirms it points to the same address before\ntrusting it. This guards against spoofed reverse records (ENS reverse records are not\nself-validating). Disable with `verify: false` to save a round-trip.\n\nA record that fails verification is reported rather than dropped:\n\n```ts\nconst result = await names.lookup('0xd8dA…')\nresult.status // 'unverified' — a name was found, but it does not own this address\nresult.name   // null — an unverified name is never presented as the answer\nresult.matches[0].name // 'someone-elses.eth' — what was claimed\n```\n\n## What resolved, and why\n\n`lookup()` returns the evidence a wallet needs to explain — or refuse — what it is about to\ndo. `resolve()` returns `null` for four different reasons; `lookup()` tells them apart.\n\n| Field | Meaning |\n| --- | --- |\n| `status` | `'resolved'` · `'not-found'` · `'unverified'` · `'ambiguous'` · `'error'` |\n| `verified` | Whether this answer is confirmed. Reverse records need a forward check; `false` also when `verify` is off — it always means \"nothing confirmed this\". |\n| `ambiguous` | Several systems resolved this name to **different** addresses. |\n| `matches` | What each system answered, including per-system `status` and `error`. |\n| `system` | Which system produced the answer. |\n\n`'error'` is deliberately distinct from `'not-found'`: \"the RPC failed\" and \"the name is\nunregistered\" are different facts, and only one of them is safe to show as \"no such name\".\n\nTo render a system without hardcoding a map of ids, ask the client what it knows:\n\n```ts\nnames.systems()\n// [{ id: 'ens', kind: 'ens', label: 'Ethereum Name Service', url: 'https://ens.domains', … },\n//  { id: 'gns', kind: 'registry', label: 'Gwei Name Service', suffixes: ['.gwei'], … }]\n\nconst result = await names.lookup('alice.gwei')\nnames.describe(result.system!)?.label // 'Gwei Name Service'\n```\n\n> **`label` and `url` are display data, not trust signals.** They come from whoever wrote\n> the config. Never render a descriptor as a verification badge — the trust signals are\n> `status`, `verified`, and `ambiguous`. A registry is free to call itself anything.\n\n## Profile links\n\nEvery system can declare where a name's public profile page lives, and\n`profileUrl(name)` builds the link offline — no network call — by routing the name exactly\nlike resolution does:\n\n```ts\nnames.profileUrl('vitalik.eth')        // 'https://app.ens.domains/vitalik.eth'\nnames.profileUrl('alice.gwei')         // 'https://gwei.domains/#alice'\nnames.profileUrl('alice.wei', 'wns')   // pin the system explicitly, skipping routing\nnames.profileUrl('unclaimed.foo')      // ENS fallback → 'https://app.ens.domains/unclaimed.foo'\n```\n\nIt returns `null` when nothing claims the name, the name is invalid in its system, or the\nsystem declares no profile URL. A standalone `profileUrl(name)` export does the same\nagainst the default registries, for code that never builds a client.\n\nCustom registries declare theirs via the `profileUrl` field — a template where `{name}`\nsubstitutes the canonical name and `{label}` the name with the matched suffix stripped\n(both URL-encoded), or a function from the canonical name to a full URL:\n\n```ts\n{ id: 'foo', suffixes: ['.foo'], contract: '0x…', profileUrl: 'https://foo.example/#{label}' }\n```\n\nThe URL format is a convention of each system's frontend, not part of any on-chain\ncontract — display data, with the same trust caveat as `label` and `url`.\n\n## Custom registries\n\nGNS and WNS are just two instances of the same shape: an on-chain registry exposing\n`computeId(string)`, `resolve(uint256)`, `reverseResolve(address)`, and\n`text(uint256, string)`. Any registry with that read interface can join the resolving path\n— no fork required. Pass it as `registries`, spreading `DEFAULT_REGISTRIES` so you *add* to\nGNS and WNS instead of replacing them:\n\n```ts\nimport { createEthereumNames, DEFAULT_REGISTRIES } from '@1001-digital/ethereum-names'\n\nconst names = createEthereumNames({\n  registries: [\n    ...DEFAULT_REGISTRIES,\n    { id: 'foo', suffixes: ['.foo'], contract: '0x…', label: 'Foo Names' },\n  ],\n})\n\nawait names.resolve('alice.foo')     // → '0x…' | null\nnames.systemsFor('alice.foo')        // → ['foo']\nawait names.reverseAll('0xd8dA…')    // → { ens, gns, wns, foo }\n```\n\nIds are **inferred**, so `reverseAll()` keys, `system()`, `bareLabel` and `priority` stay\nexactly typed — a typo is a compile error, not a silent `null`.\n\n| Registry field | Description |\n| --- | --- |\n| `id` | Names the system everywhere. Cannot be `'ens'`. |\n| `contract` | The registry address. |\n| `suffixes` | Suffixes it claims, leading dot included. The first is appended to bare labels. |\n| `bareLabels` | Whether a bare label (`alice`) can be a name here. |\n| `wildcard` | For permissionless namespaces: claims every dotted name. |\n| `excludeSuffixes` | Suffixes carved out of `wildcard`. |\n| `label`, `url` | Display data for `systems()`. Untrusted — see the note above. |\n| `profileUrl` | Where a name's profile page lives — a `{name}`/`{label}` template, or a function. Untrusted, same caveat. |\n\nRules enforced at construction, so a bad config throws instead of silently resolving to\n`null`: ids are unique, non-empty and never `'ens'`; contracts must be valid addresses;\nsuffixes must start with a dot and may not be `.eth`; a registry must claim *something*;\nand `bareLabel`/`priority` must name systems that exist.\n\nENS itself is not pluggable this way — it resolves through viem's universal resolver, which\nalready covers every TLD in the ENS root (`.eth`, `.box`, offchain CCIP-read names, …).\nThose work with no configuration at all.\n\n## Configuration\n\n```ts\nimport { createEthereumNames } from '@1001-digital/ethereum-names'\nimport { createPublicClient, http } from 'viem'\nimport { mainnet } from 'viem/chains'\n\n// Bring your own viem client (recommended for production)\nconst client = createPublicClient({ chain: mainnet, transport: http('https://my-rpc') })\nconst names = createEthereumNames({ client })\n\n// …or let the library create a mainnet client for you\nconst quick = createEthereumNames({ rpcUrl: 'https://my-rpc' })\n\n// Prefer GNS names on reverse lookups\nconst gnsFirst = createEthereumNames({ priority: ['gns', 'ens', 'wns'] })\n\n// Treat bare labels (e.g. `alice`) as `.gwei` names\nconst gwei = createEthereumNames({ bareLabel: 'gns' })\nawait gwei.resolve('alice') // → resolves alice.gwei\n```\n\n| Option | Type | Description |\n| --- | --- | --- |\n| `client` | `PublicClient` | A viem client to read from. Its chain must have ENS contracts. |\n| `rpcUrl` | `string` | RPC endpoint used when no `client` is given. |\n| `chain` | `Chain` | Chain used when no `client` is given. Defaults to `mainnet`. |\n| `registries` | `NameRegistry[]` | The non-ENS registries to resolve against. Defaults to `DEFAULT_REGISTRIES` (GNS + WNS). |\n| `gnsContract` | `Address` | Override the GNS contract address. |\n| `wnsContract` | `Address` | Override the WNS contract address. |\n| `bareLabel` | system id | System a bare label (no dot) resolves against. Defaults to `'ens'`. |\n| `priority` | system id`[]` | Order systems are tried in — reverse lookups, and `collisions: 'priority'`. Defaults to `['ens', …registries]`. |\n| `collisions` | `'safe' \\| 'priority' \\| fn` | What to do when a name resolves in several systems. Defaults to `'safe'`. |\n| `verify` | `boolean` | Forward-verify reverse lookups before trusting them. Defaults to `true`. |\n\n> **Note:** ENS resolution relies on viem's ENS actions, which require a chain with ENS\n> contracts configured (such as `mainnet`). GNS and WNS are live on Ethereum mainnet.\n\n## API\n\n### `createEthereumNames(config?) → EthereumNames`\n\n| Method | Returns | Description |\n| --- | --- | --- |\n| `resolve(nameOrAddress)` | `Promise<Address \\| null>` | Name → address. Addresses pass through, checksummed. `null` for ambiguous names. |\n| `resolveIn(system, name)` | `Promise<Address \\| null>` | Resolve in one named system, skipping routing. Throws on an unknown system. |\n| `reverse(address)` | `Promise<string \\| null>` | Address → primary name across systems. |\n| `reverseAll(address)` | `Promise<ReverseNames>` | Address → primary name from every configured system, keyed by id. |\n| `lookup(input)` | `Promise<ResolvedName>` | Resolve or reverse, with `status`, `verified`, `ambiguous` and `matches`. |\n| `getAvatar(name)` | `Promise<string \\| null>` | Avatar record (ENS avatar, or the registry's `avatar` text). |\n| `getText(name, key)` | `Promise<string \\| null>` | Arbitrary text record. |\n| `profileUrl(name, system?)` | `string \\| null` | Offline link to the name's profile page on its system's frontend. |\n| `system(name)` | system id `\\| null` | Offline detection — the single preferred system. |\n| `systemsFor(name)` | system id`[]` | Offline detection — every system claiming the name. |\n| `systems()` | `SystemDescriptor[]` | Describe every configured system, for UI. |\n| `describe(system)` | `SystemDescriptor \\| undefined` | Describe one system by id. |\n| `client` | `PublicClient` | The underlying viem client. |\n\nAlso exported: `detectSystem(name, bareLabel?, registries?)`,\n`detectSystems(name, registries?)`, `profileUrl(name, bareLabel?, registries?)`,\n`DEFAULT_REGISTRIES`, `DEFAULT_GNS_CONTRACT`, `DEFAULT_WNS_CONTRACT`, `RESERVED_SUFFIXES`,\nand the types `CollisionResolver`, `CollisionStrategy`, `EthereumNames`,\n`EthereumNamesConfig`, `MatchStatus`, `NameMatch`, `NameRegistry`, `NameSystem`,\n`ProfileUrl`, `RegistryId`, `ResolutionStatus`, `ResolvedName`, `ReverseNames`,\n`SystemDescriptor`, `SystemId`.\n\n## Credits\n\nGNS and WNS resolve against immutable mainnet registries; this library talks to them\ndirectly with a minimal ABI, so it ships with **zero runtime dependencies** (viem is a\npeer dependency). The registry interfaces come from\n[`@donnoh/gns-utils`](https://www.npmjs.com/package/@donnoh/gns-utils) by\n[lucadonnoh](https://github.com/lucadonnoh/gwei-names) and\n[`wns-utils`](https://www.npmjs.com/package/wns-utils) by\n[NaniDAO](https://github.com/NaniDAO/wns-utils).\n\n## License\n\nMIT © [1001.digital](https://1001.digital)\n","readmeFilename":"README.md"}