From 068662625d46606ee02403a7f550e68610a7ed3f Mon Sep 17 00:00:00 2001
From: Matthew Raymer <matthew.raymer@anomalistdesign.com>
Date: Wed, 28 May 2025 10:09:13 +0000
Subject: [PATCH] fix: resolve type compatibility in offerGiverDid

- Update offerGiverDid to use GenericVerifiableCredential as base type
- Add type assertion for OfferVerifiableCredential inside function
- Remove unnecessary type assertion in canFulfillOffer
---
 src/libs/endorserServer.ts | 50 +++++++++++++++++++-------------------
 src/libs/util.ts           | 13 +++++-----
 2 files changed, 32 insertions(+), 31 deletions(-)

diff --git a/src/libs/endorserServer.ts b/src/libs/endorserServer.ts
index 0a74c92a..6eae589f 100644
--- a/src/libs/endorserServer.ts
+++ b/src/libs/endorserServer.ts
@@ -110,11 +110,11 @@ export const BLANK_GENERIC_SERVER_RECORD: GenericCredWrapper<GenericVerifiableCr
     "@context": SCHEMA_ORG_CONTEXT,
     "@type": "" 
   },
-  handleId: "",
-  id: "",
-  issuedAt: "",
-  issuer: "",
-};
+    handleId: "",
+    id: "",
+    issuedAt: "",
+    issuer: "",
+  };
 
 // This is used to check for hidden info.
 // See https://github.com/trentlarson/endorser-ch/blob/0cb626f803028e7d9c67f095858a9fc8542e3dbd/server/api/services/util.js#L6
@@ -209,8 +209,8 @@ const testRecursivelyOnStrings = (
     return Object.values(input as Record<string, unknown>).some((value) =>
       testRecursivelyOnStrings(value, test)
     );
-  }
-  return false;
+    }
+    return false;
 };
 
 // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -582,17 +582,17 @@ export function errorStringForLog(error: unknown) {
   if (error && typeof error === 'object' && 'response' in error) {
     const err = error as AxiosErrorResponse;
     const errorResponseText = JSON.stringify(err.response);
-    // for some reason, error.response is not included in stringify result (eg. for 400 errors on invite redemptions)
-    if (!R.empty(errorResponseText) && !fullError.includes(errorResponseText)) {
-      // add error.response stuff
+  // for some reason, error.response is not included in stringify result (eg. for 400 errors on invite redemptions)
+  if (!R.empty(errorResponseText) && !fullError.includes(errorResponseText)) {
+    // add error.response stuff
       if (err.response?.config && err.config && R.equals(err.config, err.response.config)) {
-        // but exclude "config" because it's already in there
-        const newErrorResponseText = JSON.stringify(
+      // but exclude "config" because it's already in there
+      const newErrorResponseText = JSON.stringify(
           R.omit(["config"] as never[], err.response),
-        );
-        fullError += " - .response w/o same config JSON: " + newErrorResponseText;
-      } else {
-        fullError += " - .response JSON: " + errorResponseText;
+      );
+      fullError += " - .response w/o same config JSON: " + newErrorResponseText;
+    } else {
+      fullError += " - .response JSON: " + errorResponseText;
       }
     }
   }
@@ -1340,8 +1340,8 @@ export async function register(
   contact: Contact,
 ): Promise<{ success?: boolean; error?: string }> {
   try {
-    const vcJwt = await createInviteJwt(activeDid, contact);
-    const url = apiServer + "/api/v2/claim";
+  const vcJwt = await createInviteJwt(activeDid, contact);
+  const url = apiServer + "/api/v2/claim";
     const resp = await axios.post<{ 
       success?: { 
         handleId?: string; 
@@ -1351,15 +1351,15 @@ export async function register(
       message?: string;
     }>(url, { jwtEncoded: vcJwt });
     
-    if (resp.data?.success?.handleId) {
-      return { success: true };
-    } else if (resp.data?.success?.embeddedRecordError) {
+  if (resp.data?.success?.handleId) {
+    return { success: true };
+  } else if (resp.data?.success?.embeddedRecordError) {
       let message = "There was some problem with the registration and so it may not be complete.";
       if (typeof resp.data.success.embeddedRecordError === "string") {
-        message += " " + resp.data.success.embeddedRecordError;
-      }
-      return { error: message };
-    } else {
+      message += " " + resp.data.success.embeddedRecordError;
+    }
+    return { error: message };
+  } else {
       logger.error("Registration error:", JSON.stringify(resp.data));
       return { error: "Got a server error when registering." };
     }
diff --git a/src/libs/util.ts b/src/libs/util.ts
index 5b7ce91e..507a4ebc 100644
--- a/src/libs/util.ts
+++ b/src/libs/util.ts
@@ -384,14 +384,15 @@ export function base64ToBlob(base64DataUrl: string, sliceSize = 512) {
  * @param veriClaim is expected to have fields: claim and issuer
  */
 export function offerGiverDid(
-  veriClaim: GenericCredWrapper<OfferVerifiableCredential>,
+  veriClaim: GenericCredWrapper<GenericVerifiableCredential>,
 ): string | undefined {
   let giver;
+  const claim = veriClaim.claim as OfferVerifiableCredential;
   if (
-    veriClaim.claim.offeredBy?.identifier &&
-    !serverUtil.isHiddenDid(veriClaim.claim.offeredBy.identifier as string)
+    claim.offeredBy?.identifier &&
+    !serverUtil.isHiddenDid(claim.offeredBy.identifier as string)
   ) {
-    giver = veriClaim.claim.offeredBy.identifier;
+    giver = claim.offeredBy.identifier;
   } else if (veriClaim.issuer && !serverUtil.isHiddenDid(veriClaim.issuer)) {
     giver = veriClaim.issuer;
   }
@@ -407,7 +408,7 @@ export const canFulfillOffer = (
 ) => {
   return (
     veriClaim.claimType === "Offer" &&
-    !!offerGiverDid(veriClaim as GenericCredWrapper<OfferVerifiableCredential>)
+    !!offerGiverDid(veriClaim)
   );
 };
 
@@ -486,7 +487,7 @@ export const retrieveAccountCount = async (): Promise<number> => {
     `SELECT COUNT(*) FROM accounts`,
   );
   if (dbResult?.values?.[0]?.[0]) {
-    result = dbResult.values[0][0] as number;
+  result = dbResult.values[0][0] as number;
   }
 
   if (USE_DEXIE_DB) {