diff --git a/cli/tests/ceremony-params/ceremonyParams.test.ts b/cli/tests/ceremony-params/ceremonyParams.test.ts index cf1a48ee00..701c5d1c59 100644 --- a/cli/tests/ceremony-params/ceremonyParams.test.ts +++ b/cli/tests/ceremony-params/ceremonyParams.test.ts @@ -124,7 +124,7 @@ describe("stress tests", function test() { }); it("should signup 1 user", async () => { - await signup({ maciPubKey: users[0].pubKey.serialize(), signer }); + await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: users[0].pubKey.serialize(), signer }); }); it("should publish 2 messages", async () => { @@ -154,7 +154,7 @@ describe("stress tests", function test() { await mergeSignups({ ...mergeSignupsArgs, signer }); await genProofs({ ...genProofsCeremonyArgs, signer }); await proveOnChain({ ...proveOnChainArgs, signer }); - await verify({ ...verifyArgs, signer }); + await verify({ ...verifyArgs(), signer }); }); }); }); diff --git a/cli/tests/constants.ts b/cli/tests/constants.ts index d0833a1655..6e84e15037 100644 --- a/cli/tests/constants.ts +++ b/cli/tests/constants.ts @@ -10,8 +10,10 @@ import { MergeSignupsArgs, ProveOnChainArgs, SetVerifyingKeysArgs, + TallyData, TimeTravelArgs, VerifyArgs, + readJSONFile, } from "../ts/utils"; export const STATE_TREE_DEPTH = 10; @@ -128,10 +130,16 @@ export const proveOnChainArgs: Omit = { subsidyEnabled: false, }; -export const verifyArgs: Omit = { - pollId: 0n, - subsidyEnabled: false, - tallyFile: testTallyFilePath, +export const verifyArgs = (): Omit => { + const tallyData = readJSONFile(testTallyFilePath) as unknown as TallyData; + + return { + pollId: 0n, + subsidyEnabled: false, + tallyData, + maciAddress: tallyData.maci, + tallyAddress: tallyData.tallyAddress, + }; }; export const deployArgs: Omit = { diff --git a/cli/tests/e2e/e2e.nonQv.test.ts b/cli/tests/e2e/e2e.nonQv.test.ts index 36092cbb07..7949b7a0e4 100644 --- a/cli/tests/e2e/e2e.nonQv.test.ts +++ b/cli/tests/e2e/e2e.nonQv.test.ts @@ -81,7 +81,7 @@ describe("e2e tests", function test() { await setVerifyingKeys({ ...setVerifyingKeysNonQvArgs, signer }); }); - describe("1 signup, 1 message (with signer as argument)", () => { + describe("1 signup, 1 message", () => { after(() => { cleanVanilla(); }); @@ -96,7 +96,7 @@ describe("e2e tests", function test() { }); it("should signup one user", async () => { - await signup({ maciPubKey: user.pubKey.serialize(), signer }); + await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: user.pubKey.serialize(), signer }); }); it("should publish one message", async () => { @@ -121,8 +121,10 @@ describe("e2e tests", function test() { const tallyFileData = await genProofs({ ...genProofsArgs, signer, useQuadraticVoting: false }); await proveOnChain({ ...proveOnChainArgs, signer }); await verify({ - ...verifyArgs, + ...verifyArgs(), tallyData: tallyFileData, + maciAddress: tallyFileData.maci, + tallyAddress: tallyFileData.tallyAddress, signer, }); }); diff --git a/cli/tests/e2e/e2e.subsidy.test.ts b/cli/tests/e2e/e2e.subsidy.test.ts index c9fe82f0d0..2f6f5c7f45 100644 --- a/cli/tests/e2e/e2e.subsidy.test.ts +++ b/cli/tests/e2e/e2e.subsidy.test.ts @@ -111,12 +111,13 @@ describe("e2e with Subsidy tests", function test() { // eslint-disable-next-line @typescript-eslint/prefer-for-of for (let i = 0; i < users.length; i += 1) { // eslint-disable-next-line no-await-in-loop - await signup({ maciPubKey: users[i].pubKey.serialize(), signer }); + await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: users[i].pubKey.serialize(), signer }); } }); it("should publish six messages", async () => { await publish({ + maciContractAddress: maciAddresses.maciAddress, pubkey: users[0].pubKey.serialize(), stateIndex: 1n, voteOptionIndex: 0n, @@ -129,6 +130,7 @@ describe("e2e with Subsidy tests", function test() { }); await publish({ + maciContractAddress: maciAddresses.maciAddress, pubkey: users[1].pubKey.serialize(), stateIndex: 2n, voteOptionIndex: 1n, @@ -141,6 +143,7 @@ describe("e2e with Subsidy tests", function test() { }); await publish({ + maciContractAddress: maciAddresses.maciAddress, pubkey: users[2].pubKey.serialize(), stateIndex: 3n, voteOptionIndex: 2n, @@ -153,6 +156,7 @@ describe("e2e with Subsidy tests", function test() { }); await publish({ + maciContractAddress: maciAddresses.maciAddress, pubkey: users[3].pubKey.serialize(), stateIndex: 4n, voteOptionIndex: 3n, @@ -165,6 +169,7 @@ describe("e2e with Subsidy tests", function test() { }); await publish({ + maciContractAddress: maciAddresses.maciAddress, pubkey: users[3].pubKey.serialize(), stateIndex: 4n, voteOptionIndex: 3n, @@ -177,6 +182,7 @@ describe("e2e with Subsidy tests", function test() { }); await publish({ + maciContractAddress: maciAddresses.maciAddress, pubkey: users[3].pubKey.serialize(), stateIndex: 4n, voteOptionIndex: 3n, @@ -195,7 +201,7 @@ describe("e2e with Subsidy tests", function test() { await mergeSignups({ ...mergeSignupsArgs, signer }); await genProofs({ ...genProofsArgs, signer }); await proveOnChain({ ...proveOnChainArgs, signer }); - await verify({ ...verifyArgs, signer }); + await verify({ ...verifyArgs(), signer }); }); }); @@ -227,7 +233,7 @@ describe("e2e with Subsidy tests", function test() { // eslint-disable-next-line @typescript-eslint/prefer-for-of for (let i = 0; i < users.length; i += 1) { // eslint-disable-next-line no-await-in-loop - await signup({ maciPubKey: users[i].pubKey.serialize(), signer }); + await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: users[i].pubKey.serialize(), signer }); } }); @@ -252,7 +258,7 @@ describe("e2e with Subsidy tests", function test() { await mergeSignups({ ...mergeSignupsArgs, signer }); const tallyData = await genProofs({ ...genProofsArgs, signer }); await proveOnChain({ ...proveOnChainArgs, signer }); - await verify({ ...verifyArgs, tallyData, signer }); + await verify({ ...verifyArgs(), tallyData, signer }); }); }); @@ -273,7 +279,7 @@ describe("e2e with Subsidy tests", function test() { it("should signup eight users (same pub key)", async () => { for (let i = 0; i < 8; i += 1) { // eslint-disable-next-line no-await-in-loop - await signup({ maciPubKey: user.pubKey.serialize(), signer }); + await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: user.pubKey.serialize(), signer }); } }); @@ -301,7 +307,7 @@ describe("e2e with Subsidy tests", function test() { await mergeSignups({ ...mergeSignupsArgs, signer }); const tallyData = await genProofs({ ...genProofsArgs, signer }); await proveOnChain({ ...proveOnChainArgs, signer }); - await verify({ ...verifyArgs, tallyData, signer }); + await verify({ ...verifyArgs(), tallyData, signer }); }); }); @@ -334,7 +340,7 @@ describe("e2e with Subsidy tests", function test() { // eslint-disable-next-line @typescript-eslint/prefer-for-of for (let i = 0; i < users.length; i += 1) { // eslint-disable-next-line no-await-in-loop - await signup({ maciPubKey: users[i].pubKey.serialize(), signer }); + await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: users[i].pubKey.serialize(), signer }); } // publish await publish({ @@ -356,7 +362,7 @@ describe("e2e with Subsidy tests", function test() { await mergeSignups({ ...mergeSignupsArgs, signer }); await genProofs({ ...genProofsArgs, signer }); await proveOnChain({ ...proveOnChainArgs, signer }); - await verify({ ...verifyArgs, signer }); + await verify({ ...verifyArgs(), signer }); cleanSubsidy(); }); @@ -463,7 +469,7 @@ describe("e2e with Subsidy tests", function test() { signer, }); await verify({ - ...verifyArgs, + ...verifyArgs(), pollId: 1n, tallyData, tallyAddress: pollAddresses.tally, @@ -486,7 +492,7 @@ describe("e2e with Subsidy tests", function test() { signer, }); await verify({ - ...verifyArgs, + ...verifyArgs(), pollId: 2n, tallyData, tallyAddress: secondPollAddresses.tally, diff --git a/cli/tests/e2e/e2e.test.ts b/cli/tests/e2e/e2e.test.ts index bc9ca3bd31..3cb22d2e87 100644 --- a/cli/tests/e2e/e2e.test.ts +++ b/cli/tests/e2e/e2e.test.ts @@ -98,7 +98,7 @@ describe("e2e tests", function test() { await setVerifyingKeys({ ...setVerifyingKeysArgs, signer }); }); - describe("1 signup, 1 message (with signer as argument)", () => { + describe("1 signup, 1 message", () => { after(() => { cleanVanilla(); }); @@ -113,7 +113,7 @@ describe("e2e tests", function test() { }); it("should signup one user", async () => { - await signup({ maciPubKey: user.pubKey.serialize(), signer }); + await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: user.pubKey.serialize(), signer }); }); it("should publish one message", async () => { @@ -138,7 +138,7 @@ describe("e2e tests", function test() { const tallyFileData = await genProofs({ ...genProofsArgs, signer }); await proveOnChain({ ...proveOnChainArgs, signer }); await verify({ - ...verifyArgs, + ...verifyArgs(), tallyData: tallyFileData, signer, }); @@ -160,7 +160,7 @@ describe("e2e tests", function test() { }); it("should signup one user", async () => { - await signup({ maciPubKey: user.pubKey.serialize(), signer }); + await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: user.pubKey.serialize(), signer }); }); it("should publish one message", async () => { @@ -183,11 +183,13 @@ describe("e2e tests", function test() { await mergeMessages({ ...mergeMessagesArgs, signer }); await mergeSignups({ ...mergeSignupsArgs, signer }); const tallyFileData = await genProofs({ ...genProofsArgs, signer }); - await signup({ maciPubKey: user.pubKey.serialize(), signer }); + await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: user.pubKey.serialize(), signer }); await proveOnChain({ ...proveOnChainArgs, signer }); await verify({ - ...verifyArgs, + ...verifyArgs(), tallyData: tallyFileData, + maciAddress: tallyFileData.maci, + tallyAddress: tallyFileData.tallyAddress, signer, }); }); @@ -211,7 +213,7 @@ describe("e2e tests", function test() { // eslint-disable-next-line @typescript-eslint/prefer-for-of for (let i = 0; i < users.length; i += 1) { // eslint-disable-next-line no-await-in-loop - await signup({ maciPubKey: users[i].pubKey.serialize(), signer }); + await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: users[i].pubKey.serialize(), signer }); } }); @@ -296,7 +298,7 @@ describe("e2e tests", function test() { await mergeSignups({ ...mergeSignupsArgs, signer }); await genProofs({ ...genProofsArgs, signer }); await proveOnChain({ ...proveOnChainArgs, signer }); - await verify({ ...verifyArgs, signer }); + await verify({ ...verifyArgs(), signer }); }); }); @@ -328,7 +330,7 @@ describe("e2e tests", function test() { // eslint-disable-next-line @typescript-eslint/prefer-for-of for (let i = 0; i < users.length; i += 1) { // eslint-disable-next-line no-await-in-loop - await signup({ maciPubKey: users[i].pubKey.serialize(), signer }); + await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: users[i].pubKey.serialize(), signer }); } }); @@ -353,7 +355,7 @@ describe("e2e tests", function test() { await mergeSignups({ ...mergeSignupsArgs, signer }); const tallyFileData = await genProofs({ ...genProofsArgs, signer }); await proveOnChain({ ...proveOnChainArgs, signer }); - await verify({ ...verifyArgs, tallyData: tallyFileData, signer }); + await verify({ ...verifyArgs(), tallyData: tallyFileData, signer }); }); }); @@ -374,7 +376,7 @@ describe("e2e tests", function test() { it("should signup eight users (same pub key)", async () => { for (let i = 0; i < 8; i += 1) { // eslint-disable-next-line no-await-in-loop - await signup({ maciPubKey: user.pubKey.serialize(), signer }); + await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: user.pubKey.serialize(), signer }); } }); @@ -402,7 +404,7 @@ describe("e2e tests", function test() { await mergeSignups({ ...mergeSignupsArgs, signer }); await genProofs({ ...genProofsArgs, signer }); await proveOnChain({ ...proveOnChainArgs, signer }); - await verify({ ...verifyArgs, signer }); + await verify({ ...verifyArgs(), signer }); }); }); @@ -424,13 +426,14 @@ describe("e2e tests", function test() { // eslint-disable-next-line @typescript-eslint/prefer-for-of for (let i = 0; i < users.length; i += 1) { // eslint-disable-next-line no-await-in-loop - await signup({ maciPubKey: users[i].pubKey.serialize(), signer }); + await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: users[i].pubKey.serialize(), signer }); } }); it("should publish 4 messages", async () => { // publish four different messages await publish({ + maciContractAddress: maciAddresses.maciAddress, pubkey: users[0].pubKey.serialize(), stateIndex: 1n, voteOptionIndex: 0n, @@ -443,6 +446,7 @@ describe("e2e tests", function test() { }); await publish({ + maciContractAddress: maciAddresses.maciAddress, pubkey: users[1].pubKey.serialize(), stateIndex: 2n, voteOptionIndex: 1n, @@ -455,6 +459,7 @@ describe("e2e tests", function test() { }); await publish({ + maciContractAddress: maciAddresses.maciAddress, pubkey: users[2].pubKey.serialize(), stateIndex: 3n, voteOptionIndex: 2n, @@ -467,6 +472,7 @@ describe("e2e tests", function test() { }); await publish({ + maciContractAddress: maciAddresses.maciAddress, pubkey: users[3].pubKey.serialize(), stateIndex: 4n, voteOptionIndex: 3n, @@ -485,7 +491,7 @@ describe("e2e tests", function test() { await mergeSignups({ ...mergeSignupsArgs, signer }); const tallyFileData = await genProofs({ ...genProofsArgs, signer }); await proveOnChain({ ...proveOnChainArgs, signer }); - await verify({ ...verifyArgs, tallyData: tallyFileData, signer }); + await verify({ ...verifyArgs(), tallyData: tallyFileData, signer }); }); }); @@ -512,7 +518,7 @@ describe("e2e tests", function test() { // deploy a poll contract pollAddresses = await deployPoll({ ...deployPollArgs, signer }); // signup - await signup({ maciPubKey: user.pubKey.serialize(), signer }); + await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: user.pubKey.serialize(), signer }); // publish await publish({ pubkey: user.pubKey.serialize(), @@ -533,7 +539,7 @@ describe("e2e tests", function test() { await mergeSignups({ ...mergeSignupsArgs, signer }); const tallyFileData = await genProofs({ ...genProofsArgs, signer }); await proveOnChain({ ...proveOnChainArgs, signer }); - await verify({ ...verifyArgs, tallyData: tallyFileData, signer }); + await verify({ ...verifyArgs(), tallyData: tallyFileData, signer }); cleanVanilla(); }); @@ -562,7 +568,7 @@ describe("e2e tests", function test() { await mergeSignups({ pollId: 1n, signer }); await genProofs({ ...genProofsArgs, pollId: 1n, signer }); await proveOnChain({ ...proveOnChainArgs, pollId: 1n, signer }); - await verify({ ...verifyArgs, pollId: 1n, signer }); + await verify({ ...verifyArgs(), pollId: 1n, signer }); }); }); @@ -596,7 +602,7 @@ describe("e2e tests", function test() { // eslint-disable-next-line @typescript-eslint/prefer-for-of for (let i = 0; i < users.length; i += 1) { // eslint-disable-next-line no-await-in-loop - await signup({ maciPubKey: users[i].pubKey.serialize(), signer }); + await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: users[i].pubKey.serialize(), signer }); } // publish @@ -620,7 +626,7 @@ describe("e2e tests", function test() { await mergeSignups({ ...mergeSignupsArgs, signer }); await genProofs({ ...genProofsArgs, signer }); await proveOnChain({ ...proveOnChainArgs, signer }); - await verify({ ...verifyArgs, signer }); + await verify({ ...verifyArgs(), signer }); cleanVanilla(); }); @@ -726,7 +732,7 @@ describe("e2e tests", function test() { signer, }); await verify({ - ...verifyArgs, + ...verifyArgs(), pollId: 1n, tallyData, maciAddress: maciAddresses.maciAddress, @@ -749,7 +755,7 @@ describe("e2e tests", function test() { signer, }); await verify({ - ...verifyArgs, + ...verifyArgs(), pollId: 2n, tallyData, maciAddress: maciAddresses.maciAddress, @@ -780,7 +786,7 @@ describe("e2e tests", function test() { }); it("should signup one user", async () => { - await signup({ maciPubKey: user.pubKey.serialize(), signer }); + await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: user.pubKey.serialize(), signer }); }); it("should publish one message", async () => { @@ -816,7 +822,7 @@ describe("e2e tests", function test() { signer, }); await proveOnChain({ ...proveOnChainArgs, signer }); - await verify({ ...verifyArgs, signer }); + await verify({ ...verifyArgs(), signer }); }); }); @@ -837,7 +843,9 @@ describe("e2e tests", function test() { }); it("should signup one user", async () => { - stateIndex = BigInt(await signup({ maciPubKey: user.pubKey.serialize(), signer })); + stateIndex = BigInt( + await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: user.pubKey.serialize(), signer }), + ); }); it("should airdrop topup tokens to the coordinator user", async () => { @@ -881,7 +889,7 @@ describe("e2e tests", function test() { await mergeSignups({ ...mergeSignupsArgs, signer }); await genProofs({ ...genProofsArgs, signer }); await proveOnChain({ ...proveOnChainArgs, signer }); - await verify({ ...verifyArgs, signer }); + await verify({ ...verifyArgs(), signer }); }); }); }); diff --git a/cli/tests/e2e/keyChange.test.ts b/cli/tests/e2e/keyChange.test.ts index b9299e4456..bdc428cd49 100644 --- a/cli/tests/e2e/keyChange.test.ts +++ b/cli/tests/e2e/keyChange.test.ts @@ -103,7 +103,9 @@ describe("keyChange tests", function test() { maciAddresses = await deploy({ ...deployArgs, signer }); // deploy a poll contract await deployPoll({ ...deployPollArgs, signer }); - stateIndex = BigInt(await signup({ maciPubKey: keypair1.pubKey.serialize(), signer })); + stateIndex = BigInt( + await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: keypair1.pubKey.serialize(), signer }), + ); await publish({ pubkey: keypair1.pubKey.serialize(), stateIndex, @@ -139,7 +141,7 @@ describe("keyChange tests", function test() { await mergeSignups({ ...mergeSignupsArgs, signer }); await genProofs({ ...genProofsArgs, signer }); await proveOnChain({ ...proveOnChainArgs, signer }); - await verify({ ...verifyArgs, signer }); + await verify({ ...verifyArgs(), signer }); }); it("should confirm the tally is correct", () => { @@ -169,7 +171,9 @@ describe("keyChange tests", function test() { maciAddresses = await deploy({ ...deployArgs, signer }); // deploy a poll contract await deployPoll({ ...deployPollArgs, signer }); - stateIndex = BigInt(await signup({ maciPubKey: keypair1.pubKey.serialize(), signer })); + stateIndex = BigInt( + await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: keypair1.pubKey.serialize(), signer }), + ); await publish({ pubkey: keypair1.pubKey.serialize(), stateIndex, @@ -205,7 +209,7 @@ describe("keyChange tests", function test() { await mergeSignups({ ...mergeSignupsArgs, signer }); await genProofs({ ...genProofsArgs, signer }); await proveOnChain({ ...proveOnChainArgs, signer }); - await verify({ ...verifyArgs, signer }); + await verify({ ...verifyArgs(), signer }); }); it("should confirm the tally is correct", () => { @@ -235,7 +239,9 @@ describe("keyChange tests", function test() { maciAddresses = await deploy({ ...deployArgs, signer }); // deploy a poll contract await deployPoll({ ...deployPollArgs, signer }); - stateIndex = BigInt(await signup({ maciPubKey: keypair1.pubKey.serialize(), signer })); + stateIndex = BigInt( + await signup({ maciAddress: maciAddresses.maciAddress, maciPubKey: keypair1.pubKey.serialize(), signer }), + ); await publish({ pubkey: keypair1.pubKey.serialize(), stateIndex, @@ -271,7 +277,7 @@ describe("keyChange tests", function test() { await mergeSignups({ ...mergeSignupsArgs, signer }); await genProofs({ ...genProofsArgs, signer }); await proveOnChain({ ...proveOnChainArgs, signer }); - await verify({ ...verifyArgs, signer }); + await verify({ ...verifyArgs(), signer }); }); it("should confirm the tally is correct", () => { diff --git a/cli/ts/commands/genKeyPair.ts b/cli/ts/commands/genKeyPair.ts index 6476476283..0648abe71a 100644 --- a/cli/ts/commands/genKeyPair.ts +++ b/cli/ts/commands/genKeyPair.ts @@ -1,6 +1,7 @@ import { Keypair } from "maci-domainobjs"; -import { logGreen, success, banner } from "../utils"; +import { banner } from "../utils/banner"; +import { logGreen, success } from "../utils/theme"; /** * Generate a new Maci Key Pair diff --git a/cli/ts/commands/genPubKey.ts b/cli/ts/commands/genPubKey.ts index c973cba936..e06411af14 100644 --- a/cli/ts/commands/genPubKey.ts +++ b/cli/ts/commands/genPubKey.ts @@ -1,7 +1,8 @@ import { genPubKey } from "maci-crypto"; import { PrivKey, PubKey } from "maci-domainobjs"; -import { banner, logError, logGreen, success } from "../utils"; +import { banner } from "../utils/banner"; +import { logError, logGreen, success } from "../utils/theme"; /** * Generate a new Maci Public key from a private key diff --git a/cli/ts/commands/publish.ts b/cli/ts/commands/publish.ts index 5fe86c4938..7c653231a8 100644 --- a/cli/ts/commands/publish.ts +++ b/cli/ts/commands/publish.ts @@ -1,19 +1,13 @@ -import { MACI__factory as MACIFactory, Poll__factory as PollFactory } from "maci-contracts"; +import { MACI__factory as MACIFactory, Poll__factory as PollFactory } from "maci-contracts/typechain-types"; import { genRandomSalt } from "maci-crypto"; import { Keypair, PCommand, PrivKey, PubKey } from "maci-domainobjs"; -import { - type PublishArgs, - info, - logError, - logGreen, - logYellow, - readContractAddress, - validateSalt, - promptSensitiveValue, - contractExists, - banner, -} from "../utils"; +import type { PublishArgs } from "../utils/interfaces"; + +import { banner } from "../utils/banner"; +import { contractExists } from "../utils/contracts"; +import { validateSalt } from "../utils/salt"; +import { info, logError, logGreen, logYellow } from "../utils/theme"; /** * Publish a new message to a MACI Poll contract @@ -35,8 +29,6 @@ export const publish = async ({ }: PublishArgs): Promise => { banner(quiet); - const network = await signer.provider?.getNetwork(); - // validate that the pub key of the user is valid if (!PubKey.isValidSerializedPubKey(pubkey)) { logError("invalid MACI public key"); @@ -44,25 +36,15 @@ export const publish = async ({ // deserialize const userMaciPubKey = PubKey.deserialize(pubkey); - // validation of the maci contract address - if (!readContractAddress("MACI", network?.name) && !maciContractAddress) { - logError("MACI contract address is empty"); - } - - const maciAddress = maciContractAddress || readContractAddress("MACI", network?.name); - - if (!(await contractExists(signer.provider!, maciAddress))) { + if (!(await contractExists(signer.provider!, maciContractAddress))) { logError("MACI contract does not exist"); } - // if no private key is passed we ask it securely - const userPrivKey = privateKey || (await promptSensitiveValue("Insert your MACI private key")); - - if (!PrivKey.isValidSerializedPrivKey(userPrivKey)) { + if (!PrivKey.isValidSerializedPrivKey(privateKey)) { logError("Invalid MACI private key"); } - const userMaciPrivKey = PrivKey.deserialize(userPrivKey); + const userMaciPrivKey = PrivKey.deserialize(privateKey); // validate args if (voteOptionIndex < 0) { @@ -88,7 +70,7 @@ export const publish = async ({ logError("Invalid poll id"); } - const maciContract = MACIFactory.connect(maciAddress, signer); + const maciContract = MACIFactory.connect(maciContractAddress, signer); const pollAddress = await maciContract.getPoll(pollId); if (!(await contractExists(signer.provider!, pollAddress))) { diff --git a/cli/ts/commands/signup.ts b/cli/ts/commands/signup.ts index f7cd4e9632..d6328fb55a 100644 --- a/cli/ts/commands/signup.ts +++ b/cli/ts/commands/signup.ts @@ -1,19 +1,12 @@ -import { MACI__factory as MACIFactory } from "maci-contracts"; +import { MACI__factory as MACIFactory } from "maci-contracts/typechain-types"; import { PubKey } from "maci-domainobjs"; -import { - type SignupArgs, - banner, - contractExists, - DEFAULT_IVCP_DATA, - DEFAULT_SG_DATA, - readContractAddress, - info, - logError, - logGreen, - logYellow, - success, -} from "../utils"; +import type { SignupArgs } from "../utils/interfaces"; + +import { banner } from "../utils/banner"; +import { contractExists } from "../utils/contracts"; +import { DEFAULT_IVCP_DATA, DEFAULT_SG_DATA } from "../utils/defaults"; +import { info, logError, logGreen, logYellow, success } from "../utils/theme"; /** * Signup a user to the MACI contract @@ -30,7 +23,6 @@ export const signup = async ({ }: SignupArgs): Promise => { banner(quiet); - const network = await signer.provider?.getNetwork(); // validate user key if (!PubKey.isValidSerializedPubKey(maciPubKey)) { logError("Invalid MACI public key"); @@ -38,14 +30,7 @@ export const signup = async ({ const userMaciPubKey = PubKey.deserialize(maciPubKey); - // ensure we have the contract addresses - if (!readContractAddress("MACI", network?.name) && !maciAddress) { - logError("Invalid MACI contract address"); - } - - const maciContractAddress = maciAddress || readContractAddress("MACI", network?.name); - - if (!(await contractExists(signer.provider!, maciContractAddress))) { + if (!(await contractExists(signer.provider!, maciAddress))) { logError("There is no contract deployed at the specified address"); } @@ -63,7 +48,7 @@ export const signup = async ({ logError("invalid initial voice credit proxy data"); } - const maciContract = MACIFactory.connect(maciContractAddress, signer); + const maciContract = MACIFactory.connect(maciAddress, signer); let stateIndex = ""; try { diff --git a/cli/ts/commands/verify.ts b/cli/ts/commands/verify.ts index dea3be5eda..b84820a07d 100644 --- a/cli/ts/commands/verify.ts +++ b/cli/ts/commands/verify.ts @@ -3,26 +3,15 @@ import { MACI__factory as MACIFactory, Subsidy__factory as SubsidyFactory, Poll__factory as PollFactory, -} from "maci-contracts"; +} from "maci-contracts/typechain-types"; import { hash2, hash3, genTreeCommitment } from "maci-crypto"; -import fs from "fs"; +import type { VerifyArgs } from "../utils/interfaces"; -import { - type SubsidyData, - type TallyData, - type VerifyArgs, - banner, - contractExists, - info, - logError, - logGreen, - logYellow, - verifyPerVOSpentVoiceCredits, - verifyTallyResults, - readContractAddress, - success, -} from "../utils"; +import { banner } from "../utils/banner"; +import { contractExists } from "../utils/contracts"; +import { info, logError, logGreen, logYellow, success } from "../utils/theme"; +import { verifyPerVOSpentVoiceCredits, verifyTallyResults } from "../utils/verifiers"; /** * Verify the results of a poll and optionally the subsidy results on-chain @@ -31,39 +20,20 @@ import { export const verify = async ({ pollId, subsidyEnabled, - tallyFile, tallyData, maciAddress, tallyAddress, subsidyAddress, - subsidyFile, + subsidyData, signer, quiet = true, }: VerifyArgs): Promise => { banner(quiet); - const network = await signer.provider?.getNetwork(); - - // ensure we have either tally data or tally file - if (!(tallyData || tallyFile)) { - logError("No tally data or tally file provided."); - } - // if we have the data as param, then use that - let tallyResults: TallyData; - - if (tallyData) { - tallyResults = tallyData; - } else { - // read the tally file - if (!tallyFile || !fs.existsSync(tallyFile)) { - logError(`Unable to open ${tallyFile}`); - } - tallyResults = JSON.parse(fs.readFileSync(tallyFile!, { encoding: "utf8" })) as TallyData; - } + const tallyResults = tallyData; // we prioritize the tally file data - const tallyContractAddress = - tallyResults.tallyAddress || tallyAddress || readContractAddress(`Tally-${pollId}`, network?.name); + const tallyContractAddress = tallyResults.tallyAddress || tallyAddress; if (!tallyContractAddress) { logError("Tally contract address is empty"); @@ -74,7 +44,7 @@ export const verify = async ({ } // prioritize the tally file data - const maciContractAddress = tallyResults.maci || maciAddress || readContractAddress("MACI", network?.name); + const maciContractAddress = tallyResults.maci || maciAddress; // check existence of MACI, Tally and Subsidy contract addresses if (!maciContractAddress) { @@ -89,7 +59,7 @@ export const verify = async ({ // subsidy validation if (subsidyEnabled) { - subsidyContractAddress = subsidyAddress || readContractAddress(`Subsidy-${pollId}`, network?.name); + subsidyContractAddress = subsidyAddress!; if (!subsidyContractAddress) { logError("Subsidy contract address is empty"); @@ -221,18 +191,11 @@ export const verify = async ({ } // verify subsidy result if subsidy file is provided - if (subsidyEnabled && subsidyFile && subsidyContract !== undefined) { + if (subsidyEnabled && subsidyData && subsidyContract !== undefined) { const onChainSubsidyCommitment = BigInt(await subsidyContract.subsidyCommitment()); logYellow(quiet, info(`on-chain subsidy commitment: ${onChainSubsidyCommitment.toString(16)}`)); - // read the subsidy file - if (!fs.existsSync(subsidyFile)) { - logError(`There is no such file: ${subsidyFile}`); - } - - const subsidyData = JSON.parse(fs.readFileSync(subsidyFile, { encoding: "utf8" })) as SubsidyData; - // check the results commitment const validResultsSubsidyCommitment = subsidyData.newSubsidyCommitment.match(/0x[a-fA-F0-9]+/); diff --git a/cli/ts/index.ts b/cli/ts/index.ts index c61fa7f277..f6cd35b143 100644 --- a/cli/ts/index.ts +++ b/cli/ts/index.ts @@ -30,6 +30,7 @@ import { checkVerifyingKeys, genLocalState, } from "./commands"; +import { SubsidyData, TallyData, logError, promptSensitiveValue, readContractAddress } from "./utils"; // set the description version and name of the cli tool const { description, version, name } = JSON.parse( @@ -293,6 +294,10 @@ program .action(async (cmdObj) => { try { const signer = await getSigner(); + const network = await signer.provider?.getNetwork(); + + const maciContractAddress = cmdObj.contract || readContractAddress("MACI", network?.name); + const privateKey = cmdObj.privkey || (await promptSensitiveValue("Insert your MACI private key")); await publish({ pubkey: cmdObj.pubkey, @@ -301,9 +306,9 @@ program nonce: cmdObj.nonce, pollId: cmdObj.pollId, newVoteWeight: cmdObj.newVoteWeight, - maciContractAddress: cmdObj.contract, + maciContractAddress, salt: cmdObj.salt, - privateKey: cmdObj.privkey, + privateKey, quiet: cmdObj.quiet, signer, }); @@ -384,10 +389,13 @@ program .action(async (cmdObj) => { try { const signer = await getSigner(); + const network = await signer.provider?.getNetwork(); + + const maciContractAddress = cmdObj.maciAddress || readContractAddress("MACI", network?.name); await signup({ maciPubKey: cmdObj.pubkey, - maciAddress: cmdObj.maciAddress, + maciAddress: maciContractAddress, sgDataArg: cmdObj.sgData, ivcpDataArg: cmdObj.ivcpData, quiet: cmdObj.quiet, @@ -461,15 +469,37 @@ program .action(async (cmdObj) => { try { const signer = await getSigner(); + const network = await signer.provider?.getNetwork(); + + // read the tally file + if (!cmdObj.tallyFile || !fs.existsSync(cmdObj.tallyFile)) { + logError(`Unable to open ${cmdObj.tallyFile}`); + } + + const tallyData = JSON.parse(fs.readFileSync(cmdObj.tallyFile, { encoding: "utf8" })) as TallyData; + + const maciAddress = tallyData.maci || cmdObj.contract || readContractAddress("MACI", network?.name); + const subsidyAddress = cmdObj.subsidyContract || readContractAddress(`Subsidy-${cmdObj.pollId}`, network?.name); + const tallyAddress = + tallyData.tallyAddress || cmdObj.tallyContract || readContractAddress(`Tally-${cmdObj.pollId}`, network?.name); + + // read the subsidy file + if (cmdObj.subsidyEnabled && (!cmdObj.subsidyFile || !fs.existsSync(cmdObj.subsidyFile))) { + logError(`There is no such file: ${cmdObj.subsidyFile}`); + } + + const subsidyData = cmdObj.subsidyEnabled + ? (JSON.parse(fs.readFileSync(cmdObj.subsidyFile!, { encoding: "utf8" })) as SubsidyData) + : undefined; await verify({ + tallyData, pollId: cmdObj.pollId, subsidyEnabled: cmdObj.subsidyEnabled, - tallyFile: cmdObj.tallyFile, - maciAddress: cmdObj.contract, - tallyAddress: cmdObj.tallyContract, - subsidyAddress: cmdObj.subsidyContract, - subsidyFile: cmdObj.subsidyFile, + maciAddress, + tallyAddress, + subsidyAddress, + subsidyData, quiet: cmdObj.quiet, signer, }); @@ -667,4 +697,5 @@ export type { VerifyArgs, ProveOnChainArgs, DeployArgs, + SubsidyData, } from "./utils"; diff --git a/cli/ts/sdk/index.ts b/cli/ts/sdk/index.ts index f38a9e5fb5..de93442cbe 100644 --- a/cli/ts/sdk/index.ts +++ b/cli/ts/sdk/index.ts @@ -1,3 +1,17 @@ -export { genKeyPair, genMaciPubKey, publish, signup, verify } from "../commands"; +import { genKeyPair } from "../commands/genKeyPair"; +import { genMaciPubKey } from "../commands/genPubKey"; +import { publish } from "../commands/publish"; +import { signup } from "../commands/signup"; +import { verify } from "../commands/verify"; -export type { DeployedContracts, PollContracts, TallyData, PublishArgs, SignupArgs, VerifyArgs } from "../utils"; +export { genKeyPair, genMaciPubKey, publish, signup, verify }; + +export type { + DeployedContracts, + PollContracts, + TallyData, + SubsidyData, + PublishArgs, + SignupArgs, + VerifyArgs, +} from "../utils"; diff --git a/cli/ts/utils/interfaces.ts b/cli/ts/utils/interfaces.ts index 5113dfd9f0..03e9954715 100644 --- a/cli/ts/utils/interfaces.ts +++ b/cli/ts/utils/interfaces.ts @@ -737,17 +737,17 @@ export interface PublishArgs { /** * The address of the MACI contract */ - maciContractAddress?: string; + maciContractAddress: string; /** - * The salt of the message + * The private key of the user */ - salt?: bigint; + privateKey: string; /** - * The private key of the user + * The salt of the message */ - privateKey?: string; + salt?: bigint; /** * Whether to log the output @@ -832,7 +832,7 @@ export interface SignupArgs { /** * The address of the MACI contract */ - maciAddress?: string; + maciAddress: string; /** * The signup gateway data @@ -904,25 +904,20 @@ export interface VerifyArgs { */ signer: Signer; - /** - * The path to the tally file with results, per vote option spent credits, spent voice credits total - */ - tallyFile?: string; - /** * The tally data */ - tallyData?: TallyData; + tallyData: TallyData; /** * The address of the MACI contract */ - maciAddress?: string; + maciAddress: string; /** * The address of the Tally contract */ - tallyAddress?: string; + tallyAddress: string; /** * The address of the Subsidy contract @@ -930,9 +925,9 @@ export interface VerifyArgs { subsidyAddress?: string; /** - * The path to the subsidy file + * The subsidy data */ - subsidyFile?: string; + subsidyData?: SubsidyData; /** * Whether to log the output diff --git a/contracts/package.json b/contracts/package.json index e0cb3b7d4a..0eb7b08b44 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -3,6 +3,19 @@ "version": "1.1.2", "description": "Solidity Smart Contracts for MACI (Minimal Anti-Collusion Infrastructure)", "main": "build/ts/index.js", + "exports": { + ".": { + "types": "./build/ts/index.d.ts", + "default": "./build/ts/index.js" + }, + "./typechain-types": { + "types": "./build/typechain-types/index.d.ts", + "default": "./build/typechain-types/index.js" + } + }, + "bin": { + "maci-contracts": "./build/ts/index.js" + }, "files": [ "build", "contracts", diff --git a/contracts/ts/index.ts b/contracts/ts/index.ts index a6c763e0f2..a3c29d9b13 100644 --- a/contracts/ts/index.ts +++ b/contracts/ts/index.ts @@ -17,7 +17,6 @@ export { genJsonRpcDeployer } from "./deployer"; export { genMaciStateFromContract } from "./genMaciState"; export { formatProofForVerifierContract, getDefaultSigner, getDefaultNetwork, getSigners } from "./utils"; export { abiDir, solDir } from "./constants"; -export { parseArtifact } from "./abi"; export type { IVerifyingKeyStruct, SnarkProof, Groth16Proof } from "./types"; export * from "../typechain-types"; diff --git a/integrationTests/ts/__tests__/integration.test.ts b/integrationTests/ts/__tests__/integration.test.ts index 1080391f68..06d669b912 100644 --- a/integrationTests/ts/__tests__/integration.test.ts +++ b/integrationTests/ts/__tests__/integration.test.ts @@ -17,6 +17,7 @@ import { verify, DeployedContracts, PollContracts, + SubsidyData, } from "maci-cli"; import { getDefaultSigner } from "maci-contracts"; import { MaciState, MaxValues, TreeDepths } from "maci-core"; @@ -357,7 +358,11 @@ describe("Integration tests", function test() { maciAddress: contracts.maciAddress, tallyAddress: pollContracts.tally, subsidyAddress: pollContracts.subsidy, - subsidyFile: subsidyEnabled ? path.resolve(__dirname, "../../../cli/subsidy.json") : undefined, + subsidyData: subsidyEnabled + ? (JSON.parse( + fs.readFileSync(path.resolve(__dirname, "../../../cli/subsidy.json")).toString(), + ) as SubsidyData) + : undefined, signer, }), ).to.eventually.not.rejectedWith(); diff --git a/integrationTests/ts/__tests__/maci-keys.test.ts b/integrationTests/ts/__tests__/maci-keys.test.ts index 0418617322..2f21357cb4 100644 --- a/integrationTests/ts/__tests__/maci-keys.test.ts +++ b/integrationTests/ts/__tests__/maci-keys.test.ts @@ -1,9 +1,10 @@ import { expect } from "chai"; -import { BaseContract, Signer } from "ethers"; -import { Poll, getDefaultSigner, parseArtifact } from "maci-contracts"; +import { Poll__factory as PollFactory, type Poll, getDefaultSigner } from "maci-contracts"; import { genPrivKey, genPubKey } from "maci-crypto"; import { Keypair, PrivKey, PubKey } from "maci-domainobjs"; +import type { Signer } from "ethers"; + import { INT_STATE_TREE_DEPTH, STATE_TREE_DEPTH, @@ -95,7 +96,7 @@ describe("integration tests private/public/keypair", () => { ); // we know it's the first poll so id is 0 - pollContract = new BaseContract(await maci.polls(0), parseArtifact("Poll")[0], signer) as Poll; + pollContract = PollFactory.connect(await maci.polls(0), signer); }); it("should have the correct coordinator pub key set on chain", async () => {