attestix 0.4.0
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.
- package/CHANGELOG.md +62 -0
- package/LICENSE +190 -0
- package/README.md +296 -0
- package/SPEC.md +259 -0
- package/dist/index.cjs +940 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +580 -0
- package/dist/index.d.ts +580 -0
- package/dist/index.js +893 -0
- package/dist/index.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/client.ts","../src/verify/jcs.ts","../src/verify/base64url.ts","../src/verify/didkey.ts","../src/verify/ed25519.ts","../src/verify/credential.ts","../src/verify/delegation.ts"],"sourcesContent":["export { AttestixClient } from './client.js';\n\n// Offline cross-engine verification (Ed25519 / JCS / did:key). Verify Attestix\n// W3C VCs, VPs, and UCAN delegation chains in Node/browser without the API.\nexport {\n\tcanonicalize,\n\tcanonicalizeToString,\n\tJcsUnsupportedValueError,\n\tbase64urlDecode,\n\tpublicKeyToDidKey,\n\tdidKeyToPublicKey,\n\tdidFromVerificationMethod,\n\tbase58btcEncode,\n\tbase58btcDecode,\n\tED25519_MULTICODEC_PREFIX,\n\tverifyEd25519,\n\tverifyCredential,\n\tverifyPresentation,\n\tverifyDelegationChain,\n\tdecodeDelegationUnsafe,\n} from './verify/index.js';\n\nexport type {\n\tJsonValue,\n\tCredentialChecks,\n\tVerifyCredentialResult,\n\tVerifyCredentialOptions,\n\tVerifyPresentationResult,\n\tDelegationClaims,\n\tDelegationLinkResult,\n\tVerifyDelegationResult,\n\tVerifyDelegationOptions,\n} from './verify/index.js';\n\nexport {\n\tAttestixError,\n\tAttestixAuthError,\n\tAttestixNotFoundError,\n\tAttestixValidationError,\n\tAttestixRateLimitError,\n} from './errors.js';\n\nexport type {\n\t// Client options\n\tAttestixOptions,\n\n\t// Identity\n\tIdentity,\n\tCreateIdentityParams,\n\tListIdentitiesParams,\n\tPurgeResult,\n\n\t// Credentials\n\tCredential,\n\tIssueCredentialParams,\n\tListCredentialsParams,\n\tPresentation,\n\tCreatePresentationParams,\n\n\t// Compliance\n\tComplianceProfile,\n\tComplianceRequirement,\n\tCreateComplianceProfileParams,\n\tComplianceStatus,\n\tAssessment,\n\tRecordAssessmentParams,\n\tDeclaration,\n\tGenerateDeclarationParams,\n\n\t// Reputation\n\tReputationScore,\n\tRecordInteractionParams,\n\tQueryReputationParams,\n\n\t// Provenance\n\tProvenanceEntry,\n\tRecordTrainingDataParams,\n\tRecordModelLineageParams,\n\tAuditEntry,\n\tLogActionParams,\n\tAuditTrailParams,\n\n\t// Delegation\n\tDelegation,\n\tCreateDelegationParams,\n\tListDelegationsParams,\n\n\t// DID\n\tDIDDocument,\n\tVerificationMethod,\n\n\t// Blockchain\n\tAnchorReceipt,\n\tAnchorVerification,\n\tCostEstimate,\n\n\t// Shared\n\tVerificationResult,\n\tVerificationCheck,\n\tErrorResponse,\n} from './types.js';\n","/**\n * Base error class for all Attestix SDK errors.\n */\nexport class AttestixError extends Error {\n\tpublic readonly statusCode: number;\n\tpublic readonly detail: string;\n\n\tconstructor(message: string, statusCode: number, detail?: string) {\n\t\tsuper(message);\n\t\tthis.name = 'AttestixError';\n\t\tthis.statusCode = statusCode;\n\t\tthis.detail = detail ?? message;\n\n\t\t// Maintains proper stack trace in V8 environments\n\t\tconst ErrorWithCapture = Error as typeof Error & {\n\t\t\tcaptureStackTrace?: (target: object, constructor: Function) => void;\n\t\t};\n\t\tif (ErrorWithCapture.captureStackTrace) {\n\t\t\tErrorWithCapture.captureStackTrace(this, this.constructor);\n\t\t}\n\t}\n}\n\n/**\n * Thrown when the API returns a 401 Unauthorized response.\n * Indicates an invalid or missing API key.\n */\nexport class AttestixAuthError extends AttestixError {\n\tconstructor(detail?: string) {\n\t\tsuper(\n\t\t\tdetail ?? 'Authentication failed - check your API key',\n\t\t\t401,\n\t\t\tdetail,\n\t\t);\n\t\tthis.name = 'AttestixAuthError';\n\t}\n}\n\n/**\n * Thrown when the API returns a 404 Not Found response.\n * The requested resource does not exist.\n */\nexport class AttestixNotFoundError extends AttestixError {\n\tconstructor(detail?: string) {\n\t\tsuper(\n\t\t\tdetail ?? 'Resource not found',\n\t\t\t404,\n\t\t\tdetail,\n\t\t);\n\t\tthis.name = 'AttestixNotFoundError';\n\t}\n}\n\n/**\n * Thrown when the API returns a 400 Bad Request response.\n * The request parameters failed validation.\n */\nexport class AttestixValidationError extends AttestixError {\n\tconstructor(detail?: string) {\n\t\tsuper(\n\t\t\tdetail ?? 'Validation error - check your request parameters',\n\t\t\t400,\n\t\t\tdetail,\n\t\t);\n\t\tthis.name = 'AttestixValidationError';\n\t}\n}\n\n/**\n * Thrown when the API returns a 429 Too Many Requests response.\n * The client has exceeded the rate limit.\n */\nexport class AttestixRateLimitError extends AttestixError {\n\tpublic readonly retryAfter: number | null;\n\n\tconstructor(detail?: string, retryAfter?: number) {\n\t\tsuper(\n\t\t\tdetail ?? 'Rate limit exceeded - try again later',\n\t\t\t429,\n\t\t\tdetail,\n\t\t);\n\t\tthis.name = 'AttestixRateLimitError';\n\t\tthis.retryAfter = retryAfter ?? null;\n\t}\n}\n","import {\n\tAttestixError,\n\tAttestixAuthError,\n\tAttestixNotFoundError,\n\tAttestixValidationError,\n\tAttestixRateLimitError,\n} from './errors.js';\n\nimport type {\n\tAttestixOptions,\n\tIdentity,\n\tCreateIdentityParams,\n\tListIdentitiesParams,\n\tPurgeResult,\n\tCredential,\n\tIssueCredentialParams,\n\tListCredentialsParams,\n\tPresentation,\n\tCreatePresentationParams,\n\tComplianceProfile,\n\tCreateComplianceProfileParams,\n\tComplianceStatus,\n\tAssessment,\n\tRecordAssessmentParams,\n\tDeclaration,\n\tGenerateDeclarationParams,\n\tReputationScore,\n\tRecordInteractionParams,\n\tQueryReputationParams,\n\tProvenanceEntry,\n\tRecordTrainingDataParams,\n\tRecordModelLineageParams,\n\tAuditEntry,\n\tLogActionParams,\n\tAuditTrailParams,\n\tDelegation,\n\tCreateDelegationParams,\n\tListDelegationsParams,\n\tDIDDocument,\n\tAnchorReceipt,\n\tAnchorVerification,\n\tCostEstimate,\n\tVerificationResult,\n} from './types.js';\n\nconst DEFAULT_TIMEOUT = 30_000;\nconst RETRY_STATUS_CODES = new Set([429, 503]);\nconst MAX_RETRIES = 1;\nconst BASE_RETRY_DELAY = 1000;\n\nexport class AttestixClient {\n\tprivate readonly baseUrl: string;\n\tprivate readonly apiKey: string;\n\tprivate readonly timeout: number;\n\n\tconstructor(options: AttestixOptions) {\n\t\tthis.baseUrl = options.baseUrl.replace(/\\/+$/, '');\n\t\tthis.apiKey = options.apiKey;\n\t\tthis.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n\t}\n\n\t// ========================================================================\n\t// Identity\n\t// ========================================================================\n\n\tasync createIdentity(params: CreateIdentityParams): Promise<Identity> {\n\t\treturn this.request<Identity>('POST', '/identities', params);\n\t}\n\n\tasync getIdentity(agentId: string): Promise<Identity> {\n\t\treturn this.request<Identity>('GET', `/identities/${encodeURIComponent(agentId)}`);\n\t}\n\n\tasync listIdentities(params?: ListIdentitiesParams): Promise<Identity[]> {\n\t\tconst query = this.buildQuery(params);\n\t\treturn this.request<Identity[]>('GET', `/identities${query}`);\n\t}\n\n\tasync verifyIdentity(agentId: string): Promise<VerificationResult> {\n\t\treturn this.request<VerificationResult>('POST', `/identities/${encodeURIComponent(agentId)}/verify`);\n\t}\n\n\tasync translateIdentity(agentId: string, format: string): Promise<Record<string, unknown>> {\n\t\tconst query = this.buildQuery({ format });\n\t\treturn this.request<Record<string, unknown>>('GET', `/identities/${encodeURIComponent(agentId)}/translate${query}`);\n\t}\n\n\tasync revokeIdentity(agentId: string, reason?: string): Promise<Identity> {\n\t\treturn this.request<Identity>('POST', `/identities/${encodeURIComponent(agentId)}/revoke`, { reason });\n\t}\n\n\tasync purgeAgentData(agentId: string): Promise<PurgeResult> {\n\t\treturn this.request<PurgeResult>('DELETE', `/identities/${encodeURIComponent(agentId)}/purge`);\n\t}\n\n\t// ========================================================================\n\t// Credentials\n\t// ========================================================================\n\n\tasync issueCredential(params: IssueCredentialParams): Promise<Credential> {\n\t\treturn this.request<Credential>('POST', '/credentials', params);\n\t}\n\n\tasync getCredential(credentialId: string): Promise<Credential> {\n\t\treturn this.request<Credential>('GET', `/credentials/${encodeURIComponent(credentialId)}`);\n\t}\n\n\tasync listCredentials(params?: ListCredentialsParams): Promise<Credential[]> {\n\t\tconst query = this.buildQuery(params);\n\t\treturn this.request<Credential[]>('GET', `/credentials${query}`);\n\t}\n\n\tasync verifyCredential(credentialId: string): Promise<VerificationResult> {\n\t\treturn this.request<VerificationResult>('POST', `/credentials/${encodeURIComponent(credentialId)}/verify`);\n\t}\n\n\tasync verifyExternalCredential(credential: Record<string, unknown>): Promise<VerificationResult> {\n\t\treturn this.request<VerificationResult>('POST', '/credentials/verify-external', credential);\n\t}\n\n\tasync revokeCredential(credentialId: string, reason?: string): Promise<Credential> {\n\t\treturn this.request<Credential>('POST', `/credentials/${encodeURIComponent(credentialId)}/revoke`, { reason });\n\t}\n\n\tasync createPresentation(params: CreatePresentationParams): Promise<Presentation> {\n\t\treturn this.request<Presentation>('POST', '/credentials/presentations', params);\n\t}\n\n\t// ========================================================================\n\t// Compliance\n\t// ========================================================================\n\n\tasync createComplianceProfile(params: CreateComplianceProfileParams): Promise<ComplianceProfile> {\n\t\treturn this.request<ComplianceProfile>('POST', '/compliance/profiles', params);\n\t}\n\n\tasync getComplianceProfile(profileId: string): Promise<ComplianceProfile> {\n\t\treturn this.request<ComplianceProfile>('GET', `/compliance/profiles/${encodeURIComponent(profileId)}`);\n\t}\n\n\tasync listComplianceProfiles(): Promise<ComplianceProfile[]> {\n\t\treturn this.request<ComplianceProfile[]>('GET', '/compliance/profiles');\n\t}\n\n\tasync getComplianceStatus(profileId: string): Promise<ComplianceStatus> {\n\t\treturn this.request<ComplianceStatus>('GET', `/compliance/profiles/${encodeURIComponent(profileId)}/status`);\n\t}\n\n\tasync recordAssessment(params: RecordAssessmentParams): Promise<Assessment> {\n\t\treturn this.request<Assessment>('POST', '/compliance/assessments', params);\n\t}\n\n\tasync generateDeclaration(params: GenerateDeclarationParams): Promise<Declaration> {\n\t\treturn this.request<Declaration>('POST', '/compliance/declarations', params);\n\t}\n\n\t// ========================================================================\n\t// Reputation\n\t// ========================================================================\n\n\tasync recordInteraction(params: RecordInteractionParams): Promise<void> {\n\t\tawait this.request<void>('POST', '/reputation/interactions', params);\n\t}\n\n\tasync getReputation(agentId: string): Promise<ReputationScore> {\n\t\treturn this.request<ReputationScore>('GET', `/reputation/${encodeURIComponent(agentId)}`);\n\t}\n\n\tasync queryReputation(params?: QueryReputationParams): Promise<ReputationScore[]> {\n\t\tconst query = this.buildQuery(params);\n\t\treturn this.request<ReputationScore[]>('GET', `/reputation${query}`);\n\t}\n\n\t// ========================================================================\n\t// Provenance\n\t// ========================================================================\n\n\tasync recordTrainingData(params: RecordTrainingDataParams): Promise<ProvenanceEntry> {\n\t\treturn this.request<ProvenanceEntry>('POST', '/provenance/training-data', params);\n\t}\n\n\tasync recordModelLineage(params: RecordModelLineageParams): Promise<ProvenanceEntry> {\n\t\treturn this.request<ProvenanceEntry>('POST', '/provenance/model-lineage', params);\n\t}\n\n\tasync logAction(params: LogActionParams): Promise<AuditEntry> {\n\t\treturn this.request<AuditEntry>('POST', '/provenance/actions', params);\n\t}\n\n\tasync getProvenance(agentId: string): Promise<ProvenanceEntry[]> {\n\t\treturn this.request<ProvenanceEntry[]>('GET', `/provenance/${encodeURIComponent(agentId)}`);\n\t}\n\n\tasync getAuditTrail(params?: AuditTrailParams): Promise<AuditEntry[]> {\n\t\tconst query = this.buildQuery(params);\n\t\treturn this.request<AuditEntry[]>('GET', `/provenance/audit${query}`);\n\t}\n\n\t// ========================================================================\n\t// Delegation\n\t// ========================================================================\n\n\tasync createDelegation(params: CreateDelegationParams): Promise<Delegation> {\n\t\treturn this.request<Delegation>('POST', '/delegations', params);\n\t}\n\n\tasync listDelegations(params?: ListDelegationsParams): Promise<Delegation[]> {\n\t\tconst query = this.buildQuery(params);\n\t\treturn this.request<Delegation[]>('GET', `/delegations${query}`);\n\t}\n\n\tasync verifyDelegation(token: string): Promise<VerificationResult> {\n\t\treturn this.request<VerificationResult>('POST', '/delegations/verify', { token });\n\t}\n\n\tasync revokeDelegation(delegationId: string): Promise<void> {\n\t\tawait this.request<void>('POST', `/delegations/${encodeURIComponent(delegationId)}/revoke`);\n\t}\n\n\t// ========================================================================\n\t// DID\n\t// ========================================================================\n\n\tasync createDidKey(): Promise<DIDDocument> {\n\t\treturn this.request<DIDDocument>('POST', '/did/key');\n\t}\n\n\tasync createDidWeb(domain: string): Promise<DIDDocument> {\n\t\treturn this.request<DIDDocument>('POST', '/did/web', { domain });\n\t}\n\n\tasync resolveDid(did: string): Promise<DIDDocument> {\n\t\treturn this.request<DIDDocument>('GET', `/did/${encodeURIComponent(did)}`);\n\t}\n\n\t// ========================================================================\n\t// Blockchain Anchoring\n\t// ========================================================================\n\n\tasync anchorIdentity(agentId: string): Promise<AnchorReceipt> {\n\t\treturn this.request<AnchorReceipt>('POST', `/anchoring/identities/${encodeURIComponent(agentId)}`);\n\t}\n\n\tasync anchorCredential(credentialId: string): Promise<AnchorReceipt> {\n\t\treturn this.request<AnchorReceipt>('POST', `/anchoring/credentials/${encodeURIComponent(credentialId)}`);\n\t}\n\n\tasync anchorAuditBatch(entryIds?: string[]): Promise<AnchorReceipt> {\n\t\treturn this.request<AnchorReceipt>('POST', '/anchoring/audit-batch', { entry_ids: entryIds });\n\t}\n\n\tasync verifyAnchor(anchorId: string): Promise<AnchorVerification> {\n\t\treturn this.request<AnchorVerification>('POST', `/anchoring/${encodeURIComponent(anchorId)}/verify`);\n\t}\n\n\tasync getAnchorStatus(anchorId: string): Promise<AnchorReceipt> {\n\t\treturn this.request<AnchorReceipt>('GET', `/anchoring/${encodeURIComponent(anchorId)}`);\n\t}\n\n\tasync estimateAnchorCost(): Promise<CostEstimate> {\n\t\treturn this.request<CostEstimate>('GET', '/anchoring/estimate');\n\t}\n\n\t// ========================================================================\n\t// Internal\n\t// ========================================================================\n\n\tprivate async request<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\tbody?: unknown,\n\t): Promise<T> {\n\t\treturn this.requestWithRetry<T>(method, path, body, 0);\n\t}\n\n\tprivate async requestWithRetry<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\tbody: unknown,\n\t\tattempt: number,\n\t): Promise<T> {\n\t\tconst controller = new AbortController();\n\t\tconst timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n\t\tconst url = `${this.baseUrl}${path}`;\n\t\tconst headers: Record<string, string> = {\n\t\t\t'Authorization': `Bearer ${this.apiKey}`,\n\t\t\t'Accept': 'application/json',\n\t\t};\n\n\t\tconst init: RequestInit = {\n\t\t\tmethod,\n\t\t\theaders,\n\t\t\tsignal: controller.signal,\n\t\t};\n\n\t\tif (body !== undefined && method !== 'GET') {\n\t\t\theaders['Content-Type'] = 'application/json';\n\t\t\tinit.body = JSON.stringify(body);\n\t\t}\n\n\t\tlet response: Response;\n\n\t\ttry {\n\t\t\tresponse = await fetch(url, init);\n\t\t} catch (error) {\n\t\t\tclearTimeout(timeoutId);\n\n\t\t\tif (error instanceof DOMException && error.name === 'AbortError') {\n\t\t\t\tthrow new AttestixError(\n\t\t\t\t\t`Request timed out after ${this.timeout}ms`,\n\t\t\t\t\t0,\n\t\t\t\t\t'Request timeout',\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthrow new AttestixError(\n\t\t\t\t`Network error: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t0,\n\t\t\t\t'Network error',\n\t\t\t);\n\t\t} finally {\n\t\t\tclearTimeout(timeoutId);\n\t\t}\n\n\t\t// Retry on 429 or 503 with exponential backoff\n\t\tif (RETRY_STATUS_CODES.has(response.status) && attempt < MAX_RETRIES) {\n\t\t\tconst retryAfter = response.headers.get('Retry-After');\n\t\t\tconst delay = retryAfter\n\t\t\t\t? parseInt(retryAfter, 10) * 1000\n\t\t\t\t: BASE_RETRY_DELAY * Math.pow(2, attempt);\n\n\t\t\tawait this.sleep(delay);\n\t\t\treturn this.requestWithRetry<T>(method, path, body, attempt + 1);\n\t\t}\n\n\t\tif (!response.ok) {\n\t\t\tawait this.handleErrorResponse(response);\n\t\t}\n\n\t\t// Handle 204 No Content\n\t\tif (response.status === 204) {\n\t\t\treturn undefined as T;\n\t\t}\n\n\t\tconst text = await response.text();\n\t\tif (!text) {\n\t\t\treturn undefined as T;\n\t\t}\n\n\t\treturn JSON.parse(text) as T;\n\t}\n\n\tprivate async handleErrorResponse(response: Response): Promise<never> {\n\t\tlet detail: string;\n\n\t\ttry {\n\t\t\tconst body = await response.json();\n\t\t\tdetail = body.detail ?? body.message ?? JSON.stringify(body);\n\t\t} catch {\n\t\t\tdetail = `HTTP ${response.status}: ${response.statusText}`;\n\t\t}\n\n\t\tswitch (response.status) {\n\t\t\tcase 400:\n\t\t\t\tthrow new AttestixValidationError(detail);\n\t\t\tcase 401:\n\t\t\tcase 403:\n\t\t\t\tthrow new AttestixAuthError(detail);\n\t\t\tcase 404:\n\t\t\t\tthrow new AttestixNotFoundError(detail);\n\t\t\tcase 429: {\n\t\t\t\tconst retryAfter = response.headers.get('Retry-After');\n\t\t\t\tthrow new AttestixRateLimitError(\n\t\t\t\t\tdetail,\n\t\t\t\t\tretryAfter ? parseInt(retryAfter, 10) : undefined,\n\t\t\t\t);\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new AttestixError(detail, response.status, detail);\n\t\t}\n\t}\n\n\tprivate buildQuery(params?: object): string {\n\t\tif (!params) return '';\n\n\t\tconst searchParams = new URLSearchParams();\n\t\tconst entries = Object.entries(params) as [string, unknown][];\n\n\t\tfor (const [key, value] of entries) {\n\t\t\tif (value !== undefined && value !== null) {\n\t\t\t\tsearchParams.set(key, String(value));\n\t\t\t}\n\t\t}\n\n\t\tconst queryString = searchParams.toString();\n\t\treturn queryString ? `?${queryString}` : '';\n\t}\n\n\tprivate sleep(ms: number): Promise<void> {\n\t\treturn new Promise((resolve) => setTimeout(resolve, ms));\n\t}\n}\n","/**\n * Canonical JSON serialization matching the Python Attestix engine's\n * `auth.crypto.canonicalize_json`.\n *\n * This is NOT strict RFC 8785 — it is byte-for-byte compatible with what the\n * Python engine actually produces:\n * json.dumps(normalize(obj), sort_keys=True, separators=(\",\",\":\"),\n * ensure_ascii=False).encode(\"utf-8\")\n *\n * Rules (see SPEC.md §3):\n * - object keys sorted by Unicode code point (Python default string sort)\n * - compact separators: \",\" and \":\"\n * - non-ASCII emitted as raw UTF-8 (NOT \\uXXXX escapes)\n * - every string NFC-normalized\n * - whole-valued floats coerced to integers (1.0 -> 1)\n * - control chars U+0000–U+001F escaped as \\b \\t \\n \\f \\r or \\u00xx (lowercase)\n * - \"/\", \"<\", \">\", \"&\" NOT escaped; U+007F emitted raw\n *\n * Numbers that would serialize differently in JS vs Python (exponential\n * notation, signed zero, NaN/Infinity) are rejected up front with\n * {@link JcsUnsupportedValueError} so a verifier never produces silently-wrong\n * canonical bytes. These never occur in real Attestix payloads.\n */\n\n/** Thrown when a value cannot be canonicalized to match the Python engine. */\nexport class JcsUnsupportedValueError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = 'JcsUnsupportedValueError';\n\t}\n}\n\nexport type JsonValue =\n\t| string\n\t| number\n\t| boolean\n\t| null\n\t| JsonValue[]\n\t| { [key: string]: JsonValue };\n\n/**\n * Serialize a JSON value to its canonical string form (matching Python).\n * Use {@link canonicalize} to get the UTF-8 bytes for signing/verification.\n */\nexport function canonicalizeToString(value: JsonValue): string {\n\treturn serialize(value);\n}\n\n/**\n * Produce canonical UTF-8 bytes for a JSON value, byte-identical to the Python\n * engine's `canonicalize_json`.\n */\nexport function canonicalize(value: JsonValue): Uint8Array {\n\treturn new TextEncoder().encode(serialize(value));\n}\n\nfunction serialize(value: JsonValue): string {\n\tif (value === null) {\n\t\treturn 'null';\n\t}\n\tconst t = typeof value;\n\tif (t === 'boolean') {\n\t\treturn value ? 'true' : 'false';\n\t}\n\tif (t === 'string') {\n\t\treturn serializeString(value as string);\n\t}\n\tif (t === 'number') {\n\t\treturn serializeNumber(value as number);\n\t}\n\tif (Array.isArray(value)) {\n\t\treturn '[' + value.map((v) => serialize(v)).join(',') + ']';\n\t}\n\tif (t === 'object') {\n\t\tconst obj = value as { [key: string]: JsonValue };\n\t\t// Sort keys by Unicode code point (matches Python's default str sort).\n\t\tconst keys = Object.keys(obj).sort(compareByCodePoint);\n\t\tconst parts: string[] = [];\n\t\tfor (const k of keys) {\n\t\t\tparts.push(serializeString(k) + ':' + serialize(obj[k]));\n\t\t}\n\t\treturn '{' + parts.join(',') + '}';\n\t}\n\tthrow new JcsUnsupportedValueError(\n\t\t`Cannot canonicalize value of type ${t}`,\n\t);\n}\n\n/**\n * Compare two strings by Unicode code point. JS string comparison and Array\n * sort compare by UTF-16 code unit, which diverges from Python's code-point\n * sort for astral characters (> U+FFFF). Attestix keys are all BMP, but we\n * match Python exactly regardless.\n */\nfunction compareByCodePoint(a: string, b: string): number {\n\tconst ai = a[Symbol.iterator]();\n\tconst bi = b[Symbol.iterator]();\n\tfor (;;) {\n\t\tconst an = ai.next();\n\t\tconst bn = bi.next();\n\t\tif (an.done && bn.done) return 0;\n\t\tif (an.done) return -1;\n\t\tif (bn.done) return 1;\n\t\tconst ac = an.value.codePointAt(0) as number;\n\t\tconst bc = bn.value.codePointAt(0) as number;\n\t\tif (ac !== bc) return ac - bc;\n\t}\n}\n\nfunction serializeNumber(n: number): string {\n\tif (!Number.isFinite(n)) {\n\t\tthrow new JcsUnsupportedValueError(\n\t\t\t`Non-finite number (${n}) cannot be canonicalized`,\n\t\t);\n\t}\n\t// Reject signed zero: Python emits \"-0.0\", JS would emit \"0\".\n\tif (n === 0 && 1 / n === -Infinity) {\n\t\tthrow new JcsUnsupportedValueError(\n\t\t\t'Signed zero (-0) cannot be canonicalized (Python emits -0.0)',\n\t\t);\n\t}\n\tif (Number.isInteger(n)) {\n\t\t// Python serializes ints and whole-valued floats without a decimal\n\t\t// point or exponent. JS String(int) does too for safe integers; guard\n\t\t// against magnitudes that JS would render in exponential form.\n\t\tconst s = String(n);\n\t\tif (s.includes('e') || s.includes('E')) {\n\t\t\tthrow new JcsUnsupportedValueError(\n\t\t\t\t`Integer ${n} would serialize in exponential notation; ` +\n\t\t\t\t\t'use a string field instead',\n\t\t\t);\n\t\t}\n\t\treturn s;\n\t}\n\t// Non-integer finite float: allowed only if JS renders it without an\n\t// exponent (Python's json.dumps would otherwise diverge, e.g. 1e-7).\n\tconst s = String(n);\n\tif (s.includes('e') || s.includes('E')) {\n\t\tthrow new JcsUnsupportedValueError(\n\t\t\t`Float ${n} requires exponential notation; not supported for ` +\n\t\t\t\t'cross-engine canonicalization',\n\t\t);\n\t}\n\treturn s;\n}\n\nconst ESCAPE_MAP: Record<number, string> = {\n\t0x08: '\\\\b',\n\t0x09: '\\\\t',\n\t0x0a: '\\\\n',\n\t0x0c: '\\\\f',\n\t0x0d: '\\\\r',\n\t0x22: '\\\\\"',\n\t0x5c: '\\\\\\\\',\n};\n\nfunction serializeString(raw: string): string {\n\t// NFC-normalize first (matches unicodedata.normalize(\"NFC\", s)).\n\tconst s = raw.normalize('NFC');\n\tlet out = '\"';\n\tfor (const ch of s) {\n\t\tconst code = ch.codePointAt(0) as number;\n\t\tconst mapped = ESCAPE_MAP[code];\n\t\tif (mapped !== undefined) {\n\t\t\tout += mapped;\n\t\t} else if (code < 0x20) {\n\t\t\t// Other control chars: \\u00xx with lowercase hex (matches json.dumps).\n\t\t\tout += '\\\\u' + code.toString(16).padStart(4, '0');\n\t\t} else {\n\t\t\t// Everything else (incl. non-ASCII and U+007F) emitted raw; the\n\t\t\t// final UTF-8 encoding matches Python's ensure_ascii=False output.\n\t\t\tout += ch;\n\t\t}\n\t}\n\tout += '\"';\n\treturn out;\n}\n","/**\n * base64url decoding that accepts both the url-safe (`-_`) and standard\n * (`+/`) alphabets, with or without `=` padding. The Python engine emits\n * url-safe WITH padding (base64.urlsafe_b64encode); JWS emits url-safe\n * WITHOUT padding. Both are accepted.\n */\n\nconst STD_ALPHABET =\n\t'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\nconst DECODE = (() => {\n\tconst table = new Int16Array(128).fill(-1);\n\tfor (let i = 0; i < STD_ALPHABET.length; i++) {\n\t\ttable[STD_ALPHABET.charCodeAt(i)] = i;\n\t}\n\t// url-safe aliases\n\ttable['-'.charCodeAt(0)] = 62;\n\ttable['_'.charCodeAt(0)] = 63;\n\treturn table;\n})();\n\nexport function base64urlDecode(input: string): Uint8Array {\n\t// Strip padding and any surrounding whitespace.\n\tconst s = input.replace(/=+$/g, '').trim();\n\tconst len = s.length;\n\tconst outLen = Math.floor((len * 6) / 8);\n\tconst out = new Uint8Array(outLen);\n\tlet buffer = 0;\n\tlet bits = 0;\n\tlet pos = 0;\n\tfor (let i = 0; i < len; i++) {\n\t\tconst c = s.charCodeAt(i);\n\t\tconst val = c < 128 ? DECODE[c] : -1;\n\t\tif (val === -1) {\n\t\t\tthrow new Error(`Invalid base64url character at index ${i}`);\n\t\t}\n\t\tbuffer = (buffer << 6) | val;\n\t\tbits += 6;\n\t\tif (bits >= 8) {\n\t\t\tbits -= 8;\n\t\t\tout[pos++] = (buffer >> bits) & 0xff;\n\t\t}\n\t}\n\treturn out;\n}\n","/**\n * did:key encode/decode for Ed25519 keys, matching the Python engine's\n * `auth.crypto.public_key_to_did_key` / `did_key_to_public_key`.\n *\n * did:key:z<base58btc(0xED01 || raw_pubkey_32)>\n *\n * Multibase prefix: literal 'z' (base58btc). Multicodec prefix for\n * ed25519-pub: bytes 0xED 0x01.\n */\n\n/** Multicodec prefix for Ed25519 public key (varint 0xed01). */\nexport const ED25519_MULTICODEC_PREFIX = new Uint8Array([0xed, 0x01]);\n\nconst BASE58_ALPHABET =\n\t'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\n\nconst BASE58_MAP = (() => {\n\tconst map = new Int16Array(128).fill(-1);\n\tfor (let i = 0; i < BASE58_ALPHABET.length; i++) {\n\t\tmap[BASE58_ALPHABET.charCodeAt(i)] = i;\n\t}\n\treturn map;\n})();\n\n/** Encode bytes as base58btc (Bitcoin alphabet), preserving leading zeros. */\nexport function base58btcEncode(bytes: Uint8Array): string {\n\tif (bytes.length === 0) return '';\n\tlet zeros = 0;\n\twhile (zeros < bytes.length && bytes[zeros] === 0) zeros++;\n\n\t// Convert big-endian byte array to base58 via repeated division.\n\tconst digits: number[] = [0];\n\tfor (let i = zeros; i < bytes.length; i++) {\n\t\tlet carry = bytes[i];\n\t\tfor (let j = 0; j < digits.length; j++) {\n\t\t\tcarry += digits[j] << 8;\n\t\t\tdigits[j] = carry % 58;\n\t\t\tcarry = (carry / 58) | 0;\n\t\t}\n\t\twhile (carry > 0) {\n\t\t\tdigits.push(carry % 58);\n\t\t\tcarry = (carry / 58) | 0;\n\t\t}\n\t}\n\n\tlet out = '1'.repeat(zeros);\n\tfor (let i = digits.length - 1; i >= 0; i--) {\n\t\tout += BASE58_ALPHABET[digits[i]];\n\t}\n\treturn out;\n}\n\n/** Decode a base58btc string to bytes, preserving leading '1' -> 0x00. */\nexport function base58btcDecode(str: string): Uint8Array {\n\tif (str.length === 0) return new Uint8Array(0);\n\tlet zeros = 0;\n\twhile (zeros < str.length && str[zeros] === '1') zeros++;\n\n\tconst bytes: number[] = [0];\n\tfor (let i = zeros; i < str.length; i++) {\n\t\tconst c = str.charCodeAt(i);\n\t\tconst val = c < 128 ? BASE58_MAP[c] : -1;\n\t\tif (val === -1) {\n\t\t\tthrow new Error(`Invalid base58 character '${str[i]}' at index ${i}`);\n\t\t}\n\t\tlet carry = val;\n\t\tfor (let j = 0; j < bytes.length; j++) {\n\t\t\tcarry += bytes[j] * 58;\n\t\t\tbytes[j] = carry & 0xff;\n\t\t\tcarry >>= 8;\n\t\t}\n\t\twhile (carry > 0) {\n\t\t\tbytes.push(carry & 0xff);\n\t\t\tcarry >>= 8;\n\t\t}\n\t}\n\n\tconst out = new Uint8Array(zeros + bytes.length);\n\t// bytes are little-endian here; reverse into big-endian after the zeros.\n\tfor (let i = 0; i < bytes.length; i++) {\n\t\tout[zeros + i] = bytes[bytes.length - 1 - i];\n\t}\n\treturn out;\n}\n\n/** Encode a raw 32-byte Ed25519 public key as a did:key identifier. */\nexport function publicKeyToDidKey(rawPublicKey: Uint8Array): string {\n\tif (rawPublicKey.length !== 32) {\n\t\tthrow new Error(\n\t\t\t`Ed25519 public key must be 32 bytes, got ${rawPublicKey.length}`,\n\t\t);\n\t}\n\tconst multicodec = new Uint8Array(2 + 32);\n\tmulticodec.set(ED25519_MULTICODEC_PREFIX, 0);\n\tmulticodec.set(rawPublicKey, 2);\n\treturn `did:key:z${base58btcEncode(multicodec)}`;\n}\n\n/**\n * Extract the raw 32-byte Ed25519 public key from a did:key identifier.\n * Throws if the DID is not a did:key, lacks the 'z' multibase prefix, or does\n * not carry the Ed25519 multicodec prefix (0xED01).\n */\nexport function didKeyToPublicKey(did: string): Uint8Array {\n\tif (!did.startsWith('did:key:z')) {\n\t\tthrow new Error(`Invalid did:key format: ${did}`);\n\t}\n\tconst encoded = did.slice('did:key:z'.length);\n\tconst decoded = base58btcDecode(encoded);\n\tif (\n\t\tdecoded.length < 2 ||\n\t\tdecoded[0] !== ED25519_MULTICODEC_PREFIX[0] ||\n\t\tdecoded[1] !== ED25519_MULTICODEC_PREFIX[1]\n\t) {\n\t\tthrow new Error('Not an Ed25519 did:key (wrong multicodec prefix)');\n\t}\n\tconst raw = decoded.slice(2);\n\tif (raw.length !== 32) {\n\t\tthrow new Error(\n\t\t\t`Decoded Ed25519 public key must be 32 bytes, got ${raw.length}`,\n\t\t);\n\t}\n\treturn raw;\n}\n\n/**\n * Resolve the issuer DID from a proof's verificationMethod (the part before\n * '#'), matching the Python engine's `vm.split(\"#\")[0]`.\n */\nexport function didFromVerificationMethod(vm: string): string {\n\tconst idx = vm.indexOf('#');\n\treturn idx === -1 ? vm : vm.slice(0, idx);\n}\n","/**\n * Ed25519 signature verification (RFC 8032 / PureEdDSA), Node + browser\n * compatible, backed by the audited @noble/curves implementation.\n */\n\nimport { ed25519 } from '@noble/curves/ed25519.js';\n\n/**\n * Verify an Ed25519 signature.\n *\n * @param signature 64-byte raw Ed25519 signature.\n * @param message the exact bytes that were signed.\n * @param publicKey 32-byte raw Ed25519 public key.\n * @returns true iff the signature is valid; never throws on bad input — a\n * malformed signature/key is treated as a failed verification.\n */\nexport function verifyEd25519(\n\tsignature: Uint8Array,\n\tmessage: Uint8Array,\n\tpublicKey: Uint8Array,\n): boolean {\n\ttry {\n\t\tif (signature.length !== 64 || publicKey.length !== 32) {\n\t\t\treturn false;\n\t\t}\n\t\treturn ed25519.verify(signature, message, publicKey);\n\t} catch {\n\t\treturn false;\n\t}\n}\n","/**\n * Offline verification of Attestix W3C Verifiable Credentials and Verifiable\n * Presentations. Reproduces the Python engine's signing rules (see SPEC.md\n * §5/§6): the signature covers the credential object with `proof` and\n * `credentialStatus` removed, canonicalized via the JCS rules, verified with\n * the issuer's did:key Ed25519 public key.\n */\n\nimport { canonicalize, type JsonValue } from './jcs.js';\nimport { base64urlDecode } from './base64url.js';\nimport { didKeyToPublicKey, didFromVerificationMethod } from './didkey.js';\nimport { verifyEd25519 } from './ed25519.js';\n\n/** Per-check booleans mirroring the Python verifier's `checks` object. */\nexport interface CredentialChecks {\n\tstructure_valid: boolean;\n\tsignature_valid: boolean;\n\tnot_expired: boolean;\n\t/** Revocation cannot be confirmed offline; true unless embedded status says revoked. */\n\tnot_revoked: boolean;\n}\n\nexport interface VerifyCredentialResult {\n\tvalid: boolean;\n\treason?: string;\n\tchecks: CredentialChecks;\n\tissuer?: string;\n\tsubject?: string;\n\ttype?: string[];\n}\n\nexport interface VerifyCredentialOptions {\n\t/** Override \"now\" for expiry checks (ms epoch). Defaults to Date.now(). */\n\tnow?: number;\n\t/** If false, skip the expirationDate check. Default true. */\n\tcheckExpiry?: boolean;\n}\n\ntype JsonObject = { [key: string]: JsonValue };\n\n/** Fields excluded from the credential signature (Python MUTABLE_FIELDS). */\nconst VC_MUTABLE_FIELDS = ['proof', 'credentialStatus'];\n\nfunction isObject(v: unknown): v is JsonObject {\n\treturn typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\nfunction stripFields(obj: JsonObject, fields: string[]): JsonObject {\n\tconst out: JsonObject = {};\n\tfor (const k of Object.keys(obj)) {\n\t\tif (!fields.includes(k)) out[k] = obj[k];\n\t}\n\treturn out;\n}\n\n/**\n * Verify a single VC's Ed25519 proof, structure, expiry, and embedded\n * revocation status — without contacting the Attestix API.\n */\nexport function verifyCredential(\n\tcredential: unknown,\n\toptions: VerifyCredentialOptions = {},\n): VerifyCredentialResult {\n\tconst checks: CredentialChecks = {\n\t\tstructure_valid: false,\n\t\tsignature_valid: false,\n\t\tnot_expired: false,\n\t\tnot_revoked: true,\n\t};\n\n\tif (!isObject(credential)) {\n\t\treturn { valid: false, reason: 'Credential is not an object', checks };\n\t}\n\n\tconst type = credential.type;\n\tconst types = Array.isArray(type) ? (type as string[]) : [];\n\tif (!types.includes('VerifiableCredential')) {\n\t\treturn { valid: false, reason: 'Not a VerifiableCredential', checks };\n\t}\n\tchecks.structure_valid = true;\n\n\t// Embedded revocation status (offline can only read what's present).\n\tconst status = credential.credentialStatus;\n\tif (isObject(status) && status.revoked === true) {\n\t\tchecks.not_revoked = false;\n\t}\n\n\t// Expiry.\n\tconst checkExpiry = options.checkExpiry !== false;\n\tconst expStr = credential.expirationDate;\n\tif (checkExpiry && typeof expStr === 'string') {\n\t\tconst exp = Date.parse(expStr);\n\t\tconst now = options.now ?? Date.now();\n\t\tchecks.not_expired = Number.isNaN(exp) ? true : now < exp;\n\t} else {\n\t\tchecks.not_expired = true;\n\t}\n\n\t// Signature.\n\tconst proof = credential.proof;\n\tlet issuer: string | undefined;\n\tif (isObject(proof) && typeof proof.proofValue === 'string') {\n\t\tconst vm =\n\t\t\ttypeof proof.verificationMethod === 'string'\n\t\t\t\t? proof.verificationMethod\n\t\t\t\t: '';\n\t\tlet issuerDid = vm ? didFromVerificationMethod(vm) : '';\n\t\tif (!issuerDid && isObject(credential.issuer)) {\n\t\t\tconst iid = (credential.issuer as JsonObject).id;\n\t\t\tif (typeof iid === 'string') issuerDid = iid;\n\t\t}\n\t\tissuer = issuerDid;\n\t\ttry {\n\t\t\tconst payload = stripFields(credential, VC_MUTABLE_FIELDS);\n\t\t\tconst message = canonicalize(payload);\n\t\t\tconst sig = base64urlDecode(proof.proofValue);\n\t\t\tconst pub = didKeyToPublicKey(issuerDid);\n\t\t\tchecks.signature_valid = verifyEd25519(sig, message, pub);\n\t\t} catch {\n\t\t\tchecks.signature_valid = false;\n\t\t}\n\t}\n\n\tconst subjectId =\n\t\tisObject(credential.credentialSubject) &&\n\t\ttypeof (credential.credentialSubject as JsonObject).id === 'string'\n\t\t\t? ((credential.credentialSubject as JsonObject).id as string)\n\t\t\t: undefined;\n\n\tconst valid =\n\t\tchecks.structure_valid &&\n\t\tchecks.signature_valid &&\n\t\tchecks.not_expired &&\n\t\tchecks.not_revoked;\n\n\tconst result: VerifyCredentialResult = {\n\t\tvalid,\n\t\tchecks,\n\t\ttype: types,\n\t};\n\tif (issuer !== undefined) result.issuer = issuer;\n\tif (subjectId !== undefined) result.subject = subjectId;\n\tif (!valid) {\n\t\tresult.reason = !checks.signature_valid\n\t\t\t? 'Invalid signature'\n\t\t\t: !checks.not_expired\n\t\t\t\t? 'Credential expired'\n\t\t\t\t: !checks.not_revoked\n\t\t\t\t\t? 'Credential revoked'\n\t\t\t\t\t: 'Verification failed';\n\t}\n\treturn result;\n}\n\nexport interface VerifyPresentationResult {\n\tvalid: boolean;\n\treason?: string;\n\tholder?: string;\n\tvpSignatureValid: boolean;\n\tcredentialCount: number;\n\tcredentialResults: VerifyCredentialResult[];\n}\n\n/**\n * Verify a Verifiable Presentation: the holder's proof (signed payload is the\n * VP minus `proof` only) plus every embedded credential.\n */\nexport function verifyPresentation(\n\tpresentation: unknown,\n\toptions: VerifyCredentialOptions = {},\n): VerifyPresentationResult {\n\tconst empty: VerifyPresentationResult = {\n\t\tvalid: false,\n\t\tvpSignatureValid: false,\n\t\tcredentialCount: 0,\n\t\tcredentialResults: [],\n\t};\n\n\tif (!isObject(presentation)) {\n\t\treturn { ...empty, reason: 'Presentation is not an object' };\n\t}\n\tconst types = Array.isArray(presentation.type)\n\t\t? (presentation.type as string[])\n\t\t: [];\n\tif (!types.includes('VerifiablePresentation')) {\n\t\treturn { ...empty, reason: 'Not a VerifiablePresentation' };\n\t}\n\n\tconst holder =\n\t\ttypeof presentation.holder === 'string'\n\t\t\t? presentation.holder\n\t\t\t: undefined;\n\n\t// VP proof: signed payload excludes only `proof`.\n\tlet vpSignatureValid = false;\n\tconst proof = presentation.proof;\n\tif (isObject(proof) && typeof proof.proofValue === 'string') {\n\t\tconst vm =\n\t\t\ttypeof proof.verificationMethod === 'string'\n\t\t\t\t? proof.verificationMethod\n\t\t\t\t: '';\n\t\tconst issuerDid = vm ? didFromVerificationMethod(vm) : holder ?? '';\n\t\ttry {\n\t\t\tconst payload = stripFields(presentation, ['proof']);\n\t\t\tconst message = canonicalize(payload);\n\t\t\tconst sig = base64urlDecode(proof.proofValue);\n\t\t\tconst pub = didKeyToPublicKey(issuerDid);\n\t\t\tvpSignatureValid = verifyEd25519(sig, message, pub);\n\t\t} catch {\n\t\t\tvpSignatureValid = false;\n\t\t}\n\t}\n\n\tconst creds = Array.isArray(presentation.verifiableCredential)\n\t\t? presentation.verifiableCredential\n\t\t: [];\n\tconst credentialResults = creds.map((c) => verifyCredential(c, options));\n\n\tconst credsValid = credentialResults.every((r) => r.valid);\n\tconst valid = vpSignatureValid && credsValid;\n\n\tconst result: VerifyPresentationResult = {\n\t\tvalid,\n\t\tvpSignatureValid,\n\t\tcredentialCount: creds.length,\n\t\tcredentialResults,\n\t};\n\tif (holder !== undefined) result.holder = holder;\n\tif (!valid) {\n\t\tresult.reason = !vpSignatureValid\n\t\t\t? 'Invalid presentation signature'\n\t\t\t: 'One or more embedded credentials failed verification';\n\t}\n\treturn result;\n}\n","/**\n * Offline verification of Attestix UCAN-style delegation chains.\n *\n * Delegations are EdDSA-signed JWTs (see SPEC.md §7). A token is a compact JWS:\n * base64url(header) \".\" base64url(payload) \".\" base64url(signature)\n * The signature is Ed25519 over the ASCII signing input\n * `b64url(header).b64url(payload)`, verified with the `iss` did:key's public\n * key. The proof chain lives in the `prf` claim (a list of parent JWT strings).\n *\n * This reproduces `DelegationService.verify_delegation` (recursive prf\n * verification + cycle detection + expiry) AND the capability-attenuation rule\n * that the Python engine enforces at creation time\n * (`create_delegation`): a child's `att` must be a subset of every parent's\n * `att`. An offline verifier re-checks attenuation because it cannot trust that\n * the creation-time guard ran.\n */\n\nimport { base64urlDecode } from './base64url.js';\nimport { didKeyToPublicKey } from './didkey.js';\nimport { verifyEd25519 } from './ed25519.js';\n\nexport interface DelegationClaims {\n\tiss: string;\n\taud?: string;\n\tsub?: string;\n\tdelegator?: string;\n\tiat?: number;\n\tnbf?: number;\n\texp?: number;\n\tjti?: string;\n\tatt: string[];\n\tprf: string[];\n\ttyp?: string;\n\t[key: string]: unknown;\n}\n\nexport interface DelegationLinkResult {\n\tjti?: string;\n\tissuer: string;\n\tdelegator?: string;\n\taudience?: string;\n\tcapabilities: string[];\n\tsignatureValid: boolean;\n\texpired: boolean;\n\tnotYetValid: boolean;\n}\n\nexport interface VerifyDelegationResult {\n\tvalid: boolean;\n\treason?: string;\n\t/** Per-link results, leaf first (matching the order the chain is walked). */\n\tlinks: DelegationLinkResult[];\n\t/** The capabilities held by the leaf (effective granted set). */\n\tcapabilities: string[];\n}\n\nexport interface VerifyDelegationOptions {\n\t/** Override \"now\" in unix seconds. Defaults to current time. */\n\tnow?: number;\n\t/** Clock skew tolerance in seconds for exp/nbf. Default 0. */\n\tclockToleranceSeconds?: number;\n}\n\ninterface DecodedToken {\n\tclaims: DelegationClaims;\n\tsigningInput: Uint8Array;\n\tsignature: Uint8Array;\n}\n\nfunction decodeJwt(token: string): DecodedToken {\n\tconst parts = token.split('.');\n\tif (parts.length !== 3) {\n\t\tthrow new Error('Malformed JWT (expected 3 dot-separated segments)');\n\t}\n\tconst [h, p, s] = parts;\n\tconst payloadJson = new TextDecoder().decode(base64urlDecode(p));\n\tconst claims = JSON.parse(payloadJson) as DelegationClaims;\n\tif (!Array.isArray(claims.att)) claims.att = [];\n\tif (!Array.isArray(claims.prf)) claims.prf = [];\n\t// JWS signing input is the ASCII bytes of \"header.payload\" exactly as\n\t// transmitted (no re-encoding of header/payload).\n\tconst signingInput = new TextEncoder().encode(`${h}.${p}`);\n\tconst signature = base64urlDecode(s);\n\treturn { claims, signingInput, signature };\n}\n\nfunction isSubset(child: string[], parent: string[]): boolean {\n\tconst parentSet = new Set(parent);\n\treturn child.every((c) => parentSet.has(c));\n}\n\n/**\n * Verify a delegation token and its full proof chain.\n *\n * @param token Either a single leaf JWT string (its `prf` chain is walked\n * internally) or an array of JWT strings ordered leaf..root. When an array\n * is given, the leaf's `prf` linkage is still validated against the provided\n * parents.\n */\nexport function verifyDelegationChain(\n\ttoken: string | string[],\n\toptions: VerifyDelegationOptions = {},\n): VerifyDelegationResult {\n\tconst now = options.now ?? Math.floor(Date.now() / 1000);\n\tconst tol = options.clockToleranceSeconds ?? 0;\n\tconst links: DelegationLinkResult[] = [];\n\n\tif (Array.isArray(token)) {\n\t\tif (token.length === 0) {\n\t\t\treturn {\n\t\t\t\tvalid: false,\n\t\t\t\treason: 'Empty delegation chain',\n\t\t\t\tlinks,\n\t\t\t\tcapabilities: [],\n\t\t\t};\n\t\t}\n\t\t// Verify each provided link independently, then enforce linkage +\n\t\t// attenuation between consecutive links (leaf..root order).\n\t\tconst decoded: DecodedToken[] = [];\n\t\tfor (const t of token) {\n\t\t\tlet d: DecodedToken;\n\t\t\ttry {\n\t\t\t\td = decodeJwt(t);\n\t\t\t} catch (e) {\n\t\t\t\treturn {\n\t\t\t\t\tvalid: false,\n\t\t\t\t\treason: `Malformed token in chain: ${(e as Error).message}`,\n\t\t\t\t\tlinks,\n\t\t\t\t\tcapabilities: [],\n\t\t\t\t};\n\t\t\t}\n\t\t\tdecoded.push(d);\n\t\t}\n\t\tfor (const d of decoded) {\n\t\t\tconst link = verifySingle(d, now, tol);\n\t\t\tlinks.push(link);\n\t\t\tif (!link.signatureValid) {\n\t\t\t\treturn { valid: false, reason: 'Invalid signature in chain', links, capabilities: [] };\n\t\t\t}\n\t\t\tif (link.expired) {\n\t\t\t\treturn { valid: false, reason: 'A delegation in the chain has expired', links, capabilities: [] };\n\t\t\t}\n\t\t\tif (link.notYetValid) {\n\t\t\t\treturn { valid: false, reason: 'A delegation in the chain is not yet valid (nbf)', links, capabilities: [] };\n\t\t\t}\n\t\t}\n\t\t// Attenuation + linkage across consecutive links (child = i, parent = i+1).\n\t\tfor (let i = 0; i < decoded.length - 1; i++) {\n\t\t\tconst child = decoded[i].claims;\n\t\t\tconst parent = decoded[i + 1].claims;\n\t\t\tif (!isSubset(child.att, parent.att)) {\n\t\t\t\treturn {\n\t\t\t\t\tvalid: false,\n\t\t\t\t\treason: 'Capability escalation: child att is not a subset of parent att',\n\t\t\t\t\tlinks,\n\t\t\t\t\tcapabilities: [],\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\treturn { valid: true, links, capabilities: decoded[0].claims.att };\n\t}\n\n\t// Single token: walk its prf chain recursively.\n\tconst seen = new Set<string>();\n\tconst result = verifyRecursive(token, now, tol, seen, links, null);\n\tif (!result.ok) {\n\t\treturn { valid: false, reason: result.reason, links, capabilities: [] };\n\t}\n\treturn { valid: true, links, capabilities: links[0]?.capabilities ?? [] };\n}\n\ninterface RecursiveResult {\n\tok: boolean;\n\treason?: string;\n\tatt?: string[];\n}\n\nfunction verifyRecursive(\n\ttoken: string,\n\tnow: number,\n\ttol: number,\n\tseen: Set<string>,\n\tlinks: DelegationLinkResult[],\n\tchildAtt: string[] | null,\n): RecursiveResult {\n\tlet decoded: DecodedToken;\n\ttry {\n\t\tdecoded = decodeJwt(token);\n\t} catch (e) {\n\t\treturn { ok: false, reason: `Malformed token: ${(e as Error).message}` };\n\t}\n\n\tconst link = verifySingle(decoded, now, tol);\n\tlinks.push(link);\n\n\tif (link.jti) {\n\t\tif (seen.has(link.jti)) {\n\t\t\treturn { ok: false, reason: 'Cycle detected in delegation proof chain' };\n\t\t}\n\t\tseen.add(link.jti);\n\t}\n\tif (!link.signatureValid) {\n\t\treturn { ok: false, reason: 'Invalid token signature' };\n\t}\n\tif (link.expired) {\n\t\treturn { ok: false, reason: 'Token has expired' };\n\t}\n\tif (link.notYetValid) {\n\t\treturn { ok: false, reason: 'Token is not yet valid (nbf)' };\n\t}\n\n\tconst att = decoded.claims.att;\n\t// Attenuation: this link is the parent of `childAtt`; child must be subset.\n\tif (childAtt !== null && !isSubset(childAtt, att)) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\treason: 'Capability escalation: child att is not a subset of parent att',\n\t\t};\n\t}\n\n\t// Recurse into every parent in prf.\n\tfor (const parentToken of decoded.claims.prf) {\n\t\tif (typeof parentToken !== 'string' || !parentToken) {\n\t\t\treturn { ok: false, reason: 'Malformed parent token in proof chain' };\n\t\t}\n\t\tconst parentResult = verifyRecursive(\n\t\t\tparentToken,\n\t\t\tnow,\n\t\t\ttol,\n\t\t\tseen,\n\t\t\tlinks,\n\t\t\tatt,\n\t\t);\n\t\tif (!parentResult.ok) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\treason: `Invalid parent in proof chain: ${parentResult.reason}`,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn { ok: true, att };\n}\n\nfunction verifySingle(\n\tdecoded: DecodedToken,\n\tnow: number,\n\ttol: number,\n): DelegationLinkResult {\n\tconst c = decoded.claims;\n\tlet signatureValid = false;\n\ttry {\n\t\tconst pub = didKeyToPublicKey(c.iss);\n\t\tsignatureValid = verifyEd25519(\n\t\t\tdecoded.signature,\n\t\t\tdecoded.signingInput,\n\t\t\tpub,\n\t\t);\n\t} catch {\n\t\tsignatureValid = false;\n\t}\n\n\tconst expired = typeof c.exp === 'number' ? c.exp + tol < now : false;\n\tconst notYetValid = typeof c.nbf === 'number' ? c.nbf - tol > now : false;\n\n\tconst link: DelegationLinkResult = {\n\t\tissuer: c.iss,\n\t\tcapabilities: c.att,\n\t\tsignatureValid,\n\t\texpired,\n\t\tnotYetValid,\n\t};\n\tif (c.jti !== undefined) link.jti = c.jti;\n\tif (c.delegator !== undefined) link.delegator = c.delegator;\n\tif (c.aud !== undefined) link.audience = c.aud;\n\treturn link;\n}\n\n/** Decode a delegation JWT's claims WITHOUT verifying the signature. */\nexport function decodeDelegationUnsafe(token: string): DelegationClaims {\n\treturn decodeJwt(token).claims;\n}\n"],"mappings":"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","names":["s"]}
|