/** * Type definitions and constants for P2P replication. */ /** Lexicon NSIDs */ export const PEER_NSID = "org.p2pds.peer"; export const MANIFEST_NSID = "org.p2pds.manifest"; export const OFFER_NSID = "org.p2pds.replication.offer"; export const CONSENT_NSID = "org.p2pds.replication.consent"; /** Open consent record — declares that anyone may replicate this account's data. */ export interface ConsentRecord { $type: typeof CONSENT_NSID; /** Scope of consent. Currently only "any" is supported. */ scope: "any"; /** ISO 8601 timestamp. */ createdAt: string; } /** Peer identity record — binds a DID to an IPFS PeerID. */ export interface PeerIdentityRecord { $type: typeof PEER_NSID; peerId: string; multiaddrs: string[]; createdAt: string; } /** Replication manifest — declares that this node serves a given DID's data. */ export interface ManifestRecord { $type: typeof MANIFEST_NSID; subject: string; status: "active" | "paused"; lastSyncRev: string | null; lastSyncAt: string | null; createdAt: string; } /** Replication offer — declares willingness to replicate a given DID's data. */ export interface OfferRecord { $type: typeof OFFER_NSID; subject: string; // DID whose data I will replicate minCopies: number; // Desired redundancy (default 2) intervalSec: number; // Sync frequency in seconds (default 600) priority: number; // 0-100 (default 50) createdAt: string; // ISO 8601 } /** Operational sync state tracked in SQLite (not in repo). */ export interface SyncState { did: string; pdsEndpoint: string; peerId: string | null; peerMultiaddrs: string[]; peerInfoFetchedAt: string | null; lastSyncRev: string | null; rootCid: string | null; lastSyncAt: string | null; lastVerifiedAt: string | null; status: "pending" | "syncing" | "synced" | "error" | "tombstoned"; errorMessage: string | null; needsGc: boolean; } /** * Convert a DID to a valid rkey by replacing colons with hyphens. * e.g. "did:plc:abc123" → "did-plc-abc123" */ export function didToRkey(did: string): string { return did.replace(/:/g, "-"); } /** * Convert an rkey back to a DID-like string by replacing hyphens with colons. * Note: only works for simple DIDs without hyphens in method-specific-id. */ export function rkeyToDid(rkey: string): string { return rkey.replace(/-/g, ":"); } /** Configuration for layered remote verification. */ export interface VerificationConfig { /** Layer 1: how many blocks to sample via RASL (default 50). */ raslSampleSize: number; /** Layer 2: how many blocks to fetch via bitswap (default 5). Future use. */ bitswapSampleSize: number; /** Layer 3: how many record paths to verify (default 2). Future use. */ mstProofCount: number; /** How often to run verification in ms (default 30 minutes). */ verificationIntervalMs: number; /** Challenge epoch duration in ms (default 1 hour). */ challengeEpochDurationMs: number; /** How many records to include in challenges (default 3). */ challengeRecordCount: number; /** How many blocks to sample in challenges (default 5). */ challengeBlockSampleSize: number; /** Challenge expiration in ms (default 5 minutes). */ challengeExpirationMs: number; /** Minimum reliability score for peer trust, 0-1 (default 0.8). */ reliabilityThreshold: number; } export const DEFAULT_VERIFICATION_CONFIG: VerificationConfig = { raslSampleSize: 50, bitswapSampleSize: 5, mstProofCount: 2, verificationIntervalMs: 30 * 60 * 1000, challengeEpochDurationMs: 60 * 60 * 1000, challengeRecordCount: 3, challengeBlockSampleSize: 5, challengeExpirationMs: 5 * 60 * 1000, reliabilityThreshold: 0.8, }; /** What initiated a sync event. */ export type SyncTrigger = | "firehose" | "firehose-resync" | "gossipsub" | "periodic" | "manual" | "tombstone-recovery" | "gc" | "unknown"; /** A row from the sync_history table. */ export interface SyncHistoryRow { id: number; did: string; sourceType: string; trigger: SyncTrigger; startedAt: string; completedAt: string | null; status: string; errorMessage: string | null; blocksAdded: number; blobsAdded: number; carBytes: number; blobBytes: number; durationMs: number | null; rev: string | null; rootCid: string | null; incremental: boolean; } /** Aggregate metrics across all replicated DIDs. */ export interface AggregateMetrics { totalDids: number; totalBlocks: number; totalBlobs: number; totalRecords: number; totalBytesHeld: number; totalSyncs: number; recentTransferredBytes: number; } /** Per-DID metrics summary. */ export interface DidMetrics { blocks: number; blobs: number; records: number; bytesHeld: number; recentSyncs: SyncHistoryRow[]; } /** Result of a single verification layer. */ export interface LayerResult { layer: number; name: string; passed: boolean; checked: number; available: number; missing: string[]; error?: string; durationMs: number; } /** Combined result of all verification layers for a peer. */ export interface LayeredVerificationResult { did: string; pdsEndpoint: string; timestamp: string; layers: LayerResult[]; overallPassed: boolean; }