feat(extensions): add NIP-05 identity extension #4

Open
padreug wants to merge 5 commits from feature/nip05 into dev
Owner

Summary

  • Implements Nostr NIP-05 for human-readable identity verification (username@domain)
  • Allows users to claim usernames mapped to their Nostr public keys
  • Serves /.well-known/nostr.json endpoint per the NIP-05 specification
  • Lightning Address support: NIP-05 usernames also work as Lightning Addresses for zaps
  • Includes optional relay hints in JSON response

RPC Methods

Method Auth Description
nip05.claim User Claim a username
nip05.release User Release your username
nip05.updateRelays User Update relay hints
nip05.getMyIdentity User Get your identity
nip05.lookup Public Look up by username
nip05.lookupByPubkey Public Look up by pubkey
nip05.listIdentities Admin List all identities
nip05.deactivate Admin Deactivate an identity
nip05.reactivate Admin Reactivate an identity

HTTP Endpoints

NIP-05 Identity:

GET /.well-known/nostr.json?name=alice

Returns:

{
  "names": { "alice": "abc123...hex" },
  "relays": { "abc123...hex": ["wss://relay.example.com"] }
}

Lightning Address (LUD-16):

GET /.well-known/lnurlp/alice

Returns LNURL-pay info enabling alice@domain to receive Lightning payments and NIP-57 zaps.

How Zaps Work

  1. Wallet resolves alice@domain via NIP-05 → gets pubkey
  2. Wallet requests /.well-known/lnurlp/alice → extension looks up username, returns LNURL-pay info
  3. Wallet completes LNURL-pay flow with NIP-57 zap request
  4. Lightning.Pub processes payment and publishes zap receipt

Validation

  • Usernames: lowercase alphanumeric + underscore, must start with letter
  • Length: 1-30 characters (configurable)
  • Reserved usernames blocked (admin, root, system, etc.)
  • One username per user per application

Test plan

  • Review NIP-05 extension code
  • Verify TypeScript compilation succeeds
  • Test username claiming and release
  • Test .well-known/nostr.json endpoint response format
  • Test .well-known/lnurlp/:username endpoint for Lightning Address
  • Test zap flow end-to-end
  • Test username validation rules

🤖 Generated with Claude Code

## Summary - Implements Nostr NIP-05 for human-readable identity verification (`username@domain`) - Allows users to claim usernames mapped to their Nostr public keys - Serves `/.well-known/nostr.json` endpoint per the NIP-05 specification - **Lightning Address support**: NIP-05 usernames also work as Lightning Addresses for zaps - Includes optional relay hints in JSON response ## RPC Methods | Method | Auth | Description | |--------|------|-------------| | `nip05.claim` | User | Claim a username | | `nip05.release` | User | Release your username | | `nip05.updateRelays` | User | Update relay hints | | `nip05.getMyIdentity` | User | Get your identity | | `nip05.lookup` | Public | Look up by username | | `nip05.lookupByPubkey` | Public | Look up by pubkey | | `nip05.listIdentities` | Admin | List all identities | | `nip05.deactivate` | Admin | Deactivate an identity | | `nip05.reactivate` | Admin | Reactivate an identity | ## HTTP Endpoints **NIP-05 Identity:** ``` GET /.well-known/nostr.json?name=alice ``` Returns: ```json { "names": { "alice": "abc123...hex" }, "relays": { "abc123...hex": ["wss://relay.example.com"] } } ``` **Lightning Address (LUD-16):** ``` GET /.well-known/lnurlp/alice ``` Returns LNURL-pay info enabling `alice@domain` to receive Lightning payments and NIP-57 zaps. ## How Zaps Work 1. Wallet resolves `alice@domain` via NIP-05 → gets pubkey 2. Wallet requests `/.well-known/lnurlp/alice` → extension looks up username, returns LNURL-pay info 3. Wallet completes LNURL-pay flow with NIP-57 zap request 4. Lightning.Pub processes payment and publishes zap receipt ## Validation - Usernames: lowercase alphanumeric + underscore, must start with letter - Length: 1-30 characters (configurable) - Reserved usernames blocked (admin, root, system, etc.) - One username per user per application ## Test plan - [ ] Review NIP-05 extension code - [ ] Verify TypeScript compilation succeeds - [ ] Test username claiming and release - [ ] Test `.well-known/nostr.json` endpoint response format - [ ] Test `.well-known/lnurlp/:username` endpoint for Lightning Address - [ ] Test zap flow end-to-end - [ ] Test username validation rules 🤖 Generated with [Claude Code](https://claude.com/claude-code)
padreug added 1 commit 2026-02-13 19:29:34 +00:00
feat(extensions): add NIP-05 identity extension
Some checks are pending
Docker Compose Actions Workflow / test (push) Waiting to run
4fea2aa1b1
Implements Nostr NIP-05 for human-readable identity verification:
- Username claiming and management (username@domain)
- /.well-known/nostr.json endpoint per spec
- Optional relay hints in JSON response
- Admin controls for identity management

RPC methods:
- nip05.claim - Claim a username
- nip05.release - Release your username
- nip05.updateRelays - Update relay hints
- nip05.getMyIdentity - Get your identity
- nip05.lookup - Look up by username
- nip05.lookupByPubkey - Look up by pubkey
- nip05.listIdentities - List all (admin)
- nip05.deactivate/reactivate - Admin controls

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
padreug force-pushed feature/nip05 from 4fea2aa1b1 to 0d67c37fc6 2026-02-13 20:06:34 +00:00 Compare
padreug force-pushed feature/nip05 from 0d67c37fc6 to d7bb1d9bc5 2026-03-04 20:23:16 +00:00 Compare
padreug force-pushed feature/nip05 from d7bb1d9bc5 to b519c0e447 2026-03-26 22:46:12 +00:00 Compare
Author
Owner

NIP-05 Spec Compliance Review

Compared the implementation against the NIP-05 spec and NIP-57 (zaps). The extension is ~90% complete. Here's what needs attention:

Must Fix

1. Username validation rejects hyphens (spec violation)
The regex /^[a-z][a-z0-9_]*$/ disallows hyphens. NIP-05 spec explicitly states:

"the <local-part> part MUST only use characters a-z0-9-_."

Fix: update to /^[a-z][a-z0-9_-]*$/ in nip05Manager.ts

2. HTTP type definitions missing from types.ts
HttpRoute, HttpRequest, HttpResponse are imported in index.ts but not defined in the extension system's types.ts. This blocks TypeScript compilation. The withdraw extension likely has these defined in its copy — need to consolidate into the shared types.ts from PR #3 (extension-loader).

3. getHttpRoutes() not in the Extension interface
Same issue — the method exists in the implementation but the interface in types.ts doesn't declare it. Needs adding as an optional method in PR #3.

Should Fix

4. No HTTP redirect prevention
NIP-05 spec: "The /.well-known/nostr.json endpoint MUST NOT return any HTTP redirects." This is likely handled at the reverse proxy level, but should be documented as a deployment requirement.

5. Verify zap configuration completeness
The /.well-known/lnurlp/:username endpoint calls ctx.getLnurlPayInfo() — need to verify the response includes allowsNostr: true and nostrPubkey fields per NIP-57. Without these, wallets won't send zap requests.

Nice-to-Have (Not Blocking)

  • No _@domain root identifier support (optional per spec, low priority)
  • No relay array size limit per user (could produce large responses)
  • No-name query returns up to 1000 identities (may want a tighter default)
  • No . (period) support in usernames (spec allows it but uncommon)

Looks Good

  • /.well-known/nostr.json response format correct
  • Relay hints in response (optional relays field)
  • CORS Access-Control-Allow-Origin: * header
  • Multi-tenancy via application scoping
  • One identity per user per application constraint
  • Reserved username blocking
  • RPC method surface is comprehensive (claim, release, lookup, admin controls)
  • Lightning Address integration via LUD-16
## NIP-05 Spec Compliance Review Compared the implementation against the [NIP-05 spec](https://github.com/nostr-protocol/nips/blob/master/05.md) and NIP-57 (zaps). The extension is ~90% complete. Here's what needs attention: ### Must Fix **1. Username validation rejects hyphens (spec violation)** The regex `/^[a-z][a-z0-9_]*$/` disallows hyphens. NIP-05 spec explicitly states: > "the `<local-part>` part MUST only use characters `a-z0-9-_.`" Fix: update to `/^[a-z][a-z0-9_-]*$/` in `nip05Manager.ts` **2. HTTP type definitions missing from `types.ts`** `HttpRoute`, `HttpRequest`, `HttpResponse` are imported in `index.ts` but not defined in the extension system's `types.ts`. This blocks TypeScript compilation. The withdraw extension likely has these defined in its copy — need to consolidate into the shared `types.ts` from PR #3 (extension-loader). **3. `getHttpRoutes()` not in the `Extension` interface** Same issue — the method exists in the implementation but the interface in `types.ts` doesn't declare it. Needs adding as an optional method in PR #3. ### Should Fix **4. No HTTP redirect prevention** NIP-05 spec: "The `/.well-known/nostr.json` endpoint MUST NOT return any HTTP redirects." This is likely handled at the reverse proxy level, but should be documented as a deployment requirement. **5. Verify zap configuration completeness** The `/.well-known/lnurlp/:username` endpoint calls `ctx.getLnurlPayInfo()` — need to verify the response includes `allowsNostr: true` and `nostrPubkey` fields per NIP-57. Without these, wallets won't send zap requests. ### Nice-to-Have (Not Blocking) - No `_@domain` root identifier support (optional per spec, low priority) - No relay array size limit per user (could produce large responses) - No-name query returns up to 1000 identities (may want a tighter default) - No `.` (period) support in usernames (spec allows it but uncommon) ### Looks Good - `/.well-known/nostr.json` response format correct - Relay hints in response (optional `relays` field) - CORS `Access-Control-Allow-Origin: *` header - Multi-tenancy via application scoping - One identity per user per application constraint - Reserved username blocking - RPC method surface is comprehensive (claim, release, lookup, admin controls) - Lightning Address integration via LUD-16
padreug force-pushed feature/nip05 from b519c0e447 to a2366c40f2 2026-04-01 17:16:03 +00:00 Compare
padreug force-pushed feature/nip05 from a2366c40f2 to 17727d3e31 2026-04-01 17:25:38 +00:00 Compare
padreug added 1 commit 2026-04-01 17:31:48 +00:00
fix(nip05): add configurable limits for relays per user and identity listing
Some checks are pending
Docker Compose Actions Workflow / test (push) Waiting to run
99d83efd56
Adds max_relays_per_user (default: 10) to prevent users from attaching
excessive relay URLs that inflate .well-known/nostr.json responses.
Enforced in both claimUsername and updateRelays.

Reduces the no-name listing limit from hardcoded 1000 to configurable
max_identities_listing (default: 100) for the /.well-known/nostr.json
endpoint when no ?name= parameter is provided.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
padreug force-pushed feature/nip05 from 99d83efd56 to bd0a657527 2026-04-02 19:03:00 +00:00 Compare
padreug changed target branch from feature/extension-loader to dev 2026-04-02 19:04:56 +00:00
padreug force-pushed feature/nip05 from bd0a657527 to f59073e589 2026-04-02 19:06:25 +00:00 Compare
Some checks failed
Docker Compose Actions Workflow / test (push) Has been cancelled
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feature/nip05:feature/nip05
git checkout feature/nip05

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git checkout dev
git merge --no-ff feature/nip05
git checkout feature/nip05
git rebase dev
git checkout dev
git merge --ff-only feature/nip05
git checkout feature/nip05
git rebase dev
git checkout dev
git merge --no-ff feature/nip05
git checkout dev
git merge --squash feature/nip05
git checkout dev
git merge --ff-only feature/nip05
git checkout dev
git merge feature/nip05
git push origin dev
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: aiolabs/lightning-pub#4
No description provided.