@toon-protocol/client 0.4.2
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 +208 -0
- package/dist/index.d.ts +966 -0
- package/dist/index.js +1728 -0
- package/dist/index.js.map +1 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# @toon-protocol/client
|
|
2
|
+
|
|
3
|
+
High-level TypeScript client for publishing Nostr events to the TOON protocol — an ILP-gated Nostr relay that enables sustainable relay operation through micropayments.
|
|
4
|
+
|
|
5
|
+
## What It Does
|
|
6
|
+
|
|
7
|
+
This client handles:
|
|
8
|
+
|
|
9
|
+
- **ILP Micropayments**: Pay to publish Nostr events (read is free)
|
|
10
|
+
- **Payment Channels**: Automatic on-chain channel creation with off-chain settlement via signed balance proofs
|
|
11
|
+
- **Unified Identity**: One Nostr key = one EVM address (both use secp256k1, derived automatically)
|
|
12
|
+
- **Multi-Hop Routing**: Publish to any destination address, not just your direct peer
|
|
13
|
+
- **Network Bootstrap**: Automatically discover and register with ILP peers via NIP-02 follow lists
|
|
14
|
+
- **TOON Encoding**: Native binary format for agent-friendly event encoding
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pnpm add @toon-protocol/client @toon-protocol/core @toon-protocol/relay nostr-tools
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Prerequisites
|
|
23
|
+
|
|
24
|
+
The client requires external services. Use docker-compose for local development:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Start genesis node
|
|
28
|
+
docker compose -p toon-genesis -f docker-compose-genesis.yml up -d
|
|
29
|
+
|
|
30
|
+
# Verify services are healthy
|
|
31
|
+
curl http://localhost:8080/health # ILP Connector (runtime)
|
|
32
|
+
curl http://localhost:8081/health # ILP Connector (admin)
|
|
33
|
+
curl http://localhost:3100/health # TOON BLS
|
|
34
|
+
# Nostr relay on ws://localhost:7100 (WebSocket, no HTTP endpoint)
|
|
35
|
+
|
|
36
|
+
# Stop infrastructure
|
|
37
|
+
docker compose -p toon-genesis -f docker-compose-genesis.yml down
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
| Service | Port | Purpose |
|
|
41
|
+
| --------------------------- | ---- | --------------------------------------------------- |
|
|
42
|
+
| **ILP Connector (Runtime)** | 8080 | Routes ILP packets to relay |
|
|
43
|
+
| **ILP Connector (Admin)** | 8081 | Manages peer configuration |
|
|
44
|
+
| **TOON BLS** | 3100 | Validates events, calculates pricing, stores events |
|
|
45
|
+
| **Nostr Relay** | 7100 | WebSocket relay for peer discovery (kind:10032) |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Quick Start
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { TOONClient } from '@toon-protocol/client';
|
|
53
|
+
import { generateSecretKey, getPublicKey, finalizeEvent } from 'nostr-tools/pure';
|
|
54
|
+
import { encodeEventToToon, decodeEventFromToon } from '@toon-protocol/relay';
|
|
55
|
+
|
|
56
|
+
// 1. Generate identity — one key gives you both Nostr and EVM identities
|
|
57
|
+
const secretKey = generateSecretKey();
|
|
58
|
+
const pubkey = getPublicKey(secretKey);
|
|
59
|
+
|
|
60
|
+
// 2. Create client
|
|
61
|
+
const client = new TOONClient({
|
|
62
|
+
connectorUrl: 'http://localhost:8080',
|
|
63
|
+
secretKey,
|
|
64
|
+
ilpInfo: {
|
|
65
|
+
pubkey,
|
|
66
|
+
ilpAddress: `g.toon.${pubkey.slice(0, 8)}`,
|
|
67
|
+
btpEndpoint: 'ws://localhost:3000',
|
|
68
|
+
},
|
|
69
|
+
toonEncoder: encodeEventToToon,
|
|
70
|
+
toonDecoder: decodeEventFromToon,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// 3. Start (bootstrap network, discover peers)
|
|
74
|
+
await client.start();
|
|
75
|
+
|
|
76
|
+
// Your EVM address is derived from the same key — no separate config needed
|
|
77
|
+
console.log(`EVM address: ${client.getEvmAddress()}`);
|
|
78
|
+
|
|
79
|
+
// 4. Publish event to relay via ILP payment
|
|
80
|
+
const event = finalizeEvent(
|
|
81
|
+
{ kind: 1, content: 'Hello from TOON!', tags: [], created_at: Math.floor(Date.now() / 1000) },
|
|
82
|
+
secretKey,
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
const result = await client.publishEvent(event);
|
|
86
|
+
if (result.success) {
|
|
87
|
+
console.log(`Published: ${result.eventId}`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// 5. Clean up
|
|
91
|
+
await client.stop();
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Payment Channels
|
|
97
|
+
|
|
98
|
+
The client supports EVM-based payment channels for off-chain settlement. Your EVM identity is derived from your Nostr `secretKey` automatically — no separate EVM key needed.
|
|
99
|
+
|
|
100
|
+
### Enabling Payment Channels
|
|
101
|
+
|
|
102
|
+
To use payment channels, add chain configuration. The client already has your EVM identity from `secretKey`:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
const client = new TOONClient({
|
|
106
|
+
connectorUrl: 'http://localhost:8080',
|
|
107
|
+
secretKey,
|
|
108
|
+
ilpInfo: { pubkey, ilpAddress: `g.toon.${pubkey.slice(0, 8)}`, btpEndpoint: 'ws://localhost:3000' },
|
|
109
|
+
toonEncoder: encodeEventToToon,
|
|
110
|
+
toonDecoder: decodeEventFromToon,
|
|
111
|
+
|
|
112
|
+
// Add chain config to enable payment channels
|
|
113
|
+
supportedChains: ['evm:anvil:31337'],
|
|
114
|
+
chainRpcUrls: { 'evm:anvil:31337': 'http://localhost:8545' },
|
|
115
|
+
settlementAddresses: { 'evm:anvil:31337': client.getEvmAddress()! },
|
|
116
|
+
tokenNetworks: { 'evm:anvil:31337': '0xCafac3dD18aC6c6e92c921884f9E4176737C052c' },
|
|
117
|
+
initialDeposit: '1000000000000000000', // 1 ETH in wei
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
await client.start();
|
|
121
|
+
|
|
122
|
+
// Channels are created automatically during bootstrap
|
|
123
|
+
const channels = client.getTrackedChannels();
|
|
124
|
+
console.log(`Tracking ${channels.length} payment channels`);
|
|
125
|
+
|
|
126
|
+
// Publish with signed balance proof
|
|
127
|
+
const channelId = channels[0];
|
|
128
|
+
const claim = await client.signBalanceProof(channelId, 1000n);
|
|
129
|
+
await client.publishEvent(event, { claim });
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### How It Works
|
|
133
|
+
|
|
134
|
+
1. **Bootstrap**: Client discovers peers via NIP-02 and kind:10032 events
|
|
135
|
+
2. **Channel Creation**: Opens on-chain payment channel using your derived EVM address
|
|
136
|
+
3. **Off-chain Payments**: Signed balance proofs settle payments off-chain
|
|
137
|
+
4. **Auto-tracking**: ChannelManager automatically tracks channels and increments nonces
|
|
138
|
+
|
|
139
|
+
### Using a Separate EVM Key (Advanced)
|
|
140
|
+
|
|
141
|
+
If you need a different EVM identity than your Nostr key (e.g., hardware wallet or custodial key), pass `evmPrivateKey` explicitly:
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
const client = new TOONClient({
|
|
145
|
+
// ... required config ...
|
|
146
|
+
evmPrivateKey: '0x...', // Overrides the default derivation from secretKey
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Documentation
|
|
153
|
+
|
|
154
|
+
- **[API Reference](docs/api-reference.md)** — Constructor, config interface, and all methods
|
|
155
|
+
- **[Error Handling](docs/error-handling.md)** — Error class hierarchy, codes, and usage patterns
|
|
156
|
+
- **[HTTP Adapters](docs/adapters.md)** — Low-level `HttpRuntimeClient`, `HttpConnectorAdmin`, and `withRetry`
|
|
157
|
+
- **[Troubleshooting](docs/troubleshooting.md)** — Common issues and solutions
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Testing
|
|
162
|
+
|
|
163
|
+
### Unit & Integration Tests
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
cd packages/client
|
|
167
|
+
pnpm test # Run all unit/integration tests
|
|
168
|
+
pnpm test:coverage # Run with coverage report
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### E2E Tests
|
|
172
|
+
|
|
173
|
+
E2E tests require the genesis node infrastructure:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
# Start infrastructure
|
|
177
|
+
docker compose -p toon-genesis -f docker-compose-genesis.yml up -d
|
|
178
|
+
sleep 10
|
|
179
|
+
|
|
180
|
+
# Run E2E tests
|
|
181
|
+
cd packages/client
|
|
182
|
+
pnpm test:e2e
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
See [tests/e2e/README.md](tests/e2e/README.md) for detailed E2E setup.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Examples
|
|
190
|
+
|
|
191
|
+
See [examples/client-example/](../../examples/client-example/) for standalone client examples:
|
|
192
|
+
|
|
193
|
+
- **01 - Publish Event**: Full client lifecycle with self-describing claims
|
|
194
|
+
- **02 - Payment Channel Lifecycle**: Multiple events with incrementing balance proofs
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Related Packages
|
|
199
|
+
|
|
200
|
+
- **[@toon-protocol/core](../core/)** — Core protocol (peer discovery, bootstrap)
|
|
201
|
+
- **[@toon-protocol/relay](../relay/)** — Nostr relay with ILP payment gating
|
|
202
|
+
- **[@toon-protocol/bls](../bls/)** — Business Logic Server (pricing, validation, storage)
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## License
|
|
207
|
+
|
|
208
|
+
MIT
|