{"version":3,"file":"DataIntegrityService.mjs","names":["DataIntegrityService","contextService: ContextService","keyService: KeyService","e: unknown"],"sources":["../../src/services/DataIntegrityService.ts"],"sourcesContent":["import type { AgentContext } from '@credo-ts/core'\nimport { injectable, inject, Kms } from '@credo-ts/core'\nimport { ContextService } from './ContextService'\nimport { KeyService } from './KeyService'\nimport { DI_EDDSA_RDFC_2022 } from '../constants'\nimport { EddsaRdfc2022Cryptosuite, type EddsaRdfc2022Proof } from '../cryptosuites/EddsaRdfc2022'\n\n/**\n * DataIntegrityService\n *\n * Handles signing and verification of credentials using the eddsa-rdfc-2022 cryptosuite.\n * This produces DataIntegrityProof proofs compatible with Credly and other OBv3 issuers.\n */\n@injectable()\nexport class DataIntegrityService {\n  private readonly eddsaRdfc2022 = new EddsaRdfc2022Cryptosuite()\n\n  public constructor(\n    @inject(ContextService) private readonly contextService: ContextService,\n    @inject(KeyService) private readonly keyService: KeyService\n  ) {}\n\n  /**\n   * Sign a document using eddsa-rdfc-2022 cryptosuite\n   *\n   * Produces a DataIntegrityProof with:\n   * - type: \"DataIntegrityProof\"\n   * - cryptosuite: \"eddsa-rdfc-2022\"\n   * - RDFC-1.0 canonicalization\n   * - Ed25519 signature\n   *\n   * Uses the Credo wallet for signing (KMS-backed keys)\n   */\n  public async sign(\n    agentContext: AgentContext,\n    document: Record<string, unknown>,\n    keyHint: {\n      id: string\n      controller: string\n    }\n  ): Promise<Record<string, unknown>> {\n    // Get the Key from KMS via KeyService\n    const walletKey = await this.keyService.getKeyForVm(agentContext, keyHint.id)\n    if (!walletKey) {\n      throw new Error(`Key not found for verification method: ${keyHint.id}`)\n    }\n    if (!walletKey.kmsKeyId) {\n      throw new Error(`Key binding is missing kmsKeyId for verification method: ${keyHint.id}`)\n    }\n\n    // Map keyType to JWA signature algorithm\n    const algorithm =\n      walletKey.keyType === 'ed25519' ? 'EdDSA' : walletKey.keyType === 'p256' ? 'ES256' : 'ES384'\n\n    // Create a signer function that uses the KMS\n    const kms = agentContext.dependencyManager.resolve(Kms.KeyManagementApi)\n    const signer = async (data: Uint8Array): Promise<Uint8Array> => {\n      const { signature } = await kms.sign({\n        keyId: walletKey.kmsKeyId!,\n        algorithm: algorithm as Kms.KnownJwaSignatureAlgorithm,\n        data,\n      })\n      return new Uint8Array(signature)\n    }\n\n    return this.eddsaRdfc2022.signWithSigner({\n      document,\n      verificationMethodId: keyHint.id,\n      signer,\n      purpose: 'assertionMethod',\n    })\n  }\n\n  /**\n   * Verify a signed document with DataIntegrityProof\n   *\n   * Supports verification of eddsa-rdfc-2022 proofs by:\n   * 1. Resolving the public key from the verificationMethod DID\n   * 2. Using RDFC-1.0 canonicalization to recreate the signed hash\n   * 3. Verifying the Ed25519 signature\n   */\n  public async verify(document: Record<string, unknown>): Promise<{ verified: boolean; error?: string }> {\n    try {\n      const proof = (document as { proof?: EddsaRdfc2022Proof | EddsaRdfc2022Proof[] }).proof\n\n      if (!proof) {\n        return { verified: false, error: 'No proof found in document' }\n      }\n\n      const proofs = Array.isArray(proof) ? proof : [proof]\n\n      for (const p of proofs) {\n        // Check if this is an eddsa-rdfc-2022 proof\n        if (this.eddsaRdfc2022.matchProof(p as unknown as Record<string, unknown>)) {\n          // Resolve public key from verification method\n          const publicKeyMultibase = await this.resolvePublicKey(p.verificationMethod)\n\n          if (!publicKeyMultibase) {\n            return { verified: false, error: `Could not resolve public key from ${p.verificationMethod}` }\n          }\n\n          return this.eddsaRdfc2022.verify({\n            document,\n            proof: p,\n            publicKeyMultibase,\n            // Use internal cached contexts for verification\n            // Network contexts are fetched during real-world usage by the cryptosuite\n            useNetworkContexts: false,\n          })\n        }\n      }\n\n      return { verified: false, error: 'No matching eddsa-rdfc-2022 proof found' }\n    } catch (e: unknown) {\n      const error = e as Error\n      return { verified: false, error: error?.message || String(e) }\n    }\n  }\n\n  /**\n   * Get the default cryptosuite identifier\n   */\n  public getDefaultCryptosuite() {\n    return DI_EDDSA_RDFC_2022\n  }\n\n  /**\n   * Resolve public key from a verification method ID\n   *\n   * This fetches the DID document and extracts the publicKeyMultibase\n   * from the matching verification method.\n   */\n  private async resolvePublicKey(verificationMethodId: string): Promise<string | null> {\n    try {\n      const documentLoader = this.contextService.getDocumentLoader()\n      const result = await documentLoader(verificationMethodId)\n\n      // The document loader should return the verification method object\n      const vm = result.document as { publicKeyMultibase?: string }\n\n      if (vm.publicKeyMultibase) {\n        return vm.publicKeyMultibase\n      }\n\n      // If we got a full DID document, find the verification method\n      const didDoc = result.document as {\n        verificationMethod?: Array<{ id: string; publicKeyMultibase?: string }>\n      }\n\n      if (didDoc.verificationMethod) {\n        const method = didDoc.verificationMethod.find((m) => m.id === verificationMethodId)\n        if (method?.publicKeyMultibase) {\n          return method.publicKeyMultibase\n        }\n      }\n\n      return null\n    } catch {\n      return null\n    }\n  }\n}\n"],"mappings":";;;;;;;;;;;;;;AAcO,iCAAMA,uBAAqB;CAGhC,AAAO,YACL,AAAyCC,gBACzC,AAAqCC,YACrC;EAFyC;EACJ;OAJtB,gBAAgB,IAAI,0BAA0B;;;;;;;;;;;;;CAkB/D,MAAa,KACX,cACA,UACA,SAIkC;EAElC,MAAM,YAAY,MAAM,KAAK,WAAW,YAAY,cAAc,QAAQ,GAAG;AAC7E,MAAI,CAAC,UACH,OAAM,IAAI,MAAM,0CAA0C,QAAQ,KAAK;AAEzE,MAAI,CAAC,UAAU,SACb,OAAM,IAAI,MAAM,4DAA4D,QAAQ,KAAK;EAI3F,MAAM,YACJ,UAAU,YAAY,YAAY,UAAU,UAAU,YAAY,SAAS,UAAU;EAGvF,MAAM,MAAM,aAAa,kBAAkB,QAAQ,IAAI,iBAAiB;EACxE,MAAM,SAAS,OAAO,SAA0C;GAC9D,MAAM,EAAE,cAAc,MAAM,IAAI,KAAK;IACnC,OAAO,UAAU;IACN;IACX;IACD,CAAC;AACF,UAAO,IAAI,WAAW,UAAU;;AAGlC,SAAO,KAAK,cAAc,eAAe;GACvC;GACA,sBAAsB,QAAQ;GAC9B;GACA,SAAS;GACV,CAAC;;;;;;;;;;CAWJ,MAAa,OAAO,UAAmF;AACrG,MAAI;GACF,MAAM,QAAS,SAAmE;AAElF,OAAI,CAAC,MACH,QAAO;IAAE,UAAU;IAAO,OAAO;IAA8B;GAGjE,MAAM,SAAS,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM;AAErD,QAAK,MAAM,KAAK,OAEd,KAAI,KAAK,cAAc,WAAW,EAAwC,EAAE;IAE1E,MAAM,qBAAqB,MAAM,KAAK,iBAAiB,EAAE,mBAAmB;AAE5E,QAAI,CAAC,mBACH,QAAO;KAAE,UAAU;KAAO,OAAO,qCAAqC,EAAE;KAAsB;AAGhG,WAAO,KAAK,cAAc,OAAO;KAC/B;KACA,OAAO;KACP;KAGA,oBAAoB;KACrB,CAAC;;AAIN,UAAO;IAAE,UAAU;IAAO,OAAO;IAA2C;WACrEC,GAAY;AAEnB,UAAO;IAAE,UAAU;IAAO,OADZ,GAC0B,WAAW,OAAO,EAAE;IAAE;;;;;;CAOlE,AAAO,wBAAwB;AAC7B,SAAO;;;;;;;;CAST,MAAc,iBAAiB,sBAAsD;AACnF,MAAI;GAEF,MAAM,SAAS,MADQ,KAAK,eAAe,mBAAmB,CAC1B,qBAAqB;GAGzD,MAAM,KAAK,OAAO;AAElB,OAAI,GAAG,mBACL,QAAO,GAAG;GAIZ,MAAM,SAAS,OAAO;AAItB,OAAI,OAAO,oBAAoB;IAC7B,MAAM,SAAS,OAAO,mBAAmB,MAAM,MAAM,EAAE,OAAO,qBAAqB;AACnF,QAAI,QAAQ,mBACV,QAAO,OAAO;;AAIlB,UAAO;UACD;AACN,UAAO;;;;;CAjJZ,YAAY;oBAKR,OAAO,eAAe;oBACtB,OAAO,WAAW"}