UNPKG

@blockchain-lab-um/masca-connector

Version:

Library for using Masca on the frontend

151 lines (148 loc) 4.72 kB
import { isError } from '@blockchain-lab-um/utils'; import { getAccountId, EthereumWebAuth } from '@didtools/pkh-ethereum'; import { DIDSession } from 'did-session'; import { getEthTypesFromInputDoc } from 'eip-712-types-generation'; // src/utils.ts async function validateAndSetCeramicSession() { const api = this.getMascaApi(); const enabledCredentialStoresResult = await api.getCredentialStore(); if (isError(enabledCredentialStoresResult)) { throw new Error("Failed to get enabled VC stores."); } if (enabledCredentialStoresResult.data.ceramic === false) { return; } const session = await api.validateStoredCeramicSession(); if (!isError(session)) { return; } const provider = this.providerStore.getCurrentProvider()?.provider; if (!provider) { throw new Error("No provider found"); } const addresses = await provider.request({ method: "eth_requestAccounts" }); const accountId = await getAccountId(provider, addresses[0]); const authMethod = await EthereumWebAuth.getAuthMethod(provider, accountId); let newSession; try { newSession = await DIDSession.authorize(authMethod, { expiresInSecs: 60 * 60 * 24 * 7, resources: ["ceramic://*"] }); } catch (e) { throw new Error("User failed to sign session."); } const serializedSession = newSession.serialize(); const result = await api.setCeramicSession(serializedSession); if (isError(result)) { throw new Error("Failed to set session in Masca."); } } async function signVerifiablePresentation(presentation) { const provider = this.providerStore.getCurrentProvider()?.provider; if (!provider) throw new Error("No provider found"); const addresses = await provider.request({ method: "eth_requestAccounts" }); if (!presentation.holder.includes(addresses[0]) && !presentation.holder.includes( await this.viemClient.getEns({ address: addresses[0] }) )) { throw new Error("Wrong holder"); } const chainId = Number.parseInt( await provider.request({ method: "eth_chainId" }), 16 ); presentation.proof = { verificationMethod: `${presentation.holder}#controller`, created: presentation.issuanceDate, proofPurpose: "assertionMethod", type: "EthereumEip712Signature2021" }; const message = presentation; const domain = { chainId, name: "VerifiablePresentation", version: "1" }; const primaryType = "VerifiablePresentation"; const types = getEthTypesFromInputDoc(presentation, primaryType); const data = JSON.stringify({ domain, types, message, primaryType }); const signature = await provider.request({ method: "eth_signTypedData_v4", params: [addresses[0], data] }); presentation.proof.proofValue = signature; presentation.proof.eip712 = { domain, types, primaryType }; return presentation; } async function signVerifiableCredential(credential, params) { const provider = this.providerStore.getCurrentProvider()?.provider; if (!provider) throw new Error("No provider found"); const addresses = await provider.request({ method: "eth_requestAccounts" }); let issuer = ""; if (typeof credential.issuer === "string") { issuer = credential.issuer; } else { issuer = credential.issuer.id; } if (!issuer.includes(addresses[0]) && !issuer.includes( await this.viemClient.getEns({ address: addresses[0] }) )) { throw new Error("Invalid Issuer"); } const chainId = Number.parseInt( await provider.request({ method: "eth_chainId" }), 16 ); credential.proof = { verificationMethod: `${issuer}#controller`, created: credential.issuanceDate, proofPurpose: "assertionMethod", type: "EthereumEip712Signature2021" }; const message = credential; const domain = { chainId, name: "VerifiableCredential", version: "1" }; const primaryType = "VerifiableCredential"; const allTypes = getEthTypesFromInputDoc(credential, primaryType); const types = { ...allTypes }; const data = JSON.stringify({ domain, types, message, primaryType }); const signature = await provider.request({ method: "eth_signTypedData_v4", params: [addresses[0], data] }); credential.proof.proofValue = signature; credential.proof.eip712 = { domain, types: allTypes, primaryType }; if (params.options?.save) { const api = this.getMascaApi(); const result = await api.saveCredential( credential, { store: params.options.store } ); if (isError(result)) { throw new Error("Failed to save VC in Masca."); } } return credential; } export { signVerifiableCredential, signVerifiablePresentation, validateAndSetCeramicSession };