Skip to content

Commit

Permalink
fix: fix vote context metadata creation
Browse files Browse the repository at this point in the history
  • Loading branch information
MSzalowski committed Jun 7, 2024
1 parent 39f7663 commit e7310e9
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const VoteContextStoringInformation = ({
validateURL,
watch,
generateMetadata,
onClickDownloadJson,
onClickDownloadFile,
} = useVoteContextForm(setSavedHash, setStep, setErrorMessage);

const openGuideAboutStoringInformation = () =>
Expand Down Expand Up @@ -78,7 +78,7 @@ export const VoteContextStoringInformation = ({
<Step
component={
<Button
onClick={onClickDownloadJson}
onClick={onClickDownloadFile}
size="extraLarge"
startIcon={<img alt="download" src={ICONS.download} />}
sx={{
Expand All @@ -88,7 +88,7 @@ export const VoteContextStoringInformation = ({
}}
variant="outlined"
>
{t("govActions.voteContextJsonldFileName")}
{t("govActions.voteContextFileName")}
</Button>
}
componentsLayoutStyles={{
Expand Down
30 changes: 0 additions & 30 deletions govtool/frontend/src/consts/governanceAction/fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,33 +174,3 @@ export const GOVERNANCE_ACTION_CONTEXT = {
},
},
};

export const VOTE_TEST_CONTEXT = {
"@language": "en-us",
CIP100:
"https://github.com/cardano-foundation/CIPs/blob/master/CIP-0100/README.md#",
CIP108:
"https://github.com/cardano-foundation/CIPs/blob/master/CIP-0108/README.md#",
hashAlgorithm: "CIP100:hashAlgorithm",
body: {
"@id": "CIP108:body",
"@context": {
text: "CIP108:text",
},
},
authors: {
"@id": "CIP100:authors",
"@container": "@set" as const,
"@context": {
name: "http://xmlns.com/foaf/0.1/name",
witness: {
"@id": "CIP100:witness",
"@context": {
witnessAlgorithm: "CIP100:witnessAlgorithm",
publicKey: "CIP100:publicKey",
signature: "CIP100:signature",
},
},
},
},
};
41 changes: 15 additions & 26 deletions govtool/frontend/src/hooks/forms/useVoteContextForm.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
import { Dispatch, SetStateAction, useCallback, useState } from "react";
import { NodeObject } from "jsonld";
import { useFormContext } from "react-hook-form";
import { blake2bHex } from "blakejs";
import { captureException } from "@sentry/react";

import { CIP_108, VOTE_TEST_CONTEXT } from "@consts";
import {
canonizeJSON,
downloadJson,
generateJsonld,
generateMetadataBody,
} from "@utils";
import { downloadTextFile } from "@utils";
import { MetadataValidationStatus } from "@models";

import { useValidateMutation } from "../mutations";
Expand All @@ -28,7 +21,6 @@ export const useVoteContextForm = (
) => {
const { validateMetadata } = useValidateMutation();
const [hash, setHash] = useState<string | null>(null);
const [json, setJson] = useState<NodeObject | null>(null);

const {
control,
Expand All @@ -42,42 +34,39 @@ export const useVoteContextForm = (
} = useFormContext<VoteContextFormValues>();

const generateMetadata = useCallback(async () => {
const body = generateMetadataBody({
data: getValues(),
acceptedKeys: ["voteContextText"],
standardReference: CIP_108,
});
const { voteContextText } = getValues();

const jsonld = await generateJsonld(body, VOTE_TEST_CONTEXT);
const canonizedJson = await canonizeJSON(jsonld);
const canonizedJsonHash = blake2bHex(canonizedJson, undefined, 32);
const canonizedJsonHash = blake2bHex(voteContextText, undefined, 32);

// That allows to validate metadata hash
setHash(canonizedJsonHash);
setJson(jsonld);

return jsonld;
return voteContextText;
}, [getValues]);

const onClickDownloadJson = useCallback(() => {
if (!json) return;
downloadJson(json, "Vote_Context");
}, [json]);
const onClickDownloadFile = useCallback(() => {
const { voteContextText } = getValues();
if (!voteContextText) return;
downloadTextFile(voteContextText, "Vote_Context");
}, [getValues]);

const validateHash = useCallback(
async (url: string, localHash: string | null) => {
try {
if (!localHash) {
throw new Error(MetadataValidationStatus.INVALID_HASH);
}

const result = await validateMetadata({
url,
hash: localHash,
standard: undefined,
url,
noStandard: true,
});

if (result.status) {
throw result.status;
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
if (Object.values(MetadataValidationStatus).includes(error)) {
Expand Down Expand Up @@ -112,7 +101,7 @@ export const useVoteContextForm = (
generateMetadata,
getValues,
isValid,
onClickDownloadJson,
onClickDownloadFile,
register,
reset,
setValue,
Expand Down
2 changes: 1 addition & 1 deletion govtool/frontend/src/i18n/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ export const en = {
viewOtherDetails: "View other details",
viewProposalDetails: "View proposal details",
vote: "Vote",
voteContextJsonldFileName: "Vote_Context.jsonld",
voteContextFileName: "Vote_Context.txt",
votedOnByMe: "Voted on by me",
voteOnGovActions: "Vote on Governance Action",
voteSubmitted: "Vote submitted",
Expand Down
1 change: 1 addition & 0 deletions govtool/frontend/src/models/metadataValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ export type MetadataValidationDTO = {
url: string;
hash: string;
standard?: MetadataStandard;
noStandard?: boolean;
};
22 changes: 22 additions & 0 deletions govtool/frontend/src/utils/jsonUtils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { NodeObject } from "jsonld";

/**
* Downloads a JSON object as a file.
* @param json - The JSON object to be downloaded.
* @param fileName - The name of the file to be downloaded.
* If not provided, the default name will be "data.jsonld".
*/
export const downloadJson = (json: NodeObject, fileName?: string) => {
const jsonString = `data:text/jsonld;charset=utf-8,${encodeURIComponent(
JSON.stringify(json, null, 2),
Expand All @@ -10,3 +16,19 @@ export const downloadJson = (json: NodeObject, fileName?: string) => {

link.click();
};

/**
* Downloads a text file with the given content.
* @param text - The content of the text file.
* @param fileName - The name of the file (optional).
* If not provided, the default name will be "data.txt".
*/
export const downloadTextFile = (text: string, fileName?: string) => {
const blob = new Blob([text], { type: "text/utf-8" });
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = `${fileName || "data"}.txt`;

link.click();
};
25 changes: 18 additions & 7 deletions govtool/metadata-validation/src/app.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export class AppService {
hash,
url,
standard = MetadataStandard.CIP108,
// workaround property to not break the haskell backend
noStandard = false,
}: ValidateMetadataDTO): Promise<ValidateMetadataResult> {
let status: MetadataValidationStatus;
let metadata: any;
Expand All @@ -27,20 +29,29 @@ export class AppService {
}),
),
);
if (standard) {
if (standard && !noStandard) {
await validateMetadataStandard(data, standard);
}

metadata = parseMetadata(data.body, standard);
if (!noStandard) {
metadata = parseMetadata(data.body, standard);
}

let canonizedMetadata;
try {
canonizedMetadata = await canonizeJSON(data);
} catch (error) {
throw MetadataValidationStatus.INVALID_JSONLD;
if (!noStandard) {
try {
canonizedMetadata = await canonizeJSON(data);
} catch (error) {
throw MetadataValidationStatus.INVALID_JSONLD;
}
}

const hashedMetadata = blake.blake2bHex(canonizedMetadata, undefined, 32);
const hashedMetadata = blake.blake2bHex(
!standard ? data : canonizedMetadata,
undefined,
32,
);

if (hashedMetadata !== hash) {
throw MetadataValidationStatus.INVALID_HASH;
}
Expand Down
2 changes: 2 additions & 0 deletions govtool/metadata-validation/src/dto/validateMetadata.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ export class ValidateMetadataDTO {
url: string;

standard?: MetadataStandard;

noStandard?: boolean;
}

0 comments on commit e7310e9

Please sign in to comment.