/* eslint-disable @typescript-eslint/no-empty-function,camelcase */ import { sign, SUPPORTED_SIGNING_ALGORITHM } from "@tradetrust-tt/tradetrust"; import { v3, __unsafe__use__it__at__your__own__risks__wrapDocument as wrapDocument } from "@tradetrust-tt/tradetrust"; import { spawnSync } from "child_process"; import { writeFileSync } from "fs"; import { getLogger } from "../src/common/logger"; import { baseDidDocument, baseDnsDidDocument, baseDocumentStoreDocument, baseTokenRegistryDocument, } from "../test/fixtures/v3/documents"; const { info } = getLogger("generate.v3"); // DNS: example.tradetrust.io // Addr: 0xE712878f6E8d5d4F9e87E10DA604F9cB564C9a89 // Key: 0x497c85ed89f1874ba37532d1e33519aba15bd533cdcb90774cc497bfe3cde655 const key = { public: "did:ethr:0xE712878f6E8d5d4F9e87E10DA604F9cB564C9a89#controller", private: "0x497c85ed89f1874ba37532d1e33519aba15bd533cdcb90774cc497bfe3cde655", }; const signMerkleRoot = async (merkleRoot: string) => sign(SUPPORTED_SIGNING_ALGORITHM.Secp256k1VerificationKey2018, merkleRoot, key); const ethereumDocumentConfig = { network: "sepolia", dns: "demo-tradetrust.openattestation.com", documentStore: "0x49b2969bF0E4aa822023a9eA2293b24E4518C1DD", tokenRegistry: "0x921dC7cEF00155ac3A33f04DA7395324d7809757", wallet: { address: "0x1245e5B64D785b25057f7438F715f4aA5D965733", key: "0x416f14debf10172f04bef09f9b774480561ee3f05ee1a6f75df3c71ec0c60666", }, timeout: 5 * 60 * 1000, // 5 min timeout for contract to execute }; // Helper function to execute tradetrust commands securely const runTradetrust = (args: string[], timeoutMs?: number) => { const result = spawnSync("tradetrust", args, { timeout: timeoutMs ?? ethereumDocumentConfig.timeout, stdio: "inherit", }); if (result.error) { throw result.error; } if (result.signal) { throw new Error(`Command terminated by signal ${result.signal}`); } if (result.status !== 0) { throw new Error(`Command failed with exit code ${result.status}`); } }; interface OutLocations { revoked: string; notRevoked: string; } interface GenerateRevocationStoreArgs { logMessage: string; document: v3.OpenAttestationDocument; outLocations: OutLocations; } const baseDnsDidDocumentRevocationStore = { ...baseDnsDidDocument, openAttestationMetadata: { ...baseDnsDidDocument.openAttestationMetadata, proof: { ...baseDnsDidDocument.openAttestationMetadata.proof, revocation: { type: v3.RevocationType.RevocationStore, location: ethereumDocumentConfig.documentStore, }, }, }, } as v3.OpenAttestationDocument; const baseDidDocumentRevocationStore = { ...baseDidDocument, openAttestationMetadata: { ...baseDidDocument.openAttestationMetadata, proof: { ...baseDidDocument.openAttestationMetadata.proof, revocation: { type: v3.RevocationType.RevocationStore, location: ethereumDocumentConfig.documentStore, }, }, }, } as v3.OpenAttestationDocument; const generateRevocationStore = async ({ logMessage, document, outLocations }: GenerateRevocationStoreArgs) => { info(`${logMessage}`); const mainPath = "./test/fixtures/v3"; const rawAnother = { ...document, type: ["VerifiableCredential", "DrivingLicenceCredential", "OpenAttestationCredential"], }; const wrapped = await wrapDocument(document); const wrappedAnother = await wrapDocument(rawAnother); const { merkleRoot } = wrapped.proof; const { merkleRoot: merkleRootAnother } = wrappedAnother.proof; const signature = await signMerkleRoot(`0x${merkleRoot}`); const signatureAnother = await signMerkleRoot(`0x${merkleRootAnother}`); const signed: v3.SignedWrappedDocument = { ...wrapped, proof: { ...wrapped.proof, key: "did:ethr:0xE712878f6E8d5d4F9e87E10DA604F9cB564C9a89#controller", signature, }, }; const signedAnother: v3.SignedWrappedDocument = { ...wrappedAnother, proof: { ...wrappedAnother.proof, key: "did:ethr:0xE712878f6E8d5d4F9e87E10DA604F9cB564C9a89#controller", signature: signatureAnother, }, }; writeFileSync(`${mainPath}/${outLocations.revoked}`, JSON.stringify(signed, null, 2)); writeFileSync(`${mainPath}/${outLocations.notRevoked}`, JSON.stringify(signedAnother, null, 2)); info("Revoking document..."); runTradetrust([ "document-store", "revoke", "-h", `0x${signed.proof.merkleRoot}`, "-a", ethereumDocumentConfig.documentStore, "-k", ethereumDocumentConfig.wallet.key, "-n", ethereumDocumentConfig.network, ]); }; const generateDnsDid = async () => { info("Generating DNS-DID files"); writeFileSync("./test/fixtures/v3/dnsdid.json", JSON.stringify(baseDnsDidDocument, null, 2)); const wrappedBaseDnsDidDocument = await wrapDocument(baseDnsDidDocument); writeFileSync("./test/fixtures/v3/dnsdid-wrapped.json", JSON.stringify(wrappedBaseDnsDidDocument, null, 2)); const { merkleRoot } = wrappedBaseDnsDidDocument.proof; const signature = await signMerkleRoot(`0x${merkleRoot}`); const signedDnsDidDocument: v3.SignedWrappedDocument = { ...wrappedBaseDnsDidDocument, proof: { ...wrappedBaseDnsDidDocument.proof, key: "did:ethr:0xE712878f6E8d5d4F9e87E10DA604F9cB564C9a89#controller", signature, }, }; writeFileSync("./test/fixtures/v3/dnsdid-signed.json", JSON.stringify(signedDnsDidDocument, null, 2)); const validSignatureWithoutDnsTxt = { ...baseDnsDidDocument, openAttestationMetadata: { ...baseDnsDidDocument.openAttestationMetadata, identityProof: { type: v3.IdentityProofType.DNSDid, identifier: "notinuse.tradetrust.io", }, }, }; const wrappedInvalidDnsDidDocument = await wrapDocument(validSignatureWithoutDnsTxt); const signatureForInvalidDocument = await signMerkleRoot(`0x${wrappedInvalidDnsDidDocument.proof.merkleRoot}`); const signedInvalidDnsDidDocument: v3.SignedWrappedDocument = { ...wrappedInvalidDnsDidDocument, proof: { ...wrappedInvalidDnsDidDocument.proof, key: "did:ethr:0xE712878f6E8d5d4F9e87E10DA604F9cB564C9a89#controller", signature: signatureForInvalidDocument, }, }; writeFileSync("./test/fixtures/v3/dnsdid-invalid-signed.json", JSON.stringify(signedInvalidDnsDidDocument, null, 2)); }; const generateDid = async () => { info("Generating DID files"); writeFileSync("./test/fixtures/v3/did.json", JSON.stringify(baseDidDocument, null, 2)); const wrappedBaseDidDocument = await wrapDocument(baseDidDocument); writeFileSync("./test/fixtures/v3/did-wrapped.json", JSON.stringify(wrappedBaseDidDocument, null, 2)); const { merkleRoot } = wrappedBaseDidDocument.proof; const signature = await signMerkleRoot(`0x${merkleRoot}`); const signedDidDocument: v3.SignedWrappedDocument = { ...wrappedBaseDidDocument, proof: { ...wrappedBaseDidDocument.proof, key: "did:ethr:0xE712878f6E8d5d4F9e87E10DA604F9cB564C9a89#controller", signature, }, }; writeFileSync("./test/fixtures/v3/did-signed.json", JSON.stringify(signedDidDocument, null, 2)); const validSignatureWithoutDnsTxt = { ...baseDidDocument, openAttestationMetadata: { ...baseDidDocument.openAttestationMetadata, identityProof: { type: v3.IdentityProofType.DNSDid, identifier: "notinuse.tradetrust.io", }, }, }; const wrappedInvalidDnsDidDocument = await wrapDocument(validSignatureWithoutDnsTxt); const signatureForInvalidDocument = await signMerkleRoot(`0x${wrappedInvalidDnsDidDocument.proof.merkleRoot}`); const signedInvalidDnsDidDocument: v3.SignedWrappedDocument = { ...wrappedInvalidDnsDidDocument, proof: { ...wrappedInvalidDnsDidDocument.proof, key: "did:ethr:0xE712878f6E8d5d4F9e87E10DA604F9cB564C9a89#controller", signature: signatureForInvalidDocument, }, }; writeFileSync("./test/fixtures/v3/did-invalid-signed.json", JSON.stringify(signedInvalidDnsDidDocument, null, 2)); }; const generateDocumentStore = async () => { info("Generating Document Store files"); writeFileSync("./test/fixtures/v3/documentStore.json", JSON.stringify(baseDocumentStoreDocument, null, 2)); const wrappedBaseDocumentStoreDocument = await wrapDocument(baseDocumentStoreDocument); writeFileSync( "./test/fixtures/v3/documentStore-wrapped.json", JSON.stringify(wrappedBaseDocumentStoreDocument, null, 2) ); const issuedBaseDocumentStoreDocument = await wrapDocument(baseDocumentStoreDocument); writeFileSync( "./test/fixtures/v3/documentStore-issued.json", JSON.stringify(issuedBaseDocumentStoreDocument, null, 2) ); const revokedBaseDocumentStoreDocument = await wrapDocument(baseDocumentStoreDocument); writeFileSync( "./test/fixtures/v3/documentStore-revoked.json", JSON.stringify(revokedBaseDocumentStoreDocument, null, 2) ); const invalidDnsDocumentStoreDocument = await wrapDocument({ ...baseDocumentStoreDocument, openAttestationMetadata: { ...baseDocumentStoreDocument.openAttestationMetadata, identityProof: { type: v3.IdentityProofType.DNSTxt, identifier: "notinuse.tradetrust.io", }, }, }); writeFileSync( "./test/fixtures/v3/documentStore-invalid-issued.json", JSON.stringify(invalidDnsDocumentStoreDocument, null, 2) ); info("Issuing document(1/3)..."); runTradetrust([ "document-store", "issue", "-h", `0x${issuedBaseDocumentStoreDocument.proof.merkleRoot}`, "-a", ethereumDocumentConfig.documentStore, "-k", ethereumDocumentConfig.wallet.key, "-n", ethereumDocumentConfig.network, ]); info("Issuing document(2/3)..."); runTradetrust([ "document-store", "issue", "-h", `0x${revokedBaseDocumentStoreDocument.proof.merkleRoot}`, "-a", ethereumDocumentConfig.documentStore, "-k", ethereumDocumentConfig.wallet.key, "-n", ethereumDocumentConfig.network, ]); info("Issuing document(3/3)..."); runTradetrust([ "document-store", "issue", "-h", `0x${invalidDnsDocumentStoreDocument.proof.merkleRoot}`, "-a", ethereumDocumentConfig.documentStore, "-k", ethereumDocumentConfig.wallet.key, "-n", ethereumDocumentConfig.network, ]); info("Revoking document..."); runTradetrust([ "document-store", "revoke", "-h", `0x${revokedBaseDocumentStoreDocument.proof.merkleRoot}`, "-a", ethereumDocumentConfig.documentStore, "-k", ethereumDocumentConfig.wallet.key, "-n", ethereumDocumentConfig.network, ]); }; const generateTokenRegistry = async () => { info("Generating Token Registry files"); writeFileSync("./test/fixtures/v3/tokenRegistry.json", JSON.stringify(baseTokenRegistryDocument, null, 2)); const wrappedBaseTokenRegistryDocument = await wrapDocument(baseTokenRegistryDocument); writeFileSync( "./test/fixtures/v3/tokenRegistry-wrapped.json", JSON.stringify(wrappedBaseTokenRegistryDocument, null, 2) ); const issuedBaseTokenRegistryDocument = await wrapDocument(baseTokenRegistryDocument); writeFileSync( "./test/fixtures/v3/tokenRegistry-issued.json", JSON.stringify(issuedBaseTokenRegistryDocument, null, 2) ); const invalidDnsTokenRegistryDocument = await wrapDocument({ ...baseTokenRegistryDocument, openAttestationMetadata: { ...baseTokenRegistryDocument.openAttestationMetadata, identityProof: { type: v3.IdentityProofType.DNSTxt, identifier: "notinuse.tradetrust.io", }, }, }); writeFileSync( "./test/fixtures/v3/tokenRegistry-invalid-issued.json", JSON.stringify(invalidDnsTokenRegistryDocument, null, 2) ); info("Issuing document(1/2)..."); runTradetrust([ "token-registry", "mint", "-a", ethereumDocumentConfig.tokenRegistry, "--tokenId", `0x${issuedBaseTokenRegistryDocument.proof.merkleRoot}`, "--to", ethereumDocumentConfig.wallet.address, "-k", ethereumDocumentConfig.wallet.key, "-n", ethereumDocumentConfig.network, ]); info("Issuing document(2/2)..."); runTradetrust([ "token-registry", "mint", "-a", ethereumDocumentConfig.tokenRegistry, "--tokenId", `0x${invalidDnsTokenRegistryDocument.proof.merkleRoot}`, "--to", ethereumDocumentConfig.wallet.address, "-k", ethereumDocumentConfig.wallet.key, "-n", ethereumDocumentConfig.network, ]); }; const run = async () => { await generateDid(); await generateRevocationStore({ logMessage: "Generating DID-Revocation-Store files", document: baseDidDocumentRevocationStore, outLocations: { revoked: "did-revocation-store-signed-revoked.json", notRevoked: "did-revocation-store-signed-not-revoked.json", }, }); await generateDnsDid(); await generateRevocationStore({ logMessage: "Generating DNS-DID-Revocation-Store files", document: baseDnsDidDocumentRevocationStore, outLocations: { revoked: "dnsdid-revocation-store-signed-revoked.json", notRevoked: "dnsdid-revocation-store-signed-not-revoked.json", }, }); await generateDocumentStore(); await generateTokenRegistry(); }; run();