{"version":3,"file":"issuer.mjs","names":["widened: string[]"],"sources":["../../src/zcap/issuer.ts"],"sourcesContent":["/** ZCAP-LD issuer: mint root + delegate. */\n\nimport { Capability, type KeyMaterial } from './model'\nimport { isNonDelegable, type Caveat } from './caveats'\nimport { signCapability } from './proofs'\n\nexport class InvalidDelegationError extends Error {\n  public constructor(message: string) {\n    super(message)\n    this.name = 'InvalidDelegationError'\n  }\n}\n\n/**\n * Mint the root capability for a new vault/resource. Root's controller\n * is the issuer themselves (the vault host). Proof is self-issued.\n */\nexport function mintRoot({\n  invocationTarget,\n  controller,\n  signingKey,\n  allowedAction,\n  expires,\n  caveats = [],\n}: {\n  invocationTarget: string\n  controller: string\n  signingKey: KeyMaterial\n  allowedAction: string[]\n  expires?: string\n  caveats?: Caveat[]\n}): Capability {\n  if (!signingKey.privateKeyBytes) {\n    throw new InvalidDelegationError('mintRoot requires a signing key with privateKeyBytes')\n  }\n  const cap = new Capability({\n    id: `urn:zcap:${randomUuid()}`,\n    controller,\n    invocationTarget,\n    allowedAction: [...allowedAction],\n    expires,\n    caveat: caveats.map((c) => c.toDict()),\n  })\n  cap.proof = signCapability({\n    capabilityDict: cap.toDict(),\n    privateKeyBytes: signingKey.privateKeyBytes,\n    verificationMethod: signingKey.verificationMethod,\n    proofPurpose: 'capabilityDelegation',\n  })\n  return cap\n}\n\n/**\n * Delegate a sub-capability from `parent` to `toController`.\n *\n * Rules (enforced):\n *   * Parent MUST NOT carry NonDelegable.\n *   * `allowedAction` MUST be a subset of parent's allowedAction.\n *   * Expiry MUST NOT extend beyond parent's expiry.\n *   * Caveats stack — child carries parent caveats + new ones.\n *\n * The signing key MUST be the delegator's (parent's controller).\n */\nexport function delegate({\n  parent,\n  toController,\n  signingKey,\n  allowedAction,\n  expires,\n  addCaveats = [],\n}: {\n  parent: Capability\n  toController: string\n  signingKey: KeyMaterial\n  allowedAction?: string[]\n  expires?: string\n  addCaveats?: Caveat[]\n}): Capability {\n  if (parent.caveat.some(isNonDelegable)) {\n    throw new InvalidDelegationError(`parent capability ${parent.id} is NonDelegable; refusing`)\n  }\n\n  const parentActions = new Set(parent.allowedAction)\n  const nextActions = new Set(allowedAction ?? parent.allowedAction)\n  const widened: string[] = []\n  for (const a of nextActions) if (!parentActions.has(a)) widened.push(a)\n  if (widened.length > 0) {\n    throw new InvalidDelegationError(\n      `delegation widens allowedAction; new ${JSON.stringify(widened.sort())} not in parent ${JSON.stringify([...parentActions].sort())}`\n    )\n  }\n\n  const nextExpires = expires ?? parent.expires\n  if (expires && parent.expires && expires > parent.expires) {\n    throw new InvalidDelegationError(\n      `delegation extends expiry beyond parent (${expires} > ${parent.expires})`\n    )\n  }\n\n  const newCaveats = [...parent.caveat]\n  for (const c of addCaveats) newCaveats.push(c.toDict())\n\n  if (!signingKey.privateKeyBytes) {\n    throw new InvalidDelegationError('delegate requires a signing key with privateKeyBytes')\n  }\n\n  const cap = new Capability({\n    id: `urn:zcap:${randomUuid()}`,\n    controller: toController,\n    invocationTarget: parent.invocationTarget,\n    parentCapability: parent.id,\n    allowedAction: [...nextActions].sort(),\n    expires: nextExpires,\n    caveat: newCaveats,\n  })\n  cap.proof = signCapability({\n    capabilityDict: cap.toDict(),\n    privateKeyBytes: signingKey.privateKeyBytes,\n    verificationMethod: signingKey.verificationMethod,\n    proofPurpose: 'capabilityDelegation',\n  })\n  return cap\n}\n\nfunction randomUuid(): string {\n  // Web Crypto's randomUUID is available in Node 19+ / modern browsers\n  // / RN (with polyfill). Falls back to a hand-rolled v4 using\n  // getRandomValues so we don't pull in another dep.\n  const c = (globalThis as { crypto?: { randomUUID?: () => string; getRandomValues?: (a: Uint8Array) => Uint8Array } }).crypto\n  if (c?.randomUUID) return c.randomUUID()\n  if (!c?.getRandomValues) throw new Error('no Web Crypto API for randomUUID')\n  const bytes = new Uint8Array(16)\n  c.getRandomValues(bytes)\n  bytes[6] = (bytes[6] & 0x0f) | 0x40\n  bytes[8] = (bytes[8] & 0x3f) | 0x80\n  const h = (n: number) => n.toString(16).padStart(2, '0')\n  return (\n    [...bytes].slice(0, 4).map(h).join('') +\n    '-' +\n    [...bytes].slice(4, 6).map(h).join('') +\n    '-' +\n    [...bytes].slice(6, 8).map(h).join('') +\n    '-' +\n    [...bytes].slice(8, 10).map(h).join('') +\n    '-' +\n    [...bytes].slice(10).map(h).join('')\n  )\n}\n"],"mappings":"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"}