Skip to content

Commit

Permalink
feat: collect metadata from console and upload
Browse files Browse the repository at this point in the history
  • Loading branch information
kittybest committed Sep 23, 2024
1 parent ae1355f commit 8135f6f
Show file tree
Hide file tree
Showing 4 changed files with 236 additions and 9 deletions.
4 changes: 4 additions & 0 deletions packages/coordinator/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,7 @@ TEST_PRIVATE_KEY=""

# An RPC API KEY to interact with live networks (used in e2e tests)
RPC_API_KEY=""

# Storage for metadata
# Create a Blob database and get token here: https://vercel.com/dashboard/stores?type=blob
BLOB_READ_WRITE_TOKEN=
5 changes: 4 additions & 1 deletion packages/coordinator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
"types": "tsc -p tsconfig.json --noEmit",
"generate-keypair": "pnpm run run:node ./scripts/generateKeypair.ts",
"download-zkeys:test": "pnpm run run:node ./scripts/downloadZKeys.ts test ./zkeys",
"download-zkeys:prod": "pnpm run run:node ./scripts/downloadZKeys.ts prod ./zkeys"
"download-zkeys:prod": "pnpm run run:node ./scripts/downloadZKeys.ts prod ./zkeys",
"upload-round-metadata": "pnpm run run:node ./scripts/uploadRoundMetadata.ts"
},
"dependencies": {
"@graphprotocol/graph-cli": "^0.79.0",
Expand All @@ -38,6 +39,7 @@
"@nestjs/websockets": "^10.3.10",
"@nomicfoundation/hardhat-ethers": "^3.0.8",
"@nomicfoundation/hardhat-toolbox": "^5.0.0",
"@vercel/blob": "^0.19.0",
"@zerodev/ecdsa-validator": "^5.3.1",
"@zerodev/permissions": "^5.4.3",
"@zerodev/sdk": "^5.3.8",
Expand All @@ -54,6 +56,7 @@
"maci-contracts": "^2.3.0",
"maci-domainobjs": "^2.0.0",
"maci-subgraph": "^2.3.0",
"moment": "^2.30.1",
"mustache": "^4.2.0",
"permissionless": ">=0.1.18 <=0.1.29",
"reflect-metadata": "^0.2.0",
Expand Down
161 changes: 161 additions & 0 deletions packages/coordinator/scripts/uploadRoundMetadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import { put } from "@vercel/blob";
import dotenv from "dotenv";
import moment from "moment";

import path from "path";
import * as readline from "readline";

export interface RoundMetadata {
roundId: string;
description: string;
startsAt: Date;
registrationEndsAt: Date;
votingStartsAt: Date;
votingEndsAt: Date;
}

interface IUploadMetadataProps {
data: RoundMetadata;
name: string;
}

dotenv.config({ path: path.resolve(import.meta.dirname, "../.env") });

export async function uploadRoundMetadata({ data, name }: IUploadMetadataProps): Promise<string> {
try {
const blob = await put(name, JSON.stringify(data), {
access: "public",
token: process.env.BLOB_READ_WRITE_TOKEN,
});

return blob.url;
} catch (e) {
throw new Error(e as string);
}
}

export async function collectMetadata(): Promise<RoundMetadata> {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});

const askRoundId = () =>
new Promise<string>((resolve) => {
rl.question("How would you name your round? ", (answer) => {
// eslint-disable-next-line no-console
console.log(`Your roundId is: ${answer}`);
resolve(answer);
});
});

const askDescription = () =>
new Promise<string>((resolve) => {
rl.question("Could you briefly introduce this round? ", (answer) => {
// eslint-disable-next-line no-console
console.log(`Your round description is: ${answer}`);
resolve(answer);
});
});

const askStartTime = () =>
new Promise<Date>((resolve, reject) => {
rl.question("When would you like to start this round? (Please respond in the format yyyy-mm-dd) ", (answer) => {
const isValid = moment(answer, "yyyy-mm-dd").isValid();

if (!isValid) {
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
reject("Please answer in valid format.");
}

// eslint-disable-next-line no-console
console.log("You would like to start this round at:", answer);
resolve(new Date(answer));
});
});

const askRegistrationEndTime = () =>
new Promise<Date>((resolve, reject) => {
rl.question(
"When would you like to end the registration for applications? (Please respond in the format yyyy-mm-dd) ",
(answer) => {
const isValid = moment(answer, "yyyy-mm-dd").isValid();

if (!isValid) {
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
reject("Please answer in valid format.");
}

// eslint-disable-next-line no-console
console.log(`Your application registration end date for this round is: ${answer}`);
resolve(new Date(answer));
},
);
});

const askVotingStartTime = () =>
new Promise<Date>((resolve, reject) => {
rl.question(
"When would you like to start the voting for this round? (Please respond in the format yyyy-mm-dd) ",
(answer) => {
const isValid = moment(answer, "yyyy-mm-dd").isValid();

if (!isValid) {
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
reject("Please answer in valid format.");
}

// eslint-disable-next-line no-console
console.log(`Your voting start date for this round is: ${answer}`);
resolve(new Date(answer));
},
);
});

const askVotingEndTime = () =>
new Promise<Date>((resolve, reject) => {
rl.question(
"When would you like to end the voting for this round? (Please respond in the format yyyy-mm-dd) ",
(answer) => {
const isValid = moment(answer, "yyyy-mm-dd").isValid();

if (!isValid) {
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
reject("Please answer in valid format.");
}

// eslint-disable-next-line no-console
console.log(`Your voting end date for this round is: ${answer}`);
resolve(new Date(answer));
},
);
});

const roundId = await askRoundId();
const description = await askDescription();
const startsAt = await askStartTime();
const registrationEndsAt = await askRegistrationEndTime();
const votingStartsAt = await askVotingStartTime();
const votingEndsAt = await askVotingEndTime();

rl.close();

return {
roundId,
description,
startsAt,
registrationEndsAt,
votingStartsAt,
votingEndsAt,
};
}

async function main(): Promise<void> {
const metadata = await collectMetadata();
const url = await uploadRoundMetadata({ data: metadata, name: `${metadata.roundId}.json` });

// eslint-disable-next-line no-console
console.log("The url of uploaded metadata is:", url);
}

main();
75 changes: 67 additions & 8 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 8135f6f

Please sign in to comment.