atproto user agency toolkit for individuals and groups
at main 184 lines 5.1 kB view raw
1/** 2 * Type definitions and constants for P2P replication. 3 */ 4 5/** Lexicon NSIDs */ 6export const PEER_NSID = "org.p2pds.peer"; 7export const MANIFEST_NSID = "org.p2pds.manifest"; 8export const OFFER_NSID = "org.p2pds.replication.offer"; 9export const CONSENT_NSID = "org.p2pds.replication.consent"; 10 11/** Open consent record — declares that anyone may replicate this account's data. */ 12export interface ConsentRecord { 13 $type: typeof CONSENT_NSID; 14 /** Scope of consent. Currently only "any" is supported. */ 15 scope: "any"; 16 /** ISO 8601 timestamp. */ 17 createdAt: string; 18} 19 20/** Peer identity record — binds a DID to an IPFS PeerID. */ 21export interface PeerIdentityRecord { 22 $type: typeof PEER_NSID; 23 peerId: string; 24 multiaddrs: string[]; 25 createdAt: string; 26} 27 28/** Replication manifest — declares that this node serves a given DID's data. */ 29export interface ManifestRecord { 30 $type: typeof MANIFEST_NSID; 31 subject: string; 32 status: "active" | "paused"; 33 lastSyncRev: string | null; 34 lastSyncAt: string | null; 35 createdAt: string; 36} 37 38/** Replication offer — declares willingness to replicate a given DID's data. */ 39export interface OfferRecord { 40 $type: typeof OFFER_NSID; 41 subject: string; // DID whose data I will replicate 42 minCopies: number; // Desired redundancy (default 2) 43 intervalSec: number; // Sync frequency in seconds (default 600) 44 priority: number; // 0-100 (default 50) 45 createdAt: string; // ISO 8601 46} 47 48/** Operational sync state tracked in SQLite (not in repo). */ 49export interface SyncState { 50 did: string; 51 pdsEndpoint: string; 52 peerId: string | null; 53 peerMultiaddrs: string[]; 54 peerInfoFetchedAt: string | null; 55 lastSyncRev: string | null; 56 rootCid: string | null; 57 lastSyncAt: string | null; 58 lastVerifiedAt: string | null; 59 status: "pending" | "syncing" | "synced" | "error" | "tombstoned"; 60 errorMessage: string | null; 61 needsGc: boolean; 62} 63 64/** 65 * Convert a DID to a valid rkey by replacing colons with hyphens. 66 * e.g. "did:plc:abc123" → "did-plc-abc123" 67 */ 68export function didToRkey(did: string): string { 69 return did.replace(/:/g, "-"); 70} 71 72/** 73 * Convert an rkey back to a DID-like string by replacing hyphens with colons. 74 * Note: only works for simple DIDs without hyphens in method-specific-id. 75 */ 76export function rkeyToDid(rkey: string): string { 77 return rkey.replace(/-/g, ":"); 78} 79 80/** Configuration for layered remote verification. */ 81export interface VerificationConfig { 82 /** Layer 1: how many blocks to sample via RASL (default 50). */ 83 raslSampleSize: number; 84 /** Layer 2: how many blocks to fetch via bitswap (default 5). Future use. */ 85 bitswapSampleSize: number; 86 /** Layer 3: how many record paths to verify (default 2). Future use. */ 87 mstProofCount: number; 88 /** How often to run verification in ms (default 30 minutes). */ 89 verificationIntervalMs: number; 90 /** Challenge epoch duration in ms (default 1 hour). */ 91 challengeEpochDurationMs: number; 92 /** How many records to include in challenges (default 3). */ 93 challengeRecordCount: number; 94 /** How many blocks to sample in challenges (default 5). */ 95 challengeBlockSampleSize: number; 96 /** Challenge expiration in ms (default 5 minutes). */ 97 challengeExpirationMs: number; 98 /** Minimum reliability score for peer trust, 0-1 (default 0.8). */ 99 reliabilityThreshold: number; 100} 101 102export const DEFAULT_VERIFICATION_CONFIG: VerificationConfig = { 103 raslSampleSize: 50, 104 bitswapSampleSize: 5, 105 mstProofCount: 2, 106 verificationIntervalMs: 30 * 60 * 1000, 107 challengeEpochDurationMs: 60 * 60 * 1000, 108 challengeRecordCount: 3, 109 challengeBlockSampleSize: 5, 110 challengeExpirationMs: 5 * 60 * 1000, 111 reliabilityThreshold: 0.8, 112}; 113 114/** What initiated a sync event. */ 115export type SyncTrigger = 116 | "firehose" 117 | "firehose-resync" 118 | "gossipsub" 119 | "periodic" 120 | "manual" 121 | "tombstone-recovery" 122 | "gc" 123 | "unknown"; 124 125/** A row from the sync_history table. */ 126export interface SyncHistoryRow { 127 id: number; 128 did: string; 129 sourceType: string; 130 trigger: SyncTrigger; 131 startedAt: string; 132 completedAt: string | null; 133 status: string; 134 errorMessage: string | null; 135 blocksAdded: number; 136 blobsAdded: number; 137 carBytes: number; 138 blobBytes: number; 139 durationMs: number | null; 140 rev: string | null; 141 rootCid: string | null; 142 incremental: boolean; 143} 144 145/** Aggregate metrics across all replicated DIDs. */ 146export interface AggregateMetrics { 147 totalDids: number; 148 totalBlocks: number; 149 totalBlobs: number; 150 totalRecords: number; 151 totalBytesHeld: number; 152 totalSyncs: number; 153 recentTransferredBytes: number; 154} 155 156/** Per-DID metrics summary. */ 157export interface DidMetrics { 158 blocks: number; 159 blobs: number; 160 records: number; 161 bytesHeld: number; 162 recentSyncs: SyncHistoryRow[]; 163} 164 165/** Result of a single verification layer. */ 166export interface LayerResult { 167 layer: number; 168 name: string; 169 passed: boolean; 170 checked: number; 171 available: number; 172 missing: string[]; 173 error?: string; 174 durationMs: number; 175} 176 177/** Combined result of all verification layers for a peer. */ 178export interface LayeredVerificationResult { 179 did: string; 180 pdsEndpoint: string; 181 timestamp: string; 182 layers: LayerResult[]; 183 overallPassed: boolean; 184}