import { CeramicClient } from "@ceramicnetwork/http-client"; import { TileDocument } from "@ceramicnetwork/stream-tile"; import { encodeDIDWithLit, Secp256k1ProviderWithLit } from "key-did-provider-secp256k1-with-lit"; import { DID } from "dids"; import { getResolver } from "key-did-resolver"; import { splitSignature } from "@ethersproject/bytes"; import { computePublicKey, recoverPublicKey } from "@ethersproject/signing-key"; import { verifyMessage } from "@ethersproject/wallet"; import { VerifyCredentialResponse } from "./interfaces"; export default async function verifyCredential(vcId: string, issuer: string): Promise { let encodedDID: string; // acceptCredential will initially get and show the credential. actual acceptance functionality will come later const ceramicNetwork = process.env?.REACT_APP_CERAMIC_NETWORK ?? "https://ceramic-clay.3boxlabs.com"; const ceramic = new CeramicClient(ceramicNetwork); encodedDID = await encodeDIDWithLit({ pkpPublicKey: issuer }); const provider = new Secp256k1ProviderWithLit({ did: encodedDID, ipfsId: "QmcZ2MuxkNrMbNKAVtK37tEmKJ8zwvFudin3rBEcHyhqJc", }); const did = new DID({provider, resolver: getResolver()}); // -- authenticate await did.authenticate(); ceramic.did = did; // -- read a ceramic stream var loadDoc = await TileDocument.load(ceramic, vcId); const recoveredCredential: any = loadDoc.content // deep copy credential and delete `proof` property to get original credential const originalCredential = JSON.parse(JSON.stringify(recoveredCredential)); const proofObj = recoveredCredential.proof; delete originalCredential.proof; const stringifiedOriginalCredential = JSON.stringify(originalCredential); const encodedSig = proofObj.jws; const dataSigned = recoveredCredential.proof.verificationMethod; const recoveredPubkey = recoverPublicKey(dataSigned, encodedSig); const compressedRecoveredPubkey = computePublicKey(recoveredPubkey, true); const recoveredAddressViaMessage = verifyMessage(stringifiedOriginalCredential, encodedSig); return { recoveredCredential, verified: recoveredCredential.issuer === compressedRecoveredPubkey.slice(2) && !!recoveredAddressViaMessage }; }