Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: user sdk #2064

Merged
merged 2 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 18 additions & 15 deletions apps/website/src/scripts/setupTypedoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,24 +50,27 @@ function parseAndRenameDirectory(dir: string) {
updateMdFiles(modulesFile, generateSidebarString({ title: `${label} Module`, label: "module", position: 1 }));
}

const innerDirs = fs.readdirSync(dirname);
innerDirs.forEach((innerDir) => {
const innerDirname = path.resolve(dirname, innerDir);

if (fs.statSync(innerDirname).isDirectory()) {
const innerFiles = fs.readdirSync(innerDirname);
innerFiles.forEach((innerFile) => {
const innerLabel = innerFile.split(".")[0];
updateMdFiles(
path.resolve(innerDirname, innerFile),
generateSidebarString({ title: innerLabel, label: innerLabel }),
);
});
}
});
processDirectory(dirname);
}
}

/**
* A function that processes a directory and updates the markdown files.
* @param directory - the directory being processed
*/
function processDirectory(directory: string) {
const items = fs.readdirSync(directory);
items.forEach((item) => {
const itemPath = path.resolve(directory, item);
if (fs.statSync(itemPath).isDirectory()) {
processDirectory(itemPath); // Recursively process subdirectories
} else if (fs.statSync(itemPath).isFile()) {
const itemLabel = item.split(".")[0];
updateMdFiles(itemPath, generateSidebarString({ title: itemLabel, label: itemLabel }));
}
});
}

/**
* A function that parses a sub-directory of typedoc/,
* defines label for it and updates the markdown files.
Expand Down
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"maci-core": "^2.5.0",
"maci-crypto": "^2.5.0",
"maci-domainobjs": "^2.5.0",
"maci-sdk": "^0.0.1",
"prompt": "^1.3.0"
},
"devDependencies": {
Expand Down
81 changes: 66 additions & 15 deletions packages/cli/ts/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env node

import { Command } from "@commander-js/extra-typings";
import { generateTallyCommitments, getPollParams, verify, getPoll, isUserRegistered, signup } from "maci-sdk";

import fs from "fs";
import path from "path";
Expand All @@ -15,14 +16,10 @@ import {
deploy,
showContracts,
deployPoll,
getPoll,
publish,
setVerifyingKeys,
mergeSignups,
timeTravel,
signup,
isRegisteredUser,
verify,
genProofs,
fundWallet,
proveOnChain,
Expand All @@ -32,7 +29,17 @@ import {
joinPoll,
isJoinedUser,
} from "./commands";
import { TallyData, logError, promptSensitiveValue, readContractAddress } from "./utils";
import {
DEFAULT_SG_DATA,
TallyData,
banner,
logError,
logGreen,
logRed,
promptSensitiveValue,
readContractAddress,
success,
} from "./utils";

// set the description version and name of the cli tool
const { description, version, name } = JSON.parse(
Expand Down Expand Up @@ -466,13 +473,17 @@ program

const maciAddress = cmdObj.maciAddress || (await readContractAddress("MACI", network?.name));

await signup({
const data = await signup({
maciPubKey: cmdObj.pubkey,
maciAddress,
sgDataArg: cmdObj.sgData,
quiet: cmdObj.quiet,
sgData: cmdObj.sgData ?? DEFAULT_SG_DATA,
signer,
});

logGreen(
cmdObj.quiet,
success(`State index: ${data.stateIndex.toString()}\n Transaction hash: ${data.transactionHash}`),
);
} catch (error) {
program.error((error as Error).message, { exitCode: 1 });
}
Expand All @@ -490,12 +501,17 @@ program

const maciAddress = cmdObj.maciAddress || (await readContractAddress("MACI", network?.name));

await isRegisteredUser({
const data = await isUserRegistered({
maciPubKey: cmdObj.pubkey,
maciAddress,
signer,
quiet: cmdObj.quiet,
});

if (data.isRegistered) {
logGreen(cmdObj.quiet, success(`State index: ${data.stateIndex?.toString()}`));
} else {
logRed(cmdObj.quiet, "User is not registered");
}
} catch (error) {
program.error((error as Error).message, { exitCode: 1 });
}
Expand All @@ -517,14 +533,28 @@ program

const maciAddress = cmdObj.maciAddress || (await readContractAddress("MACI", network?.name));

await isJoinedUser({
const data = await isJoinedUser({
pollPubKey: cmdObj.pubkey,
startBlock: cmdObj.startBlock!,
maciAddress,
pollId: cmdObj.pollId,
signer,
quiet: cmdObj.quiet,
});

if (data.isJoined) {
logGreen(
cmdObj.quiet,
success(
[
`Poll state index: ${data.pollStateIndex?.toString()}, registered: ${data.isJoined}`,
`Voice credits: ${data.voiceCredits?.toString()}`,
].join("\n"),
),
);
} else {
logRed(cmdObj.quiet, "User has not joined the poll");
}
} catch (error) {
program.error((error as Error).message, { exitCode: 1 });
}
Expand All @@ -535,20 +565,32 @@ program
.description("Get deployed poll from MACI contract")
.option("-p, --poll <poll>", "the poll id")
.option("-x, --maci-address <maciAddress>", "the MACI contract address")
.option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
.action(async (cmdObj) => {
try {
const signer = await getSigner();
const network = await signer.provider?.getNetwork();

const maciAddress = cmdObj.maciAddress || (await readContractAddress("MACI", network?.name));

await getPoll({
const details = await getPoll({
pollId: cmdObj.poll,
maciAddress,
signer,
quiet: cmdObj.quiet,
});

logGreen(
true,
success(
[
`ID: ${details.id}`,
`Deploy time: ${new Date(Number(details.deployTime) * 1000).toString()}`,
`End time: ${new Date(Number(details.deployTime) + Number(details.duration) * 1000).toString()}`,
`Number of signups ${details.numSignups}`,
`State tree merged: ${details.isMerged}`,
`Mode: ${details.mode === 0n ? "Quadratic Voting" : "Non-Quadratic Voting"}`,
].join("\n"),
),
);
} catch (error) {
program.error((error as Error).message, { exitCode: 1 });
}
Expand Down Expand Up @@ -582,6 +624,7 @@ program
.option("-r, --rpc-provider <provider>", "the rpc provider URL")
.action(async (cmdObj) => {
try {
banner(cmdObj.quiet);
const signer = await getSigner();
const network = await signer.provider?.getNetwork();

Expand All @@ -595,12 +638,20 @@ program

const maciAddress = tallyData.maci || cmdObj.maciAddress || (await readContractAddress("MACI", network?.name));

const pollParams = await getPollParams({ pollId: cmdObj.pollId, maciContractAddress: maciAddress, signer });
const tallyCommitments = generateTallyCommitments({
tallyData,
voteOptionTreeDepth: pollParams.voteOptionTreeDepth,
});

await verify({
tallyData,
pollId: cmdObj.pollId,
maciAddress,
quiet: cmdObj.quiet,
signer,
tallyCommitments,
numVoteOptions: pollParams.numVoteOptions,
voteOptionTreeDepth: pollParams.voteOptionTreeDepth,
});
} catch (error) {
program.error((error as Error).message, { exitCode: 1 });
Expand Down
20 changes: 20 additions & 0 deletions packages/sdk/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const path = require("path");

module.exports = {
root: true,
extends: ["../../.eslintrc.js"],
parser: "@typescript-eslint/parser",
parserOptions: {
project: path.resolve(__dirname, "./tsconfig.json"),
sourceType: "module",
typescript: true,
ecmaVersion: 2022,
experimentalDecorators: true,
requireConfigFile: false,
ecmaFeatures: {
classes: true,
impliedStrict: true,
},
warnOnUnsupportedTypeScriptVersion: true,
},
};
6 changes: 6 additions & 0 deletions packages/sdk/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
contractAddresses.json
contractAddresses.old.json
contractAddress.old
contractAddress.txt
localState.json
zkeys
4 changes: 4 additions & 0 deletions packages/sdk/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
tests
build/tests
.etherlime-store
.env
12 changes: 12 additions & 0 deletions packages/sdk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# maci-sdk

[![NPM Package][sdk-npm-badge]][sdk-npm-link]
[![Actions Status][sdk-actions-badge]][sdk-actions-link]

Please refer to the [documentation for the
SDK](https://maci.pse.dev/docs/developers-references/typescript-code/sdk).

[sdk-npm-badge]: https://img.shields.io/npm/v/maci-sdk.svg
[sdk-actions-badge]: https://github.com/privacy-scaling-explorations/maci/actions/workflows/e2e.yml/badge.svg
[sdk-npm-link]: https://www.npmjs.com/package/maci-sdk
[sdk-actions-link]: https://github.com/privacy-scaling-explorations/maci/actions?query=workflow%3ACI
71 changes: 71 additions & 0 deletions packages/sdk/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"name": "maci-sdk",
"version": "0.0.1",
"description": "MACI's SDK",
"main": "build/ts/index.js",
"exports": {
".": {
"types": "./build/ts/index.d.ts",
"default": "./build/ts/index.js"
},
"./sdk": {
"types": "./build/ts/sdk/index.d.ts",
"default": "./build/ts/sdk/index.js"
}
},
"bin": {
"maci-sdk": "./build/ts/index.js"
},
"files": [
"build",
"CHANGELOG.md",
"README.md"
],
"scripts": {
"watch": "tsc --watch",
"build": "tsc -p tsconfig.build.json",
"postbuild": "cp package.json ./build && mkdir -p ./zkeys",
"types": "tsc -p tsconfig.json --noEmit",
"test": "nyc ts-mocha --exit tests/unit/*.test.ts",
"docs": "typedoc --plugin typedoc-plugin-markdown --options ./typedoc.json"
},
"dependencies": {
"ethers": "^6.13.4",
"maci-contracts": "^2.5.0",
"maci-crypto": "^2.5.0",
"maci-domainobjs": "^2.5.0"
},
"devDependencies": {
"@types/chai": "^4.3.9",
"@types/chai-as-promised": "^7.1.8",
"@types/mocha": "^10.0.8",
"@types/node": "^22.9.0",
"chai": "^4.3.10",
"chai-as-promised": "^7.1.2",
"mocha": "^10.7.3",
"nyc": "^17.1.0",
"ts-mocha": "^10.0.0",
"typescript": "^5.6.3"
},
"nyc": {
"reporter": [
"text",
"lcov"
],
"extensions": [
".ts"
],
"all": true,
"exclude": [
"**/*.js",
"**/*.d.ts",
"hardhat.config.ts",
"tests/**/*.ts",
"ts/index.ts"
],
"branches": ">50%",
"lines": ">50%",
"functions": ">50%",
"statements": ">50%"
}
}
17 changes: 17 additions & 0 deletions packages/sdk/ts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export { getPoll, getPollParams } from "./poll";
export { verify } from "./verify";
export { generateTallyCommitments } from "./tallyCommitments";
export { isUserRegistered, isJoinedUser, signup } from "./user";

export {
linkPoseidonLibraries,
Deployment,
ContractStorage,
EContracts,
EMode,
type IVerifyingKeyStruct,
} from "maci-contracts";

export * from "maci-contracts/typechain-types";

export type { TallyData, VerifyArgs, IGetPollArgs, IGetPollData, IIsRegisteredUser, IIsJoinedUser } from "./utils";
Loading
Loading