Skip to content

Commit 0b91326

Browse files
vveerrggclaude
andcommitted
feat: add NIP-46 remote signer support (v0.5.0)
Client-side Nip46AuthHandler for browser bunker auth and server-side Nip46SignerMiddleware for Express apps acting as NIP-46 signers. 25 new tests, updated docs with flow diagrams and API reference. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 18836ee commit 0b91326

19 files changed

Lines changed: 2073 additions & 50 deletions

CHANGELOG.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.5.0] - 2026-03-08
11+
12+
### Added
13+
- **NIP-46 Remote Signer Support** — full client and server-side NIP-46 authentication
14+
- `Nip46SignerMiddleware` — Express middleware that acts as a NIP-46 signer
15+
- `POST /request` — receive and respond to kind 24133 events
16+
- `GET /info` — signer metadata (pubkey, relays, supported methods)
17+
- `GET /bunker-uri` — generate bunker:// connection URI
18+
- In-memory session tracking with configurable timeout and periodic cleanup
19+
- `Nip46AuthHandler` — browser-side handler for authenticating via remote signers (bunkers)
20+
- Transport-agnostic via `Nip46Transport` interface (consumer provides relay I/O)
21+
- `connect()` / `authenticate()` / `validateSession()` / `destroy()` lifecycle
22+
- `createNip46Signer()` factory function (mirrors `createNostrAuth()` pattern)
23+
- New types: `Nip46AuthConfig`, `Nip46SignerConfig`, `Nip46AuthResult`
24+
- `nostr-crypto-utils/nip46` subpath module declaration in type definitions
25+
- esbuild alias for `nostr-crypto-utils/nip46` in browser bundle
26+
- 25 new tests (13 signer middleware, 12 auth handler)
27+
- Updated documentation: README, API reference, authentication flow, browser auth guide
28+
29+
### Changed
30+
- `nostr-crypto-utils` dependency upgraded from ^0.6.0 to ^0.7.0
31+
32+
## [0.4.0] - 2026-03-06
33+
34+
### Changed
35+
- Migrated build system from webpack to esbuild
36+
- Upgraded to Noble 2.0 (`@noble/curves` ^2.0.1, `@noble/hashes` ^2.0.1)
37+
- Upgraded to vitest 4, ESLint 10
38+
- Zero production vulnerabilities
39+
1040
## [0.3.5] - 2025-02-19
1141

1242
### Changed

README.md

Lines changed: 83 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Nostr Auth Middleware
22

3-
A focused, security-first authentication middleware for Nostr applications.
3+
A focused, security-first authentication middleware for Nostr applications. Supports both NIP-07 (browser extension) and NIP-46 (remote signer / bunker) authentication flows.
44

55
## Requirements
66

@@ -23,19 +23,26 @@ Developers using this middleware must inform their users about the critical natu
2323

2424
### ESM (Recommended)
2525
```javascript
26-
import { NostrAuthMiddleware } from 'nostr-auth-middleware';
26+
import { NostrAuthMiddleware, Nip46SignerMiddleware } from 'nostr-auth-middleware';
2727
```
2828

2929
### CommonJS
3030
```javascript
31-
const { NostrAuthMiddleware } = require('nostr-auth-middleware');
31+
const { NostrAuthMiddleware, Nip46SignerMiddleware } = require('nostr-auth-middleware');
3232
```
3333

3434
### Browser
3535
```html
3636
<script src="dist/browser/nostr-auth-middleware.min.js"></script>
3737
<script>
38+
// NIP-07 (browser extension)
3839
const auth = new NostrAuthMiddleware.NostrBrowserAuth();
40+
41+
// NIP-46 (remote signer / bunker)
42+
const nip46 = new NostrAuthMiddleware.Nip46AuthHandler({
43+
bunkerUri: 'bunker://...?relay=wss://relay.example.com',
44+
serverUrl: 'https://auth.example.com'
45+
});
3946
</script>
4047
```
4148

@@ -55,26 +62,32 @@ This middleware follows key principles that promote security, auditability, and
5562

5663
### 3. Integration Ready
5764
```
58-
+---------------+
59-
| Client App |
60-
+-------+-------+
61-
|
62-
v
63-
+---------------+
64-
| Nostr Auth | <-- This Service
65-
| Service | Simple Auth Only
66-
+-------+-------+
67-
|
68-
v
69-
+---------------+
70-
| App Platform | <-- Your Business Logic
71-
| API | User Tiers
72-
+---------------+ Rate Limits
65+
+------------------+ +------------------+
66+
| Client App | | NIP-46 Bunker |
67+
| (NIP-07 ext or | | (Remote Signer) |
68+
| NIP-46 bunker) | +--------+---------+
69+
+--------+---------+ |
70+
| |
71+
v kind 24133 v
72+
+----------------------------------+
73+
| Nostr Auth Service | <-- This Service
74+
| NIP-07 challenge/verify | Simple Auth Only
75+
| NIP-46 signer middleware |
76+
+----------------+-----------------+
77+
|
78+
v
79+
+------------------+
80+
| App Platform | <-- Your Business Logic
81+
| API | User Tiers
82+
+------------------+ Rate Limits
7383
```
7484

7585
## Core Features
7686

77-
- Authentication: NIP-07 Compatible Authentication
87+
- **NIP-07 Authentication**: Browser extension auth via `window.nostr` (nos2x, Alby, NostrKey, etc.)
88+
- **NIP-46 Authentication**: Remote signer / bunker auth via encrypted kind 24133 events
89+
- **NIP-46 Signer Middleware**: Express middleware to act as a NIP-46 signer (accept remote signing requests)
90+
- **NIP-46 Client Handler**: Browser-side handler to authenticate via remote signers
7891
- Enrollment: Secure User Enrollment with Nostr
7992
- Validation: Comprehensive Event Validation
8093
- Cryptography: Advanced Cryptographic Operations
@@ -198,7 +211,9 @@ Profile Cache Cleared: { pubkey }
198211
## Documentation
199212

200213
- [Getting Started](docs/getting-started.md) - Quick start guide
201-
- [API Documentation](docs/api.md) - API endpoints and usage
214+
- [API Documentation](docs/api.md) - Full API reference (NIP-07 + NIP-46)
215+
- [Authentication Flow](docs/authentication-flow.md) - NIP-07 and NIP-46 flow diagrams
216+
- [Browser Authentication](docs/browser-authentication.md) - Client-side auth (NIP-07 + NIP-46)
202217
- [Security Guide](docs/security.md) - Security best practices and key management
203218
- [TypeScript Guide](docs/typescript.md) - TypeScript declaration patterns and best practices
204219

@@ -250,6 +265,54 @@ const challenge = await auth.signChallenge();
250265
const isValid = await auth.validateSession(session);
251266
```
252267

268+
## NIP-46 Remote Signer Authentication
269+
270+
For applications that authenticate users via NIP-46 bunkers (remote signers like NostrKey), instead of directly through browser extensions.
271+
272+
### Client Side (Browser)
273+
274+
```typescript
275+
import { Nip46AuthHandler } from 'nostr-auth-middleware/browser';
276+
277+
const auth = new Nip46AuthHandler({
278+
bunkerUri: 'bunker://<remote-pubkey>?relay=wss://relay.example.com&secret=...',
279+
serverUrl: 'https://auth.example.com',
280+
});
281+
282+
// Provide your own relay transport
283+
auth.setTransport({
284+
sendEvent: async (event) => { /* publish to relay */ },
285+
subscribe: (filter, onEvent) => { /* subscribe and call onEvent */ return () => {}; },
286+
});
287+
288+
await auth.connect();
289+
const result = await auth.authenticate();
290+
// result: { pubkey, signedEvent, sessionInfo, timestamp }
291+
```
292+
293+
### Server Side (Express Signer Middleware)
294+
295+
```typescript
296+
import { Nip46SignerMiddleware, createNip46Signer } from 'nostr-auth-middleware';
297+
298+
const signer = createNip46Signer(
299+
{
300+
signerSecretKey: process.env.SIGNER_SECRET_KEY,
301+
relays: ['wss://relay.example.com'],
302+
secret: 'optional-connection-secret',
303+
},
304+
{
305+
getPublicKey: () => myPubkey,
306+
signEvent: (eventJson) => JSON.stringify(signMyEvent(JSON.parse(eventJson))),
307+
}
308+
);
309+
310+
app.use('/nip46', signer.getRouter());
311+
// Routes: POST /nip46/request, GET /nip46/info, GET /nip46/bunker-uri
312+
```
313+
314+
See the [Authentication Flow Guide](docs/authentication-flow.md) for detailed NIP-46 sequence diagrams.
315+
253316
## Development Mode
254317

255318
Features enabled in development mode:

0 commit comments

Comments
 (0)