{"version":3,"file":"index.mjs","names":["lookup: { kid: string; publicKey: Uint8Array }"],"sources":["../../src/recipient/index.ts"],"sourcesContent":["/**\n * Recipient resolution for both sides of the JWE wire.\n *\n * Signer side (decrypt): given a received JWE, walk `recipients[]`\n * and pull the first X25519 private key the wallet actually holds.\n *\n * Operator side (encrypt): given a connection id, resolve the peer's\n * X25519 KeyAgreement public key into a `Recipient` ready for\n * `encrypt()`.\n *\n * Both functions are wallet-implementation agnostic — callers pass\n * async callbacks that bridge to Credo's wallet APIs.\n */\n\nimport { ALG_ECDH_ES, type JweGeneralJson, type Recipient } from '../jwe'\n\nexport class RecipientNotInWallet extends Error {\n  public constructor(message: string) {\n    super(message)\n    this.name = 'RecipientNotInWallet'\n  }\n}\n\nexport class PeerKeyLookupFailed extends Error {\n  public constructor(message: string) {\n    super(message)\n    this.name = 'PeerKeyLookupFailed'\n  }\n}\n\n/** `(kid) -> 32-byte X25519 priv` or `null` if the wallet doesn't hold it. */\nexport type WalletPrivLookup = (kid: string) => Promise<Uint8Array | null | undefined>\n\n/** `(connection_id) -> (kid, 32-byte X25519 pub)` for the peer. */\nexport type PeerPubLookup = (connectionId: string) => Promise<{ kid: string; publicKey: Uint8Array }>\n\n/**\n * Walk `jwe.recipients[]` for a key the wallet holds. First match\n * wins — multi-recipient JWEs can address the same wallet under\n * multiple kids (key rotation, did:peer rotation) and any match\n * decrypts the same CEK because the bulk body is shared.\n */\nexport async function findDecryptionKey(args: {\n  jwe: JweGeneralJson\n  walletLookup: WalletPrivLookup\n}): Promise<{ kid: string; privateKey: Uint8Array }> {\n  const recipients = args.jwe.recipients ?? []\n  for (const entry of recipients) {\n    if (typeof entry !== 'object' || entry === null) continue\n    const kid = (entry.header as Record<string, unknown> | undefined)?.kid as string | undefined\n    if (!kid) continue\n    const priv = await args.walletLookup(kid)\n    if (priv && priv.length > 0) return { kid, privateKey: priv }\n  }\n  throw new RecipientNotInWallet('no JWE recipient matches a key in this wallet')\n}\n\n/**\n * Resolve the peer's static X25519 KeyAgreement key into a\n * `Recipient`. The peer's pub key was published in their DID Document\n * at connection setup; we just look it up.\n *\n * Defaults to `alg: ECDH-ES`. Pass `alg` to use pq-hybrid later.\n */\nexport async function resolveRecipientForConnection(args: {\n  connectionId: string\n  peerLookup: PeerPubLookup\n  alg?: string\n}): Promise<Recipient> {\n  let lookup: { kid: string; publicKey: Uint8Array }\n  try {\n    lookup = await args.peerLookup(args.connectionId)\n  } catch (err) {\n    throw new PeerKeyLookupFailed(\n      `could not resolve peer key for connection ${args.connectionId}: ${(err as Error).message}`\n    )\n  }\n  if (!lookup?.kid || !lookup?.publicKey?.length) {\n    throw new PeerKeyLookupFailed(`peerLookup returned empty kid/pub for ${args.connectionId}`)\n  }\n  const alg = args.alg ?? ALG_ECDH_ES\n  if (alg === ALG_ECDH_ES && lookup.publicKey.length !== 32) {\n    // Defensive: ECDH-ES expects raw 32-byte X25519. A 1184-byte\n    // ML-KEM blob means the lookup gave us a pq-hybrid pub by\n    // accident — silent JWE corruption would follow.\n    throw new PeerKeyLookupFailed(\n      `ECDH-ES requires 32-byte X25519 pub; got ${lookup.publicKey.length} bytes (pq-hybrid leak?)`\n    )\n  }\n  return { kid: lookup.kid, publicKey: lookup.publicKey, alg }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAgBA,IAAa,uBAAb,cAA0C,MAAM;CAC9C,AAAO,YAAY,SAAiB;AAClC,QAAM,QAAQ;AACd,OAAK,OAAO;;;AAIhB,IAAa,sBAAb,cAAyC,MAAM;CAC7C,AAAO,YAAY,SAAiB;AAClC,QAAM,QAAQ;AACd,OAAK,OAAO;;;;;;;;;AAgBhB,eAAsB,kBAAkB,MAGa;CACnD,MAAM,aAAa,KAAK,IAAI,cAAc,EAAE;AAC5C,MAAK,MAAM,SAAS,YAAY;AAC9B,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM;EACjD,MAAM,MAAO,MAAM,QAAgD;AACnE,MAAI,CAAC,IAAK;EACV,MAAM,OAAO,MAAM,KAAK,aAAa,IAAI;AACzC,MAAI,QAAQ,KAAK,SAAS,EAAG,QAAO;GAAE;GAAK,YAAY;GAAM;;AAE/D,OAAM,IAAI,qBAAqB,gDAAgD;;;;;;;;;AAUjF,eAAsB,8BAA8B,MAI7B;CACrB,IAAIA;AACJ,KAAI;AACF,WAAS,MAAM,KAAK,WAAW,KAAK,aAAa;UAC1C,KAAK;AACZ,QAAM,IAAI,oBACR,6CAA6C,KAAK,aAAa,IAAK,IAAc,UACnF;;AAEH,KAAI,CAAC,QAAQ,OAAO,CAAC,QAAQ,WAAW,OACtC,OAAM,IAAI,oBAAoB,yCAAyC,KAAK,eAAe;CAE7F,MAAM,MAAM,KAAK,OAAO;AACxB,KAAI,QAAQ,eAAe,OAAO,UAAU,WAAW,GAIrD,OAAM,IAAI,oBACR,4CAA4C,OAAO,UAAU,OAAO,0BACrE;AAEH,QAAO;EAAE,KAAK,OAAO;EAAK,WAAW,OAAO;EAAW;EAAK"}