@toon-protocol/relay 1.3.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -93
- package/dist/chunk-745ADETR.js +1027 -0
- package/dist/chunk-745ADETR.js.map +1 -0
- package/dist/cli.js +38 -206
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +107 -977
- package/dist/index.js +6 -447
- package/dist/index.js.map +1 -1
- package/package.json +4 -9
- package/dist/chunk-ZKWFGHZ7.js +0 -2029
- package/dist/chunk-ZKWFGHZ7.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
# @toon-protocol/relay
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A Nostr relay app: free NIP-01 WebSocket reads plus an HTTP `POST /write`
|
|
4
|
+
surface for storing events.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
The relay contains **no ILP, connector, settlement, or pricing logic**. Payment
|
|
7
|
+
is enforced entirely upstream by an external terminator — by the time a write
|
|
8
|
+
reaches this process it is already proven paid, so the relay simply stores the
|
|
9
|
+
event and serves reads.
|
|
6
10
|
|
|
7
11
|
## Install
|
|
8
12
|
|
|
@@ -10,6 +14,41 @@ ILP-gated Nostr relay with payment verification, event storage, and dynamic pric
|
|
|
10
14
|
npm install @toon-protocol/relay
|
|
11
15
|
```
|
|
12
16
|
|
|
17
|
+
## Run (CLI)
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
NOSTR_SECRET_KEY=<64-char-hex> npx @toon-protocol/relay
|
|
21
|
+
# reads: ws://localhost:7100
|
|
22
|
+
# writes: http://localhost:3100/write
|
|
23
|
+
# health: http://localhost:3100/health
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
| Env var | Default | Description |
|
|
27
|
+
|---------|---------|-------------|
|
|
28
|
+
| `TOON_SECRET_KEY` / `NOSTR_SECRET_KEY` | — | 64-char hex identity key (one of these or `TOON_MNEMONIC` is required) |
|
|
29
|
+
| `TOON_MNEMONIC` | — | BIP-39 mnemonic (NIP-06 derivation) |
|
|
30
|
+
| `TOON_RELAY_PORT` | `7100` | WebSocket read port |
|
|
31
|
+
| `TOON_BLS_PORT` | `3100` | HTTP write/health port |
|
|
32
|
+
| `TOON_DATA_DIR` | `./data` | SQLite data directory |
|
|
33
|
+
| `TOON_DEV_MODE` | `false` | Skip event-signature verification on `POST /write` |
|
|
34
|
+
|
|
35
|
+
## Run (programmatic)
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { startRelay } from '@toon-protocol/relay';
|
|
39
|
+
|
|
40
|
+
const relay = await startRelay({ secretKey });
|
|
41
|
+
// ... POST /write on 3100, read NIP-01 on 7100 ...
|
|
42
|
+
await relay.stop();
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## HTTP surface
|
|
46
|
+
|
|
47
|
+
| Method | Path | Description |
|
|
48
|
+
|--------|------|-------------|
|
|
49
|
+
| `POST` | `/write` | Store an event. Body `{ "event": <NostrEvent> }`. Trusts injected `X-TOON-Payer`/`-Amount`/`-Chain` headers (echoed, not validated); verifies only the event signature. |
|
|
50
|
+
| `GET` | `/health` | Liveness, identity (`pubkey`), `capabilities`, and `version`. |
|
|
51
|
+
|
|
13
52
|
## WebSocket Relay Server
|
|
14
53
|
|
|
15
54
|
NIP-01 compliant WebSocket server that stores and serves Nostr events in TOON format.
|
|
@@ -21,124 +60,43 @@ const eventStore = new SqliteEventStore('./events.db');
|
|
|
21
60
|
const relay = new NostrRelayServer({ port: 7100 }, eventStore);
|
|
22
61
|
|
|
23
62
|
await relay.start();
|
|
24
|
-
|
|
25
|
-
console.log(`Connected clients: ${relay.getClientCount()}`);
|
|
26
|
-
|
|
27
|
-
// Push an event to all matching subscriptions
|
|
28
|
-
relay.broadcastEvent(event);
|
|
29
|
-
|
|
63
|
+
relay.broadcastEvent(event); // push to matching subscriptions
|
|
30
64
|
await relay.stop();
|
|
31
65
|
```
|
|
32
66
|
|
|
33
|
-
### Configuration
|
|
34
|
-
|
|
35
|
-
```ts
|
|
36
|
-
import { DEFAULT_RELAY_CONFIG } from '@toon-protocol/relay';
|
|
37
|
-
|
|
38
|
-
const config = {
|
|
39
|
-
port: 7100, // Default: 7000
|
|
40
|
-
maxConnections: 100, // Default: 100
|
|
41
|
-
maxSubscriptionsPerConnection: 20, // Default: 20
|
|
42
|
-
maxFiltersPerSubscription: 10, // Default: 10
|
|
43
|
-
databasePath: './events.db', // Default: ':memory:'
|
|
44
|
-
};
|
|
45
|
-
```
|
|
46
|
-
|
|
47
67
|
## Event Storage
|
|
48
68
|
|
|
49
|
-
Two built-in storage backends.
|
|
50
|
-
|
|
51
69
|
```ts
|
|
52
70
|
import { InMemoryEventStore, SqliteEventStore } from '@toon-protocol/relay';
|
|
53
71
|
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
// SQLite (for persistent storage)
|
|
58
|
-
const sqlStore = new SqliteEventStore('./events.db');
|
|
72
|
+
const memStore = new InMemoryEventStore(); // ephemeral
|
|
73
|
+
const sqlStore = new SqliteEventStore('./events.db'); // persistent
|
|
59
74
|
|
|
60
|
-
// Both implement the EventStore interface
|
|
61
75
|
memStore.store(event);
|
|
62
76
|
const found = memStore.get(event.id);
|
|
63
77
|
const results = memStore.query([{ kinds: [1], limit: 10 }]);
|
|
64
78
|
```
|
|
65
79
|
|
|
66
|
-
## Business Logic Server (BLS)
|
|
67
|
-
|
|
68
|
-
HTTP server that verifies ILP payment packets, validates events, and gates writes behind payment.
|
|
69
|
-
|
|
70
|
-
```ts
|
|
71
|
-
import { BusinessLogicServer, SqliteEventStore } from '@toon-protocol/relay';
|
|
72
|
-
|
|
73
|
-
const eventStore = new SqliteEventStore('./events.db');
|
|
74
|
-
const bls = new BusinessLogicServer({
|
|
75
|
-
basePricePerByte: 10n,
|
|
76
|
-
ownerPubkey: 'abc123...', // Owner events bypass payment
|
|
77
|
-
}, eventStore);
|
|
78
|
-
|
|
79
|
-
// Start HTTP server
|
|
80
|
-
bls.listen(3100);
|
|
81
|
-
|
|
82
|
-
// Or handle packets directly
|
|
83
|
-
const response = bls.handlePacket({
|
|
84
|
-
amount: '5000',
|
|
85
|
-
destination: 'g.toon.node-a',
|
|
86
|
-
data: 'base64-encoded-toon-event',
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
if (response.accept) {
|
|
90
|
-
console.log('Event stored:', response.metadata?.eventId);
|
|
91
|
-
}
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
### Endpoints
|
|
95
|
-
|
|
96
|
-
| Method | Path | Description |
|
|
97
|
-
|--------|------|-------------|
|
|
98
|
-
| `GET` | `/health` | Health check with pricing, capabilities, chain info |
|
|
99
|
-
| `POST` | `/handle-packet` | Process ILP payment packets |
|
|
100
|
-
|
|
101
|
-
## Pricing Service
|
|
102
|
-
|
|
103
|
-
Dynamic per-byte pricing with kind-specific overrides.
|
|
104
|
-
|
|
105
|
-
```ts
|
|
106
|
-
import { PricingService } from '@toon-protocol/relay';
|
|
107
|
-
|
|
108
|
-
const pricing = new PricingService({
|
|
109
|
-
basePricePerByte: 10n,
|
|
110
|
-
kindOverrides: new Map([
|
|
111
|
-
[1, 5n], // Short notes: cheaper
|
|
112
|
-
[30023, 20n], // Long-form articles: premium
|
|
113
|
-
]),
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
const price = pricing.computePrice(1, eventSizeInBytes);
|
|
117
|
-
```
|
|
118
|
-
|
|
119
80
|
## TOON Codec
|
|
120
81
|
|
|
121
|
-
Re-exported from [`@toon-protocol/core`](
|
|
82
|
+
Re-exported from [`@toon-protocol/core`](https://github.com/toon-protocol/core) for convenience.
|
|
122
83
|
|
|
123
84
|
```ts
|
|
124
85
|
import { encodeEventToToon, decodeEventFromToon } from '@toon-protocol/relay';
|
|
125
|
-
|
|
126
|
-
const toonBytes = encodeEventToToon(nostrEvent);
|
|
127
|
-
const event = decodeEventFromToon(toonBytes);
|
|
128
86
|
```
|
|
129
87
|
|
|
130
88
|
## Full API
|
|
131
89
|
|
|
132
90
|
| Category | Exports |
|
|
133
91
|
|----------|---------|
|
|
134
|
-
| **
|
|
135
|
-
| **
|
|
136
|
-
| **
|
|
137
|
-
| **
|
|
92
|
+
| **Launcher** | `startRelay`, `RelayConfig`, `RelayInstance`, `RelaySubscription`, `ResolvedRelayConfig` |
|
|
93
|
+
| **Relay** | `NostrRelayServer`, `ConnectionHandler`, `RelayServerConfig`, `DEFAULT_RELAY_CONFIG` |
|
|
94
|
+
| **Storage** | `EventStore`, `InMemoryEventStore`, `SqliteEventStore`, `RelayError` |
|
|
95
|
+
| **Write/Health** | `createWriteHandler`, `createHealthResponse` |
|
|
138
96
|
| **Codec** | `encodeEventToToon`, `decodeEventFromToon`, `ToonEncodeError`, `ToonDecodeError` |
|
|
97
|
+
| **Subscriber** | `RelaySubscriber`, `RelaySubscriberConfig` |
|
|
139
98
|
| **Filter** | `matchFilter` |
|
|
140
|
-
| **
|
|
141
|
-
| **Constants** | `ILP_ERROR_CODES`, `PUBKEY_REGEX`, `VERSION` |
|
|
99
|
+
| **Constants** | `VERSION` |
|
|
142
100
|
|
|
143
101
|
## License
|
|
144
102
|
|