@ixo/credentials-kit 0.0.0-stage → 0.1.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.
Files changed (72) hide show
  1. package/README.md +469 -2
  2. package/dist/chunk-2SF56NEJ.js +1053 -0
  3. package/dist/chunk-2SF56NEJ.js.map +1 -0
  4. package/dist/chunk-46VRPQPD.js +176 -0
  5. package/dist/chunk-46VRPQPD.js.map +1 -0
  6. package/dist/chunk-AQ3IINHC.js +138 -0
  7. package/dist/chunk-AQ3IINHC.js.map +1 -0
  8. package/dist/chunk-FSKCDHZ7.js +613 -0
  9. package/dist/chunk-FSKCDHZ7.js.map +1 -0
  10. package/dist/chunk-I6GBYFIJ.js +89 -0
  11. package/dist/chunk-I6GBYFIJ.js.map +1 -0
  12. package/dist/chunk-JBUX6V2Q.js +210 -0
  13. package/dist/chunk-JBUX6V2Q.js.map +1 -0
  14. package/dist/chunk-Q3MZNMCK.js +183 -0
  15. package/dist/chunk-Q3MZNMCK.js.map +1 -0
  16. package/dist/chunk-RKKRO4ZK.js +133 -0
  17. package/dist/chunk-RKKRO4ZK.js.map +1 -0
  18. package/dist/chunk-STMMFNVW.js +391 -0
  19. package/dist/chunk-STMMFNVW.js.map +1 -0
  20. package/dist/chunk-VXKONZK4.js +189 -0
  21. package/dist/chunk-VXKONZK4.js.map +1 -0
  22. package/dist/chunk-WIEGZFUO.js +337 -0
  23. package/dist/chunk-WIEGZFUO.js.map +1 -0
  24. package/dist/chunk-WND2LZ4O.js +66 -0
  25. package/dist/chunk-WND2LZ4O.js.map +1 -0
  26. package/dist/chunk-XREZY53L.js +260 -0
  27. package/dist/chunk-XREZY53L.js.map +1 -0
  28. package/dist/chunk-ZZY4WGQ6.js +13 -0
  29. package/dist/chunk-ZZY4WGQ6.js.map +1 -0
  30. package/dist/did.d.ts +182 -0
  31. package/dist/did.js +6 -0
  32. package/dist/did.js.map +1 -0
  33. package/dist/display.d.ts +117 -0
  34. package/dist/display.js +5 -0
  35. package/dist/display.js.map +1 -0
  36. package/dist/errors-BKQmNpXX.d.ts +11 -0
  37. package/dist/holder.d.ts +85 -0
  38. package/dist/holder.js +8 -0
  39. package/dist/holder.js.map +1 -0
  40. package/dist/http-BhuJ_-RZ.d.ts +25 -0
  41. package/dist/index.d.ts +15 -0
  42. package/dist/index.js +16 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/jose.d.ts +134 -0
  45. package/dist/jose.js +4 -0
  46. package/dist/jose.js.map +1 -0
  47. package/dist/oid4vci.d.ts +428 -0
  48. package/dist/oid4vci.js +11 -0
  49. package/dist/oid4vci.js.map +1 -0
  50. package/dist/oid4vp.d.ts +416 -0
  51. package/dist/oid4vp.js +11 -0
  52. package/dist/oid4vp.js.map +1 -0
  53. package/dist/profile.d.ts +218 -0
  54. package/dist/profile.js +4 -0
  55. package/dist/profile.js.map +1 -0
  56. package/dist/sdjwt.d.ts +133 -0
  57. package/dist/sdjwt.js +5 -0
  58. package/dist/sdjwt.js.map +1 -0
  59. package/dist/sender.d.ts +8 -0
  60. package/dist/sender.js +7 -0
  61. package/dist/sender.js.map +1 -0
  62. package/dist/status.d.ts +108 -0
  63. package/dist/status.js +7 -0
  64. package/dist/status.js.map +1 -0
  65. package/dist/util-DOTEZgTt.d.ts +3 -0
  66. package/dist/verify.d.ts +144 -0
  67. package/dist/verify.js +9 -0
  68. package/dist/verify.js.map +1 -0
  69. package/dist/webhook.d.ts +62 -0
  70. package/dist/webhook.js +7 -0
  71. package/dist/webhook.js.map +1 -0
  72. package/package.json +168 -4
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/oid4vci.ts"],"names":["res"],"mappings":"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","file":"chunk-FSKCDHZ7.js","sourcesContent":["/**\n * `@ixo/credentials-kit/oid4vci` — OpenID for Verifiable Credential Issuance 1.0, pre-authorized\n * code flow only, `dc+sd-jwt` only, `jwt` key proofs (EdDSA, key named by a DID URL `kid`).\n *\n * Wallet flow (`redeemOffer`):\n * 1. issuer metadata GET <host>/.well-known/openid-credential-issuer[<path>] (§12.2.2)\n * 2. AS metadata GET <host>/.well-known/oauth-authorization-server[<path>] (RFC 8414 §3;\n * the AS is the credential issuer unless `authorization_servers` says otherwise, §12.2.4)\n * 3. token POST token_endpoint, form: grant_type=urn:ietf:params:oauth:grant-type:\n * pre-authorized_code & pre-authorized_code=… [& tx_code=…] (§6.1)\n * 4. nonce POST nonce_endpoint → { c_nonce } (§7)\n * 5. credential POST credential_endpoint, Bearer, JSON { credential_configuration_id\n * (or credential_identifier), proofs: { jwt: [ proof ] } } (§8.2)\n * → 200 { credentials: [{ credential }], notification_id? }\n * | 202 { transaction_id, interval } (§8.3)\n * 6. deferred POST deferred_credential_endpoint { transaction_id } (§9)\n * 7. notification POST notification_endpoint { notification_id, event } (§11)\n *\n * Proof JWT (Appendix F.1): header { typ: 'openid4vci-proof+jwt', alg: 'EdDSA' (or 'Ed25519'\n * when that is the only one the issuer lists), kid: <DID URL> } (never `jwk` or `x5c`), payload\n * { aud: <credential issuer identifier>, iat, nonce: c_nonce } (no `iss`: anonymous\n * pre-authorized access). The wallet refuses an offer whose configuration does not list\n * `did:<method of the holder DID>` in `cryptographic_binding_methods_supported` (when present).\n *\n * The wallet checks every credential it receives with `verifyIssuedCredential` before returning\n * it (RFC 9901 §7.2; opt out with `verify: false`).\n */\nimport {\n ResolverUnavailable,\n didFromKid,\n findKey,\n type DidResolver,\n} from './did';\nimport { utf8 } from './internal/bytes';\nimport { CredentialsKitError } from './internal/errors';\nimport {\n HttpError,\n isFetchableUrl,\n request,\n type FetchLike,\n type HostPolicy,\n} from './internal/http';\nimport { CLOCK_SKEW_S, clockMs, isRecord, toSeconds } from './internal/util';\nimport {\n decodeJws,\n isEd25519JwsAlg,\n publicJwkFromRaw,\n signJws,\n verifyEd25519,\n type Ed25519JwsAlg,\n type Ed25519PublicJwk,\n type Signer,\n} from './jose';\nimport { PRE_AUTHORIZED_CODE_GRANT, PROOF_JWT_TYP } from './profile';\nimport {\n verifyIssuedCredential,\n type VerifiedPresentation,\n type VerifyIssuedCredentialOptions,\n} from './verify';\n\n// ---------------------------------------------------------------------------------------------\n// Types (field names exactly as OpenID4VCI 1.0).\n\nexport interface Display {\n name: string;\n locale?: string;\n description?: string;\n logo?: { uri: string; alt_text?: string };\n background_color?: string;\n text_color?: string;\n}\n\nexport interface ClaimDescription {\n path: (string | number | null)[];\n mandatory?: boolean;\n display?: { name?: string; locale?: string }[];\n}\n\nexport interface CredentialConfiguration {\n format: 'dc+sd-jwt';\n vct: string;\n scope?: string;\n cryptographic_binding_methods_supported?: string[];\n credential_signing_alg_values_supported?: string[];\n proof_types_supported?: Record<\n string,\n { proof_signing_alg_values_supported: string[] }\n >;\n credential_metadata?: { display?: Display[]; claims?: ClaimDescription[] };\n [name: string]: unknown;\n}\n\nexport interface CredentialIssuerMetadata {\n credential_issuer: string;\n authorization_servers?: string[];\n credential_endpoint: string;\n nonce_endpoint?: string;\n deferred_credential_endpoint?: string;\n notification_endpoint?: string;\n display?: Display[];\n credential_configurations_supported: Record<string, CredentialConfiguration>;\n [name: string]: unknown;\n}\n\n/** RFC 8414 metadata, as much of it as the pre-authorized code flow needs. */\nexport interface AuthorizationServerMetadata {\n issuer: string;\n token_endpoint: string;\n grant_types_supported?: string[];\n token_endpoint_auth_methods_supported?: string[];\n 'pre-authorized_grant_anonymous_access_supported'?: boolean;\n [name: string]: unknown;\n}\n\nexport interface TxCode {\n input_mode?: 'numeric' | 'text';\n length?: number;\n description?: string;\n}\n\nexport interface PreAuthorizedCodeGrant {\n 'pre-authorized_code': string;\n tx_code?: TxCode;\n authorization_server?: string;\n}\n\nexport interface CredentialOffer {\n credential_issuer: string;\n credential_configuration_ids: string[];\n grants: {\n 'urn:ietf:params:oauth:grant-type:pre-authorized_code': PreAuthorizedCodeGrant;\n [grant: string]: unknown;\n };\n}\n\n/** Form parameters of the token request (§6.1). */\nexport interface TokenRequest {\n grant_type: typeof PRE_AUTHORIZED_CODE_GRANT;\n 'pre-authorized_code': string;\n tx_code?: string;\n}\n\nexport interface TokenResponse {\n access_token: string;\n token_type: string;\n expires_in?: number;\n authorization_details?: {\n type: 'openid_credential';\n credential_configuration_id: string;\n credential_identifiers: string[];\n }[];\n}\n\nexport interface NonceResponse {\n c_nonce: string;\n}\n\nexport type CredentialRequest =\n | { credential_configuration_id: string; proofs: { jwt: string[] } }\n | { credential_identifier: string; proofs: { jwt: string[] } };\n\nexport interface CredentialResponse {\n credentials: { credential: string }[];\n notification_id?: string;\n}\n\nexport interface DeferredCredentialResponse {\n transaction_id: string;\n interval: number;\n}\n\nexport interface DeferredCredentialRequest {\n transaction_id: string;\n}\n\nexport type NotificationEvent =\n 'credential_accepted' | 'credential_failure' | 'credential_deleted';\n\nexport interface NotificationRequest {\n notification_id: string;\n event: NotificationEvent;\n event_description?: string;\n}\n\n/** Error response of the token, credential, deferred and notification endpoints. */\nexport interface OAuthErrorResponse {\n error: string;\n error_description?: string;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Errors.\n\nexport type Oid4vciErrorCode =\n | 'invalid_offer'\n | 'unsupported_offer'\n | 'invalid_metadata'\n | 'issuer_unavailable'\n | 'tx_code_unsupported'\n | 'token_error'\n | 'issuer_error'\n | 'invalid_response'\n | 'invalid_proof'\n | 'invalid_nonce'\n | 'invalid_credential';\n\nconst OID4VCI_MESSAGES: Record<Oid4vciErrorCode, string> = {\n invalid_offer: 'The credential offer is not well formed.',\n unsupported_offer:\n 'The credential offer uses a feature this profile does not support.',\n invalid_metadata: \"The issuer's metadata is missing or not well formed.\",\n issuer_unavailable: 'The issuer could not be reached.',\n tx_code_unsupported:\n 'The offer needs a transaction code, which this wallet does not support.',\n token_error: 'The issuer refused the pre-authorized code.',\n issuer_error: 'The issuer refused the request.',\n invalid_response: \"The issuer's answer is not well formed.\",\n invalid_proof: 'The key proof is not valid.',\n invalid_nonce: 'The key proof does not carry a valid nonce.',\n invalid_credential:\n 'The issuer sent a credential that does not check out, so it was not kept.',\n};\n\nexport class Oid4vciError extends CredentialsKitError {\n declare readonly code: Oid4vciErrorCode;\n /** The OAuth / OpenID4VCI error code the server answered (sanitised), when there was one. */\n readonly oauthError?: string;\n /**\n * For `invalid_proof` / `invalid_nonce`: a constant cause for logs. For `invalid_credential`:\n * the `verifyIssuedCredential` failure code (`bad_signature`, `wrong_subject`, …).\n */\n readonly reason?: string;\n constructor(\n code: Oid4vciErrorCode,\n extra: { oauthError?: string; reason?: string } = {}\n ) {\n super(code, OID4VCI_MESSAGES[code]);\n if (extra.oauthError !== undefined) this.oauthError = extra.oauthError;\n if (extra.reason !== undefined) this.reason = extra.reason;\n }\n}\n\n// ---------------------------------------------------------------------------------------------\n// Well-known URLs.\n\nfunction insertWellKnown(identifier: string, suffix: string): string {\n const u = new URL(identifier);\n const path = u.pathname === '/' ? '' : u.pathname.replace(/\\/$/, '');\n return `${u.origin}/.well-known/${suffix}${path}`;\n}\n\n/**\n * The Credential Issuer Metadata URL (§12.2.2): `/.well-known/openid-credential-issuer` inserted\n * between the host and the identifier's path (`https://h/identity` →\n * `https://h/.well-known/openid-credential-issuer/identity`).\n */\nexport function issuerMetadataUrl(credentialIssuer: string): string {\n return insertWellKnown(credentialIssuer, 'openid-credential-issuer');\n}\n\n/** The RFC 8414 Authorization Server Metadata URL, built the same way. */\nexport function authorizationServerMetadataUrl(issuer: string): string {\n return insertWellKnown(issuer, 'oauth-authorization-server');\n}\n\n// ---------------------------------------------------------------------------------------------\n// Issuer helpers.\n\nexport interface IssuerConfigurationInput {\n vct: string;\n display?: Display[];\n claims?: ClaimDescription[];\n}\n\nexport interface BuildIssuerMetadataInput {\n /** The Credential Issuer Identifier (https URL, no query or fragment). */\n credentialIssuer: string;\n /** Keyed by credential configuration id. */\n configurations: Record<string, IssuerConfigurationInput>;\n display?: Display[];\n /** Omit when the issuer is its own Authorization Server (the usual case). */\n authorizationServers?: string[];\n /**\n * Publish each configuration's id as its `scope` (§12.2.4). Default false: `scope` is for the\n * authorization code flow, which the pre-authorized-only profile does not offer.\n */\n includeScope?: boolean;\n /**\n * Endpoint URLs. Default: `<credentialIssuer>/oid4vci/{credential,nonce,notification}` (the\n * layout Self uses). The deferred endpoint is published only when given.\n */\n endpoints?: {\n credential?: string;\n nonce?: string;\n deferred?: string;\n notification?: string;\n };\n}\n\n/**\n * Credential Issuer Metadata (§12.2.4) for `dc+sd-jwt` configurations with Ed25519 DID-bound\n * proofs. Signing algorithms are listed as `[\"EdDSA\", \"Ed25519\"]` (the JWS name the kit signs\n * with, and the fully-specified RFC 9864 name it also accepts).\n */\nexport function buildIssuerMetadata(\n input: BuildIssuerMetadataInput\n): CredentialIssuerMetadata {\n const base = input.credentialIssuer.replace(/\\/$/, '');\n const ep = input.endpoints ?? {};\n const configurations: Record<string, CredentialConfiguration> = {};\n for (const [id, c] of Object.entries(input.configurations)) {\n configurations[id] = {\n format: 'dc+sd-jwt',\n vct: c.vct,\n ...(input.includeScope ? { scope: id } : {}),\n cryptographic_binding_methods_supported: ['did:ixo'],\n credential_signing_alg_values_supported: ['EdDSA', 'Ed25519'],\n proof_types_supported: {\n jwt: { proof_signing_alg_values_supported: ['EdDSA', 'Ed25519'] },\n },\n ...(c.display || c.claims\n ? {\n credential_metadata: {\n ...(c.display ? { display: c.display } : {}),\n ...(c.claims ? { claims: c.claims } : {}),\n },\n }\n : {}),\n };\n }\n return {\n credential_issuer: input.credentialIssuer,\n ...(input.authorizationServers\n ? { authorization_servers: input.authorizationServers }\n : {}),\n credential_endpoint: ep.credential ?? `${base}/oid4vci/credential`,\n nonce_endpoint: ep.nonce ?? `${base}/oid4vci/nonce`,\n ...(ep.deferred !== undefined\n ? { deferred_credential_endpoint: ep.deferred }\n : {}),\n notification_endpoint: ep.notification ?? `${base}/oid4vci/notification`,\n ...(input.display ? { display: input.display } : {}),\n credential_configurations_supported: configurations,\n };\n}\n\n/**\n * RFC 8414 metadata for an issuer that is its own Authorization Server and supports only the\n * pre-authorized code grant, anonymously (OpenID4VCI §12.3). Serve it at\n * `authorizationServerMetadataUrl(credentialIssuer)`. Default token endpoint:\n * `<credentialIssuer>/oid4vci/token`.\n */\nexport function buildAuthorizationServerMetadata(input: {\n issuer: string;\n tokenEndpoint?: string;\n}): AuthorizationServerMetadata {\n return {\n issuer: input.issuer,\n token_endpoint:\n input.tokenEndpoint ?? `${input.issuer.replace(/\\/$/, '')}/oid4vci/token`,\n grant_types_supported: [PRE_AUTHORIZED_CODE_GRANT],\n // No client authentication at the token endpoint (RFC 8414 §2's default would be basic).\n token_endpoint_auth_methods_supported: ['none'],\n 'pre-authorized_grant_anonymous_access_supported': true,\n };\n}\n\n/** A pre-authorized code credential offer (§4.1.1). */\nexport function buildCredentialOffer(input: {\n credentialIssuer: string;\n configurationIds: string[];\n preAuthorizedCode: string;\n txCode?: TxCode;\n}): CredentialOffer {\n return validateCredentialOffer(\n {\n credential_issuer: input.credentialIssuer,\n credential_configuration_ids: input.configurationIds,\n grants: {\n [PRE_AUTHORIZED_CODE_GRANT]: {\n 'pre-authorized_code': input.preAuthorizedCode,\n ...(input.txCode ? { tx_code: input.txCode } : {}),\n },\n },\n },\n { allowHttp: true, allowLocal: true }\n );\n}\n\n/**\n * Validate a credential offer object: https `credential_issuer` on a public host (http only on a\n * loopback host with `allowHttp` + `allowLocal`), no query or fragment, non-empty unique\n * `credential_configuration_ids`, and a pre-authorized code grant with a non-empty code. Returns\n * it normalised (only known members); throws `Oid4vciError('invalid_offer')`, or\n * `unsupported_offer` for a well-formed offer with no pre-authorized code grant (e.g. only\n * `authorization_code`).\n */\nexport function validateCredentialOffer(\n v: unknown,\n opts: HostPolicy = {}\n): CredentialOffer {\n const bad = () => new Oid4vciError('invalid_offer');\n if (!isRecord(v)) throw bad();\n const issuer = v.credential_issuer;\n if (typeof issuer !== 'string' || !isFetchableUrl(issuer, opts)) throw bad();\n if (new URL(issuer).search !== '') throw bad();\n const ids = v.credential_configuration_ids;\n if (\n !Array.isArray(ids) ||\n ids.length === 0 ||\n !ids.every(i => typeof i === 'string' && i.length > 0 && i.length <= 256) ||\n new Set(ids).size !== ids.length\n ) {\n throw bad();\n }\n const grants = isRecord(v.grants) ? v.grants : null;\n const grant = grants ? grants[PRE_AUTHORIZED_CODE_GRANT] : undefined;\n if (grant === undefined && grants && Object.keys(grants).length > 0)\n throw new Oid4vciError('unsupported_offer');\n if (!isRecord(grant)) throw bad();\n const code = grant['pre-authorized_code'];\n if (typeof code !== 'string' || code.length === 0 || code.length > 4096)\n throw bad();\n const out: PreAuthorizedCodeGrant = { 'pre-authorized_code': code };\n if (grant.tx_code !== undefined) {\n const t = grant.tx_code;\n if (!isRecord(t)) throw bad();\n const tx: TxCode = {};\n if (t.input_mode !== undefined) {\n if (t.input_mode !== 'numeric' && t.input_mode !== 'text') throw bad();\n tx.input_mode = t.input_mode;\n }\n if (t.length !== undefined) {\n if (\n typeof t.length !== 'number' ||\n !Number.isInteger(t.length) ||\n t.length <= 0\n )\n throw bad();\n tx.length = t.length;\n }\n if (t.description !== undefined) {\n if (typeof t.description !== 'string' || t.description.length > 300)\n throw bad();\n tx.description = t.description;\n }\n out.tx_code = tx;\n }\n if (grant.authorization_server !== undefined) {\n if (typeof grant.authorization_server !== 'string') throw bad();\n out.authorization_server = grant.authorization_server;\n }\n return {\n credential_issuer: issuer,\n credential_configuration_ids: [...(ids as string[])],\n grants: { [PRE_AUTHORIZED_CODE_GRANT]: out },\n };\n}\n\nexport interface VerifiedProof {\n /** The holder DID the proof key belongs to (`kid` without its fragment). */\n did: string;\n kid: string;\n publicKey: Uint8Array;\n jwk: Ed25519PublicJwk;\n /** The proof's `nonce`, when it has one. */\n nonce?: string;\n}\n\nexport interface VerifyProofJwtOptions {\n /** The Credential Issuer Identifier: the proof's `aud` must equal it. */\n audience: string;\n /**\n * The expected c_nonce, or a check for it (e.g. a stateless signed nonce). Omit only when the\n * issuer has no nonce endpoint.\n */\n nonce?: string | ((nonce: string) => boolean | Promise<boolean>);\n resolver: DidResolver;\n /** ms since the epoch; default `Date.now()`. */\n now?: number;\n /** Oldest acceptable `iat`, in seconds before now (default 300). */\n maxAgeSeconds?: number;\n}\n\n/**\n * Verify an OpenID4VCI `jwt` key proof (Appendix F.1). The key must be an Ed25519 key listed\n * under `authentication` on the DID document the `kid` names, controlled by that DID. The\n * signature is checked before `opts.nonce` is called, so a single-use nonce store is consulted\n * (and consumed) only for a proof the holder really signed. Returns\n * the DID and key; the CALLER then enforces subject binding (the DID is the offer's subject) and\n * binds `cnf` to exactly `jwk`. Throws `Oid4vciError` with code `invalid_proof` or\n * `invalid_nonce` (the spec's error codes, ready for the error response) and a `reason`;\n * `ResolverUnavailable` propagates.\n */\nexport async function verifyProofJwt(\n jwt: string,\n opts: VerifyProofJwtOptions\n): Promise<VerifiedProof> {\n const invalid = (reason: string) =>\n new Oid4vciError('invalid_proof', { reason });\n let jws;\n try {\n jws = decodeJws(typeof jwt === 'string' ? jwt.trim() : '');\n } catch {\n throw invalid('malformed');\n }\n const { header, payload } = jws;\n if (header.typ !== PROOF_JWT_TYP) throw invalid('wrong_typ');\n if (!isEd25519JwsAlg(header.alg)) throw invalid('unsupported_alg');\n if (header.jwk !== undefined || header.x5c !== undefined)\n throw invalid('key_not_by_kid');\n const kid = header.kid;\n if (\n typeof kid !== 'string' ||\n !kid.startsWith('did:') ||\n !kid.includes('#')\n ) {\n throw invalid('kid_not_did_url');\n }\n if (payload.aud !== opts.audience) throw invalid('wrong_audience');\n const nowS = toSeconds(clockMs(opts.now));\n const maxAge = opts.maxAgeSeconds ?? 300;\n if (\n typeof payload.iat !== 'number' ||\n payload.iat > nowS + CLOCK_SKEW_S ||\n payload.iat < nowS - maxAge - CLOCK_SKEW_S\n ) {\n throw invalid('stale');\n }\n const nonce = payload.nonce;\n if (opts.nonce !== undefined) {\n if (typeof nonce !== 'string' || nonce.length === 0) {\n throw new Oid4vciError('invalid_proof', { reason: 'no_nonce' });\n }\n } else if (nonce !== undefined && typeof nonce !== 'string') {\n throw invalid('malformed');\n }\n const did = didFromKid(kid);\n let doc;\n try {\n doc = await opts.resolver(did);\n } catch (e) {\n if (e instanceof ResolverUnavailable) throw e;\n throw invalid('unknown_did');\n }\n const key = doc ? findKey(doc, kid, 'authentication') : null;\n if (!key) throw invalid('key_not_on_did');\n if (!verifyEd25519(jws.signature, utf8(jws.signingInput), key.publicKey)) {\n throw invalid('bad_signature');\n }\n // Last: a callback may consume a single-use c_nonce, so only a proof whose signature holds\n // reaches it (a forged proof must not burn the holder's nonce).\n if (opts.nonce !== undefined) {\n const ok =\n typeof opts.nonce === 'string'\n ? nonce === opts.nonce\n : await opts.nonce(nonce as string);\n if (!ok) throw new Oid4vciError('invalid_nonce', { reason: 'wrong_nonce' });\n }\n return {\n did,\n kid: key.id,\n publicKey: key.publicKey,\n jwk: publicJwkFromRaw(key.publicKey),\n ...(typeof nonce === 'string' ? { nonce } : {}),\n };\n}\n\n// ---------------------------------------------------------------------------------------------\n// Wallet helpers.\n\n/** A `jwt` key proof for `audience` (the Credential Issuer Identifier) with the issuer's c_nonce. */\nexport function createProofJwt(input: {\n signer: Signer;\n audience: string;\n nonce?: string;\n /** ms since the epoch; default `Date.now()`. */\n now?: number;\n /** Default `EdDSA`. */\n alg?: Ed25519JwsAlg;\n}): Promise<string> {\n return signJws(\n { alg: input.alg ?? 'EdDSA', typ: PROOF_JWT_TYP, kid: input.signer.kid },\n {\n aud: input.audience,\n iat: toSeconds(clockMs(input.now)),\n ...(input.nonce !== undefined ? { nonce: input.nonce } : {}),\n },\n input.signer\n );\n}\n\nconst MAX_METADATA_BYTES = 256 * 1024;\nconst MAX_TOKEN_RESPONSE_BYTES = 64 * 1024;\nconst MAX_CREDENTIAL_RESPONSE_BYTES = 256 * 1024;\nconst OAUTH_ERROR = /^[\\x20-\\x21\\x23-\\x5b\\x5d-\\x7e]{1,64}$/;\n\ninterface Http extends HostPolicy {\n fetch: FetchLike;\n timeoutMs?: number;\n}\n\nfunction httpOf(opts: {\n fetch: FetchLike;\n allowHttp?: boolean;\n allowLocal?: boolean;\n timeoutMs?: number;\n}): Http {\n return {\n fetch: opts.fetch,\n allowHttp: opts.allowHttp ?? false,\n allowLocal: opts.allowLocal ?? false,\n ...(opts.timeoutMs !== undefined ? { timeoutMs: opts.timeoutMs } : {}),\n };\n}\n\nasync function call(\n http: Http,\n url: string,\n init: {\n method: 'GET' | 'POST';\n headers: Record<string, string>;\n body?: string;\n maxBytes: number;\n }\n): Promise<{ status: number; json: unknown }> {\n if (!isFetchableUrl(url, http)) throw new Oid4vciError('invalid_metadata');\n let res;\n try {\n res = await request(http.fetch, url, {\n method: init.method,\n headers: init.headers,\n ...(init.body !== undefined ? { body: init.body } : {}),\n maxBytes: init.maxBytes,\n ...(http.timeoutMs !== undefined ? { timeoutMs: http.timeoutMs } : {}),\n });\n } catch (e) {\n if (e instanceof HttpError && e.kind === 'too_large') {\n throw new Oid4vciError('invalid_response');\n }\n throw new Oid4vciError('issuer_unavailable');\n }\n if (res.status >= 500) throw new Oid4vciError('issuer_unavailable');\n if (res.text.length === 0) return { status: res.status, json: null };\n try {\n return { status: res.status, json: JSON.parse(res.text) as unknown };\n } catch {\n if (res.status >= 200 && res.status < 300)\n throw new Oid4vciError('invalid_response');\n return { status: res.status, json: null };\n }\n}\n\nfunction oauthErrorOf(json: unknown): string | undefined {\n if (\n isRecord(json) &&\n typeof json.error === 'string' &&\n OAUTH_ERROR.test(json.error)\n ) {\n return json.error;\n }\n return undefined;\n}\n\nfunction refused(\n code: 'token_error' | 'issuer_error',\n json: unknown\n): Oid4vciError {\n const oauthError = oauthErrorOf(json);\n return new Oid4vciError(code, oauthError !== undefined ? { oauthError } : {});\n}\n\n/** Fetch and check Credential Issuer Metadata (`credential_issuer` must match exactly, §12.2.4). */\nexport async function fetchIssuerMetadata(\n credentialIssuer: string,\n opts: { fetch: FetchLike; timeoutMs?: number } & HostPolicy\n): Promise<CredentialIssuerMetadata> {\n const http = httpOf(opts);\n const { status, json } = await call(\n http,\n issuerMetadataUrl(credentialIssuer),\n {\n method: 'GET',\n headers: { accept: 'application/json' },\n maxBytes: MAX_METADATA_BYTES,\n }\n );\n if (status !== 200 || !isRecord(json))\n throw new Oid4vciError('invalid_metadata');\n if (json.credential_issuer !== credentialIssuer)\n throw new Oid4vciError('invalid_metadata');\n const endpointOk = (v: unknown) =>\n v === undefined || (typeof v === 'string' && isFetchableUrl(v, http));\n if (\n typeof json.credential_endpoint !== 'string' ||\n !endpointOk(json.credential_endpoint) ||\n !endpointOk(json.nonce_endpoint) ||\n !endpointOk(json.deferred_credential_endpoint) ||\n !endpointOk(json.notification_endpoint) ||\n !isRecord(json.credential_configurations_supported)\n ) {\n throw new Oid4vciError('invalid_metadata');\n }\n if (\n json.authorization_servers !== undefined &&\n (!Array.isArray(json.authorization_servers) ||\n json.authorization_servers.length === 0 ||\n !json.authorization_servers.every(a => typeof a === 'string'))\n ) {\n throw new Oid4vciError('invalid_metadata');\n }\n return json as CredentialIssuerMetadata;\n}\n\nasync function tokenEndpointOf(\n http: Http,\n metadata: CredentialIssuerMetadata,\n grant: PreAuthorizedCodeGrant\n): Promise<string> {\n const servers = metadata.authorization_servers;\n let as: string;\n if (grant.authorization_server !== undefined) {\n if (!servers?.includes(grant.authorization_server))\n throw new Oid4vciError('invalid_offer');\n as = grant.authorization_server;\n } else if (servers) {\n if (servers.length !== 1) throw new Oid4vciError('unsupported_offer');\n as = servers[0]!;\n } else {\n as = metadata.credential_issuer;\n }\n if (!isFetchableUrl(as, http)) throw new Oid4vciError('invalid_metadata');\n const { status, json } = await call(\n http,\n authorizationServerMetadataUrl(as),\n {\n method: 'GET',\n headers: { accept: 'application/json' },\n maxBytes: MAX_METADATA_BYTES,\n }\n );\n if (\n status !== 200 ||\n !isRecord(json) ||\n json.issuer !== as ||\n typeof json.token_endpoint !== 'string' ||\n !isFetchableUrl(json.token_endpoint, http)\n ) {\n throw new Oid4vciError('invalid_metadata');\n }\n return json.token_endpoint;\n}\n\nfunction readCredentialResponse(json: unknown): {\n credential: string;\n notificationId?: string;\n} {\n if (\n !isRecord(json) ||\n !Array.isArray(json.credentials) ||\n json.credentials.length !== 1\n ) {\n throw new Oid4vciError('invalid_response');\n }\n const first: unknown = json.credentials[0];\n if (\n !isRecord(first) ||\n typeof first.credential !== 'string' ||\n first.credential.length === 0\n ) {\n throw new Oid4vciError('invalid_response');\n }\n if (\n json.notification_id !== undefined &&\n typeof json.notification_id !== 'string'\n ) {\n throw new Oid4vciError('invalid_response');\n }\n return {\n credential: first.credential,\n ...(typeof json.notification_id === 'string'\n ? { notificationId: json.notification_id }\n : {}),\n };\n}\n\nfunction readDeferredResponse(json: unknown): {\n transactionId: string;\n interval: number;\n} {\n if (\n !isRecord(json) ||\n typeof json.transaction_id !== 'string' ||\n json.transaction_id.length === 0 ||\n typeof json.interval !== 'number' ||\n !(json.interval > 0)\n ) {\n throw new Oid4vciError('invalid_response');\n }\n return { transactionId: json.transaction_id, interval: json.interval };\n}\n\nconst MAX_OFFER_BYTES = 64 * 1024;\n\n/**\n * GET a credential offer by reference (§4.1.3): https only (http on loopback with `allowHttp`),\n * no redirects, timeout, 64 KiB cap, `application/json`; never cached. Returns the validated\n * offer; throws `Oid4vciError` (`invalid_offer`, `issuer_unavailable`, `issuer_error`).\n */\nexport async function fetchCredentialOffer(\n credentialOfferUri: string,\n opts: { fetch: FetchLike; timeoutMs?: number } & HostPolicy\n): Promise<CredentialOffer> {\n const http = httpOf(opts);\n if (!isFetchableUrl(credentialOfferUri, http)) {\n throw new Oid4vciError('invalid_offer');\n }\n const res = await call(http, credentialOfferUri, {\n method: 'GET',\n headers: { accept: 'application/json', 'cache-control': 'no-store' },\n maxBytes: MAX_OFFER_BYTES,\n });\n if (res.status !== 200) throw refused('issuer_error', res.json);\n return validateCredentialOffer(res.json, http);\n}\n\nexport interface IssuedResult {\n status: 'issued';\n /** The SD-JWT VC as issued (`<jwt>~<disclosures>~`). */\n credential: string;\n notificationId?: string;\n /** Needed for `sendNotification`. */\n accessToken: string;\n notificationEndpoint?: string;\n /** What `verifyIssuedCredential` found (absent only with `verify: false`). */\n verified?: VerifiedPresentation;\n}\n\nexport interface DeferredResult {\n status: 'deferred';\n transactionId: string;\n /** Seconds to wait before polling. */\n interval: number;\n accessToken: string;\n deferredEndpoint: string;\n notificationEndpoint?: string;\n /**\n * What to check the credential against when it arrives: pass it to `pollDeferred` as\n * `verification` (null with `verify: false`).\n */\n verification: Omit<VerifyIssuedCredentialOptions, 'now'> | null;\n}\n\nexport interface RedeemOfferInput {\n /** The offer by value (validated here; a `CredentialOffer` or the raw JSON). */\n offer?: unknown;\n /**\n * The offer by reference (§4.1.3): fetched here on every call, never cached (each fetch mints a\n * fresh, single-use pre-authorized code). Give exactly one of `offer` / `credentialOfferUri`.\n */\n credentialOfferUri?: string;\n /**\n * The holder key (its `kid` is a DID URL of the holder; the issuer binds `cnf` to it). When it\n * carries `publicKey` (an `Ed25519Signer`) that key is the expected `cnf`; otherwise the key\n * `kid` names under `authentication` on the holder's DID document is.\n */\n signer: Signer & { publicKey?: Uint8Array };\n fetch: FetchLike;\n /**\n * Resolves the issuer's DID (and the holder's, when the signer has no `publicKey`) to check the\n * credential. Required unless `verify: false`.\n */\n resolver?: DidResolver;\n /**\n * The DID the credential's `iss` must be (e.g. the DID that deposited the offer). REQUIRED\n * unless `verify: false` (`TypeError` otherwise). `false` accepts ANY issuer whose own DID\n * document signs the credential: UNSAFE, since anyone can then mint a credential of your types\n * (an offer link the person opened is enough). Use it only when you judge `out.verified.issuer`\n * yourself before storing or showing anything.\n */\n expectedIssuer?: string | false;\n /**\n * Default true: check the credential with `verifyIssuedCredential` (signature, `iss`, `sub` =\n * the holder DID, `cnf` = the holder key, `vct` = the offered configuration's, validity,\n * disclosures). A credential that fails is NOT returned: `Oid4vciError('invalid_credential')`\n * (and a best-effort `credential_failure` notification to the issuer).\n */\n verify?: boolean;\n /** Allow http on loopback hosts (local development only; needs `allowLocal`). */\n allowHttp?: boolean;\n /** Allow loopback / private / local-name hosts (local development only). */\n allowLocal?: boolean;\n /** ms since the epoch (proof `iat`, validity); default `Date.now()`. */\n now?: number;\n timeoutMs?: number;\n}\n\nasync function holderKeyOf(\n signer: RedeemOfferInput['signer'],\n resolver: DidResolver\n): Promise<Uint8Array> {\n if (signer.publicKey instanceof Uint8Array && signer.publicKey.length === 32)\n return signer.publicKey;\n const doc = await resolver(didFromKid(signer.kid));\n const key = doc ? findKey(doc, signer.kid, 'authentication') : null;\n if (!key)\n throw new Oid4vciError('invalid_proof', { reason: 'key_not_on_did' });\n return key.publicKey;\n}\n\n/** `verifyIssuedCredential`, mapped to `Oid4vciError('invalid_credential')`. */\nasync function checkCredential(\n credential: string,\n verification: Omit<VerifyIssuedCredentialOptions, 'now'>,\n now: number | undefined,\n onFailure: () => Promise<void>\n): Promise<VerifiedPresentation> {\n const result = await verifyIssuedCredential(credential, {\n ...verification,\n ...(now !== undefined ? { now } : {}),\n });\n if (result.ok) return result;\n await onFailure().catch(() => undefined);\n throw new Oid4vciError('invalid_credential', { reason: result.code });\n}\n\n/**\n * Redeem a pre-authorized code offer (by value, or fetched from `credentialOfferUri`) for ONE\n * credential configuration (the offer must name exactly one; one that needs a `tx_code` is\n * refused with `tx_code_unsupported`): issuer metadata → OAuth server metadata (token endpoint)\n * → token (anonymous: no `client_id`) → nonce → credential (one retry with a fresh nonce on\n * `invalid_nonce`) → `verifyIssuedCredential` (unless `verify: false`). Returns the checked\n * credential, or the deferred transaction. Throws `Oid4vciError` (`invalid_credential` for a\n * credential that does not check out), `VerificationUnavailable` / `ResolverUnavailable` when a\n * DID document needed for the check cannot be read, and `TypeError` without `resolver` or\n * `expectedIssuer` (unless `verify: false`). Store only what this returns, with\n * `credentialRecordFromSdJwt`.\n */\nexport async function redeemOffer(\n input: RedeemOfferInput\n): Promise<IssuedResult | DeferredResult> {\n const http = httpOf(input);\n const verify = input.verify ?? true;\n if (verify && input.resolver === undefined) {\n throw new TypeError(\n 'redeemOffer needs a resolver to check the credential (or verify: false).'\n );\n }\n const expectedIssuer: unknown = input.expectedIssuer;\n if (\n verify &&\n expectedIssuer !== false &&\n (typeof expectedIssuer !== 'string' || expectedIssuer.length === 0)\n ) {\n throw new TypeError(\n 'redeemOffer needs expectedIssuer (the DID that should have issued the credential), or expectedIssuer: false to accept any issuer.'\n );\n }\n if (\n (input.offer === undefined) ===\n (input.credentialOfferUri === undefined)\n ) {\n throw new TypeError('Give exactly one of offer and credentialOfferUri.');\n }\n const offer =\n input.credentialOfferUri !== undefined\n ? await fetchCredentialOffer(input.credentialOfferUri, http)\n : validateCredentialOffer(input.offer, http);\n if (offer.credential_configuration_ids.length !== 1) {\n throw new Oid4vciError('unsupported_offer');\n }\n const configurationId = offer.credential_configuration_ids[0]!;\n const grant = offer.grants[PRE_AUTHORIZED_CODE_GRANT];\n if (grant.tx_code !== undefined)\n throw new Oid4vciError('tx_code_unsupported');\n\n const metadata = await fetchIssuerMetadata(offer.credential_issuer, http);\n const configuration =\n metadata.credential_configurations_supported[configurationId];\n if (!isRecord(configuration) || configuration.format !== 'dc+sd-jwt') {\n throw new Oid4vciError('unsupported_offer');\n }\n // §12.2.4: the holder binding this wallet can do is a DID URL `kid` of the holder's DID.\n const holderDid = didFromKid(input.signer.kid);\n const bindingMethods = configuration.cryptographic_binding_methods_supported;\n if (bindingMethods !== undefined) {\n const method = /^did:[a-z0-9]+/.exec(holderDid)?.[0];\n if (\n !Array.isArray(bindingMethods) ||\n method === undefined ||\n !bindingMethods.includes(method)\n )\n throw new Oid4vciError('unsupported_offer');\n }\n let proofAlg: Ed25519JwsAlg = 'EdDSA';\n const proofTypes = configuration.proof_types_supported;\n if (proofTypes !== undefined) {\n const jwtProof: unknown = isRecord(proofTypes) ? proofTypes.jwt : undefined;\n const algs = isRecord(jwtProof)\n ? jwtProof.proof_signing_alg_values_supported\n : undefined;\n if (!Array.isArray(algs)) throw new Oid4vciError('unsupported_offer');\n if (algs.includes('EdDSA')) proofAlg = 'EdDSA';\n else if (algs.includes('Ed25519')) proofAlg = 'Ed25519';\n else throw new Oid4vciError('unsupported_offer');\n }\n if (typeof configuration.vct !== 'string' || configuration.vct.length === 0)\n throw new Oid4vciError('invalid_metadata');\n const verification: Omit<VerifyIssuedCredentialOptions, 'now'> | null =\n verify && input.resolver\n ? {\n subject: holderDid,\n holderKey: await holderKeyOf(input.signer, input.resolver),\n vct: configuration.vct,\n resolver: input.resolver,\n issuer: typeof expectedIssuer === 'string' ? expectedIssuer : false,\n }\n : null;\n\n // Token.\n const tokenEndpoint = await tokenEndpointOf(http, metadata, grant);\n const form = new URLSearchParams({\n grant_type: PRE_AUTHORIZED_CODE_GRANT,\n 'pre-authorized_code': grant['pre-authorized_code'],\n });\n const token = await call(http, tokenEndpoint, {\n method: 'POST',\n headers: {\n 'content-type': 'application/x-www-form-urlencoded',\n accept: 'application/json',\n },\n body: form.toString(),\n maxBytes: MAX_TOKEN_RESPONSE_BYTES,\n });\n if (token.status !== 200) throw refused('token_error', token.json);\n const tj = token.json;\n if (\n !isRecord(tj) ||\n typeof tj.access_token !== 'string' ||\n tj.access_token.length === 0 ||\n typeof tj.token_type !== 'string' ||\n tj.token_type.toLowerCase() !== 'bearer'\n ) {\n throw new Oid4vciError('invalid_response');\n }\n const accessToken = tj.access_token;\n // §6.2: when the AS returns credential_identifiers, the request must use one of them.\n let credentialIdentifier: string | undefined;\n if (Array.isArray(tj.authorization_details)) {\n const detail: unknown = tj.authorization_details.find(\n d =>\n isRecord(d) &&\n d.type === 'openid_credential' &&\n d.credential_configuration_id === configurationId\n );\n if (isRecord(detail) && Array.isArray(detail.credential_identifiers)) {\n const first: unknown = detail.credential_identifiers[0];\n if (typeof first !== 'string') throw new Oid4vciError('invalid_response');\n credentialIdentifier = first;\n }\n }\n\n const getNonce = async (): Promise<string | undefined> => {\n if (metadata.nonce_endpoint === undefined) return undefined;\n const res = await call(http, metadata.nonce_endpoint, {\n method: 'POST',\n headers: { accept: 'application/json' },\n maxBytes: MAX_TOKEN_RESPONSE_BYTES,\n });\n if (\n res.status !== 200 ||\n !isRecord(res.json) ||\n typeof res.json.c_nonce !== 'string'\n ) {\n throw new Oid4vciError('invalid_response');\n }\n return res.json.c_nonce;\n };\n\n const requestCredential = async (nonce: string | undefined) => {\n const proof = await createProofJwt({\n signer: input.signer,\n audience: metadata.credential_issuer,\n alg: proofAlg,\n ...(nonce !== undefined ? { nonce } : {}),\n ...(input.now !== undefined ? { now: input.now } : {}),\n });\n const body: CredentialRequest =\n credentialIdentifier !== undefined\n ? {\n credential_identifier: credentialIdentifier,\n proofs: { jwt: [proof] },\n }\n : {\n credential_configuration_id: configurationId,\n proofs: { jwt: [proof] },\n };\n return call(http, metadata.credential_endpoint, {\n method: 'POST',\n headers: {\n authorization: `Bearer ${accessToken}`,\n 'content-type': 'application/json',\n accept: 'application/json',\n },\n body: JSON.stringify(body),\n maxBytes: MAX_CREDENTIAL_RESPONSE_BYTES,\n });\n };\n\n let res = await requestCredential(await getNonce());\n if (res.status === 400 && oauthErrorOf(res.json) === 'invalid_nonce') {\n res = await requestCredential(await getNonce());\n }\n const notificationEndpoint = metadata.notification_endpoint;\n if (res.status === 200) {\n const issued = readCredentialResponse(res.json);\n let verified: VerifiedPresentation | undefined;\n if (verification) {\n verified = await checkCredential(\n issued.credential,\n verification,\n input.now,\n async () => {\n if (notificationEndpoint && issued.notificationId)\n await sendNotification({\n notificationEndpoint,\n accessToken,\n notificationId: issued.notificationId,\n event: 'credential_failure',\n eventDescription: 'credential did not verify',\n ...http,\n });\n }\n );\n }\n return {\n status: 'issued',\n ...issued,\n accessToken,\n ...(notificationEndpoint !== undefined ? { notificationEndpoint } : {}),\n ...(verified ? { verified } : {}),\n };\n }\n if (res.status === 202) {\n const deferredEndpoint = metadata.deferred_credential_endpoint;\n if (deferredEndpoint === undefined)\n throw new Oid4vciError('invalid_metadata');\n return {\n status: 'deferred',\n ...readDeferredResponse(res.json),\n accessToken,\n deferredEndpoint,\n ...(notificationEndpoint !== undefined ? { notificationEndpoint } : {}),\n verification,\n };\n }\n throw refused('issuer_error', res.json);\n}\n\n/**\n * Poll the Deferred Credential Endpoint once (§9). `verification` is the `DeferredResult`'s:\n * an issued credential is checked with `verifyIssuedCredential` and refused with\n * `Oid4vciError('invalid_credential')` when it fails; pass `false` only to opt out explicitly.\n */\nexport async function pollDeferred(\n input: {\n deferredEndpoint: string;\n accessToken: string;\n transactionId: string;\n verification: Omit<VerifyIssuedCredentialOptions, 'now'> | false;\n fetch: FetchLike;\n timeoutMs?: number;\n /** ms since the epoch (validity); default `Date.now()`. */\n now?: number;\n } & HostPolicy\n): Promise<\n | {\n status: 'issued';\n credential: string;\n notificationId?: string;\n verified?: VerifiedPresentation;\n }\n | { status: 'deferred'; transactionId: string; interval: number }\n> {\n if (input.verification === undefined || input.verification === null)\n throw new TypeError(\n 'pollDeferred needs the verification from redeemOffer (or false).'\n );\n const http = httpOf(input);\n const body: DeferredCredentialRequest = {\n transaction_id: input.transactionId,\n };\n const res = await call(http, input.deferredEndpoint, {\n method: 'POST',\n headers: {\n authorization: `Bearer ${input.accessToken}`,\n 'content-type': 'application/json',\n accept: 'application/json',\n },\n body: JSON.stringify(body),\n maxBytes: MAX_CREDENTIAL_RESPONSE_BYTES,\n });\n if (res.status === 200) {\n const issued = readCredentialResponse(res.json);\n if (input.verification === false) return { status: 'issued', ...issued };\n const verified = await checkCredential(\n issued.credential,\n input.verification,\n input.now,\n () => Promise.resolve()\n );\n return { status: 'issued', ...issued, verified };\n }\n if (res.status === 202)\n return { status: 'deferred', ...readDeferredResponse(res.json) };\n throw refused('issuer_error', res.json);\n}\n\nconst EVENT_DESCRIPTION = /^[\\x20-\\x21\\x23-\\x5b\\x5d-\\x7e]*$/;\n\n/** Tell the issuer what happened to the credential (§11). Throws `Oid4vciError` on refusal. */\nexport async function sendNotification(input: {\n notificationEndpoint: string;\n accessToken: string;\n notificationId: string;\n event: NotificationEvent;\n /** ASCII without `\"` and `\\` (§11.1). */\n eventDescription?: string;\n fetch: FetchLike;\n allowHttp?: boolean;\n allowLocal?: boolean;\n timeoutMs?: number;\n}): Promise<void> {\n if (\n input.eventDescription !== undefined &&\n !EVENT_DESCRIPTION.test(input.eventDescription)\n ) {\n throw new TypeError(\n 'eventDescription must be printable ASCII without \" and \\\\'\n );\n }\n const http = httpOf(input);\n const body: NotificationRequest = {\n notification_id: input.notificationId,\n event: input.event,\n ...(input.eventDescription !== undefined\n ? { event_description: input.eventDescription }\n : {}),\n };\n const res = await call(http, input.notificationEndpoint, {\n method: 'POST',\n headers: {\n authorization: `Bearer ${input.accessToken}`,\n 'content-type': 'application/json',\n accept: 'application/json',\n },\n body: JSON.stringify(body),\n maxBytes: MAX_TOKEN_RESPONSE_BYTES,\n });\n if (res.status < 200 || res.status >= 300)\n throw refused('issuer_error', res.json);\n}\n"]}
@@ -0,0 +1,89 @@
1
+ import { bytesToHex, utf8 } from './chunk-AQ3IINHC.js';
2
+ import { sha256 } from '@noble/hashes/sha2.js';
3
+
4
+ var IDENTITY_LEVEL1_VCT_VALUE = "https://credentials.ixo.world/types/IdentityLevel1";
5
+ var KYC_AML_LEVEL1_VCT_VALUE = "https://github.com/ixofoundation/ns/blob/main/protocol/credentials/v1/KYCAMLLevel1.json";
6
+ var UCAN_RESOURCE = "ixo:credentials";
7
+ function entityResource(entityDid) {
8
+ return `${UCAN_RESOURCE}/${entityDid}`;
9
+ }
10
+ var ABILITY_ISSUE = "credentials/issue";
11
+ var ABILITY_VERIFY = "credentials/verify";
12
+ var ABILITY_HOLD = "credentials/hold";
13
+ var ABILITY_OFFER = "credentials/offer";
14
+ var ABILITY_PRESENT = "credentials/present";
15
+ var ABILITIES = {
16
+ issue: ABILITY_ISSUE,
17
+ verify: ABILITY_VERIFY,
18
+ hold: ABILITY_HOLD,
19
+ offer: ABILITY_OFFER,
20
+ present: ABILITY_PRESENT
21
+ };
22
+ var CREDENTIAL_FORMAT = "dc+sd-jwt";
23
+ var SD_JWT_TYP = "dc+sd-jwt";
24
+ var KB_JWT_TYP = "kb+jwt";
25
+ var STATUS_LIST_JWT_TYP = "statuslist+jwt";
26
+ var REQUEST_OBJECT_TYP = "oauth-authz-req+jwt";
27
+ var PROOF_JWT_TYP = "openid4vci-proof+jwt";
28
+ var MEDIA_TYPES = {
29
+ statusList: "application/statuslist+jwt",
30
+ requestObject: "application/oauth-authz-req+jwt",
31
+ json: "application/json",
32
+ form: "application/x-www-form-urlencoded"
33
+ };
34
+ var CLIENT_ID_PREFIX = "decentralized_identifier:";
35
+ var PRE_AUTHORIZED_CODE_GRANT = "urn:ietf:params:oauth:grant-type:pre-authorized_code";
36
+ var WEBHOOK_SIGNATURE_HEADER = "x-ixo-signature";
37
+ var HEADERS = {
38
+ webhookSignature: WEBHOOK_SIGNATURE_HEADER,
39
+ authorization: "authorization"
40
+ };
41
+ var VAULT_CREDENTIAL_EVENT_TYPE = "ixo.credential";
42
+ var VAULT_CREDENTIAL_INDEX_TYPE = "ixo.credential.index";
43
+ var VAULT_CREDENTIAL_CONTENT_FIELD = "credential";
44
+ var VCT_STATE_KEYS = Object.freeze(
45
+ Object.assign(/* @__PURE__ */ Object.create(null), {
46
+ [IDENTITY_LEVEL1_VCT_VALUE]: "identitylevel1",
47
+ [KYC_AML_LEVEL1_VCT_VALUE]: "kycamllevel1"
48
+ })
49
+ );
50
+ function stateKeyForVct(vct) {
51
+ if (typeof vct !== "string" || vct.length === 0)
52
+ throw new TypeError("vct must be a non-empty string");
53
+ const known = VCT_STATE_KEYS[vct];
54
+ if (known !== void 0) return known;
55
+ return `vct-${bytesToHex(sha256(utf8(vct))).slice(0, 32)}`;
56
+ }
57
+ var IDENTITY_LEVEL1_VCT = IDENTITY_LEVEL1_VCT_VALUE;
58
+ var KYC_AML_LEVEL1_VCT = KYC_AML_LEVEL1_VCT_VALUE;
59
+ var IDENTITY_LEVEL1_CONFIGURATION_ID = "IdentityLevel1";
60
+ var AGE_CLAIMS = [
61
+ "age_over_18",
62
+ "age_over_21",
63
+ "age_birth_year"
64
+ ];
65
+ var REGISTERED_CLAIMS = [
66
+ "iss",
67
+ "sub",
68
+ "iat",
69
+ "nbf",
70
+ "exp",
71
+ "vct",
72
+ "vct#integrity",
73
+ "cnf",
74
+ "status",
75
+ "_sd",
76
+ "_sd_alg"
77
+ ];
78
+ var MAX_BLOCKS_PER_PERSON = 500;
79
+ var BLOCKED_ERROR = "blocked";
80
+ var WEBHOOK_EVENT_TYPES = [
81
+ "offer.created",
82
+ "request.created",
83
+ "offer.retracted",
84
+ "request.cancelled"
85
+ ];
86
+
87
+ export { ABILITIES, ABILITY_HOLD, ABILITY_ISSUE, ABILITY_OFFER, ABILITY_PRESENT, ABILITY_VERIFY, AGE_CLAIMS, BLOCKED_ERROR, CLIENT_ID_PREFIX, CREDENTIAL_FORMAT, HEADERS, IDENTITY_LEVEL1_CONFIGURATION_ID, IDENTITY_LEVEL1_VCT, KB_JWT_TYP, KYC_AML_LEVEL1_VCT, MAX_BLOCKS_PER_PERSON, MEDIA_TYPES, PRE_AUTHORIZED_CODE_GRANT, PROOF_JWT_TYP, REGISTERED_CLAIMS, REQUEST_OBJECT_TYP, SD_JWT_TYP, STATUS_LIST_JWT_TYP, UCAN_RESOURCE, VAULT_CREDENTIAL_CONTENT_FIELD, VAULT_CREDENTIAL_EVENT_TYPE, VAULT_CREDENTIAL_INDEX_TYPE, VCT_STATE_KEYS, WEBHOOK_EVENT_TYPES, WEBHOOK_SIGNATURE_HEADER, entityResource, stateKeyForVct };
88
+ //# sourceMappingURL=chunk-I6GBYFIJ.js.map
89
+ //# sourceMappingURL=chunk-I6GBYFIJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/profile.ts"],"names":[],"mappings":";;;AAeA,IAAM,yBAAA,GACJ,oDAAA;AACF,IAAM,wBAAA,GACJ,yFAAA;AAMK,IAAM,aAAA,GAAgB;AAGtB,SAAS,eAAe,SAAA,EAA2B;AACxD,EAAA,OAAO,CAAA,EAAG,aAAa,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA;AACtC;AAEO,IAAM,aAAA,GAAgB;AACtB,IAAM,cAAA,GAAiB;AACvB,IAAM,YAAA,GAAe;AAErB,IAAM,aAAA,GAAgB;AAEtB,IAAM,eAAA,GAAkB;AAExB,IAAM,SAAA,GAAY;AAAA,EACvB,KAAA,EAAO,aAAA;AAAA,EACP,MAAA,EAAQ,cAAA;AAAA,EACR,IAAA,EAAM,YAAA;AAAA,EACN,KAAA,EAAO,aAAA;AAAA,EACP,OAAA,EAAS;AACX;AAOO,IAAM,iBAAA,GAAoB;AAC1B,IAAM,UAAA,GAAa;AACnB,IAAM,UAAA,GAAa;AACnB,IAAM,mBAAA,GAAsB;AAC5B,IAAM,kBAAA,GAAqB;AAC3B,IAAM,aAAA,GAAgB;AAEtB,IAAM,WAAA,GAAc;AAAA,EACzB,UAAA,EAAY,4BAAA;AAAA,EACZ,aAAA,EAAe,iCAAA;AAAA,EACf,IAAA,EAAM,kBAAA;AAAA,EACN,IAAA,EAAM;AACR;AAGO,IAAM,gBAAA,GAAmB;AAGzB,IAAM,yBAAA,GACX;AAGK,IAAM,wBAAA,GAA2B;AAEjC,IAAM,OAAA,GAAU;AAAA,EACrB,gBAAA,EAAkB,wBAAA;AAAA,EAClB,aAAA,EAAe;AACjB;AAKO,IAAM,2BAAA,GAA8B;AACpC,IAAM,2BAAA,GAA8B;AACpC,IAAM,8BAAA,GAAiC;AAMvC,IAAM,iBAAmD,MAAA,CAAO,MAAA;AAAA,EACrE,MAAA,CAAO,MAAA,iBAAO,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA,EAA6B;AAAA,IAC3D,CAAC,yBAAyB,GAAG,gBAAA;AAAA,IAC7B,CAAC,wBAAwB,GAAG;AAAA,GAC7B;AACH;AAUO,SAAS,eAAe,GAAA,EAAqB;AAClD,EAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,IAAY,GAAA,CAAI,MAAA,KAAW,CAAA;AAC5C,IAAA,MAAM,IAAI,UAAU,gCAAgC,CAAA;AACtD,EAAA,MAAM,KAAA,GAAQ,eAAe,GAAG,CAAA;AAChC,EAAA,IAAI,KAAA,KAAU,QAAW,OAAO,KAAA;AAChC,EAAA,OAAO,CAAA,IAAA,EAAO,UAAA,CAAW,MAAA,CAAO,IAAA,CAAK,GAAG,CAAC,CAAC,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA,CAAA;AAC1D;AAMO,IAAM,mBAAA,GAAsB;AAE5B,IAAM,kBAAA,GAAqB;AAE3B,IAAM,gCAAA,GAAmC;AAGzC,IAAM,UAAA,GAAa;AAAA,EACxB,aAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF;AAIO,IAAM,iBAAA,GAAoB;AAAA,EAC/B,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,eAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF;AA0JO,IAAM,qBAAA,GAAwB;AAG9B,IAAM,aAAA,GAAgB;AAKtB,IAAM,mBAAA,GAAsB;AAAA,EACjC,eAAA;AAAA,EACA,iBAAA;AAAA,EACA,iBAAA;AAAA,EACA;AACF","file":"chunk-I6GBYFIJ.js","sourcesContent":["/**\n * `@ixo/credentials-kit/profile` — the IXO Credentials profile's constants and shared types\n * (SPEC §3, §5): UCAN resource and abilities, header names, media types, webhook event types,\n * the Credentials worker's catalog / offer / request shapes, and `stateKeyForVct`.\n *\n * JSON shapes are those of the Credentials worker's HTTP API (snake_case members; every\n * timestamp is unix seconds, an integer).\n */\nimport { sha256 } from '@noble/hashes/sha2.js';\nimport type { CardDisplay } from './display';\nimport { bytesToHex, utf8 } from './internal/bytes';\n\nexport type { CardDisplay } from './display';\n\n// Declared before use: `VCT_STATE_KEYS` below is built at module load.\nconst IDENTITY_LEVEL1_VCT_VALUE =\n 'https://credentials.ixo.world/types/IdentityLevel1';\nconst KYC_AML_LEVEL1_VCT_VALUE =\n 'https://github.com/ixofoundation/ns/blob/main/protocol/credentials/v1/KYCAMLLevel1.json';\n\n// ---------------------------------------------------------------------------------------------\n// UCAN.\n\n/** The UCAN resource of the Credentials worker; the caller acts as itself. */\nexport const UCAN_RESOURCE = 'ixo:credentials';\n\n/** `ixo:credentials/<entity DID>`: the caller acts as that entity (SPEC §5.1). */\nexport function entityResource(entityDid: string): string {\n return `${UCAN_RESOURCE}/${entityDid}`;\n}\n\nexport const ABILITY_ISSUE = 'credentials/issue';\nexport const ABILITY_VERIFY = 'credentials/verify';\nexport const ABILITY_HOLD = 'credentials/hold';\n/** Consent: the holder lets an issuer deposit offers that the wallet may store automatically. */\nexport const ABILITY_OFFER = 'credentials/offer';\n/** Standing presentation consent: the holder lets a verifier be answered without asking. */\nexport const ABILITY_PRESENT = 'credentials/present';\n\nexport const ABILITIES = {\n issue: ABILITY_ISSUE,\n verify: ABILITY_VERIFY,\n hold: ABILITY_HOLD,\n offer: ABILITY_OFFER,\n present: ABILITY_PRESENT,\n} as const;\n\nexport type Ability = (typeof ABILITIES)[keyof typeof ABILITIES];\n\n// ---------------------------------------------------------------------------------------------\n// Formats, media types, headers.\n\nexport const CREDENTIAL_FORMAT = 'dc+sd-jwt';\nexport const SD_JWT_TYP = 'dc+sd-jwt';\nexport const KB_JWT_TYP = 'kb+jwt';\nexport const STATUS_LIST_JWT_TYP = 'statuslist+jwt';\nexport const REQUEST_OBJECT_TYP = 'oauth-authz-req+jwt';\nexport const PROOF_JWT_TYP = 'openid4vci-proof+jwt';\n\nexport const MEDIA_TYPES = {\n statusList: 'application/statuslist+jwt',\n requestObject: 'application/oauth-authz-req+jwt',\n json: 'application/json',\n form: 'application/x-www-form-urlencoded',\n} as const;\n\n/** OpenID4VP Client Identifier Prefix for DID verifiers. */\nexport const CLIENT_ID_PREFIX = 'decentralized_identifier:';\n\n/** OAuth grant type of the OpenID4VCI pre-authorized code flow. */\nexport const PRE_AUTHORIZED_CODE_GRANT =\n 'urn:ietf:params:oauth:grant-type:pre-authorized_code';\n\n/** Webhook signature header (Credentials worker → Hub). */\nexport const WEBHOOK_SIGNATURE_HEADER = 'x-ixo-signature';\n\nexport const HEADERS = {\n webhookSignature: WEBHOOK_SIGNATURE_HEADER,\n authorization: 'authorization',\n} as const;\n\n// ---------------------------------------------------------------------------------------------\n// Vault (Matrix) shapes shared with the portal and Self.\n\nexport const VAULT_CREDENTIAL_EVENT_TYPE = 'ixo.credential';\nexport const VAULT_CREDENTIAL_INDEX_TYPE = 'ixo.credential.index';\nexport const VAULT_CREDENTIAL_CONTENT_FIELD = 'credential';\n\n/**\n * Vault index state keys of the known credential types, by their FULL `vct` (exact match). These\n * slots are shared with Self's web app (`identitylevel1`) and the portal (`kycamllevel1`).\n */\nexport const VCT_STATE_KEYS: Readonly<Record<string, string>> = Object.freeze(\n Object.assign(Object.create(null) as Record<string, string>, {\n [IDENTITY_LEVEL1_VCT_VALUE]: 'identitylevel1',\n [KYC_AML_LEVEL1_VCT_VALUE]: 'kycamllevel1',\n })\n);\n\n/**\n * The Vault index state key for a `vct`, from the FULL `vct` (exact match, no normalising): a\n * known type's slot from `VCT_STATE_KEYS` (`IDENTITY_LEVEL1_VCT` → `identitylevel1`,\n * `KYC_AML_LEVEL1_VCT` → `kycamllevel1`), else `vct-` + the first 32 hex characters of\n * SHA-256(vct). Two different `vct` values never share a slot, so a foreign issuer's look-alike\n * type (`https://evil.example/Identity-Level_1.json`) cannot land in a known type's slot. Throws\n * `TypeError` for an empty or non-string `vct`.\n */\nexport function stateKeyForVct(vct: string): string {\n if (typeof vct !== 'string' || vct.length === 0)\n throw new TypeError('vct must be a non-empty string');\n const known = VCT_STATE_KEYS[vct];\n if (known !== undefined) return known;\n return `vct-${bytesToHex(sha256(utf8(vct))).slice(0, 32)}`;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Credentials.\n\n/** Self's identity credential type (unchanged in v1). */\nexport const IDENTITY_LEVEL1_VCT = IDENTITY_LEVEL1_VCT_VALUE;\n/** The portal's KYC/AML credential type (pay-convert-oracle `KYC_VCT`). */\nexport const KYC_AML_LEVEL1_VCT = KYC_AML_LEVEL1_VCT_VALUE;\n/** Self's OpenID4VCI credential configuration id. */\nexport const IDENTITY_LEVEL1_CONFIGURATION_ID = 'IdentityLevel1';\n\n/** Derived age claims a credential with a birth date carries, each its own disclosure. */\nexport const AGE_CLAIMS = [\n 'age_over_18',\n 'age_over_21',\n 'age_birth_year',\n] as const;\nexport type AgeClaim = (typeof AGE_CLAIMS)[number];\n\n/** Registered / structural claims that are never selectively disclosable in the profile. */\nexport const REGISTERED_CLAIMS = [\n 'iss',\n 'sub',\n 'iat',\n 'nbf',\n 'exp',\n 'vct',\n 'vct#integrity',\n 'cnf',\n 'status',\n '_sd',\n '_sd_alg',\n] as const;\n\n// ---------------------------------------------------------------------------------------------\n// Catalog (SPEC §5.3).\n\nexport type ClaimDisclosure = 'always' | 'allowed' | 'never';\n\nexport interface CatalogClaim {\n name: string;\n label: string;\n /** Whether the claim is selectively disclosable. */\n sd: ClaimDisclosure;\n}\n\nexport interface CatalogIssuerType {\n vct: string;\n name: string;\n description?: string;\n type_metadata_uri?: string;\n claims: CatalogClaim[];\n /** The card look for credentials of this type (SPEC §15.1; validated, unknown members dropped). */\n display?: CardDisplay;\n}\n\nexport interface CatalogIssuerEntry {\n did: string;\n name: string;\n description?: string;\n url?: string;\n /** The OpenID4VCI Credential Issuer Identifier (https URL). */\n credential_issuer: string;\n types: CatalogIssuerType[];\n /** The issuer's mark (https image URL; png, jpeg or webp). */\n logo_uri?: string;\n /** The issuer's mark colour, `#rrggbb`. */\n color?: string;\n}\n\nexport interface CatalogVerifierAccept {\n purpose: string;\n vct: string;\n claims: string[];\n issuers: string[];\n}\n\nexport interface CatalogVerifierEntry {\n did: string;\n name: string;\n description?: string;\n url?: string;\n accepts: CatalogVerifierAccept[];\n /** The verifier's mark (https image URL; png, jpeg or webp). */\n logo_uri?: string;\n /** The verifier's mark colour, `#rrggbb`. */\n color?: string;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Inbox and broker (SPEC §5.2, §5.3).\n\nexport type OfferStatus =\n 'pending' | 'accepted' | 'declined' | 'retracted' | 'expired';\nexport type RequestStatus =\n 'pending' | 'answered' | 'declined' | 'cancelled' | 'expired';\n\n/**\n * An offer's `display`: name, type and description only (SPEC §16.1). The card look, the issuer's\n * name and its logo come only from the issuer's catalog entry (`CatalogIssuerEntry`), so an offer\n * cannot change them; the worker drops anything else and lists it in `display_dropped`.\n */\nexport interface OfferDisplay {\n name: string;\n vct: string;\n description?: string;\n}\n\n/** An offer as the worker lists it (never the pre-authorized code). */\nexport interface OfferSummary {\n id: string;\n issuer: string;\n subject: string;\n ref: string;\n credential_issuer: string;\n vct: string;\n display: OfferDisplay;\n status: OfferStatus;\n /** Whether a valid `credentials/offer` delegation from the subject came with the offer. */\n consent: 'valid' | 'none';\n /** unix seconds */\n created_at: number;\n /** unix seconds */\n expires_at: number;\n}\n\n/** One credential query of a request, as `summarizeDcql` reports it. */\nexport interface DcqlQuerySummary {\n id: string;\n vctValues: string[];\n /** Claim names asked for (never `iss`). */\n claims: string[];\n /** The accepted-issuer filter, when the query has one. */\n issuers?: string[];\n}\n\n/** A presentation request as the worker lists it. */\nexport interface RequestSummary {\n id: string;\n verifier: string;\n subject: string;\n ref: string;\n /** The verifier's full OpenID4VP client_id (`decentralized_identifier:<did>`). */\n client_id: string;\n purpose: string;\n summary: DcqlQuerySummary[];\n /** Host of the request's `response_uri`. */\n response_host: string;\n status: RequestStatus;\n /** unix seconds */\n created_at: number;\n /** unix seconds */\n expires_at: number;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Block list (SPEC §16.1): a person refuses a sender's offers and requests at the worker.\n\n/** One entry of a person's block list (`GET /v1/blocks`). */\nexport interface SenderBlock {\n /** The blocked DID, exactly as written: the block covers exactly this DID (SPEC §17.4). */\n sender: string;\n /** unix seconds */\n created_at: number;\n}\n\n/** `POST /v1/blocks` answer. */\nexport interface BlockSenderResult extends SenderBlock {\n /** Waiting offers + requests from this sender for the person, closed as declined by this call. */\n closed: number;\n}\n\n/** `POST /v1/blocks/remove` answer. */\nexport interface UnblockSenderResult {\n sender: string;\n /** False when the sender was not blocked. */\n removed: boolean;\n}\n\n/** `GET /v1/blocks` answer (newest first). */\nexport interface SenderBlockList {\n items: SenderBlock[];\n next_cursor: string | null;\n}\n\n/** At most this many blocks per person (`too_many_blocks` above it). */\nexport const MAX_BLOCKS_PER_PERSON = 500;\n\n/** The worker's error code for a deposit from a sender the person blocked (HTTP 403). */\nexport const BLOCKED_ERROR = 'blocked';\n\n// ---------------------------------------------------------------------------------------------\n// Webhook (SPEC §5.4).\n\nexport const WEBHOOK_EVENT_TYPES = [\n 'offer.created',\n 'request.created',\n 'offer.retracted',\n 'request.cancelled',\n] as const;\nexport type WebhookEventType = (typeof WEBHOOK_EVENT_TYPES)[number];\n\n/** The webhook body. It carries no secret: the Hub fetches details itself. */\nexport interface WebhookEvent {\n /** `evt_…` */\n id: string;\n type: WebhookEventType;\n /** The holder DID the offer / request is for. */\n subject: string;\n /** The offer or request id (`ofr_…` / `req_…`), NOT the issuer's / verifier's `ref`. */\n object_id: string;\n /** unix seconds */\n created_at: number;\n}\n"]}
@@ -0,0 +1,210 @@
1
+ import { findKey } from './chunk-WIEGZFUO.js';
2
+ import { CredentialsKitError, toSeconds, signJws, decodeJws, JoseError, isEd25519JwsAlg, verifyEd25519, clockMs, CLOCK_SKEW_S, isRecord } from './chunk-VXKONZK4.js';
3
+ import { base64urlEncode, utf8, base64urlDecode } from './chunk-AQ3IINHC.js';
4
+
5
+ // src/status.ts
6
+ var STATUS_LIST_TYP = "statuslist+jwt";
7
+ var STATUS_LIST_MEDIA_TYPE = "application/statuslist+jwt";
8
+ var MAX_STATUS_LIST_BYTES = 1024 * 1024;
9
+ var MAX_STATUS_LIST_TOKEN_LENGTH = 64 * 1024;
10
+ var STATUS_VALID = 0;
11
+ var STATUS_INVALID = 1;
12
+ var STATUS_SUSPENDED = 2;
13
+ var STATUS_MESSAGES = {
14
+ malformed: "The status list token is not well formed.",
15
+ wrong_type: "The token is not a status list token.",
16
+ wrong_subject: "The status list token is for another list.",
17
+ wrong_issuer: "The status list token was issued by someone else.",
18
+ issuer_key_unpublished: "The status list token's signing key is not an assertion key of the issuer.",
19
+ bad_signature: "The status list token signature does not verify.",
20
+ expired: "The status list token has expired.",
21
+ not_yet_valid: "The status list token is not valid yet.",
22
+ rolled_back: "The status list token is older than one already seen.",
23
+ too_large: "The status list is larger than allowed.",
24
+ out_of_range: "The index is outside the status list."
25
+ };
26
+ var StatusListError = class extends CredentialsKitError {
27
+ constructor(code) {
28
+ super(code, STATUS_MESSAGES[code]);
29
+ }
30
+ };
31
+ function newStatusBits(bytes) {
32
+ if (!Number.isSafeInteger(bytes) || bytes <= 0 || bytes > MAX_STATUS_LIST_BYTES) {
33
+ throw new StatusListError("out_of_range");
34
+ }
35
+ return new Uint8Array(bytes);
36
+ }
37
+ function checkIndex(bits, idx, bitsPerEntry) {
38
+ if (!Number.isSafeInteger(idx) || idx < 0 || (idx + 1) * bitsPerEntry > bits.length * 8) {
39
+ throw new StatusListError("out_of_range");
40
+ }
41
+ }
42
+ function setStatusBit(bits, idx) {
43
+ checkIndex(bits, idx, 1);
44
+ bits[idx >> 3] = bits[idx >> 3] | 1 << (idx & 7);
45
+ }
46
+ function getStatusBit(bits, idx) {
47
+ checkIndex(bits, idx, 1);
48
+ return bits[idx >> 3] >> (idx & 7) & 1;
49
+ }
50
+ function statusAt(bits, idx, bitsPerEntry = 1) {
51
+ checkIndex(bits, idx, bitsPerEntry);
52
+ const bit = idx * bitsPerEntry;
53
+ return bits[bit >> 3] >> (bit & 7) & (1 << bitsPerEntry) - 1;
54
+ }
55
+ function randomFreeIndex(used, size) {
56
+ if (!Number.isSafeInteger(size) || size <= 0 || size > used.length * 8) {
57
+ throw new StatusListError("out_of_range");
58
+ }
59
+ const random = new Uint32Array(1);
60
+ for (let attempt = 0; attempt < 64; attempt++) {
61
+ crypto.getRandomValues(random);
62
+ const limit = Math.floor(4294967296 / size) * size;
63
+ if (random[0] >= limit) continue;
64
+ const idx = random[0] % size;
65
+ if (getStatusBit(used, idx) === 0) return idx;
66
+ }
67
+ crypto.getRandomValues(random);
68
+ const start = random[0] % size;
69
+ for (let i = 0; i < size; i++) {
70
+ const idx = (start + i) % size;
71
+ if (getStatusBit(used, idx) === 0) return idx;
72
+ }
73
+ throw new StatusListError("out_of_range");
74
+ }
75
+ async function pipeThrough(bytes, transform, max) {
76
+ const reader = new Blob([bytes]).stream().pipeThrough(transform).getReader();
77
+ const chunks = [];
78
+ let size = 0;
79
+ for (; ; ) {
80
+ const { done, value } = await reader.read();
81
+ if (done) break;
82
+ size += value.byteLength;
83
+ if (size > max) {
84
+ await reader.cancel().catch(() => void 0);
85
+ throw new StatusListError("too_large");
86
+ }
87
+ chunks.push(value);
88
+ }
89
+ const out = new Uint8Array(size);
90
+ let at = 0;
91
+ for (const c of chunks) {
92
+ out.set(c, at);
93
+ at += c.byteLength;
94
+ }
95
+ return out;
96
+ }
97
+ function deflateStatusList(bytes) {
98
+ return pipeThrough(
99
+ bytes,
100
+ new CompressionStream("deflate"),
101
+ Number.MAX_SAFE_INTEGER
102
+ );
103
+ }
104
+ async function inflateStatusList(bytes, max = MAX_STATUS_LIST_BYTES) {
105
+ try {
106
+ return await pipeThrough(bytes, new DecompressionStream("deflate"), max);
107
+ } catch (e) {
108
+ if (e instanceof StatusListError) throw e;
109
+ throw new StatusListError("malformed");
110
+ }
111
+ }
112
+ async function createStatusListToken(input) {
113
+ const iat = input.iat ?? toSeconds(Date.now());
114
+ if (!Number.isSafeInteger(input.ttl) || input.ttl <= 0) {
115
+ throw new StatusListError("malformed");
116
+ }
117
+ if (!Number.isSafeInteger(input.exp) || input.exp <= iat) {
118
+ throw new StatusListError("malformed");
119
+ }
120
+ const lst = base64urlEncode(await deflateStatusList(input.bits));
121
+ return signJws(
122
+ { alg: "EdDSA", typ: STATUS_LIST_TYP, kid: input.signer.kid },
123
+ {
124
+ sub: input.uri,
125
+ iss: input.iss,
126
+ iat,
127
+ exp: input.exp,
128
+ ttl: input.ttl,
129
+ status_list: { bits: 1, lst }
130
+ },
131
+ input.signer
132
+ );
133
+ }
134
+ async function verifyStatusListToken(token, opts) {
135
+ if (typeof token !== "string" || token.length > MAX_STATUS_LIST_TOKEN_LENGTH) {
136
+ throw new StatusListError("too_large");
137
+ }
138
+ let jws;
139
+ try {
140
+ jws = decodeJws(token.trim());
141
+ } catch (e) {
142
+ if (e instanceof JoseError) throw new StatusListError("malformed");
143
+ throw e;
144
+ }
145
+ const { header, payload } = jws;
146
+ if (header.typ !== STATUS_LIST_TYP) throw new StatusListError("wrong_type");
147
+ if (!isEd25519JwsAlg(header.alg)) throw new StatusListError("bad_signature");
148
+ const kid = typeof header.kid === "string" ? header.kid : "";
149
+ const key = findKey(opts.issuerDoc, kid, "assertionMethod");
150
+ if (!key) throw new StatusListError("issuer_key_unpublished");
151
+ if (!verifyEd25519(jws.signature, utf8(jws.signingInput), key.publicKey)) {
152
+ throw new StatusListError("bad_signature");
153
+ }
154
+ if (payload.sub !== opts.uri) throw new StatusListError("wrong_subject");
155
+ if (payload.iss !== void 0 && payload.iss !== opts.issuerDoc.id) {
156
+ throw new StatusListError("wrong_issuer");
157
+ }
158
+ const iat = payload.iat;
159
+ if (typeof iat !== "number" || !Number.isFinite(iat)) {
160
+ throw new StatusListError("malformed");
161
+ }
162
+ if (opts.minIat !== void 0 && iat < opts.minIat) {
163
+ throw new StatusListError("rolled_back");
164
+ }
165
+ const nowS = toSeconds(clockMs(opts.now));
166
+ const nbf = payload.nbf;
167
+ if (nbf !== void 0) {
168
+ if (typeof nbf !== "number" || !Number.isFinite(nbf))
169
+ throw new StatusListError("malformed");
170
+ if (nowS + CLOCK_SKEW_S < nbf) throw new StatusListError("not_yet_valid");
171
+ }
172
+ const exp = payload.exp;
173
+ if (exp !== void 0 && (typeof exp !== "number" || !Number.isFinite(exp))) {
174
+ throw new StatusListError("malformed");
175
+ }
176
+ if (typeof exp === "number" && nowS > exp + CLOCK_SKEW_S) {
177
+ throw new StatusListError("expired");
178
+ }
179
+ const ttl = payload.ttl;
180
+ if (ttl !== void 0 && (typeof ttl !== "number" || !(ttl > 0))) {
181
+ throw new StatusListError("malformed");
182
+ }
183
+ const list = payload.status_list;
184
+ if (!isRecord(list) || typeof list.lst !== "string") {
185
+ throw new StatusListError("malformed");
186
+ }
187
+ const bitsPerEntry = list.bits;
188
+ if (bitsPerEntry !== 1 && bitsPerEntry !== 2 && bitsPerEntry !== 4 && bitsPerEntry !== 8) {
189
+ throw new StatusListError("malformed");
190
+ }
191
+ let compressed;
192
+ try {
193
+ compressed = base64urlDecode(list.lst);
194
+ } catch {
195
+ throw new StatusListError("malformed");
196
+ }
197
+ const bits = await inflateStatusList(compressed);
198
+ return {
199
+ bits,
200
+ bitsPerEntry,
201
+ ttl: typeof ttl === "number" ? ttl : null,
202
+ exp: typeof exp === "number" ? exp : null,
203
+ iat,
204
+ kid: key.id
205
+ };
206
+ }
207
+
208
+ export { MAX_STATUS_LIST_BYTES, MAX_STATUS_LIST_TOKEN_LENGTH, STATUS_INVALID, STATUS_LIST_MEDIA_TYPE, STATUS_LIST_TYP, STATUS_SUSPENDED, STATUS_VALID, StatusListError, createStatusListToken, deflateStatusList, getStatusBit, inflateStatusList, newStatusBits, randomFreeIndex, setStatusBit, statusAt, verifyStatusListToken };
209
+ //# sourceMappingURL=chunk-JBUX6V2Q.js.map
210
+ //# sourceMappingURL=chunk-JBUX6V2Q.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/status.ts"],"names":[],"mappings":"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","file":"chunk-JBUX6V2Q.js","sourcesContent":["/**\n * `@ixo/credentials-kit/status` — IETF Token Status List (draft-ietf-oauth-status-list), JWT\n * form, as Self issues it today (`ixo-self/worker/src/service/credential/status-list.ts`):\n *\n * header { alg: 'EdDSA', typ: 'statuslist+jwt', kid: <issuer assertionMethod id> }\n * payload { sub: <the list's public URI>, iss: <issuer DID>, iat, exp, ttl,\n * status_list: { bits: 1, lst: base64url(ZLIB-DEFLATE(bytes)) } }\n * entry i byte i >> 3, bit i & 7 (least significant bit first); 0 = VALID, 1 = INVALID.\n *\n * DEFLATE/INFLATE use `CompressionStream` / `DecompressionStream('deflate')` (the ZLIB format,\n * RFC 1950), available in workerd, Node 22 and browsers. Inflation is capped.\n */\nimport { findKey, type DidDocument } from './did';\nimport { base64urlDecode, base64urlEncode, utf8 } from './internal/bytes';\nimport { CredentialsKitError } from './internal/errors';\nimport { CLOCK_SKEW_S, clockMs, isRecord, toSeconds } from './internal/util';\nimport {\n JoseError,\n decodeJws,\n isEd25519JwsAlg,\n signJws,\n verifyEd25519,\n type Signer,\n} from './jose';\n\nexport const STATUS_LIST_TYP = 'statuslist+jwt';\nexport const STATUS_LIST_MEDIA_TYPE = 'application/statuslist+jwt';\n/** Largest status list a verifier inflates (1 MiB = 8,388,608 one-bit entries). */\nexport const MAX_STATUS_LIST_BYTES = 1024 * 1024;\n/** Largest status list token accepted (64 KiB, the Credentials worker's limit). */\nexport const MAX_STATUS_LIST_TOKEN_LENGTH = 64 * 1024;\n\nexport const STATUS_VALID = 0;\nexport const STATUS_INVALID = 1;\nexport const STATUS_SUSPENDED = 2;\n\nexport type StatusListErrorCode =\n | 'malformed'\n | 'wrong_type'\n | 'wrong_subject'\n | 'wrong_issuer'\n | 'issuer_key_unpublished'\n | 'bad_signature'\n | 'expired'\n | 'not_yet_valid'\n | 'rolled_back'\n | 'too_large'\n | 'out_of_range';\n\nconst STATUS_MESSAGES: Record<StatusListErrorCode, string> = {\n malformed: 'The status list token is not well formed.',\n wrong_type: 'The token is not a status list token.',\n wrong_subject: 'The status list token is for another list.',\n wrong_issuer: 'The status list token was issued by someone else.',\n issuer_key_unpublished:\n \"The status list token's signing key is not an assertion key of the issuer.\",\n bad_signature: 'The status list token signature does not verify.',\n expired: 'The status list token has expired.',\n not_yet_valid: 'The status list token is not valid yet.',\n rolled_back: 'The status list token is older than one already seen.',\n too_large: 'The status list is larger than allowed.',\n out_of_range: 'The index is outside the status list.',\n};\n\nexport class StatusListError extends CredentialsKitError {\n declare readonly code: StatusListErrorCode;\n constructor(code: StatusListErrorCode) {\n super(code, STATUS_MESSAGES[code]);\n }\n}\n\n// ---------------------------------------------------------------------------------------------\n// Bits (1 bit per entry, the profile's list).\n\n/** A new, all-VALID list of `bytes` bytes (`bytes * 8` entries). */\nexport function newStatusBits(bytes: number): Uint8Array {\n if (\n !Number.isSafeInteger(bytes) ||\n bytes <= 0 ||\n bytes > MAX_STATUS_LIST_BYTES\n ) {\n throw new StatusListError('out_of_range');\n }\n return new Uint8Array(bytes);\n}\n\nfunction checkIndex(bits: Uint8Array, idx: number, bitsPerEntry: number): void {\n if (\n !Number.isSafeInteger(idx) ||\n idx < 0 ||\n (idx + 1) * bitsPerEntry > bits.length * 8\n ) {\n throw new StatusListError('out_of_range');\n }\n}\n\n/** Set entry `idx` to INVALID (1), in place. Idempotent. */\nexport function setStatusBit(bits: Uint8Array, idx: number): void {\n checkIndex(bits, idx, 1);\n bits[idx >> 3] = bits[idx >> 3]! | (1 << (idx & 7));\n}\n\n/** The 1-bit entry at `idx` (0 VALID, 1 INVALID). */\nexport function getStatusBit(bits: Uint8Array, idx: number): 0 | 1 {\n checkIndex(bits, idx, 1);\n return ((bits[idx >> 3]! >> (idx & 7)) & 1) as 0 | 1;\n}\n\n/**\n * The status value at `idx` of a list with `bitsPerEntry` bits per entry (1, 2, 4 or 8;\n * default 1). Throws `out_of_range` for an index past the list.\n */\nexport function statusAt(\n bits: Uint8Array,\n idx: number,\n bitsPerEntry: 1 | 2 | 4 | 8 = 1\n): number {\n checkIndex(bits, idx, bitsPerEntry);\n const bit = idx * bitsPerEntry;\n return (bits[bit >> 3]! >> (bit & 7)) & ((1 << bitsPerEntry) - 1);\n}\n\n/**\n * A uniformly random index in `[0, size)` whose bit is 0 in `used`, a bitmap of indices\n * already handed out (same LSB-first layout; pass the issuer's allocation bitmap, not the\n * revocation bits, because a VALID entry is also 0 there). Random indices give herd privacy\n * (TSL §12.5). Throws `out_of_range` when every index is taken.\n */\nexport function randomFreeIndex(used: Uint8Array, size: number): number {\n if (!Number.isSafeInteger(size) || size <= 0 || size > used.length * 8) {\n throw new StatusListError('out_of_range');\n }\n const random = new Uint32Array(1);\n // Rejection sampling with a bounded number of tries, then a scan from a random start.\n for (let attempt = 0; attempt < 64; attempt++) {\n crypto.getRandomValues(random);\n const limit = Math.floor(0x1_0000_0000 / size) * size;\n if (random[0]! >= limit) continue;\n const idx = random[0]! % size;\n if (getStatusBit(used, idx) === 0) return idx;\n }\n crypto.getRandomValues(random);\n const start = random[0]! % size;\n for (let i = 0; i < size; i++) {\n const idx = (start + i) % size;\n if (getStatusBit(used, idx) === 0) return idx;\n }\n throw new StatusListError('out_of_range');\n}\n\n// ---------------------------------------------------------------------------------------------\n// Compression.\n\nasync function pipeThrough(\n bytes: Uint8Array,\n transform: CompressionStream | DecompressionStream,\n max: number\n): Promise<Uint8Array> {\n const reader = new Blob([bytes as Uint8Array<ArrayBuffer>])\n .stream()\n .pipeThrough(transform)\n .getReader();\n const chunks: Uint8Array[] = [];\n let size = 0;\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n size += value.byteLength;\n if (size > max) {\n await reader.cancel().catch(() => undefined);\n throw new StatusListError('too_large');\n }\n chunks.push(value);\n }\n const out = new Uint8Array(size);\n let at = 0;\n for (const c of chunks) {\n out.set(c, at);\n at += c.byteLength;\n }\n return out;\n}\n\n/** ZLIB (RFC 1950) DEFLATE, as the `lst` member requires. */\nexport function deflateStatusList(bytes: Uint8Array): Promise<Uint8Array> {\n return pipeThrough(\n bytes,\n new CompressionStream('deflate'),\n Number.MAX_SAFE_INTEGER\n );\n}\n\n/** ZLIB INFLATE, at most `max` output bytes (default `MAX_STATUS_LIST_BYTES`). */\nexport async function inflateStatusList(\n bytes: Uint8Array,\n max = MAX_STATUS_LIST_BYTES\n): Promise<Uint8Array> {\n try {\n return await pipeThrough(bytes, new DecompressionStream('deflate'), max);\n } catch (e) {\n if (e instanceof StatusListError) throw e;\n throw new StatusListError('malformed');\n }\n}\n\n// ---------------------------------------------------------------------------------------------\n// Issuer side.\n\nexport interface CreateStatusListTokenInput {\n /** The list bytes (1 bit per entry). */\n bits: Uint8Array;\n /** The list's public URI, exactly as credentials carry it in `status.status_list.uri`. */\n uri: string;\n /** The issuer DID. */\n iss: string;\n /** Signs with the issuer's assertionMethod key; `signer.kid` becomes the header `kid`. */\n signer: Signer;\n /** Seconds a verifier may cache the token. */\n ttl: number;\n /** Expiry, unix seconds. */\n exp: number;\n /** Issued at, unix seconds; default now. */\n iat?: number;\n}\n\n/** A signed `statuslist+jwt` (bits 1). */\nexport async function createStatusListToken(\n input: CreateStatusListTokenInput\n): Promise<string> {\n const iat = input.iat ?? toSeconds(Date.now());\n if (!Number.isSafeInteger(input.ttl) || input.ttl <= 0) {\n throw new StatusListError('malformed');\n }\n if (!Number.isSafeInteger(input.exp) || input.exp <= iat) {\n throw new StatusListError('malformed');\n }\n const lst = base64urlEncode(await deflateStatusList(input.bits));\n return signJws(\n { alg: 'EdDSA', typ: STATUS_LIST_TYP, kid: input.signer.kid },\n {\n sub: input.uri,\n iss: input.iss,\n iat,\n exp: input.exp,\n ttl: input.ttl,\n status_list: { bits: 1, lst },\n },\n input.signer\n );\n}\n\n// ---------------------------------------------------------------------------------------------\n// Verifier side.\n\nexport interface VerifyStatusListTokenOptions {\n /** The URI the credential points to; the token's `sub` must equal it exactly. */\n uri: string;\n /** The issuer's resolved DID document; the token must be signed by its assertionMethod key. */\n issuerDoc: DidDocument;\n /** ms since the epoch; default `Date.now()`. */\n now?: number;\n /**\n * Refuse a token issued before this (unix seconds), e.g. the `iat` of the newest token already\n * accepted for this URI (`rolled_back`).\n */\n minIat?: number;\n}\n\nexport interface VerifiedStatusList {\n /** The inflated list bytes. */\n bits: Uint8Array;\n /** Bits per entry (1, 2, 4 or 8); pass to `statusAt`. */\n bitsPerEntry: 1 | 2 | 4 | 8;\n ttl: number | null;\n exp: number | null;\n iat: number;\n /** The header `kid` that verified. */\n kid: string;\n}\n\n/**\n * Verify a `statuslist+jwt` for `uri` issued by `issuerDoc.id`: typ, Ed25519 signature (`alg`\n * `EdDSA` or `Ed25519`) by the issuer's assertionMethod key named by `kid`, `sub` = `uri`, `iss`\n * (when present) = the issuer, `iat` present (and ≥ `minIat`), `exp` not past and `nbf` not in\n * the future (2 min skew), `bits` ∈ {1,2,4,8}, `lst` inflates within the cap. Throws\n * `StatusListError`.\n */\nexport async function verifyStatusListToken(\n token: string,\n opts: VerifyStatusListTokenOptions\n): Promise<VerifiedStatusList> {\n if (\n typeof token !== 'string' ||\n token.length > MAX_STATUS_LIST_TOKEN_LENGTH\n ) {\n throw new StatusListError('too_large');\n }\n let jws;\n try {\n jws = decodeJws(token.trim());\n } catch (e) {\n if (e instanceof JoseError) throw new StatusListError('malformed');\n throw e;\n }\n const { header, payload } = jws;\n if (header.typ !== STATUS_LIST_TYP) throw new StatusListError('wrong_type');\n if (!isEd25519JwsAlg(header.alg)) throw new StatusListError('bad_signature');\n const kid = typeof header.kid === 'string' ? header.kid : '';\n const key = findKey(opts.issuerDoc, kid, 'assertionMethod');\n if (!key) throw new StatusListError('issuer_key_unpublished');\n if (!verifyEd25519(jws.signature, utf8(jws.signingInput), key.publicKey)) {\n throw new StatusListError('bad_signature');\n }\n if (payload.sub !== opts.uri) throw new StatusListError('wrong_subject');\n if (payload.iss !== undefined && payload.iss !== opts.issuerDoc.id) {\n throw new StatusListError('wrong_issuer');\n }\n const iat = payload.iat;\n if (typeof iat !== 'number' || !Number.isFinite(iat)) {\n throw new StatusListError('malformed');\n }\n if (opts.minIat !== undefined && iat < opts.minIat) {\n throw new StatusListError('rolled_back');\n }\n const nowS = toSeconds(clockMs(opts.now));\n const nbf = payload.nbf;\n if (nbf !== undefined) {\n if (typeof nbf !== 'number' || !Number.isFinite(nbf))\n throw new StatusListError('malformed');\n if (nowS + CLOCK_SKEW_S < nbf) throw new StatusListError('not_yet_valid');\n }\n const exp = payload.exp;\n if (exp !== undefined && (typeof exp !== 'number' || !Number.isFinite(exp))) {\n throw new StatusListError('malformed');\n }\n if (typeof exp === 'number' && nowS > exp + CLOCK_SKEW_S) {\n throw new StatusListError('expired');\n }\n const ttl = payload.ttl;\n if (ttl !== undefined && (typeof ttl !== 'number' || !(ttl > 0))) {\n throw new StatusListError('malformed');\n }\n const list = payload.status_list;\n if (!isRecord(list) || typeof list.lst !== 'string') {\n throw new StatusListError('malformed');\n }\n const bitsPerEntry = list.bits;\n if (\n bitsPerEntry !== 1 &&\n bitsPerEntry !== 2 &&\n bitsPerEntry !== 4 &&\n bitsPerEntry !== 8\n ) {\n throw new StatusListError('malformed');\n }\n let compressed: Uint8Array;\n try {\n compressed = base64urlDecode(list.lst);\n } catch {\n throw new StatusListError('malformed');\n }\n const bits = await inflateStatusList(compressed);\n return {\n bits,\n bitsPerEntry,\n ttl: typeof ttl === 'number' ? ttl : null,\n exp: typeof exp === 'number' ? exp : null,\n iat,\n kid: key.id,\n };\n}\n"]}