# Web of Trust (WoT) Integration This document describes the Web of Trust trust scoring system in SkateSpots, inspired by ContextVM's Relatr approach. ## Overview **Web of Trust (WoT)** is a decentralized trust system that computes personalized trust scores by analyzing social graph connections on Nostr. SkateSpots uses Web of Trust to: 1. **Display trust badges** on spot cards to help users identify trusted contributors 2. **Show trust scores** in Pyramid rankings to highlight quality contributors 3. **Future: Gate bounty claims** to prevent spam (when bounty system is implemented) ## What is a Trust Score? Trust scores (0-100) are calculated using Nostr social graph analysis: - **100**: Self (your own content) - **90**: Direct follow (you follow them) - **60**: Friend-of-friend (you follow someone who follows them, 2 hops) - **30**: Has NIP-05 verification (basic credibility) - **0**: No connection or verification **Trust is personalized** - scores are calculated from the viewer's perspective. If a user is logged in, trust is based on who THEY follow. If not logged in, trust is based on a default admin pubkey. ## Implementation ### 1. Trust Score Hook (`src/hooks/useTrustScore.ts`) The `useTrustScore` hook calculates trust scores client-side using Nostr follow lists: ```typescript import { useTrustScore } from '@/hooks/useTrustScore'; function MyComponent({ pubkey }: { pubkey: string }) { const { data: trustScore } = useTrustScore(pubkey); // trustScore is 0-100, or undefined if not available console.log('Trust score:', trustScore); } ``` **How it works:** 1. Fetches viewer's follow list (kind 3 event) 2. Checks if target is directly followed → Score: 90 3. Fetches friends' follow lists (kind 3 events) 4. Checks if target is followed by a friend → Score: 60 5. Checks if target has NIP-05 verification → Score: 30 6. Otherwise → Score: 0 **Features:** - Client-side calculation (no external API required) - Personalized to current user (or admin if logged out) - Caches scores for 1 hour (trust changes slowly) - Graceful error handling (returns undefined on failure) ### 2. Spot Card Trust Badges Trust badges appear next to the creator's name on spot cards: - **VERIFIED** (green): Trust score 80-100 - **TRUSTED** (yellow): Trust score 50-79 - **No badge**: Trust score below 50 ### 3. Pyramid Rankings Trust scores appear as a new column in the Pyramid leaderboard: - **Green**: 80-100 (Highly trusted) - **Yellow**: 50-79 (Trusted) - **Gray**: Below 50 or unknown ## Configuration ### Default Trust Source When users are not logged in, trust scores are calculated from a default admin pubkey: ```typescript const DEFAULT_SOURCE_PUBKEY = '20e7c953439e66f3882ab96fe0faa8ba246d6fb12c03b0cb4e2dc4623b8bcb21'; ``` When users ARE logged in, trust scores are calculated from **their own perspective** (using their follow list). ### No External Dependencies Trust calculation happens entirely client-side using: - Kind 3 events (follow lists) from Nostr relays - Kind 0 events (profile metadata) for NIP-05 verification - No external APIs required ## Future: Advanced Trust with ContextVM Relatr For more sophisticated trust calculations, you could integrate ContextVM's Relatr service: ### Benefits of Full Relatr Integration: - **Deeper graph analysis** (3+ hops instead of 2) - **Profile validation metrics** (Lightning addresses, event activity) - **Reciprocity checking** (mutual follows weighted higher) - **Configurable scoring weights** - **Pre-computed trust database** (faster queries) ### Implementation: Relatr is an **MCP (Model Context Protocol) server**, designed for AI agents. To use it from a web app, you would need to: 1. **Self-host Relatr** with a custom HTTP wrapper 2. **Use ContextVM SDK** over Nostr transport 3. **Build a proxy service** that exposes HTTP endpoints For most use cases, the **current client-side WoT calculation is sufficient** and requires no infrastructure. ## Performance ### Caching Strategy Trust scores are cached aggressively since they change slowly: ```typescript staleTime: 3600000, // 1 hour gcTime: 86400000, // 24 hours in cache ``` ### Lazy Loading Trust scores are only fetched when the component using them is rendered. For optimal performance, consider using intersection observers for large lists. ## Future Enhancements ### 1. Bounty Spam Prevention When the bounty system is implemented, trust scores can gate bounty claims: ```typescript function BountyClaimButton({ bounty }) { const { user } = useCurrentUser(); const { data: trustScore } = useTrustScore(user?.pubkey); const MIN_TRUST = 30; if (!trustScore || trustScore < MIN_TRUST) { return
Trust score too low to claim bounties
; } return ; } ``` ### 2. Trust-Weighted Sorting Rankings can be weighted by trust score: ```typescript const trustWeighted = (spots + events) * (trustScore / 100); ``` This would prioritize quality over quantity in leaderboards. ### 3. Trust Filters Add filters to map/list views: ```typescript // Show only verified spots const verifiedSpots = spots.filter(spot => spot.trustScore >= 80); ``` ## API Reference ### `useTrustScore(pubkey: string | undefined)` Fetch trust score for a Nostr pubkey. **Parameters:** - `pubkey` - Hex-encoded Nostr pubkey (or undefined) **Returns:** - `data: number | undefined` - Trust score (0-100) or undefined - Standard React Query properties (`isLoading`, `error`, etc.) **Example:** ```typescript const { data: trustScore, isLoading } = useTrustScore(userPubkey); ``` ### `getTrustBadgeConfig(score: number | undefined)` Get badge configuration based on trust score. **Parameters:** - `score` - Trust score (0-100) or undefined **Returns:** ```typescript { show: boolean; // Whether to show badge variant: 'default' | 'outline'; className: string; // Tailwind classes label: string; // 'VERIFIED', 'TRUSTED', or 'UNVERIFIED' icon: 'check' | 'shield' | null; } ``` ## Resources - [ContextVM GitHub](https://github.com/ContextVM) - [Relatr Repository](https://github.com/ContextVM/relatr) - [ContextVM Documentation](https://docs.contextvm.org) - [Public Relatr Instance](https://relatr.xyz) ## Support For issues with Relatr integration: 1. Check browser console for API errors 2. Verify Relatr API is accessible: `curl https://relatr.xyz/api/health` 3. Review trust score calculation in Relatr docs For SkateSpots integration issues: - File an issue on the repository - Check `useTrustScore` hook for error handling