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 +21 -0
- package/README.md +308 -0
- package/dist/index.cjs +529 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +497 -0
- package/dist/index.d.ts +497 -0
- package/dist/index.js +513 -0
- package/dist/index.js.map +1 -0
- package/dist/local/index.cjs +773 -0
- package/dist/local/index.cjs.map +1 -0
- package/dist/local/index.d.cts +376 -0
- package/dist/local/index.d.ts +376 -0
- package/dist/local/index.js +761 -0
- package/dist/local/index.js.map +1 -0
- package/dist/react/index.cjs +747 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.cts +534 -0
- package/dist/react/index.d.ts +534 -0
- package/dist/react/index.js +738 -0
- package/dist/react/index.js.map +1 -0
- package/package.json +89 -0
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
|