{"version":3,"file":"KeyService.mjs","names":["KeyService","bindings: OpenBadgesKeyBindingRepository","contexts: ContextService","jwk: any"],"sources":["../../src/services/KeyService.ts"],"sourcesContent":["import type { AgentContext } from '@credo-ts/core'\nimport { injectable, inject, Kms, Hasher, TypedArrayEncoder } from '@credo-ts/core'\nimport { OpenBadgesKeyBindingRepository } from '../repository/OpenBadgesKeyBindingRepository'\nimport { OpenBadgesKeyBindingRecord } from '../repository/OpenBadgesKeyBindingRecord'\nimport { ContextService } from './ContextService'\nimport bs58 from 'bs58'\n\n/**\n * Local key type enum (replaces credo-ts 0.5 KeyType)\n */\nexport enum KeyType {\n  Ed25519 = 'ed25519',\n  P256 = 'p256',\n  P384 = 'p384',\n}\n\n/**\n * Lightweight reference to a public key used internally (replaces 0.5 Key class)\n */\nexport interface OpenBadgesKey {\n  publicKey: Uint8Array\n  keyType: KeyType\n  kmsKeyId?: string\n}\n\nfunction keyTypeToAlgorithm(keyType: KeyType): Kms.KnownJwaSignatureAlgorithm {\n  switch (keyType) {\n    case KeyType.Ed25519:\n      return 'EdDSA'\n    case KeyType.P256:\n      return 'ES256'\n    case KeyType.P384:\n      return 'ES384'\n  }\n}\n\nfunction extractRawPublicKey(publicJwk: Kms.PublicJwk): Uint8Array {\n  const pk = publicJwk.publicKey as unknown as { publicKey: Uint8Array }\n  return pk.publicKey\n}\n\n/**\n * Supported DID methods for key binding\n */\nexport type SupportedDidMethod = 'did:web' | 'did:key' | 'did:jwk'\n\n/**\n * Options for ensuring a key binding\n */\nexport interface EnsureBindingOptions {\n  controller: string\n  vmId: string\n  keyType?: KeyType\n  didMethod?: SupportedDidMethod\n}\n\n/**\n * Multicodec prefixes for different key types\n * @see https://github.com/multiformats/multicodec/blob/master/table.csv\n */\nconst MULTICODEC_ED25519_PUB = Buffer.from([0xed, 0x01])\nconst MULTICODEC_P256_PUB = Buffer.from([0x80, 0x24])\nconst MULTICODEC_P384_PUB = Buffer.from([0x81, 0x24])\n\n@injectable()\nexport class KeyService {\n  public constructor(\n    @inject(OpenBadgesKeyBindingRepository) private readonly bindings: OpenBadgesKeyBindingRepository,\n    @inject(ContextService) private readonly contexts: ContextService\n  ) {}\n\n  private bindingId(vmId: string) {\n    // Use Credo's cross-platform Hasher instead of Node's crypto\n    const hashBytes = Hasher.hash(TypedArrayEncoder.fromString(vmId), 'sha-256')\n    const hash = TypedArrayEncoder.toHex(hashBytes)\n    return `vm_${hash}`\n  }\n\n  /**\n   * Get the multicodec prefix for a key type\n   */\n  private getMulticodecPrefix(keyType: KeyType): Buffer {\n    switch (keyType) {\n      case KeyType.Ed25519:\n        return MULTICODEC_ED25519_PUB\n      case KeyType.P256:\n        return MULTICODEC_P256_PUB\n      case KeyType.P384:\n        return MULTICODEC_P384_PUB\n      default:\n        return MULTICODEC_ED25519_PUB\n    }\n  }\n\n  /**\n   * Get the verification method type for a key type\n   */\n  private getVerificationMethodType(keyType: KeyType): string {\n    switch (keyType) {\n      case KeyType.Ed25519:\n        return 'Ed25519VerificationKey2020'\n      case KeyType.P256:\n      case KeyType.P384:\n        return 'JsonWebKey2020'\n      default:\n        return 'Multikey'\n    }\n  }\n\n  /**\n   * Generate a did:key DID from public key material\n   */\n  public generateDidKey(publicKey: Buffer, keyType: KeyType): { did: string; vmId: string } {\n    const prefix = this.getMulticodecPrefix(keyType)\n    const withHeader = Buffer.concat([prefix, publicKey])\n    const fingerprint = 'z' + bs58.encode(withHeader)\n    const did = `did:key:${fingerprint}`\n    const vmId = `${did}#${fingerprint}`\n    return { did, vmId }\n  }\n\n  /**\n   * Generate a did:jwk DID from public key material\n   */\n  public generateDidJwk(publicKey: Buffer, keyType: KeyType): { did: string; vmId: string } {\n    let jwk: any\n    if (keyType === KeyType.Ed25519) {\n      jwk = {\n        kty: 'OKP',\n        crv: 'Ed25519',\n        x: publicKey.toString('base64url'),\n      }\n    } else if (keyType === KeyType.P256) {\n      // P-256 public keys are 65 bytes (uncompressed) or 33 bytes (compressed)\n      // Uncompressed format: 0x04 || x || y\n      if (publicKey.length === 65 && publicKey[0] === 0x04) {\n        const x = publicKey.slice(1, 33)\n        const y = publicKey.slice(33, 65)\n        jwk = {\n          kty: 'EC',\n          crv: 'P-256',\n          x: x.toString('base64url'),\n          y: y.toString('base64url'),\n        }\n      } else {\n        throw new Error('P-256 key must be in uncompressed format (65 bytes starting with 0x04)')\n      }\n    } else if (keyType === KeyType.P384) {\n      if (publicKey.length === 97 && publicKey[0] === 0x04) {\n        const x = publicKey.slice(1, 49)\n        const y = publicKey.slice(49, 97)\n        jwk = {\n          kty: 'EC',\n          crv: 'P-384',\n          x: x.toString('base64url'),\n          y: y.toString('base64url'),\n        }\n      } else {\n        throw new Error('P-384 key must be in uncompressed format (97 bytes starting with 0x04)')\n      }\n    } else {\n      throw new Error(`Unsupported key type for did:jwk: ${keyType}`)\n    }\n\n    const jwkJson = JSON.stringify(jwk)\n    const jwkBase64url = Buffer.from(jwkJson).toString('base64url')\n    const did = `did:jwk:${jwkBase64url}`\n    const vmId = `${did}#0`\n    return { did, vmId }\n  }\n\n  /**\n   * Parse a did:key to extract public key bytes and determine key type\n   */\n  public parseDidKey(did: string): { publicKey: Buffer; keyType: KeyType } | null {\n    if (!did.startsWith('did:key:z')) return null\n    const fingerprint = did.replace('did:key:', '').split('#')[0]\n    if (!fingerprint.startsWith('z')) return null\n\n    const decoded = Buffer.from(bs58.decode(fingerprint.slice(1)))\n\n    // Check multicodec prefix\n    if (decoded.length > 2 && decoded[0] === 0xed && decoded[1] === 0x01) {\n      return { publicKey: decoded.slice(2), keyType: KeyType.Ed25519 }\n    } else if (decoded.length > 2 && decoded[0] === 0x80 && decoded[1] === 0x24) {\n      return { publicKey: decoded.slice(2), keyType: KeyType.P256 }\n    } else if (decoded.length > 2 && decoded[0] === 0x81 && decoded[1] === 0x24) {\n      return { publicKey: decoded.slice(2), keyType: KeyType.P384 }\n    }\n\n    return null\n  }\n\n  /**\n   * Parse a did:jwk to extract the JWK and determine key type\n   */\n  public parseDidJwk(did: string): { jwk: any; keyType: KeyType } | null {\n    if (!did.startsWith('did:jwk:')) return null\n    const encoded = did.replace('did:jwk:', '').split('#')[0]\n\n    try {\n      const jwkJson = Buffer.from(encoded, 'base64url').toString()\n      const jwk = JSON.parse(jwkJson)\n\n      if (jwk.kty === 'OKP' && jwk.crv === 'Ed25519') {\n        return { jwk, keyType: KeyType.Ed25519 }\n      } else if (jwk.kty === 'EC' && jwk.crv === 'P-256') {\n        return { jwk, keyType: KeyType.P256 }\n      } else if (jwk.kty === 'EC' && jwk.crv === 'P-384') {\n        return { jwk, keyType: KeyType.P384 }\n      }\n    } catch {\n      return null\n    }\n\n    return null\n  }\n\n  /**\n   * Ensure a KMS-backed key exists and is bound to a verificationMethod id\n   * Supports Ed25519, P-256, and P-384 key types\n   * Supports did:web, did:key, and did:jwk DID methods\n   */\n  public async ensureBinding(agentContext: AgentContext, opts: EnsureBindingOptions) {\n    const logger = agentContext.config.logger\n    const keyType = opts.keyType ?? KeyType.Ed25519\n    const didMethod = opts.didMethod ?? 'did:web'\n\n    logger.debug('[OB][KeyService] ensureBinding', { vmId: opts.vmId, controller: opts.controller, keyType, didMethod })\n    const id = this.bindingId(opts.vmId)\n    const existing = await this.bindings.getById(agentContext, id).catch((e) => {\n      logger.warn('[OB][KeyService] getById error (will treat as no binding)', { error: (e as any)?.message || String(e) })\n      return null\n    })\n    if (existing) {\n      logger.debug('[OB][KeyService] binding exists', { vmId: opts.vmId })\n      return existing\n    }\n\n    // Create key via KMS with specified key type\n    const algorithm = keyTypeToAlgorithm(keyType)\n    const kms = agentContext.dependencyManager.resolve(Kms.KeyManagementApi)\n    const created = await kms.createKeyForSignatureAlgorithm({ algorithm })\n    const publicJwk = Kms.PublicJwk.fromPublicJwk(\n      created.publicJwk as Parameters<typeof Kms.PublicJwk.fromPublicJwk>[0]\n    )\n    const raw = Buffer.from(extractRawPublicKey(publicJwk))\n    logger.debug('[OB][KeyService] created KMS key', { keyType, publicKeyLength: raw.length })\n\n    // Derive multibase public key\n    const prefix = this.getMulticodecPrefix(keyType)\n    const withHeader = Buffer.concat([prefix, raw])\n    const publicKeyMultibase = 'z' + bs58.encode(withHeader)\n\n    // Clean up any legacy record saved under raw vmId\n    try {\n      await this.bindings.deleteById(agentContext, opts.vmId)\n      logger.debug('[OB][KeyService] deleted legacy binding with raw id', { vmId: opts.vmId })\n    } catch {}\n\n    const rec = new OpenBadgesKeyBindingRecord({\n      id,\n      controller: opts.controller,\n      vmId: opts.vmId,\n      publicKeyMultibase,\n      kmsKeyId: created.keyId,\n      algorithm,\n    })\n    logger.debug('[OB][KeyService] saving binding', { vmId: opts.vmId })\n    try {\n      await this.bindings.save(agentContext, rec)\n    } catch (e) {\n      logger.warn('[OB][KeyService] save binding failed (duplicate?)', { error: (e as any)?.message || String(e) })\n      // Try to load existing (raw id) binding for backward compatibility\n      const existingRaw = await this.bindings.getById(agentContext, opts.vmId).catch(() => null)\n      if (existingRaw) return existingRaw\n    }\n    this.seedVerificationMethodDocument({ controller: opts.controller, keyId: opts.vmId, publicKeyMultibase })\n    return rec\n  }\n\n  public async getBindingByVm(agentContext: AgentContext, vmId: string) {\n    const logger = agentContext.config.logger\n    logger.trace('[OB][KeyService] getBindingByVm', { vmId })\n    const id = this.bindingId(vmId)\n    try {\n      return await this.bindings.getById(agentContext, id)\n    } catch (e) {\n      logger.trace('[OB][KeyService] getBindingByVm hashed id miss; trying raw id', { error: (e as any)?.message || String(e) })\n      try {\n        return await this.bindings.getById(agentContext, vmId)\n      } catch (e2) {\n        logger.trace('[OB][KeyService] getBindingByVm raw id miss; trying getAll', { error: (e2 as any)?.message || String(e2) })\n        try {\n          const all = await this.bindings.getAll(agentContext)\n          const match = (all as any[]).find((b) => b.vmId === vmId)\n          return match ?? null\n        } catch (e3) {\n          logger.warn('[OB][KeyService] getBindingByVm getAll failed', { error: (e3 as any)?.message || String(e3) })\n          return null\n        }\n      }\n    }\n  }\n\n  public async getPublicJwkByVm(agentContext: AgentContext, vmId: string) {\n    const logger = agentContext.config.logger\n    const binding = await this.getBindingByVm(agentContext, vmId).catch((e) => {\n      logger.warn('[OB][KeyService] getPublicJwkByVm binding lookup failed', { error: (e as any)?.message || String(e) })\n      return null\n    })\n    if (!binding) return null\n    // derive jwk from multibase with key type detection\n    const b58 = binding.publicKeyMultibase.startsWith('z') ? binding.publicKeyMultibase.slice(1) : binding.publicKeyMultibase\n    const decoded = Buffer.from(bs58.decode(b58))\n\n    // Detect key type from multicodec prefix\n    if (decoded.length > 2 && decoded[0] === 0xed && decoded[1] === 0x01) {\n      // Ed25519\n      const raw = decoded.slice(2)\n      return { kty: 'OKP', crv: 'Ed25519', x: raw.toString('base64url') }\n    } else if (decoded.length > 2 && decoded[0] === 0x80 && decoded[1] === 0x24) {\n      // P-256 (uncompressed)\n      const raw = decoded.slice(2)\n      if (raw.length === 65 && raw[0] === 0x04) {\n        return {\n          kty: 'EC',\n          crv: 'P-256',\n          x: raw.slice(1, 33).toString('base64url'),\n          y: raw.slice(33, 65).toString('base64url'),\n        }\n      }\n    } else if (decoded.length > 2 && decoded[0] === 0x81 && decoded[1] === 0x24) {\n      // P-384 (uncompressed)\n      const raw = decoded.slice(2)\n      if (raw.length === 97 && raw[0] === 0x04) {\n        return {\n          kty: 'EC',\n          crv: 'P-384',\n          x: raw.slice(1, 49).toString('base64url'),\n          y: raw.slice(49, 97).toString('base64url'),\n        }\n      }\n    }\n\n    // Fallback for unknown format - try as Ed25519\n    const raw = decoded.length > 2 ? decoded.slice(2) : decoded\n    return { kty: 'OKP', crv: 'Ed25519', x: raw.toString('base64url') }\n  }\n\n  public async getKeyForVm(agentContext: AgentContext, vmId: string): Promise<OpenBadgesKey | null> {\n    const logger = agentContext.config.logger\n    const binding = await this.getBindingByVm(agentContext, vmId).catch((e) => {\n      logger.warn('[OB][KeyService] getKeyForVm binding lookup failed', { error: (e as any)?.message || String(e) })\n      return null\n    })\n    if (!binding) return null\n    // Reconstruct a Key from the stored public key bytes with key type detection\n    const b58 = binding.publicKeyMultibase.startsWith('z') ? binding.publicKeyMultibase.slice(1) : binding.publicKeyMultibase\n    const decoded = Buffer.from(bs58.decode(b58))\n    const kmsKeyId = binding.kmsKeyId\n\n    // Detect key type from multicodec prefix\n    if (decoded.length > 2 && decoded[0] === 0xed && decoded[1] === 0x01) {\n      // Ed25519\n      return { publicKey: decoded.slice(2), keyType: KeyType.Ed25519, kmsKeyId }\n    } else if (decoded.length > 2 && decoded[0] === 0x80 && decoded[1] === 0x24) {\n      // P-256\n      return { publicKey: decoded.slice(2), keyType: KeyType.P256, kmsKeyId }\n    } else if (decoded.length > 2 && decoded[0] === 0x81 && decoded[1] === 0x24) {\n      // P-384\n      return { publicKey: decoded.slice(2), keyType: KeyType.P384, kmsKeyId }\n    }\n\n    // Fallback to Ed25519 for unknown format\n    return { publicKey: decoded, keyType: KeyType.Ed25519, kmsKeyId }\n  }\n\n  private seedVerificationMethodDocument(key: {\n    controller: string\n    keyId: string\n    publicKeyMultibase: string\n    keyType?: KeyType\n  }) {\n    const vmType = this.getVerificationMethodType(key.keyType ?? KeyType.Ed25519)\n    const vmDoc = {\n      id: key.keyId,\n      type: vmType,\n      controller: key.controller,\n      publicKeyMultibase: key.publicKeyMultibase,\n    }\n    this.contexts.addCached(key.keyId, vmDoc)\n    // Also seed a minimal DID Document for the controller with the VM\n    const didDoc = {\n      '@context': 'https://www.w3.org/ns/did/v1',\n      id: key.controller,\n      verificationMethod: [vmDoc],\n      assertionMethod: [key.keyId],\n    }\n    this.contexts.addCached(key.controller, didDoc)\n  }\n\n  /**\n   * Create a new key binding with a did:key DID\n   * Returns the generated DID and verification method ID\n   */\n  public async createDidKeyBinding(\n    agentContext: AgentContext,\n    keyType: KeyType = KeyType.Ed25519\n  ): Promise<{ did: string; vmId: string; publicKeyMultibase: string }> {\n    const algorithm = keyTypeToAlgorithm(keyType)\n    const kms = agentContext.dependencyManager.resolve(Kms.KeyManagementApi)\n    const created = await kms.createKeyForSignatureAlgorithm({ algorithm })\n    const publicJwk = Kms.PublicJwk.fromPublicJwk(\n      created.publicJwk as Parameters<typeof Kms.PublicJwk.fromPublicJwk>[0]\n    )\n    const rawPub = Buffer.from(extractRawPublicKey(publicJwk))\n    const { did, vmId } = this.generateDidKey(rawPub, keyType)\n\n    const prefix = this.getMulticodecPrefix(keyType)\n    const withHeader = Buffer.concat([prefix, rawPub])\n    const publicKeyMultibase = 'z' + bs58.encode(withHeader)\n\n    const id = this.bindingId(vmId)\n    const rec = new OpenBadgesKeyBindingRecord({\n      id,\n      controller: did,\n      vmId,\n      publicKeyMultibase,\n      kmsKeyId: created.keyId,\n      algorithm,\n    })\n\n    await this.bindings.save(agentContext, rec)\n    this.seedVerificationMethodDocument({ controller: did, keyId: vmId, publicKeyMultibase, keyType })\n\n    agentContext.config.logger.debug('[OB][KeyService] created did:key binding', { did })\n    return { did, vmId, publicKeyMultibase }\n  }\n\n  /**\n   * Create a new key binding with a did:jwk DID\n   * Returns the generated DID and verification method ID\n   */\n  public async createDidJwkBinding(\n    agentContext: AgentContext,\n    keyType: KeyType = KeyType.Ed25519\n  ): Promise<{ did: string; vmId: string; publicKeyMultibase: string }> {\n    const algorithm = keyTypeToAlgorithm(keyType)\n    const kms = agentContext.dependencyManager.resolve(Kms.KeyManagementApi)\n    const created = await kms.createKeyForSignatureAlgorithm({ algorithm })\n    const publicJwk = Kms.PublicJwk.fromPublicJwk(\n      created.publicJwk as Parameters<typeof Kms.PublicJwk.fromPublicJwk>[0]\n    )\n    const rawPub = Buffer.from(extractRawPublicKey(publicJwk))\n    const { did, vmId } = this.generateDidJwk(rawPub, keyType)\n\n    const prefix = this.getMulticodecPrefix(keyType)\n    const withHeader = Buffer.concat([prefix, rawPub])\n    const publicKeyMultibase = 'z' + bs58.encode(withHeader)\n\n    const id = this.bindingId(vmId)\n    const rec = new OpenBadgesKeyBindingRecord({\n      id,\n      controller: did,\n      vmId,\n      publicKeyMultibase,\n      kmsKeyId: created.keyId,\n      algorithm,\n    })\n\n    await this.bindings.save(agentContext, rec)\n    this.seedVerificationMethodDocument({ controller: did, keyId: vmId, publicKeyMultibase, keyType })\n\n    agentContext.config.logger.debug('[OB][KeyService] created did:jwk binding', { did })\n    return { did, vmId, publicKeyMultibase }\n  }\n\n  /**\n   * Get a JWK for a did:key or did:jwk DID\n   */\n  public getJwkForDid(did: string): any | null {\n    // Try did:key\n    const didKeyParsed = this.parseDidKey(did)\n    if (didKeyParsed) {\n      const { publicKey, keyType } = didKeyParsed\n      if (keyType === KeyType.Ed25519) {\n        return {\n          kty: 'OKP',\n          crv: 'Ed25519',\n          x: publicKey.toString('base64url'),\n        }\n      } else if (keyType === KeyType.P256 && publicKey.length === 65 && publicKey[0] === 0x04) {\n        return {\n          kty: 'EC',\n          crv: 'P-256',\n          x: publicKey.slice(1, 33).toString('base64url'),\n          y: publicKey.slice(33, 65).toString('base64url'),\n        }\n      } else if (keyType === KeyType.P384 && publicKey.length === 97 && publicKey[0] === 0x04) {\n        return {\n          kty: 'EC',\n          crv: 'P-384',\n          x: publicKey.slice(1, 49).toString('base64url'),\n          y: publicKey.slice(49, 97).toString('base64url'),\n        }\n      }\n    }\n\n    // Try did:jwk\n    const didJwkParsed = this.parseDidJwk(did)\n    if (didJwkParsed) {\n      return didJwkParsed.jwk\n    }\n\n    return null\n  }\n}\n"],"mappings":"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"}