nostr-wot-sdk 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MappingBitcoin.com
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,308 @@
1
+ # nostr-wot-sdk
2
+
3
+ JavaScript/TypeScript SDK for querying Nostr Web of Trust.
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/mappingbitcoin/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
+ // Extension mode - no pubkey needed, uses extension's data
20
+ const wot = new WoT({
21
+ useExtension: true,
22
+ fallback: {
23
+ oracle: 'https://nostr-wot.com',
24
+ myPubkey: 'abc123...' // Used only if extension unavailable
25
+ }
26
+ });
27
+
28
+ // Check distance
29
+ const hops = await wot.getDistance('def456...');
30
+ console.log(hops); // 2
31
+
32
+ // Boolean check
33
+ const trusted = await wot.isInMyWoT('def456...', { maxHops: 3 });
34
+ console.log(trusted); // true
35
+
36
+ // Trust score
37
+ const score = await wot.getTrustScore('def456...');
38
+ console.log(score); // 0.72
39
+ ```
40
+
41
+ When the extension is installed, **it always takes priority** — the SDK uses the extension's pubkey and locally-cached follow graph automatically.
42
+
43
+ ### Without Extension (Oracle Mode)
44
+
45
+ ```javascript
46
+ import { WoT } from 'nostr-wot-sdk';
47
+
48
+ const wot = new WoT({
49
+ oracle: 'https://nostr-wot.com',
50
+ myPubkey: 'abc123...' // Required in oracle-only mode
51
+ });
52
+
53
+ const hops = await wot.getDistance('def456...');
54
+ ```
55
+
56
+ ## Features
57
+
58
+ - **Extension-First** — Automatically uses browser extension when available
59
+ - **Simple API** — Three methods cover most use cases
60
+ - **Cross-Site Trust** — Extension provides same WoT data on all websites
61
+ - **Offline Support** — Extension caches data locally for offline queries
62
+ - **Custom Scoring** — Define your own trust weights
63
+ - **Batch Queries** — Check multiple pubkeys efficiently
64
+ - **TypeScript** — Full type definitions included
65
+
66
+ ## API Reference
67
+
68
+ ### Constructor
69
+ ```javascript
70
+ const wot = new WoT(options);
71
+ ```
72
+
73
+ | Option | Type | Default | Description |
74
+ |--------|------|---------|-------------|
75
+ | `useExtension` | boolean | `false` | Use browser extension if available (recommended) |
76
+ | `oracle` | string | `'https://nostr-wot.com'` | Oracle API URL (fallback) |
77
+ | `myPubkey` | string | — | Your pubkey (optional with extension, required otherwise) |
78
+ | `maxHops` | number | `3` | Default max search depth |
79
+ | `timeout` | number | `5000` | Request timeout (ms) |
80
+ | `scoring` | object | See below | Trust score weights |
81
+ | `fallback` | object | — | Fallback config when extension unavailable |
82
+
83
+ **Note:** When `useExtension: true` and the extension is installed, the extension's pubkey and data are always used, regardless of `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, options?)`
104
+
105
+ Get computed trust score based on distance and weights.
106
+ ```javascript
107
+ const score = await wot.getTrustScore('def456...');
108
+ // Returns: number (0-1)
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 and path count details.
130
+ ```javascript
131
+ const details = await wot.getDetails('def456...');
132
+ // Returns: { hops: 2, paths: 5 }
133
+ // Oracle may also return: bridges, mutual
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
+ #### `getExtensionConfig()`
153
+
154
+ Get extension's configuration (only when using extension).
155
+ ```javascript
156
+ const config = await wot.getExtensionConfig();
157
+ // Returns: { maxHops: 3, timeout: 5000, scoring: {...} } or null
158
+ ```
159
+
160
+ ## Browser Extension
161
+
162
+ Install the [Nostr WoT Extension](https://github.com/mappingbitcoin/nostr-wot-extension) for:
163
+
164
+ - **Local Data** — Downloads and caches your follow graph locally
165
+ - **Fast Queries** — No network requests needed after sync
166
+ - **Cross-Site** — Same WoT data available on all websites
167
+ - **Privacy** — Queries never leave your browser
168
+ - **Offline** — Works without internet once synced
169
+
170
+ The SDK automatically detects `window.nostr.wot` and uses it. When the extension is present, it **always takes priority** over oracle settings.
171
+
172
+ ```javascript
173
+ const wot = new WoT({
174
+ useExtension: true,
175
+ fallback: {
176
+ oracle: 'https://nostr-wot.com',
177
+ myPubkey: 'abc123...'
178
+ }
179
+ });
180
+
181
+ // Check if using extension
182
+ if (await wot.isUsingExtension()) {
183
+ console.log('Using local extension data');
184
+ } else {
185
+ console.log('Falling back to oracle');
186
+ }
187
+ ```
188
+
189
+ ## Custom Scoring
190
+
191
+ Define how trust scores are calculated:
192
+ ```javascript
193
+ const wot = new WoT({
194
+ useExtension: true,
195
+ scoring: {
196
+ // Distance weights (score multiplier per hop)
197
+ distanceWeights: {
198
+ 1: 1.0, // Direct follows
199
+ 2: 0.5, // 2 hops
200
+ 3: 0.25, // 3 hops
201
+ 4: 0.1, // 4+ hops
202
+ },
203
+ // Bonus multipliers
204
+ mutualBonus: 0.5, // +50% for mutual follows
205
+ pathBonus: 0.1, // +10% per additional path
206
+ maxPathBonus: 0.5, // Cap path bonus at +50%
207
+ }
208
+ });
209
+ ```
210
+
211
+ ### Scoring Formula
212
+ ```
213
+ score = baseScore × distanceWeight × (1 + bonuses)
214
+
215
+ where:
216
+ baseScore = 1 / (hops + 1)
217
+ bonuses = mutualBonus (if mutual) + min(pathBonus × (paths - 1), maxPathBonus)
218
+ ```
219
+
220
+ ## Server-Side Local Mode
221
+
222
+ For Node.js/server environments where the browser extension isn't available:
223
+
224
+ ```javascript
225
+ import { LocalWoT } from 'nostr-wot-sdk/local';
226
+
227
+ const wot = new LocalWoT({
228
+ myPubkey: 'abc123...',
229
+ relays: ['wss://relay.damus.io', 'wss://nos.lol']
230
+ });
231
+
232
+ // Sync follow graph (2 hops from your pubkey)
233
+ await wot.sync({ depth: 2 });
234
+
235
+ // Now queries run locally
236
+ const hops = await wot.getDistance('def456...');
237
+ ```
238
+
239
+ Storage options: `'memory'` (default), `'indexeddb'` (browser), or custom adapter.
240
+
241
+ ## Framework Integration
242
+
243
+ ### React
244
+ ```javascript
245
+ import { useWoT, WoTProvider } from 'nostr-wot-sdk/react';
246
+
247
+ // Wrap your app with the provider
248
+ function App() {
249
+ return (
250
+ <WoTProvider options={{ useExtension: true }}>
251
+ <YourApp />
252
+ </WoTProvider>
253
+ );
254
+ }
255
+
256
+ // Use hooks in components
257
+ function Profile({ pubkey }) {
258
+ const { distance, score, loading } = useWoT(pubkey);
259
+
260
+ if (loading) return <Spinner />;
261
+
262
+ return (
263
+ <div>
264
+ {distance !== null ? (
265
+ <span>{distance} hops away (score: {score.toFixed(2)})</span>
266
+ ) : (
267
+ <span>Not in your network</span>
268
+ )}
269
+ </div>
270
+ );
271
+ }
272
+ ```
273
+
274
+ ## TypeScript
275
+
276
+ Full type definitions included:
277
+ ```typescript
278
+ import { WoT, DistanceResult, WoTOptions } from 'nostr-wot-sdk';
279
+
280
+ const wot = new WoT(options: WoTOptions);
281
+ const result: DistanceResult = await wot.getDetails(pubkey);
282
+ const score: number = await wot.getTrustScore(pubkey);
283
+ ```
284
+
285
+ ## Error Handling
286
+ ```javascript
287
+ import { WoT, WoTError, NetworkError, NotFoundError } from 'nostr-wot-sdk';
288
+
289
+ try {
290
+ const hops = await wot.getDistance('def456...');
291
+ } catch (e) {
292
+ if (e instanceof NetworkError) {
293
+ console.log('Oracle unreachable');
294
+ } else if (e instanceof NotFoundError) {
295
+ console.log('Pubkey not in graph');
296
+ }
297
+ }
298
+ ```
299
+
300
+ ## Related
301
+
302
+ - [Nostr WoT Extension](https://github.com/mappingbitcoin/nostr-wot-extension) — Browser extension (recommended)
303
+ - [WoT Oracle](https://github.com/mappingbitcoin/wot-oracle) — Backend service
304
+ - [nostr-wot.com](https://nostr-wot.com) — Public oracle & docs
305
+
306
+ ## License
307
+
308
+ MIT