| name | wot |
| description | Web of Trust operations for Nostr pubkeys — trust scoring, sybil detection, trust path analysis, neighbor discovery, follow recommendations, and network health. Free tier (wot.klabo.world, 50 req/day) with paid fallback (maximumsats.com, 100 sats via L402). Covers 52K+ pubkeys and 2.4M+ zap-weighted trust edges. Use --key-source to select nip06 (default), taproot, or stacks derivation path. |
| metadata | {"author":"arc0btc","author-agent":"Trustless Indra","user-invocable":"false","arguments":"trust-score | sybil-check | neighbors | trust-path | recommend | network-health | config | cache-status","entry":"wot/SKILL.md","mcp-tools":"nostr_get_pubkey, nostr_get_profile","requires":"wallet","tags":"read-only"} |
Web of Trust (WoT) Skill
Pre-transaction counterparty risk assessment using Nostr Web of Trust scores. Accepts Nostr hex pubkeys or npub1... bech32 addresses only.
- 52K+ pubkeys indexed with 2.4M+ trust edges
- Trust edges weighted by zap receipts (economic signal, harder to fake)
- Free tier:
wot.klabo.world (50 req/day per IP), no key required
- Paid fallback:
maximumsats.com/api/wot-report (100 sats via L402) when free tier exhausted
- 1-hour local cache to avoid redundant API calls
This is a doc-only MCP-tool skill. Agents derive the Nostr pubkey via nostr_get_pubkey and then call external WoT APIs directly. There is no wot.ts CLI entrypoint — all operations use MCP tool calls or direct HTTP requests to the WoT API.
Key Derivation
Use nostr_get_pubkey to get the agent's Nostr pubkey before calling WoT API endpoints:
nostr_get_pubkey({})
Returns { pubkey: "2b4603d2...", npub: "npub1abc..." }.
Key Source
The Nostr pubkey derivation path is configured in the nostr skill settings. Options:
| Value | Path | Description |
|---|
nip06 (default) | m/44'/1237'/0'/0/0 | NIP-06 standard — compatible with Alby, Damus, Amethyst |
taproot | m/86'/coin_type'/0'/0/0 | Taproot x-only key — same keypair as bc1p address |
stacks | m/84'/coin_type'/0'/0/0 | BTC SegWit path — backward-compat with pre-NIP-06 agents |
What WoT Accepts
WoT is a Nostr-native protocol. It indexes secp256k1 x-only public keys (32 bytes). The only valid inputs are:
| Format | Example | Works |
|---|
| Nostr hex pubkey | 2b4603d2... (64 hex chars) | Yes |
| Nostr npub bech32 | npub1abc... | Yes |
| Stacks address | SP1ABC... | No — hashed; original key not recoverable |
| BTC address (bc1q) | bc1q... | No — hashed P2WPKH |
| BTC address (bc1p) | bc1p... | No — hashed P2TR |
| Ordinals address | bc1p... | No — same as bc1p, hashed |
Why hashed addresses don't work: Bitcoin and Stacks addresses are derived by hashing the public key (HASH160 or SHA256). The original secp256k1 key cannot be recovered from the address. WoT requires the raw 32-byte x-only pubkey to look up nodes in the trust graph.
Future cross-protocol identity: Cross-protocol identity mapping (e.g. linking a Stacks address to a Nostr npub) is not yet standardized. When it is, the taproot key source provides the best bridge — the taproot x-only pubkey is both a valid Nostr pubkey AND the internal key of the agent's bc1p address, making it externally verifiable from on-chain data. The stacks key source cannot bridge this gap because the Stacks address uses a different hash.
Usage
This skill has no CLI entrypoint. Agents:
- Call
nostr_get_pubkey({}) to get the Nostr pubkey.
- Use
HTTP GET to query the WoT API endpoints directly.
Subcommands
trust-score
Look up WoT trust score, rank, and percentile for a pubkey via the klabo.world API.
nostr_get_pubkey({})
// → { pubkey: "2b4603d2..." }
GET https://wot.klabo.world/api/trust-score?pubkey=2b4603d2...
Output:
{
"success": true,
"cached": false,
"api": "free",
"pubkey": "2b4603d2...",
"trusted": true,
"normalized_score": 87,
"rank": 142,
"percentile": 99.7
}
sybil-check
Classify a pubkey as normal, suspicious, or likely_sybil using follower quality, mutual trust ratio, and community integration signals.
GET https://wot.klabo.world/api/sybil-check?pubkey=2b4603d2...
Output:
{
"success": true,
"pubkey": "2b4603d2...",
"classification": "normal",
"is_sybil": false,
"is_suspicious": false
}
neighbors
Discover trust graph neighbors — connected pubkeys with combined trust scores.
GET https://wot.klabo.world/api/neighbors?pubkey=2b4603d2...
Output: array of connected pubkeys with their trust scores and edge weights.
trust-path
Find the trust path between two pubkeys in the WoT graph. Shows the chain of trust edges connecting from to to.
GET https://wot.klabo.world/api/trust-path?from=2b4603d2...&to=dbe4d9fb...
Output: ordered list of pubkeys forming the trust path, with hop count and per-hop scores.
recommend
Get personalized follow recommendations for a pubkey based on WoT graph proximity and trust score.
GET https://wot.klabo.world/api/recommend?pubkey=2b4603d2...
Output: array of recommended pubkeys with trust scores and reasoning.
network-health
Graph-wide stats: total nodes, edges, Gini coefficient, power law alpha. No pubkey required.
GET https://wot.klabo.world/api/network-health
Output:
{
"success": true,
"total_nodes": 52000,
"total_edges": 2400000,
"gini_coefficient": 0.72,
"power_law_alpha": 2.1
}
config
Trust threshold configuration is managed locally. The recommended thresholds:
minRank: maximum rank to accept as trusted. Default: 10000
requireTop100: reject if not in top 100. Default: false
cache-status
The WoT API responses should be cached locally for 1 hour to avoid hitting the 50 req/day free tier limit. Use the credentials skill to store L402 tokens for the paid tier.
Trust Thresholds
| Rank | Meaning |
|---|
| 1–100 | Elite (top 100 Nostr users by WoT) |
| 101–1000 | Well-connected, high economic activity |
| 1001–10000 | Active community member |
| >10000 | Low trust, new account, or no Nostr activity |
API Details
Two endpoints, tried in order:
| Base | Auth | Cost | Rate |
|---|
https://wot.klabo.world | None | Free | 50 req/day/IP |
https://maximumsats.com/api/wot-report | L402 | 100 sats | Unlimited |
Free tier returns HTTP 402 when exhausted; skill auto-falls back to paid endpoint. L402 payment requires a Lightning client — without one, paid calls return an error with the BOLT11 invoice.
L402 Payment Flow
When the 50 req/day free tier is exhausted, the API returns HTTP 402 with a Lightning invoice in WWW-Authenticate. After paying:
arc creds set --service wot --key l402-token --value "<token>:<preimage>"
The credential is automatically read on subsequent calls.
Key Derivation Reference
All three derivation paths produce secp256k1 x-only pubkeys that WoT can look up:
BIP39 mnemonic → BIP32 seed → derivation path → 32-byte secp256k1 private key → x-only pubkey
NIP-06 (default): m/44'/1237'/0'/0/0
- Standard Nostr path — coin_type 1237 registered for Nostr
- Same mnemonic produces the same npub in Alby, Damus, Amethyst, Snort, etc.
- Recommended for agents without a specific on-chain identity requirement
Taproot: m/86'/coin_type'/0'/0/0
- x-only pubkey is identical to the Taproot internal key (bc1p address)
- Externally verifiable: anyone with the agent's bc1p address can derive the expected npub
- Best path for cross-protocol identity (Nostr + on-chain BTC)
Stacks (backward-compat): m/84'/coin_type'/0'/0/0
- Original derivation used before NIP-06 update
- Only needed if the agent already has a published Nostr identity from the old path
- Not recommended for new agents