import { CeramicClient } from "@ceramicnetwork/http-client"; import { TileDocument } from "@ceramicnetwork/stream-tile"; import { getResolver } from "key-did-resolver"; import { DID } from "dids"; import { Proof, Credential } from "./interfaces"; import { encodeDIDWithLit, Secp256k1ProviderWithLit } from "key-did-provider-secp256k1-with-lit"; import { signMessageWithLit } from "./helpers/litHelpers"; const noMessageLitActionCode = (r: string) => { return ` const go = async () => { // this is the string "Hello World" for testing const toSign = [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]; // this requests a signature share from the Lit Node // the signature share will be automatically returned in the HTTP response from the node const sigShare = await LitActions.signEcdsa({ toSign, publicKey: ${r}", sigName: "sig1", }); }; go();` } // this code will be run on the node const litActionCode = ` const go = async () => { // this requests a signature share from the Lit Node // the signature share will be automatically returned in the HTTP response from the node // all the params (toSign, publicKey, sigName) are passed in from the LitJsSdk.executeJs() function const sigShare = await LitActions.ethPersonalSignMessageEcdsa({ message, publicKey , sigName }); }; go(); `; const proof = { // signature suite "type": "ECSDASignature", // timestamp "created": "2017-06-18T21:19:10Z", // purpose of proof "proofPurpose": "assertionMethod", // issuer public key "verificationMethod": "", // digital signature "jws": "" } // export default async function issueCredential(credential: Credential, recipient: string): Promise { export default async function issueCredential(credential: Credential, recipient: string): Promise { let proofHolder = proof; let fullCredential = credential; let encodedDID: string; let doc; let docId: string; console.log('%%%%% -> start of issue credential') const {dataSigned, encodedSig} = await signMessageWithLit(credential, litActionCode, credential.issuer); console.log('%%%%% -> start of issue credential') // create ceramic cli const ceramicNetwork = process.env?.REACT_APP_CERAMIC_NETWORK ?? "https://ceramic-clay.3boxlabs.com"; const ceramic = new CeramicClient(ceramicNetwork); // append signatures to proof object proofHolder.verificationMethod = dataSigned; proofHolder.jws = encodedSig; // append proof object to credential and stringify fullCredential['proof'] = proofHolder as Proof; const stringifiedCredential = fullCredential; // start of creating DID for recipient encodedDID = await encodeDIDWithLit({ pkpPublicKey: recipient, }); const provider = new Secp256k1ProviderWithLit({ did: encodedDID, // litCode: litActionCode ipfsId: "QmcZ2MuxkNrMbNKAVtK37tEmKJ8zwvFudin3rBEcHyhqJc", }); const did = new DID({provider, resolver: getResolver()}); // -- authenticate await did.authenticate(); ceramic.did = did; console.log("DID:", did); // -- write to ceramic stream doc = await TileDocument.create(ceramic, stringifiedCredential); docId = doc.id.toString(); // // TODO: remove code unused code // const splitSig = splitSignature(encodedSig); // console.log("splitSig", splitSig); // // const recoveredPubkey = recoverPublicKey(dataSigned, encodedSig); // console.log("uncompressed recoveredPubkey", recoveredPubkey); // const compressedRecoveredPubkey = computePublicKey(recoveredPubkey, true); // console.log("compressed recoveredPubkey", compressedRecoveredPubkey); // const recoveredAddress = recoverAddress(dataSigned, encodedSig); // console.log("recoveredAddress", recoveredAddress); // // const recoveredAddressViaMessage = verifyMessage(stringifiedCredential, encodedSig); // console.log("recoveredAddressViaMessage", recoveredAddressViaMessage); // return { // message: 'Credential Issued Successfully', // docId, // dataSigned, // docContents: fullCredential // } return docId; }