@peac/adapter-did 0.12.6

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/resolver.ts","../src/errors.ts","../src/multicodec.ts","../src/did-key.ts","../src/did-web.ts","../src/extract-key.ts","../src/cache.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * DID Resolver interface and composite resolver.\n *\n * Pluggable resolver architecture: callers instantiate and configure\n * resolvers explicitly (DD-52: no ambient key discovery).\n */\n\nimport type { DIDResolutionResult } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Interface\n// ---------------------------------------------------------------------------\n\n/**\n * Interface for DID resolvers.\n *\n * Each resolver handles one or more DID methods (e.g., ['key'], ['web']).\n * Resolution returns a W3C DID Resolution Result.\n */\nexport interface DIDResolver {\n /** DID methods this resolver handles (e.g., ['key'] for did:key) */\n readonly methods: readonly string[];\n /** Resolve a DID to its DID Document */\n resolve(did: string): Promise<DIDResolutionResult>;\n}\n\n// ---------------------------------------------------------------------------\n// Composite Resolver\n// ---------------------------------------------------------------------------\n\n/**\n * Create a composite resolver that delegates to method-specific resolvers.\n *\n * Tries resolvers in order by method match. The first resolver whose\n * `methods` array includes the DID's method handles the resolution.\n *\n * @param resolvers - Array of method-specific resolvers\n * @returns A composite resolver that delegates by method\n */\nexport function createCompositeResolver(resolvers: DIDResolver[]): DIDResolver {\n return {\n methods: resolvers.flatMap((r) => [...r.methods]),\n\n async resolve(did: string): Promise<DIDResolutionResult> {\n const method = extractMethod(did);\n if (!method) {\n return {\n didDocument: null,\n didResolutionMetadata: { error: 'invalidDid' },\n didDocumentMetadata: {},\n };\n }\n\n for (const resolver of resolvers) {\n if (resolver.methods.includes(method)) {\n return resolver.resolve(did);\n }\n }\n\n return {\n didDocument: null,\n didResolutionMetadata: { error: 'methodNotSupported' },\n didDocumentMetadata: {},\n };\n },\n };\n}\n\n/**\n * Extract the method from a DID string (e.g., \"key\" from \"did:key:z6Mk...\").\n */\nfunction extractMethod(did: string): string | null {\n if (!did.startsWith('did:')) return null;\n const parts = did.split(':');\n if (parts.length < 3) return null;\n return parts[1];\n}\n","/**\n * DID adapter error types.\n *\n * Uses error codes registered in specs/kernel/errors.json (PR3 #571).\n */\n\n/** DID-specific error codes (registered in kernel) */\nexport type DIDErrorCode =\n | 'E_DID_RESOLUTION_FAILED'\n | 'E_DID_DOCUMENT_INVALID'\n | 'E_DID_KEY_NOT_FOUND'\n | 'E_DID_UNSUPPORTED_METHOD'\n | 'E_DID_DEACTIVATED'\n | 'E_DID_KEY_AMBIGUOUS';\n\n/**\n * Error thrown by DID adapter operations.\n */\nexport class DIDError extends Error {\n readonly code: DIDErrorCode;\n\n constructor(code: DIDErrorCode, message: string) {\n super(message);\n this.name = 'DIDError';\n this.code = code;\n }\n}\n","/**\n * Ed25519 multicodec prefix parsing.\n *\n * Supports both multibase forms allowed by the did:key spec (CCG v0.9):\n * - 'z' prefix: base58btc encoding\n * - 'u' prefix: base64url encoding\n *\n * The Ed25519 multicodec prefix is 0xed01 as a varint (2 bytes).\n * After stripping the 2-byte prefix, the remaining 32 bytes are\n * the raw Ed25519 public key.\n */\n\nimport { DIDError } from './errors.js';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Ed25519 multicodec prefix as varint: [0xed, 0x01] */\nconst ED25519_MULTICODEC_PREFIX = new Uint8Array([0xed, 0x01]);\n\n/** Expected Ed25519 public key length in bytes */\nconst ED25519_KEY_LENGTH = 32;\n\n/** Total expected length: 2 byte prefix + 32 byte key */\nconst ED25519_MULTICODEC_LENGTH = ED25519_MULTICODEC_PREFIX.length + ED25519_KEY_LENGTH;\n\n// ---------------------------------------------------------------------------\n// Base58btc decoder (minimal, for 'z' prefix multibase)\n// ---------------------------------------------------------------------------\n\nconst BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\nconst BASE58_MAP = new Map<string, number>();\nfor (let i = 0; i < BASE58_ALPHABET.length; i++) {\n BASE58_MAP.set(BASE58_ALPHABET[i], i);\n}\n\nfunction base58btcDecode(input: string): Uint8Array {\n if (input.length === 0) return new Uint8Array(0);\n\n // Count leading '1's (zero bytes)\n let zeros = 0;\n while (zeros < input.length && input[zeros] === '1') {\n zeros++;\n }\n\n // Decode\n const size = Math.ceil((input.length * 733) / 1000) + 1;\n const b256 = new Uint8Array(size);\n let length = 0;\n\n for (let i = zeros; i < input.length; i++) {\n const value = BASE58_MAP.get(input[i]);\n if (value === undefined) {\n throw new DIDError('E_DID_DOCUMENT_INVALID', `Invalid base58btc character: ${input[i]}`);\n }\n let carry = value;\n for (let j = 0; j < length || carry > 0; j++) {\n carry += 58 * (b256[j] || 0);\n b256[j] = carry % 256;\n carry = Math.floor(carry / 256);\n if (j >= length) length = j + 1;\n }\n }\n\n // Build result with leading zeros\n const result = new Uint8Array(zeros + length);\n for (let i = 0; i < length; i++) {\n result[zeros + length - 1 - i] = b256[i];\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Base64url decoder (for 'u' prefix multibase)\n// ---------------------------------------------------------------------------\n\nfunction base64urlDecode(input: string): Uint8Array {\n return new Uint8Array(Buffer.from(input, 'base64url'));\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Extract an Ed25519 public key from a multibase-encoded multicodec value.\n *\n * Supports both multibase prefixes:\n * - 'z': base58btc (e.g., did:key:z6Mk...)\n * - 'u': base64url\n *\n * @param multibaseValue - The multibase-encoded value (including prefix character)\n * @returns 32-byte Ed25519 public key\n * @throws DIDError if not Ed25519 or malformed\n */\nexport function extractEd25519FromMultibase(multibaseValue: string): Uint8Array {\n if (multibaseValue.length < 2) {\n throw new DIDError('E_DID_DOCUMENT_INVALID', 'Multibase value too short');\n }\n\n const prefix = multibaseValue[0];\n const encoded = multibaseValue.slice(1);\n let decoded: Uint8Array;\n\n if (prefix === 'z') {\n decoded = base58btcDecode(encoded);\n } else if (prefix === 'u') {\n decoded = base64urlDecode(encoded);\n } else {\n throw new DIDError(\n 'E_DID_DOCUMENT_INVALID',\n `Unsupported multibase prefix: '${prefix}'. Expected 'z' (base58btc) or 'u' (base64url).`\n );\n }\n\n // Check total length\n if (decoded.length !== ED25519_MULTICODEC_LENGTH) {\n throw new DIDError(\n 'E_DID_KEY_NOT_FOUND',\n `Expected ${ED25519_MULTICODEC_LENGTH} bytes (2 prefix + 32 key), got ${decoded.length}`\n );\n }\n\n // Verify Ed25519 multicodec prefix (0xed, 0x01)\n if (decoded[0] !== ED25519_MULTICODEC_PREFIX[0] || decoded[1] !== ED25519_MULTICODEC_PREFIX[1]) {\n // Non-Ed25519 key type: do NOT throw an oracle-revealing error about\n // what type it is. Just say Ed25519 not found.\n throw new DIDError('E_DID_KEY_NOT_FOUND', 'Multicodec prefix does not indicate Ed25519');\n }\n\n return decoded.slice(2);\n}\n","/**\n * did:key resolver (Ed25519, zero network I/O).\n *\n * Implements the did:key method spec (W3C CCG v0.9).\n * Parses the multicodec-encoded Ed25519 public key directly from\n * the DID string. No network requests, no ambient discovery.\n *\n * Only Ed25519 keys (multicodec 0xed01) are supported.\n * Non-Ed25519 did:key DIDs produce an error without revealing\n * the actual key type (no oracle).\n */\n\nimport type { DIDDocument, VerificationMethod } from './types.js';\nimport type { DIDResolutionResult } from './types.js';\nimport type { DIDResolver } from './resolver.js';\nimport { extractEd25519FromMultibase } from './multicodec.js';\nimport { DIDError } from './errors.js';\n\n// ---------------------------------------------------------------------------\n// did:key Resolver\n// ---------------------------------------------------------------------------\n\n/**\n * Resolver for the did:key method.\n *\n * did:key encodes the public key directly in the DID string.\n * Resolution is pure computation with zero network I/O.\n *\n * @example\n * ```typescript\n * const resolver = new DidKeyResolver();\n * const result = await resolver.resolve('did:key:z6MkhaXgBZDvotDkL...');\n * const key = extractVerificationKey(result.didDocument!);\n * ```\n */\nexport class DidKeyResolver implements DIDResolver {\n readonly methods = ['key'] as const;\n\n async resolve(did: string): Promise<DIDResolutionResult> {\n // Validate DID format\n if (!did.startsWith('did:key:')) {\n return {\n didDocument: null,\n didResolutionMetadata: { error: 'invalidDid' },\n didDocumentMetadata: {},\n };\n }\n\n const multibaseValue = did.slice('did:key:'.length);\n if (!multibaseValue) {\n return {\n didDocument: null,\n didResolutionMetadata: { error: 'invalidDid' },\n didDocumentMetadata: {},\n };\n }\n\n // Extract Ed25519 public key (validates multicodec prefix).\n // Validate the multibase value contains a valid Ed25519 key.\n // Error boundary: DIDError.code is PEAC-internal (E_DID_*).\n // didResolutionMetadata.error uses DID-resolution-style values\n // for the public adapter contract.\n try {\n extractEd25519FromMultibase(multibaseValue);\n } catch (e) {\n if (e instanceof DIDError) {\n return {\n didDocument: null,\n didResolutionMetadata: { error: e.code },\n didDocumentMetadata: {},\n };\n }\n return {\n didDocument: null,\n didResolutionMetadata: { error: 'invalidDid' },\n didDocumentMetadata: {},\n };\n }\n\n // Build DID Document with the extracted key\n const keyId = `${did}#${multibaseValue}`;\n\n const verificationMethod: VerificationMethod = {\n id: keyId,\n type: 'Ed25519VerificationKey2020',\n controller: did,\n publicKeyMultibase: multibaseValue,\n };\n\n const document: DIDDocument = {\n '@context': [\n 'https://www.w3.org/ns/did/v1',\n 'https://w3id.org/security/suites/ed25519-2020/v1',\n ],\n id: did,\n verificationMethod: [verificationMethod],\n authentication: [keyId],\n assertionMethod: [keyId],\n };\n\n return {\n didDocument: document,\n didResolutionMetadata: { contentType: 'application/did+json' },\n didDocumentMetadata: {},\n };\n }\n}\n","/**\n * did:web resolver using a caller-provided SSRF-hardened fetch.\n *\n * Implements the did:web method spec (W3C CCG draft).\n * Resolves did:web DIDs to DID Documents via HTTPS fetch.\n *\n * Callers MUST provide a hardened fetch function (e.g., safeFetchJson\n * from @peac/net-node) that enforces:\n * - HTTPS only\n * - No redirects\n * - Private-IP / DNS-rebinding protections\n * - Timeout\n * - Response size limit\n *\n * This resolver adds:\n * - did:web authority/path validation (no userinfo, no query/fragment,\n * no empty segments, no IP literals)\n * - Content-type enforcement (application/did+json or application/json)\n * - Exact DID Document id match (DD-203)\n * - Domain allowlist (optional)\n *\n * URL transformation rules:\n * - did:web:example.com -> https://example.com/.well-known/did.json\n * - did:web:example.com:path:to -> https://example.com/path/to/did.json\n * - did:web:example.com%3A8443 -> https://example.com:8443/.well-known/did.json\n */\n\nimport type { DIDDocument } from './types.js';\nimport type { DIDResolutionResult } from './types.js';\nimport type { DIDResolver } from './resolver.js';\n\n// ---------------------------------------------------------------------------\n// Fetch Contract\n// ---------------------------------------------------------------------------\n\n/**\n * Result shape for the caller-provided hardened fetch function.\n *\n * Callers should use safeFetchJson from @peac/net-node, which returns\n * this shape. The resolver uses contentType and finalUrl for additional\n * validation beyond what the fetch function itself enforces.\n */\nexport interface HardenedFetchResult<T = unknown> {\n ok: boolean;\n data?: T;\n code?: string;\n error?: string;\n /** Content-Type of the response (for validation) */\n contentType?: string;\n /** Final URL after any processing (for redirect detection) */\n finalUrl?: string;\n}\n\nexport type HardenedFetchFn = <T = unknown>(\n url: string,\n options?: { timeoutMs?: number; maxResponseBytes?: number; maxRedirects?: number }\n) => Promise<HardenedFetchResult<T>>;\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface DidWebResolverOptions {\n /** Request timeout in milliseconds (default: 5000) */\n timeoutMs?: number;\n /**\n * Optional domain allowlist (lowercase). If set, only these domains\n * are permitted. Comparison is case-insensitive.\n */\n allowedDomains?: string[];\n /**\n * SSRF-hardened fetch function. Required.\n * Use safeFetchJson from @peac/net-node for production.\n */\n fetchFn: HardenedFetchFn;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst MAX_DOCUMENT_BYTES = 256 * 1024;\nconst DEFAULT_TIMEOUT_MS = 5000;\n\n/** Acceptable content types for DID Documents */\nconst ACCEPTABLE_CONTENT_TYPES = new Set(['application/did+json', 'application/json']);\n\n// ---------------------------------------------------------------------------\n// did:web Resolver\n// ---------------------------------------------------------------------------\n\nexport class DidWebResolver implements DIDResolver {\n readonly methods = ['web'] as const;\n\n private readonly timeoutMs: number;\n private readonly allowedDomains: string[] | undefined;\n private readonly fetchFn: HardenedFetchFn;\n\n constructor(options: DidWebResolverOptions) {\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.allowedDomains = options.allowedDomains?.map(normalizeHostname);\n this.fetchFn = options.fetchFn;\n }\n\n async resolve(did: string): Promise<DIDResolutionResult> {\n // 1. Validate DID format\n if (!did.startsWith('did:web:')) {\n return errorResult('invalidDid');\n }\n\n const methodSpecificId = did.slice('did:web:'.length);\n if (!methodSpecificId) {\n return errorResult('invalidDid');\n }\n\n // 2. Validate and transform to URL\n const urlResult = validateAndTransform(methodSpecificId);\n if (!urlResult.ok) {\n return errorResult('invalidDid');\n }\n const url = urlResult.url;\n\n // 3. Domain allowlist check (case-insensitive, trailing-dot-normalized)\n const hostname = normalizeHostname(urlResult.hostname);\n if (this.allowedDomains && !this.allowedDomains.includes(hostname)) {\n return errorResult('invalidDid');\n }\n\n // 4. Fetch DID Document\n let fetchResult: HardenedFetchResult;\n try {\n fetchResult = await this.fetchFn<unknown>(url, {\n timeoutMs: this.timeoutMs,\n maxResponseBytes: MAX_DOCUMENT_BYTES,\n maxRedirects: 0,\n });\n } catch {\n return errorResult('notFound');\n }\n\n if (!fetchResult.ok || !fetchResult.data) {\n return errorResult('notFound');\n }\n\n // 5. Redirect detection: if finalUrl is provided, it must match the\n // requested URL exactly. The fetch contract uses maxRedirects: 0, so\n // any discrepancy indicates the fetcher did not enforce no-redirect.\n if (fetchResult.finalUrl && fetchResult.finalUrl !== url) {\n return errorResult('invalidDid');\n }\n\n // 6. Content-type enforcement (application/did+json or application/json)\n if (fetchResult.contentType) {\n const baseType = fetchResult.contentType.split(';')[0].trim().toLowerCase();\n if (!ACCEPTABLE_CONTENT_TYPES.has(baseType)) {\n return errorResult('invalidDid');\n }\n }\n\n // 7. Validate response is a JSON object with `id` field\n const raw = fetchResult.data;\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n return errorResult('invalidDid');\n }\n\n const doc = raw as DIDDocument;\n\n if (typeof doc.id !== 'string') {\n return errorResult('invalidDid');\n }\n\n // 8. Exact `id` match (DD-203)\n if (doc.id !== did) {\n return errorResult('invalidDid');\n }\n\n return {\n didDocument: doc,\n didResolutionMetadata: { contentType: 'application/did+json' },\n didDocumentMetadata: {},\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Authority + Path Validation (Fix 2: strict validation)\n// ---------------------------------------------------------------------------\n\ninterface ValidationResult {\n ok: boolean;\n url: string;\n hostname: string;\n}\n\n/**\n * Validate and transform a did:web method-specific identifier to an HTTPS URL.\n *\n * Rejects:\n * - IP literals (IPv4, IPv6)\n * - Userinfo in authority\n * - Query or fragment components\n * - Empty path segments\n * - Malformed percent encoding\n * - Empty host\n */\nfunction validateAndTransform(methodSpecificId: string): ValidationResult {\n const fail: ValidationResult = { ok: false, url: '', hostname: '' };\n\n // Split on ':' for domain + optional path segments\n const parts = methodSpecificId.split(':');\n if (parts.length === 0 || !parts[0]) {\n return fail;\n }\n\n // Decode authority (handles %3A for port)\n let authority: string;\n try {\n authority = decodeURIComponent(parts[0]);\n } catch {\n return fail; // Malformed percent encoding\n }\n\n // Reject empty authority\n if (!authority) {\n return fail;\n }\n\n // Reject userinfo (@ in authority)\n if (authority.includes('@')) {\n return fail;\n }\n\n // Reject query/fragment in authority\n if (authority.includes('?') || authority.includes('#')) {\n return fail;\n }\n\n // Reject encoded slashes in authority (path traversal attempt)\n if (authority.includes('/')) {\n return fail;\n }\n\n // Parse hostname (with possible port)\n let hostname: string;\n try {\n const testUrl = new URL(`https://${authority}`);\n hostname = testUrl.hostname;\n\n // Reject if URL constructor added unexpected components\n if (testUrl.username || testUrl.password) {\n return fail;\n }\n } catch {\n return fail; // Invalid authority\n }\n\n // Reject IP literals\n if (isIPLiteral(hostname)) {\n return fail;\n }\n\n // Reject empty hostname\n if (!hostname) {\n return fail;\n }\n\n // Decode and validate path segments\n if (parts.length > 1) {\n const pathParts = parts.slice(1);\n\n for (const segment of pathParts) {\n // Reject empty path segments\n if (!segment) {\n return fail;\n }\n\n // Decode and reject slashes/query/fragment in segments\n let decoded: string;\n try {\n decoded = decodeURIComponent(segment);\n } catch {\n return fail;\n }\n\n if (decoded.includes('/') || decoded.includes('?') || decoded.includes('#')) {\n return fail;\n }\n }\n\n const decodedSegments = pathParts.map(decodeURIComponent);\n return {\n ok: true,\n url: `https://${authority}/${decodedSegments.join('/')}/did.json`,\n hostname,\n };\n }\n\n return {\n ok: true,\n url: `https://${authority}/.well-known/did.json`,\n hostname,\n };\n}\n\n/**\n * Check if a hostname is an IP literal (IPv4 or IPv6).\n */\nfunction isIPLiteral(hostname: string): boolean {\n if (hostname.startsWith('[')) return true;\n const parts = hostname.split('.');\n if (parts.length === 4 && parts.every((p) => /^\\d+$/.test(p))) return true;\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Normalize a hostname for consistent comparison.\n * Lowercases and strips trailing dot (DNS root).\n */\nfunction normalizeHostname(host: string): string {\n return host.toLowerCase().replace(/\\.$/, '');\n}\n\nfunction errorResult(error: string): DIDResolutionResult {\n return {\n didDocument: null,\n didResolutionMetadata: { error },\n didDocumentMetadata: {},\n };\n}\n","/**\n * Verification key extraction from DID Documents.\n *\n * Implements DD-202 (DID Verification Method Selection Policy):\n * 1. Prefer methods referenced in authentication/assertionMethod\n * 2. If multiple eligible Ed25519 methods remain, require caller keyId\n * or fail with E_DID_KEY_AMBIGUOUS\n * 3. Only Ed25519 keys extracted; other types silently skipped\n * 4. Iterates ALL methods regardless of match (no early-return oracle)\n */\n\nimport type { DIDDocument, VerificationMethod } from './types.js';\nimport { extractEd25519FromMultibase } from './multicodec.js';\nimport { DIDError } from './errors.js';\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface ExtractKeyOptions {\n /**\n * Explicit key ID to select.\n * If provided, only methods with this ID are considered.\n */\n keyId?: string;\n /**\n * Which verification relationship to prefer.\n * Default: 'authentication'\n */\n relationship?: 'authentication' | 'assertionMethod';\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Extract an Ed25519 public key from a DID Document.\n *\n * Selection policy (DD-202):\n * 1. Collect all verification methods from the document\n * 2. Filter by keyId if provided\n * 3. Filter by relationship references (authentication/assertionMethod)\n * 4. Try to extract Ed25519 key from each eligible method\n * 5. If exactly one Ed25519 key found: return it\n * 6. If zero found: return null\n * 7. If multiple found without keyId: throw E_DID_KEY_AMBIGUOUS\n *\n * All methods are iterated regardless of match to prevent key-type oracle.\n *\n * @param document - The resolved DID Document\n * @param options - Key selection options\n * @returns 32-byte Ed25519 public key, or null if no suitable key found\n * @throws DIDError with E_DID_KEY_AMBIGUOUS if multiple eligible keys\n */\nexport function extractVerificationKey(\n document: DIDDocument,\n options?: ExtractKeyOptions\n): Uint8Array | null {\n const methods = document.verificationMethod ?? [];\n const relationship = options?.relationship ?? 'authentication';\n const keyId = options?.keyId;\n\n // Get relationship-referenced method IDs\n const relationshipRefs = getRelationshipRefs(document, relationship);\n\n // Collect all eligible Ed25519 keys (iterate ALL methods, no early return)\n const candidates: Uint8Array[] = [];\n\n for (const method of methods) {\n // Filter by keyId if specified\n if (keyId && method.id !== keyId) {\n continue;\n }\n\n // Prefer relationship-referenced methods if refs exist\n if (relationshipRefs.length > 0 && !relationshipRefs.includes(method.id)) {\n continue;\n }\n\n // Try to extract Ed25519 key (silently skip non-Ed25519)\n const key = tryExtractEd25519(method);\n if (key) {\n candidates.push(key);\n }\n }\n\n // If no relationship-referenced methods found, fall back to all methods\n if (candidates.length === 0 && relationshipRefs.length > 0) {\n for (const method of methods) {\n if (keyId && method.id !== keyId) continue;\n const key = tryExtractEd25519(method);\n if (key) candidates.push(key);\n }\n }\n\n if (candidates.length === 0) {\n return null;\n }\n\n if (candidates.length === 1) {\n return candidates[0];\n }\n\n // Multiple Ed25519 keys without explicit keyId selection\n throw new DIDError(\n 'E_DID_KEY_AMBIGUOUS',\n `Found ${candidates.length} eligible Ed25519 keys. Provide keyId to select.`\n );\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Get verification method IDs referenced by a relationship.\n */\nfunction getRelationshipRefs(\n document: DIDDocument,\n relationship: 'authentication' | 'assertionMethod'\n): string[] {\n const refs = document[relationship];\n if (!refs) return [];\n\n return refs\n .map((ref) => (typeof ref === 'string' ? ref : ref.id))\n .filter((id): id is string => typeof id === 'string');\n}\n\n/**\n * Try to extract an Ed25519 key from a verification method.\n * Returns null for non-Ed25519 methods (no oracle).\n */\nfunction tryExtractEd25519(method: VerificationMethod): Uint8Array | null {\n // Try publicKeyMultibase (Multikey / Ed25519VerificationKey2020)\n if (method.publicKeyMultibase) {\n try {\n return extractEd25519FromMultibase(method.publicKeyMultibase);\n } catch {\n return null;\n }\n }\n\n // Try publicKeyJwk (JsonWebKey2020, OKP/Ed25519)\n if (method.publicKeyJwk) {\n const jwk = method.publicKeyJwk;\n if (jwk.kty === 'OKP' && jwk.crv === 'Ed25519' && typeof jwk.x === 'string') {\n try {\n // JWK x value is base64url-encoded raw key\n const bytes = new Uint8Array(Buffer.from(jwk.x, 'base64url'));\n if (bytes.length === 32) return bytes;\n } catch {\n return null;\n }\n }\n return null;\n }\n\n return null;\n}\n","/**\n * Caching resolver wrapper.\n *\n * Wraps any DIDResolver with TTL-based in-memory caching.\n * Cache entries expire after configurable TTL and are evicted\n * when maxEntries is reached (oldest-first).\n *\n * The cache key is the full DID string.\n */\n\nimport type { DIDResolutionResult } from './types.js';\nimport type { DIDResolver } from './resolver.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface CachingResolverOptions {\n /** Time-to-live in milliseconds (default: 300000 = 5 minutes) */\n ttlMs?: number;\n /** Maximum number of cached entries (default: 1000) */\n maxEntries?: number;\n}\n\ninterface CacheEntry {\n result: DIDResolutionResult;\n expiresAt: number;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_TTL_MS = 5 * 60 * 1000; // 5 minutes\nconst DEFAULT_MAX_ENTRIES = 1000;\n\n// ---------------------------------------------------------------------------\n// CachingResolver\n// ---------------------------------------------------------------------------\n\n/**\n * Caching wrapper for any DIDResolver.\n *\n * - TTL-based expiry: entries older than ttlMs are evicted on access\n * - Max entries: oldest entries evicted when capacity is reached\n * - Only successful resolutions are cached (didDocument !== null)\n * - Failed resolutions are NOT cached (each attempt is fresh)\n *\n * @example\n * ```typescript\n * const inner = new DidKeyResolver();\n * const cached = new CachingResolver(inner, { ttlMs: 60000 });\n * const result = await cached.resolve('did:key:z6Mk...');\n * ```\n */\nexport class CachingResolver implements DIDResolver {\n readonly methods: readonly string[];\n\n private readonly inner: DIDResolver;\n private readonly ttlMs: number;\n private readonly maxEntries: number;\n private readonly cache = new Map<string, CacheEntry>();\n\n constructor(inner: DIDResolver, options?: CachingResolverOptions) {\n this.inner = inner;\n this.methods = inner.methods;\n this.ttlMs = options?.ttlMs ?? DEFAULT_TTL_MS;\n this.maxEntries = options?.maxEntries ?? DEFAULT_MAX_ENTRIES;\n }\n\n async resolve(did: string): Promise<DIDResolutionResult> {\n const now = Date.now();\n\n // Check cache (return deep clone to prevent caller mutation of cached data)\n const cached = this.cache.get(did);\n if (cached && cached.expiresAt > now) {\n return deepCloneResult(cached.result);\n }\n\n // Evict expired entry if present\n if (cached) {\n this.cache.delete(did);\n }\n\n // Resolve from inner\n const result = await this.inner.resolve(did);\n\n // Only cache successful resolutions (deep clone on store to isolate)\n if (result.didDocument !== null) {\n // Evict oldest if at capacity\n if (this.cache.size >= this.maxEntries) {\n const oldestKey = this.cache.keys().next().value;\n if (oldestKey !== undefined) {\n this.cache.delete(oldestKey);\n }\n }\n\n this.cache.set(did, {\n result: deepCloneResult(result),\n expiresAt: now + this.ttlMs,\n });\n }\n\n return result;\n }\n\n /** Invalidate a specific cached entry */\n invalidate(did: string): void {\n this.cache.delete(did);\n }\n\n /** Clear the entire cache */\n clear(): void {\n this.cache.clear();\n }\n\n /** Current number of cached entries */\n get size(): number {\n return this.cache.size;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Deep clone a DIDResolutionResult to prevent caller mutation of cached data.\n * Uses structuredClone (available since Node 17) for correctness.\n */\nfunction deepCloneResult(result: DIDResolutionResult): DIDResolutionResult {\n return structuredClone(result);\n}\n"]}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @peac/adapter-did
3
+ *
4
+ * DID document resolution for PEAC receipt verification.
5
+ * Interoperability adapter layer for W3C DID Core v1.0.
6
+ *
7
+ * Supported DID methods:
8
+ * - did:key (Ed25519, zero network I/O)
9
+ * - did:web (HTTPS, SSRF-hardened; added in PR7)
10
+ *
11
+ * @packageDocumentation
12
+ */
13
+ export type { DIDDocument, DIDResolutionResult, DIDResolutionMetadata, DIDDocumentMetadata, VerificationMethod, JsonWebKey, } from './types.js';
14
+ export type { DIDResolver } from './resolver.js';
15
+ export { createCompositeResolver } from './resolver.js';
16
+ export { DidKeyResolver } from './did-key.js';
17
+ export type { DidWebResolverOptions, HardenedFetchResult, HardenedFetchFn } from './did-web.js';
18
+ export { DidWebResolver } from './did-web.js';
19
+ export type { ExtractKeyOptions } from './extract-key.js';
20
+ export { extractVerificationKey } from './extract-key.js';
21
+ export { extractEd25519FromMultibase } from './multicodec.js';
22
+ export type { CachingResolverOptions } from './cache.js';
23
+ export { CachingResolver } from './cache.js';
24
+ export { DIDError } from './errors.js';
25
+ export type { DIDErrorCode } from './errors.js';
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,YAAY,EACV,WAAW,EACX,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,UAAU,GACX,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAGxD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9C,YAAY,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAChG,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAG1D,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAG9D,YAAY,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAG7C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ /**
3
+ * @peac/adapter-did
4
+ *
5
+ * DID document resolution for PEAC receipt verification.
6
+ * Interoperability adapter layer for W3C DID Core v1.0.
7
+ *
8
+ * Supported DID methods:
9
+ * - did:key (Ed25519, zero network I/O)
10
+ * - did:web (HTTPS, SSRF-hardened; added in PR7)
11
+ *
12
+ * @packageDocumentation
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.DIDError = exports.extractEd25519FromMultibase = exports.extractVerificationKey = exports.DidKeyResolver = exports.createCompositeResolver = void 0;
16
+ var resolver_js_1 = require("./resolver.js");
17
+ Object.defineProperty(exports, "createCompositeResolver", { enumerable: true, get: function () { return resolver_js_1.createCompositeResolver; } });
18
+ // did:key resolver
19
+ var did_key_js_1 = require("./did-key.js");
20
+ Object.defineProperty(exports, "DidKeyResolver", { enumerable: true, get: function () { return did_key_js_1.DidKeyResolver; } });
21
+ var extract_key_js_1 = require("./extract-key.js");
22
+ Object.defineProperty(exports, "extractVerificationKey", { enumerable: true, get: function () { return extract_key_js_1.extractVerificationKey; } });
23
+ // Multicodec utilities
24
+ var multicodec_js_1 = require("./multicodec.js");
25
+ Object.defineProperty(exports, "extractEd25519FromMultibase", { enumerable: true, get: function () { return multicodec_js_1.extractEd25519FromMultibase; } });
26
+ // Errors
27
+ var errors_js_1 = require("./errors.js");
28
+ Object.defineProperty(exports, "DIDError", { enumerable: true, get: function () { return errors_js_1.DIDError; } });
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;AAcH,6CAAwD;AAA/C,sHAAA,uBAAuB,OAAA;AAEhC,mBAAmB;AACnB,2CAA8C;AAArC,4GAAA,cAAc,OAAA;AAIvB,mDAA0D;AAAjD,wHAAA,sBAAsB,OAAA;AAE/B,uBAAuB;AACvB,iDAA8D;AAArD,4HAAA,2BAA2B,OAAA;AAEpC,SAAS;AACT,yCAAuC;AAA9B,qGAAA,QAAQ,OAAA"}
package/dist/index.mjs ADDED
@@ -0,0 +1,453 @@
1
+ // src/resolver.ts
2
+ function createCompositeResolver(resolvers) {
3
+ return {
4
+ methods: resolvers.flatMap((r) => [...r.methods]),
5
+ async resolve(did) {
6
+ const method = extractMethod(did);
7
+ if (!method) {
8
+ return {
9
+ didDocument: null,
10
+ didResolutionMetadata: { error: "invalidDid" },
11
+ didDocumentMetadata: {}
12
+ };
13
+ }
14
+ for (const resolver of resolvers) {
15
+ if (resolver.methods.includes(method)) {
16
+ return resolver.resolve(did);
17
+ }
18
+ }
19
+ return {
20
+ didDocument: null,
21
+ didResolutionMetadata: { error: "methodNotSupported" },
22
+ didDocumentMetadata: {}
23
+ };
24
+ }
25
+ };
26
+ }
27
+ function extractMethod(did) {
28
+ if (!did.startsWith("did:")) return null;
29
+ const parts = did.split(":");
30
+ if (parts.length < 3) return null;
31
+ return parts[1];
32
+ }
33
+
34
+ // src/errors.ts
35
+ var DIDError = class extends Error {
36
+ code;
37
+ constructor(code, message) {
38
+ super(message);
39
+ this.name = "DIDError";
40
+ this.code = code;
41
+ }
42
+ };
43
+
44
+ // src/multicodec.ts
45
+ var ED25519_MULTICODEC_PREFIX = new Uint8Array([237, 1]);
46
+ var ED25519_KEY_LENGTH = 32;
47
+ var ED25519_MULTICODEC_LENGTH = ED25519_MULTICODEC_PREFIX.length + ED25519_KEY_LENGTH;
48
+ var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
49
+ var BASE58_MAP = /* @__PURE__ */ new Map();
50
+ for (let i = 0; i < BASE58_ALPHABET.length; i++) {
51
+ BASE58_MAP.set(BASE58_ALPHABET[i], i);
52
+ }
53
+ function base58btcDecode(input) {
54
+ if (input.length === 0) return new Uint8Array(0);
55
+ let zeros = 0;
56
+ while (zeros < input.length && input[zeros] === "1") {
57
+ zeros++;
58
+ }
59
+ const size = Math.ceil(input.length * 733 / 1e3) + 1;
60
+ const b256 = new Uint8Array(size);
61
+ let length = 0;
62
+ for (let i = zeros; i < input.length; i++) {
63
+ const value = BASE58_MAP.get(input[i]);
64
+ if (value === void 0) {
65
+ throw new DIDError("E_DID_DOCUMENT_INVALID", `Invalid base58btc character: ${input[i]}`);
66
+ }
67
+ let carry = value;
68
+ for (let j = 0; j < length || carry > 0; j++) {
69
+ carry += 58 * (b256[j] || 0);
70
+ b256[j] = carry % 256;
71
+ carry = Math.floor(carry / 256);
72
+ if (j >= length) length = j + 1;
73
+ }
74
+ }
75
+ const result = new Uint8Array(zeros + length);
76
+ for (let i = 0; i < length; i++) {
77
+ result[zeros + length - 1 - i] = b256[i];
78
+ }
79
+ return result;
80
+ }
81
+ function base64urlDecode(input) {
82
+ return new Uint8Array(Buffer.from(input, "base64url"));
83
+ }
84
+ function extractEd25519FromMultibase(multibaseValue) {
85
+ if (multibaseValue.length < 2) {
86
+ throw new DIDError("E_DID_DOCUMENT_INVALID", "Multibase value too short");
87
+ }
88
+ const prefix = multibaseValue[0];
89
+ const encoded = multibaseValue.slice(1);
90
+ let decoded;
91
+ if (prefix === "z") {
92
+ decoded = base58btcDecode(encoded);
93
+ } else if (prefix === "u") {
94
+ decoded = base64urlDecode(encoded);
95
+ } else {
96
+ throw new DIDError(
97
+ "E_DID_DOCUMENT_INVALID",
98
+ `Unsupported multibase prefix: '${prefix}'. Expected 'z' (base58btc) or 'u' (base64url).`
99
+ );
100
+ }
101
+ if (decoded.length !== ED25519_MULTICODEC_LENGTH) {
102
+ throw new DIDError(
103
+ "E_DID_KEY_NOT_FOUND",
104
+ `Expected ${ED25519_MULTICODEC_LENGTH} bytes (2 prefix + 32 key), got ${decoded.length}`
105
+ );
106
+ }
107
+ if (decoded[0] !== ED25519_MULTICODEC_PREFIX[0] || decoded[1] !== ED25519_MULTICODEC_PREFIX[1]) {
108
+ throw new DIDError("E_DID_KEY_NOT_FOUND", "Multicodec prefix does not indicate Ed25519");
109
+ }
110
+ return decoded.slice(2);
111
+ }
112
+
113
+ // src/did-key.ts
114
+ var DidKeyResolver = class {
115
+ methods = ["key"];
116
+ async resolve(did) {
117
+ if (!did.startsWith("did:key:")) {
118
+ return {
119
+ didDocument: null,
120
+ didResolutionMetadata: { error: "invalidDid" },
121
+ didDocumentMetadata: {}
122
+ };
123
+ }
124
+ const multibaseValue = did.slice("did:key:".length);
125
+ if (!multibaseValue) {
126
+ return {
127
+ didDocument: null,
128
+ didResolutionMetadata: { error: "invalidDid" },
129
+ didDocumentMetadata: {}
130
+ };
131
+ }
132
+ try {
133
+ extractEd25519FromMultibase(multibaseValue);
134
+ } catch (e) {
135
+ if (e instanceof DIDError) {
136
+ return {
137
+ didDocument: null,
138
+ didResolutionMetadata: { error: e.code },
139
+ didDocumentMetadata: {}
140
+ };
141
+ }
142
+ return {
143
+ didDocument: null,
144
+ didResolutionMetadata: { error: "invalidDid" },
145
+ didDocumentMetadata: {}
146
+ };
147
+ }
148
+ const keyId = `${did}#${multibaseValue}`;
149
+ const verificationMethod = {
150
+ id: keyId,
151
+ type: "Ed25519VerificationKey2020",
152
+ controller: did,
153
+ publicKeyMultibase: multibaseValue
154
+ };
155
+ const document = {
156
+ "@context": [
157
+ "https://www.w3.org/ns/did/v1",
158
+ "https://w3id.org/security/suites/ed25519-2020/v1"
159
+ ],
160
+ id: did,
161
+ verificationMethod: [verificationMethod],
162
+ authentication: [keyId],
163
+ assertionMethod: [keyId]
164
+ };
165
+ return {
166
+ didDocument: document,
167
+ didResolutionMetadata: { contentType: "application/did+json" },
168
+ didDocumentMetadata: {}
169
+ };
170
+ }
171
+ };
172
+
173
+ // src/did-web.ts
174
+ var MAX_DOCUMENT_BYTES = 256 * 1024;
175
+ var DEFAULT_TIMEOUT_MS = 5e3;
176
+ var ACCEPTABLE_CONTENT_TYPES = /* @__PURE__ */ new Set(["application/did+json", "application/json"]);
177
+ var DidWebResolver = class {
178
+ methods = ["web"];
179
+ timeoutMs;
180
+ allowedDomains;
181
+ fetchFn;
182
+ constructor(options) {
183
+ this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
184
+ this.allowedDomains = options.allowedDomains?.map(normalizeHostname);
185
+ this.fetchFn = options.fetchFn;
186
+ }
187
+ async resolve(did) {
188
+ if (!did.startsWith("did:web:")) {
189
+ return errorResult("invalidDid");
190
+ }
191
+ const methodSpecificId = did.slice("did:web:".length);
192
+ if (!methodSpecificId) {
193
+ return errorResult("invalidDid");
194
+ }
195
+ const urlResult = validateAndTransform(methodSpecificId);
196
+ if (!urlResult.ok) {
197
+ return errorResult("invalidDid");
198
+ }
199
+ const url = urlResult.url;
200
+ const hostname = normalizeHostname(urlResult.hostname);
201
+ if (this.allowedDomains && !this.allowedDomains.includes(hostname)) {
202
+ return errorResult("invalidDid");
203
+ }
204
+ let fetchResult;
205
+ try {
206
+ fetchResult = await this.fetchFn(url, {
207
+ timeoutMs: this.timeoutMs,
208
+ maxResponseBytes: MAX_DOCUMENT_BYTES,
209
+ maxRedirects: 0
210
+ });
211
+ } catch {
212
+ return errorResult("notFound");
213
+ }
214
+ if (!fetchResult.ok || !fetchResult.data) {
215
+ return errorResult("notFound");
216
+ }
217
+ if (fetchResult.finalUrl && fetchResult.finalUrl !== url) {
218
+ return errorResult("invalidDid");
219
+ }
220
+ if (fetchResult.contentType) {
221
+ const baseType = fetchResult.contentType.split(";")[0].trim().toLowerCase();
222
+ if (!ACCEPTABLE_CONTENT_TYPES.has(baseType)) {
223
+ return errorResult("invalidDid");
224
+ }
225
+ }
226
+ const raw = fetchResult.data;
227
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
228
+ return errorResult("invalidDid");
229
+ }
230
+ const doc = raw;
231
+ if (typeof doc.id !== "string") {
232
+ return errorResult("invalidDid");
233
+ }
234
+ if (doc.id !== did) {
235
+ return errorResult("invalidDid");
236
+ }
237
+ return {
238
+ didDocument: doc,
239
+ didResolutionMetadata: { contentType: "application/did+json" },
240
+ didDocumentMetadata: {}
241
+ };
242
+ }
243
+ };
244
+ function validateAndTransform(methodSpecificId) {
245
+ const fail = { ok: false, url: "", hostname: "" };
246
+ const parts = methodSpecificId.split(":");
247
+ if (parts.length === 0 || !parts[0]) {
248
+ return fail;
249
+ }
250
+ let authority;
251
+ try {
252
+ authority = decodeURIComponent(parts[0]);
253
+ } catch {
254
+ return fail;
255
+ }
256
+ if (!authority) {
257
+ return fail;
258
+ }
259
+ if (authority.includes("@")) {
260
+ return fail;
261
+ }
262
+ if (authority.includes("?") || authority.includes("#")) {
263
+ return fail;
264
+ }
265
+ if (authority.includes("/")) {
266
+ return fail;
267
+ }
268
+ let hostname;
269
+ try {
270
+ const testUrl = new URL(`https://${authority}`);
271
+ hostname = testUrl.hostname;
272
+ if (testUrl.username || testUrl.password) {
273
+ return fail;
274
+ }
275
+ } catch {
276
+ return fail;
277
+ }
278
+ if (isIPLiteral(hostname)) {
279
+ return fail;
280
+ }
281
+ if (!hostname) {
282
+ return fail;
283
+ }
284
+ if (parts.length > 1) {
285
+ const pathParts = parts.slice(1);
286
+ for (const segment of pathParts) {
287
+ if (!segment) {
288
+ return fail;
289
+ }
290
+ let decoded;
291
+ try {
292
+ decoded = decodeURIComponent(segment);
293
+ } catch {
294
+ return fail;
295
+ }
296
+ if (decoded.includes("/") || decoded.includes("?") || decoded.includes("#")) {
297
+ return fail;
298
+ }
299
+ }
300
+ const decodedSegments = pathParts.map(decodeURIComponent);
301
+ return {
302
+ ok: true,
303
+ url: `https://${authority}/${decodedSegments.join("/")}/did.json`,
304
+ hostname
305
+ };
306
+ }
307
+ return {
308
+ ok: true,
309
+ url: `https://${authority}/.well-known/did.json`,
310
+ hostname
311
+ };
312
+ }
313
+ function isIPLiteral(hostname) {
314
+ if (hostname.startsWith("[")) return true;
315
+ const parts = hostname.split(".");
316
+ if (parts.length === 4 && parts.every((p) => /^\d+$/.test(p))) return true;
317
+ return false;
318
+ }
319
+ function normalizeHostname(host) {
320
+ return host.toLowerCase().replace(/\.$/, "");
321
+ }
322
+ function errorResult(error) {
323
+ return {
324
+ didDocument: null,
325
+ didResolutionMetadata: { error },
326
+ didDocumentMetadata: {}
327
+ };
328
+ }
329
+
330
+ // src/extract-key.ts
331
+ function extractVerificationKey(document, options) {
332
+ const methods = document.verificationMethod ?? [];
333
+ const relationship = options?.relationship ?? "authentication";
334
+ const keyId = options?.keyId;
335
+ const relationshipRefs = getRelationshipRefs(document, relationship);
336
+ const candidates = [];
337
+ for (const method of methods) {
338
+ if (keyId && method.id !== keyId) {
339
+ continue;
340
+ }
341
+ if (relationshipRefs.length > 0 && !relationshipRefs.includes(method.id)) {
342
+ continue;
343
+ }
344
+ const key = tryExtractEd25519(method);
345
+ if (key) {
346
+ candidates.push(key);
347
+ }
348
+ }
349
+ if (candidates.length === 0 && relationshipRefs.length > 0) {
350
+ for (const method of methods) {
351
+ if (keyId && method.id !== keyId) continue;
352
+ const key = tryExtractEd25519(method);
353
+ if (key) candidates.push(key);
354
+ }
355
+ }
356
+ if (candidates.length === 0) {
357
+ return null;
358
+ }
359
+ if (candidates.length === 1) {
360
+ return candidates[0];
361
+ }
362
+ throw new DIDError(
363
+ "E_DID_KEY_AMBIGUOUS",
364
+ `Found ${candidates.length} eligible Ed25519 keys. Provide keyId to select.`
365
+ );
366
+ }
367
+ function getRelationshipRefs(document, relationship) {
368
+ const refs = document[relationship];
369
+ if (!refs) return [];
370
+ return refs.map((ref) => typeof ref === "string" ? ref : ref.id).filter((id) => typeof id === "string");
371
+ }
372
+ function tryExtractEd25519(method) {
373
+ if (method.publicKeyMultibase) {
374
+ try {
375
+ return extractEd25519FromMultibase(method.publicKeyMultibase);
376
+ } catch {
377
+ return null;
378
+ }
379
+ }
380
+ if (method.publicKeyJwk) {
381
+ const jwk = method.publicKeyJwk;
382
+ if (jwk.kty === "OKP" && jwk.crv === "Ed25519" && typeof jwk.x === "string") {
383
+ try {
384
+ const bytes = new Uint8Array(Buffer.from(jwk.x, "base64url"));
385
+ if (bytes.length === 32) return bytes;
386
+ } catch {
387
+ return null;
388
+ }
389
+ }
390
+ return null;
391
+ }
392
+ return null;
393
+ }
394
+
395
+ // src/cache.ts
396
+ var DEFAULT_TTL_MS = 5 * 60 * 1e3;
397
+ var DEFAULT_MAX_ENTRIES = 1e3;
398
+ var CachingResolver = class {
399
+ methods;
400
+ inner;
401
+ ttlMs;
402
+ maxEntries;
403
+ cache = /* @__PURE__ */ new Map();
404
+ constructor(inner, options) {
405
+ this.inner = inner;
406
+ this.methods = inner.methods;
407
+ this.ttlMs = options?.ttlMs ?? DEFAULT_TTL_MS;
408
+ this.maxEntries = options?.maxEntries ?? DEFAULT_MAX_ENTRIES;
409
+ }
410
+ async resolve(did) {
411
+ const now = Date.now();
412
+ const cached = this.cache.get(did);
413
+ if (cached && cached.expiresAt > now) {
414
+ return deepCloneResult(cached.result);
415
+ }
416
+ if (cached) {
417
+ this.cache.delete(did);
418
+ }
419
+ const result = await this.inner.resolve(did);
420
+ if (result.didDocument !== null) {
421
+ if (this.cache.size >= this.maxEntries) {
422
+ const oldestKey = this.cache.keys().next().value;
423
+ if (oldestKey !== void 0) {
424
+ this.cache.delete(oldestKey);
425
+ }
426
+ }
427
+ this.cache.set(did, {
428
+ result: deepCloneResult(result),
429
+ expiresAt: now + this.ttlMs
430
+ });
431
+ }
432
+ return result;
433
+ }
434
+ /** Invalidate a specific cached entry */
435
+ invalidate(did) {
436
+ this.cache.delete(did);
437
+ }
438
+ /** Clear the entire cache */
439
+ clear() {
440
+ this.cache.clear();
441
+ }
442
+ /** Current number of cached entries */
443
+ get size() {
444
+ return this.cache.size;
445
+ }
446
+ };
447
+ function deepCloneResult(result) {
448
+ return structuredClone(result);
449
+ }
450
+
451
+ export { CachingResolver, DIDError, DidKeyResolver, DidWebResolver, createCompositeResolver, extractEd25519FromMultibase, extractVerificationKey };
452
+ //# sourceMappingURL=index.mjs.map
453
+ //# sourceMappingURL=index.mjs.map