nostr-wot-sdk 0.7.0 → 0.8.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.
Files changed (46) hide show
  1. package/README.md +16 -668
  2. package/dist/data/cache/index.cjs +14 -0
  3. package/dist/data/cache/index.cjs.map +1 -0
  4. package/dist/data/cache/index.d.cts +1 -0
  5. package/dist/data/cache/index.d.ts +1 -0
  6. package/dist/data/cache/index.js +3 -0
  7. package/dist/data/cache/index.js.map +1 -0
  8. package/dist/data/index.cjs +14 -0
  9. package/dist/data/index.cjs.map +1 -0
  10. package/dist/data/index.d.cts +1 -0
  11. package/dist/data/index.d.ts +1 -0
  12. package/dist/data/index.js +3 -0
  13. package/dist/data/index.js.map +1 -0
  14. package/dist/index.cjs +9 -616
  15. package/dist/index.cjs.map +1 -0
  16. package/dist/index.d.cts +1 -623
  17. package/dist/index.d.ts +1 -623
  18. package/dist/index.js +3 -607
  19. package/dist/index.js.map +1 -0
  20. package/dist/react/index.cjs +32 -910
  21. package/dist/react/index.cjs.map +1 -1
  22. package/dist/react/index.d.cts +36 -729
  23. package/dist/react/index.d.ts +36 -729
  24. package/dist/react/index.js +22 -902
  25. package/dist/react/index.js.map +1 -1
  26. package/dist/relay/index.cjs +7 -873
  27. package/dist/relay/index.cjs.map +1 -1
  28. package/dist/relay/index.d.cts +1 -280
  29. package/dist/relay/index.d.ts +1 -280
  30. package/dist/relay/index.js +1 -874
  31. package/dist/relay/index.js.map +1 -1
  32. package/dist/relay/react/index.cjs +7 -960
  33. package/dist/relay/react/index.cjs.map +1 -1
  34. package/dist/relay/react/index.d.cts +1 -342
  35. package/dist/relay/react/index.d.ts +1 -342
  36. package/dist/relay/react/index.js +1 -955
  37. package/dist/relay/react/index.js.map +1 -1
  38. package/dist/solid/index.cjs +7 -906
  39. package/dist/solid/index.cjs.map +1 -1
  40. package/dist/solid/index.d.cts +1 -740
  41. package/dist/solid/index.d.ts +1 -740
  42. package/dist/solid/index.js +1 -901
  43. package/dist/solid/index.js.map +1 -1
  44. package/package.json +35 -29
  45. package/CHANGELOG.md +0 -310
  46. package/LICENSE +0 -21
package/README.md CHANGED
@@ -1,677 +1,25 @@
1
1
  # nostr-wot-sdk
2
2
 
3
- JavaScript/TypeScript SDK for querying Nostr Web of Trust. Includes first-class React and SolidJS support.
3
+ > **This package is a back-compat meta re-export.** New code should depend on the scoped packages directly.
4
4
 
5
- ## Install
6
- ```bash
7
- npm install nostr-wot-sdk
8
- ```
9
-
10
- ## Quick Start
11
-
12
- ### With Browser Extension (Recommended)
13
-
14
- Install the [Nostr WoT Extension](https://github.com/nostr-wot/nostr-wot-extension) for the best experience. The extension downloads your follow graph locally and works across all websites.
15
-
16
- ```javascript
17
- import { WoT } from 'nostr-wot-sdk';
18
-
19
- // The SDK automatically uses the extension when available
20
- const wot = new WoT({
21
- fallback: {
22
- oracle: 'https://nostr-wot.com',
23
- myPubkey: 'abc123...' // Used only if extension unavailable
24
- }
25
- });
26
-
27
- // Check distance
28
- const hops = await wot.getDistance('def456...');
29
- console.log(hops); // 2
30
-
31
- // Boolean check
32
- const trusted = await wot.isInMyWoT('def456...', { maxHops: 3 });
33
- console.log(trusted); // true
34
-
35
- // Trust score (from extension)
36
- const score = await wot.getTrustScore('def456...');
37
- console.log(score); // 0.72
38
- ```
39
-
40
- When the extension is installed, **it always takes priority** — the SDK uses the extension's pubkey and locally-cached follow graph automatically.
41
-
42
- ### Without Extension (Oracle Fallback)
43
-
44
- ```javascript
45
- import { WoT } from 'nostr-wot-sdk';
46
-
47
- const wot = new WoT({
48
- oracle: 'https://nostr-wot.com',
49
- myPubkey: 'abc123...' // Required for oracle fallback
50
- });
51
-
52
- const hops = await wot.getDistance('def456...');
53
- ```
54
-
55
- ## Features
56
-
57
- - **Extension-First** — Automatically uses browser extension when available
58
- - **Simple API** — Three methods cover most use cases
59
- - **Cross-Site Trust** — Extension provides same WoT data on all websites
60
- - **Offline Support** — Extension caches data locally for offline queries
61
- - **Batch Queries** — Check multiple pubkeys efficiently
62
- - **Relay Utilities** — Reusable relay pool, query batching, and stats tracking
63
- - **TypeScript** — Full type definitions included
64
-
65
- ## API Reference
66
-
67
- ### Constructor
68
- ```javascript
69
- const wot = new WoT(options);
70
- ```
71
-
72
- | Option | Type | Default | Description |
73
- |--------|------|---------|-------------|
74
- | `oracle` | string | `'https://nostr-wot.com'` | Oracle API URL (fallback when extension unavailable) |
75
- | `myPubkey` | string | — | Your pubkey (optional - fetched from extension when available) |
76
- | `maxHops` | number | `3` | Default max search depth |
77
- | `timeout` | number | `5000` | Request timeout (ms) |
78
- | `fallback` | object | — | Fallback config when extension unavailable |
79
- | `extensionId` | string | — | Chrome Web Store extension ID (for detecting "installed but not enabled" state) |
80
-
81
- Trust scores are calculated by the extension and not configurable via the SDK.
82
-
83
- **Note:** When the extension is installed, it always takes priority over `myPubkey` or `oracle` settings.
84
-
85
- ### Methods
86
-
87
- #### `getDistance(target, options?)`
88
-
89
- Get shortest path length to target pubkey.
90
- ```javascript
91
- const hops = await wot.getDistance('def456...');
92
- // Returns: number | null
93
- ```
94
-
95
- #### `isInMyWoT(target, options?)`
96
-
97
- Check if target is within your Web of Trust.
98
- ```javascript
99
- const trusted = await wot.isInMyWoT('def456...', { maxHops: 2 });
100
- // Returns: boolean
101
- ```
102
-
103
- #### `getTrustScore(target)`
104
-
105
- Get computed trust score from the extension.
106
- ```javascript
107
- const score = await wot.getTrustScore('def456...');
108
- // Returns: number (0-1), or 0 if extension unavailable
109
- ```
110
-
111
- #### `getDistanceBetween(from, to, options?)`
112
-
113
- Get distance between any two pubkeys.
114
- ```javascript
115
- const hops = await wot.getDistanceBetween('abc...', 'def...');
116
- // Returns: number | null
117
- ```
118
-
119
- #### `batchCheck(targets, options?)`
120
-
121
- Check multiple pubkeys efficiently.
122
- ```javascript
123
- const results = await wot.batchCheck(['pk1...', 'pk2...', 'pk3...']);
124
- // Returns: Map<string, BatchResult>
125
- ```
126
-
127
- #### `getDetails(target, options?)`
128
-
129
- Get distance, path count, and score details.
130
- ```javascript
131
- const details = await wot.getDetails('def456...');
132
- // Returns: { hops: 2, paths: 5, score: 0.65 }
133
- // Oracle may also return: bridges, mutual (but score will be 0)
134
- ```
135
-
136
- #### `getMyPubkey()`
137
-
138
- Get the current pubkey (from extension or fallback).
139
- ```javascript
140
- const pubkey = await wot.getMyPubkey();
141
- // Returns: string
142
- ```
143
-
144
- #### `isUsingExtension()`
145
-
146
- Check if extension is available and being used.
147
- ```javascript
148
- const usingExt = await wot.isUsingExtension();
149
- // Returns: boolean
150
- ```
151
-
152
- #### `getExtensionStatus()`
153
-
154
- Get detailed extension connection status. Useful for showing appropriate UI based on why the extension isn't working.
155
- ```javascript
156
- const status = await wot.getExtensionStatus();
157
- // Returns: 'connected' | 'not-enabled' | 'unavailable' | 'not-browser'
158
- ```
159
-
160
- | Status | Description |
161
- |--------|-------------|
162
- | `'connected'` | Extension is enabled and working on this domain |
163
- | `'not-enabled'` | Extension is installed but not enabled for this domain |
164
- | `'unavailable'` | Extension is not installed (or using local dev build) |
165
- | `'not-browser'` | Running in SSR/Node.js environment |
166
-
167
- **Note:** Detecting `'not-enabled'` requires providing the `extensionId` option.
168
-
169
- #### `getExtensionConfig()`
170
-
171
- Get extension's configuration.
172
- ```javascript
173
- const config = await wot.getExtensionConfig();
174
- // Returns: { maxHops: 3, timeout: 5000, scoring: {...} } or null
175
- ```
176
-
177
- ### Batch Operations
178
-
179
- #### `getDistanceBatch(targets, options?)`
180
-
181
- Get distances for multiple pubkeys in a single call.
182
- ```javascript
183
- // Default (just hops)
184
- const distances = await wot.getDistanceBatch(['pk1...', 'pk2...']);
185
- // Returns: { 'pk1...': 2, 'pk2...': null }
186
-
187
- // With paths
188
- const withPaths = await wot.getDistanceBatch(['pk1...', 'pk2...'], { includePaths: true });
189
- // Returns: { 'pk1...': { hops: 2, paths: 5 }, 'pk2...': null }
190
-
191
- // With scores
192
- const withScores = await wot.getDistanceBatch(['pk1...', 'pk2...'], { includeScores: true });
193
- // Returns: { 'pk1...': { hops: 2, score: 0.65 }, 'pk2...': null }
194
-
195
- // With both
196
- const full = await wot.getDistanceBatch(['pk1...', 'pk2...'], { includePaths: true, includeScores: true });
197
- // Returns: { 'pk1...': { hops: 2, paths: 5, score: 0.65 }, 'pk2...': null }
198
-
199
- // Legacy boolean still works (backwards compatible)
200
- const legacy = await wot.getDistanceBatch(['pk1...'], true); // same as { includePaths: true }
201
- ```
202
-
203
- #### `getTrustScoreBatch(targets)`
204
-
205
- Get trust scores for multiple pubkeys in a single call.
206
- ```javascript
207
- const scores = await wot.getTrustScoreBatch(['pk1...', 'pk2...']);
208
- // Returns: { 'pk1...': 0.72, 'pk2...': null }
209
- ```
210
-
211
- #### `filterByWoT(pubkeys, options?)`
212
-
213
- Filter a list of pubkeys to only those within the Web of Trust.
214
- ```javascript
215
- const trusted = await wot.filterByWoT(['pk1...', 'pk2...', 'pk3...']);
216
- // Returns: ['pk1...', 'pk3...'] (only those in WoT)
217
- ```
218
-
219
- ### Graph Queries (Extension-only)
220
-
221
- These methods require the browser extension and return `null`/empty when unavailable.
222
-
223
- #### `getFollows(pubkey?)`
224
-
225
- Get the follow list for a pubkey (defaults to your pubkey).
226
- ```javascript
227
- const follows = await wot.getFollows();
228
- // Returns: ['pk1...', 'pk2...', ...]
229
- ```
230
-
231
- #### `getCommonFollows(pubkey)`
232
-
233
- Get mutual follows between you and a target.
234
- ```javascript
235
- const common = await wot.getCommonFollows('def456...');
236
- // Returns: ['pk1...', 'pk2...'] (people you both follow)
237
- ```
238
-
239
- #### `getPath(target)`
240
-
241
- Get the actual path from you to a target.
242
- ```javascript
243
- const path = await wot.getPath('def456...');
244
- // Returns: ['myPubkey', 'friend', 'friendOfFriend', 'def456...']
245
- ```
246
-
247
- #### `getStats()`
248
-
249
- Get graph statistics.
250
- ```javascript
251
- const stats = await wot.getStats();
252
- // Returns: { nodes: 50000, edges: 150000, lastSync: 1699999999, size: '12 MB' }
253
- ```
254
-
255
- #### `isConfigured()`
256
-
257
- Check if the extension is configured and ready.
258
- ```javascript
259
- const status = await wot.isConfigured();
260
- // Returns: { configured: true, mode: 'local', hasLocalGraph: true }
261
- ```
262
-
263
- ## Browser Extension
264
-
265
- Install the [Nostr WoT Extension](https://github.com/nostr-wot/nostr-wot-extension) for:
266
-
267
- - **Local Data** — Downloads and caches your follow graph locally
268
- - **Fast Queries** — No network requests needed after sync
269
- - **Cross-Site** — Same WoT data available on all websites
270
- - **Privacy** — Queries never leave your browser
271
- - **Offline** — Works without internet once synced
272
-
273
- The SDK automatically detects the extension via `window.nostr.wot`. When the extension is present (with auto-inject enabled), it **always takes priority** over oracle settings.
274
-
275
- ```javascript
276
- const wot = new WoT({
277
- fallback: {
278
- oracle: 'https://nostr-wot.com',
279
- myPubkey: 'abc123...'
280
- }
281
- });
282
-
283
- // Check if using extension
284
- if (await wot.isUsingExtension()) {
285
- console.log('Using local extension data');
286
- } else {
287
- console.log('Falling back to oracle');
288
- }
289
- ```
290
-
291
- ## Framework Integration
5
+ | Old import | New import |
6
+ |---|---|
7
+ | `nostr-wot-sdk` | `@nostr-wot/wot` |
8
+ | `nostr-wot-sdk/react` | `@nostr-wot/wot/react` + `@nostr-wot/data/react` |
9
+ | `nostr-wot-sdk/solid` | `@nostr-wot/wot/solid` |
10
+ | `nostr-wot-sdk/relay` | `@nostr-wot/relay` |
11
+ | `nostr-wot-sdk/relay/react` | `@nostr-wot/relay/react` |
12
+ | `nostr-wot-sdk/data` | `@nostr-wot/data` |
13
+ | `nostr-wot-sdk/data/cache` | `@nostr-wot/data/cache` |
292
14
 
293
- ### React
15
+ Existing imports keep working — this package just re-exports the scoped packages so older consumers don't break. It will continue to be published in lock-step with `@nostr-wot/*` minor releases.
294
16
 
295
- The SDK provides first-class React support with automatic extension detection. Just wrap your app with `WoTProvider` and you're ready to go — no additional configuration needed.
296
-
297
- ```javascript
298
- import { WoTProvider, useWoT, useExtension } from 'nostr-wot-sdk/react';
299
-
300
- // Wrap your app - automatically detects extension
301
- function App() {
302
- return (
303
- <WoTProvider>
304
- <YourApp />
305
- </WoTProvider>
306
- );
307
- }
308
-
309
- // Check extension status anywhere
310
- function ExtensionStatus() {
311
- const { isConnected, isChecking } = useExtension();
312
-
313
- if (isChecking) return <span>Checking for extension...</span>;
314
- if (isConnected) return <span>Extension connected!</span>;
315
- return <span>Extension not available</span>;
316
- }
317
-
318
- // Use WoT data in components
319
- function Profile({ pubkey }) {
320
- const { distance, score, loading } = useWoT(pubkey);
321
-
322
- if (loading) return <Spinner />;
323
-
324
- return (
325
- <div>
326
- {distance !== null ? (
327
- <span>{distance} hops away (score: {score.toFixed(2)})</span>
328
- ) : (
329
- <span>Not in your network</span>
330
- )}
331
- </div>
332
- );
333
- }
334
- ```
335
-
336
- #### Provider Options
337
-
338
- ```javascript
339
- // With fallback for when extension is not available
340
- <WoTProvider options={{
341
- fallback: { myPubkey: 'abc123...' }
342
- }}>
343
- ```
344
-
345
- #### Available Hooks
346
-
347
- | Hook | Description |
348
- |------|-------------|
349
- | `useWoT(pubkey)` | Get distance, score, and details for a pubkey |
350
- | `useIsInWoT(pubkey)` | Check if pubkey is in your WoT (boolean) |
351
- | `useTrustScore(pubkey)` | Get trust score only |
352
- | `useBatchWoT(pubkeys[])` | Check multiple pubkeys efficiently |
353
- | `useExtension()` | Get extension connection state |
354
- | `useWoTInstance()` | Get raw WoT instance for advanced usage |
355
-
356
- #### Extension State
357
-
358
- The `useExtension()` hook provides extension status:
359
-
360
- ```javascript
361
- const {
362
- state, // 'checking' | 'connected' | 'not-available'
363
- isConnected, // Extension is connected and ready
364
- isChecking, // Currently checking
365
- isChecked, // Check complete
366
- refresh, // Function to re-check extension availability
367
- } = useExtension();
368
- ```
369
-
370
- ### SolidJS
371
-
372
- The SDK also provides SolidJS support with reactive primitives and automatic extension detection. Wrap your app with `WoTProvider` and use `create*` primitives for fine-grained reactivity.
373
-
374
- ```javascript
375
- import { WoTProvider, useExtension, createWoT } from 'nostr-wot-sdk/solid';
376
-
377
- // Wrap your app - automatically detects extension
378
- function App() {
379
- return (
380
- <WoTProvider>
381
- <YourApp />
382
- </WoTProvider>
383
- );
384
- }
385
-
386
- // Check extension status anywhere
387
- function ExtensionStatus() {
388
- const ext = useExtension();
389
-
390
- return (
391
- <Show when={!ext.isChecking()} fallback={<span>Checking...</span>}>
392
- <Show when={ext.isConnected()} fallback={<span>Extension not available</span>}>
393
- <span>Extension connected!</span>
394
- </Show>
395
- </Show>
396
- );
397
- }
398
-
399
- // Use WoT data in components
400
- function Profile(props: { pubkey: string }) {
401
- const wot = createWoT(() => props.pubkey);
402
-
403
- return (
404
- <Show when={!wot.loading()} fallback={<Spinner />}>
405
- <Show when={wot.distance() !== null} fallback={<span>Not in your network</span>}>
406
- <span>{wot.distance()} hops away (score: {wot.score().toFixed(2)})</span>
407
- </Show>
408
- </Show>
409
- );
410
- }
411
- ```
412
-
413
- #### Provider Options
414
-
415
- ```javascript
416
- // With fallback for when extension is not available
417
- <WoTProvider options={{
418
- fallback: { myPubkey: 'abc123...' }
419
- }}>
420
- ```
421
-
422
- #### Available Primitives
423
-
424
- | Primitive | Description |
425
- |-----------|-------------|
426
- | `createWoT(pubkey)` | Get distance, score, and details for a pubkey |
427
- | `createIsInWoT(pubkey)` | Check if pubkey is in your WoT (boolean) |
428
- | `createTrustScore(pubkey)` | Get trust score only |
429
- | `createBatchWoT(pubkeys[])` | Check multiple pubkeys efficiently |
430
- | `useExtension()` | Get extension connection state |
431
- | `useWoTInstance()` | Get raw WoT instance for advanced usage |
432
-
433
- #### Extension State
434
-
435
- The `useExtension()` function provides extension status:
436
-
437
- ```javascript
438
- const ext = useExtension();
439
-
440
- ext.state() // 'checking' | 'connected' | 'not-available'
441
- ext.isConnected() // Extension is connected and ready
442
- ext.isChecking() // Currently checking
443
- ext.isChecked() // Check complete
444
- ext.refresh() // Function to re-check extension availability
445
- ```
446
-
447
- ## Relay Utilities
448
-
449
- The SDK includes a standalone relay subpackage for managing Nostr relay connections, batching queries, and tracking relay performance. These utilities are pool-agnostic and work with any `PoolLike` implementation (e.g. `SimplePool` from nostr-tools).
17
+ For new projects, install only the scoped package(s) you actually need:
450
18
 
451
19
  ```bash
452
- npm install nostr-wot-sdk nostr-tools
453
- ```
454
-
455
- ### Basic Usage
456
-
457
- ```javascript
458
- import { QueryBatcher, RelayPool, RelayStats } from 'nostr-wot-sdk/relay';
459
- import { SimplePool } from 'nostr-tools';
460
-
461
- // Optional: track relay performance
462
- const stats = new RelayStats();
463
- await stats.init(); // works in-memory, or pass a persistence adapter
464
-
465
- // Create a relay pool
466
- const pool = new RelayPool({
467
- urls: ['wss://relay.damus.io', 'wss://nos.lol'],
468
- prioritizeUrls: (urls) => stats.getPrioritizedUrls(urls),
469
- onStatusChange: (statuses) => console.log('Relay statuses:', statuses),
470
- });
471
-
472
- // Initialize with SimplePool
473
- pool.ensurePool(() => new SimplePool());
474
-
475
- // Query with automatic batching + progressive results
476
- const events = await pool.query(
477
- { kinds: [1], limit: 50 },
478
- { onUpdate: (partial) => renderNotes(partial) }
479
- );
480
-
481
- // Subscribe to live events
482
- const sub = pool.subscribe({ kinds: [1], since: Math.floor(Date.now() / 1000) }, {
483
- onEvent: (event) => console.log('New note:', event.content),
484
- onEose: () => console.log('Caught up'),
485
- });
486
-
487
- // Clean up
488
- sub.close();
489
- pool.destroy();
490
- stats.destroy();
20
+ npm i @nostr-wot/data # event fetchers + cache + hooks
21
+ npm i @nostr-wot/wot # WoT scoring + browser-extension bridge
22
+ npm i @nostr-wot/relay # low-level relay utilities
491
23
  ```
492
24
 
493
- ### QueryBatcher
494
-
495
- Debounces and merges concurrent relay queries for efficiency. Queries made within the debounce window are batched together, compatible filters are merged, and results stream progressively.
496
-
497
- ```javascript
498
- import { QueryBatcher } from 'nostr-wot-sdk/relay';
499
- import { SimplePool } from 'nostr-tools';
500
-
501
- const batcher = new QueryBatcher(new SimplePool(), {
502
- debounceMs: 100, // batch window (default: 100)
503
- collectionWindowMs: 200, // wait after first event (default: 200)
504
- maxWaitMs: 5000, // hard timeout (default: 5000)
505
- });
506
-
507
- // These concurrent queries get merged into fewer relay requests
508
- const [profiles, contacts] = await Promise.all([
509
- batcher.query(['wss://relay.damus.io'], { kinds: [0], authors: pubkeys }),
510
- batcher.query(['wss://relay.damus.io'], { kinds: [3], authors: pubkeys }),
511
- ]);
512
-
513
- // For user-initiated actions, bypass the debounce
514
- const notes = await batcher.queryImmediate(urls, { kinds: [1], limit: 20 });
515
-
516
- batcher.destroy();
517
- ```
518
-
519
- ### RelayStats
520
-
521
- Tracks per-relay latency, success rate, and applies exponential backoff to failing relays.
522
-
523
- ```javascript
524
- import { RelayStats } from 'nostr-wot-sdk/relay';
525
-
526
- const stats = new RelayStats({ maxBackoffMs: 30000 });
527
-
528
- // Optional: load persisted stats (e.g. from IndexedDB)
529
- await stats.init({
530
- load: async () => db.getAll('relayStats'),
531
- save: async (data) => db.putAll('relayStats', data),
532
- });
533
-
534
- // Record relay performance
535
- stats.recordSuccess('wss://relay.damus.io', 150); // 150ms latency
536
- stats.recordFailure('wss://slow.relay.com', 'timeout');
537
-
538
- // Get URLs sorted by reliability + speed
539
- const prioritized = stats.getPrioritizedUrls([
540
- 'wss://relay.damus.io',
541
- 'wss://slow.relay.com',
542
- 'wss://nos.lol',
543
- ]);
544
-
545
- // Check backoff status
546
- stats.isBackedOff('wss://slow.relay.com'); // true
547
-
548
- stats.destroy();
549
- ```
550
-
551
- ### RelayPool
552
-
553
- Manages pool lifecycle, subscriptions, publishing, and NIP-65 relay list fetching.
554
-
555
- ```javascript
556
- import { RelayPool } from 'nostr-wot-sdk/relay';
557
- import { SimplePool } from 'nostr-tools';
558
-
559
- const pool = new RelayPool({
560
- urls: ['wss://relay.damus.io', 'wss://nos.lol'],
561
- authorChunkSize: 150, // chunk large author lists
562
- onRelaysChanged: (urls) => saveToSettings(urls),
563
- });
564
-
565
- pool.ensurePool(() => new SimplePool());
566
-
567
- // Subscribe to notes from followed authors (auto-chunks large lists)
568
- const sub = pool.subscribeAuthors(followedPubkeys, { kinds: [1], since, limit: 200 },
569
- (event) => addToFeed(event),
570
- () => console.log('Caught up')
571
- );
572
-
573
- // Publish events
574
- await pool.publish(signedEvent);
575
-
576
- // Fetch a user's NIP-65 relay list
577
- const userRelays = await pool.fetchUserRelays(pubkey);
578
-
579
- // Manage relays
580
- pool.addRelay('wss://new.relay.com');
581
- pool.removeRelay('wss://old.relay.com');
582
-
583
- pool.destroy();
584
- ```
585
-
586
- ### React Integration
587
-
588
- ```javascript
589
- import { RelayProvider, useRelayPool, useRelayStatuses } from 'nostr-wot-sdk/relay/react';
590
- import { SimplePool } from 'nostr-tools';
591
-
592
- function App() {
593
- return (
594
- <RelayProvider
595
- urls={['wss://relay.damus.io', 'wss://nos.lol']}
596
- createPool={() => new SimplePool()}
597
- enableStats={true}
598
- >
599
- <Feed />
600
- </RelayProvider>
601
- );
602
- }
603
-
604
- function Feed() {
605
- const pool = useRelayPool();
606
- const { statuses, connectedCount } = useRelayStatuses();
607
-
608
- useEffect(() => {
609
- pool.query({ kinds: [1], limit: 30 }).then(setNotes);
610
- }, [pool]);
611
-
612
- return (
613
- <div>
614
- <span>{connectedCount} relays connected</span>
615
- {/* render notes */}
616
- </div>
617
- );
618
- }
619
- ```
620
-
621
- #### Provider Props
622
-
623
- | Prop | Type | Default | Description |
624
- |------|------|---------|-------------|
625
- | `urls` | `string[]` | required | Relay WebSocket URLs |
626
- | `createPool` | `() => PoolLike` | required | Factory to create pool instance |
627
- | `poolOptions` | `Partial<RelayPoolOptions>` | — | Options for RelayPool |
628
- | `batcherOptions` | `QueryBatcherOptions` | — | Options for QueryBatcher |
629
- | `statsPersistence` | `RelayStatsPersistence` | — | Persistence adapter for stats |
630
- | `statsOptions` | `RelayStatsOptions` | — | Options for RelayStats |
631
- | `enableStats` | `boolean` | `true` | Enable relay performance tracking |
632
-
633
- #### Available Hooks
634
-
635
- | Hook | Returns | Description |
636
- |------|---------|-------------|
637
- | `useRelayPool()` | `RelayPool` | Access the RelayPool instance |
638
- | `useQueryBatcher()` | `QueryBatcher` | Access the QueryBatcher instance |
639
- | `useRelayStats()` | `RelayStats \| null` | Access RelayStats (null if disabled) |
640
- | `useRelayStatuses()` | `{ statuses, connectedCount }` | Reactive connection statuses |
641
- | `useRelayContext()` | `RelayContextValue` | Full context with all instances |
642
-
643
- ## TypeScript
644
-
645
- Full type definitions included:
646
- ```typescript
647
- import { WoT, DistanceResult, WoTOptions } from 'nostr-wot-sdk';
648
-
649
- const wot = new WoT();
650
- const result: DistanceResult | null = await wot.getDetails(pubkey);
651
- const score: number = await wot.getTrustScore(pubkey);
652
- ```
653
-
654
- ## Error Handling
655
- ```javascript
656
- import { WoT, WoTError, NetworkError, NotFoundError } from 'nostr-wot-sdk';
657
-
658
- try {
659
- const hops = await wot.getDistance('def456...');
660
- } catch (e) {
661
- if (e instanceof NetworkError) {
662
- console.log('Oracle unreachable');
663
- } else if (e instanceof NotFoundError) {
664
- console.log('Pubkey not in graph');
665
- }
666
- }
667
- ```
668
-
669
- ## Related
670
-
671
- - [Nostr WoT Extension](https://github.com/nostr-wot/nostr-wot-extension) — Browser extension (recommended)
672
- - [WoT Oracle](https://github.com/nostr-wot/nostr-wot-oracle) — Backend service
673
- - [nostr-wot.com](https://nostr-wot.com) — Public oracle & docs
674
-
675
- ## License
676
-
677
- MIT
25
+ See [the monorepo README](https://github.com/nostr-wot/nostr-wot-sdk) for architecture and per-package docs.
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ var cache = require('@nostr-wot/data/cache');
4
+
5
+
6
+
7
+ Object.keys(cache).forEach(function (k) {
8
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
9
+ enumerable: true,
10
+ get: function () { return cache[k]; }
11
+ });
12
+ });
13
+ //# sourceMappingURL=index.cjs.map
14
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.cjs","sourcesContent":[]}