@maci-protocol/cli 0.0.0-ci.185b643

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +797 -0
  2. package/LICENSE +22 -0
  3. package/README.md +12 -0
  4. package/build/hardhat.config.d.ts +5 -0
  5. package/build/hardhat.config.d.ts.map +1 -0
  6. package/build/hardhat.config.js +27 -0
  7. package/build/hardhat.config.js.map +1 -0
  8. package/build/package.json +78 -0
  9. package/build/ts/cliInit.d.ts +2 -0
  10. package/build/ts/cliInit.d.ts.map +1 -0
  11. package/build/ts/cliInit.js +11 -0
  12. package/build/ts/cliInit.js.map +1 -0
  13. package/build/ts/index.d.ts +3 -0
  14. package/build/ts/index.d.ts.map +1 -0
  15. package/build/ts/index.js +912 -0
  16. package/build/ts/index.js.map +1 -0
  17. package/build/ts/utils/banner.d.ts +6 -0
  18. package/build/ts/utils/banner.d.ts.map +1 -0
  19. package/build/ts/utils/banner.js +30 -0
  20. package/build/ts/utils/banner.js.map +1 -0
  21. package/build/ts/utils/constants.d.ts +2 -0
  22. package/build/ts/utils/constants.d.ts.map +1 -0
  23. package/build/ts/utils/constants.js +10 -0
  24. package/build/ts/utils/constants.js.map +1 -0
  25. package/build/ts/utils/defaults.d.ts +7 -0
  26. package/build/ts/utils/defaults.d.ts.map +1 -0
  27. package/build/ts/utils/defaults.js +16 -0
  28. package/build/ts/utils/defaults.js.map +1 -0
  29. package/build/ts/utils/index.d.ts +6 -0
  30. package/build/ts/utils/index.d.ts.map +1 -0
  31. package/build/ts/utils/index.js +21 -0
  32. package/build/ts/utils/index.js.map +1 -0
  33. package/build/ts/utils/interfaces.d.ts +41 -0
  34. package/build/ts/utils/interfaces.d.ts.map +1 -0
  35. package/build/ts/utils/interfaces.js +3 -0
  36. package/build/ts/utils/interfaces.js.map +1 -0
  37. package/build/ts/utils/prompts.d.ts +7 -0
  38. package/build/ts/utils/prompts.d.ts.map +1 -0
  39. package/build/ts/utils/prompts.js +16 -0
  40. package/build/ts/utils/prompts.js.map +1 -0
  41. package/build/ts/utils/storage.d.ts +25 -0
  42. package/build/ts/utils/storage.d.ts.map +1 -0
  43. package/build/ts/utils/storage.js +65 -0
  44. package/build/ts/utils/storage.js.map +1 -0
  45. package/build/tsconfig.build.tsbuildinfo +1 -0
  46. package/package.json +79 -0
@@ -0,0 +1,912 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ const extra_typings_1 = require("@commander-js/extra-typings");
41
+ const domainobjs_1 = require("@maci-protocol/domainobjs");
42
+ const sdk_1 = require("@maci-protocol/sdk");
43
+ const ethers_1 = require("ethers");
44
+ const fs_1 = __importDefault(require("fs"));
45
+ const path_1 = __importDefault(require("path"));
46
+ require("./cliInit");
47
+ const utils_1 = require("./utils");
48
+ const defaults_1 = require("./utils/defaults");
49
+ // set the description version and name of the cli tool
50
+ const { description, version, name } = JSON.parse(fs_1.default.readFileSync(path_1.default.resolve(__dirname, "..", "package.json"), "utf8"));
51
+ const program = new extra_typings_1.Command();
52
+ program.name(name).description(description).version(version);
53
+ const getSigner = async () => Promise.resolve().then(() => __importStar(require("@maci-protocol/sdk"))).then((m) => m.getDefaultSigner());
54
+ // add the commands
55
+ program
56
+ .command("create")
57
+ .description("deploy the contracts")
58
+ .option("--poseidonT3Address <poseidonT3Address>", "PoseidonT3 contract address")
59
+ .option("--poseidonT4Address <poseidonT4Address>", "PoseidonT4 contract address")
60
+ .option("--poseidonT5Address <poseidonT5Address>", "PoseidonT5 contract address")
61
+ .option("--poseidonT6Address <poseidonT6Address>", "PoseidonT6 contract address")
62
+ .option("-g, --signupPolicyAddress <signupPolicyAddress>", "the signup policy contract address")
63
+ .option("--freeForAllCheckerFactoryAddress <freeForAllCheckerFactoryAddress>", "the free for all checker factory address (optional, using for deployment optimization)")
64
+ .option("--freeForAllPolicyFactoryAddress <freeForAllPolicyFactoryAddress>", "the free for all policy factory address (optional, using for deployment optimization)")
65
+ .requiredOption("--signupPolicyContractName <signupPolicyContractName>", "the signup policy contract name")
66
+ .option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
67
+ .option("-r, --rpc-provider <provider>", "the rpc provider URL")
68
+ .requiredOption("-s, --stateTreeDepth <stateTreeDepth>", "the state tree depth", parseInt)
69
+ .action(async (cmdOptions) => {
70
+ try {
71
+ const signer = await getSigner();
72
+ (0, utils_1.banner)(cmdOptions.quiet);
73
+ const network = await signer.provider?.getNetwork();
74
+ const [poseidonT3, poseidonT4, poseidonT5, poseidonT6] = (0, utils_1.readContractAddresses)({
75
+ contractNames: [sdk_1.EContracts.PoseidonT3, sdk_1.EContracts.PoseidonT4, sdk_1.EContracts.PoseidonT5, sdk_1.EContracts.PoseidonT6],
76
+ network: network?.name,
77
+ });
78
+ let [signupPolicyContractAddress] = (0, utils_1.readContractAddresses)({
79
+ contractNames: [cmdOptions.signupPolicyContractName.toString()],
80
+ network: network?.name,
81
+ });
82
+ if (!signupPolicyContractAddress) {
83
+ const checkerFactory = cmdOptions.freeForAllCheckerFactoryAddress
84
+ ? sdk_1.FreeForAllCheckerFactory__factory.connect(cmdOptions.freeForAllCheckerFactoryAddress, signer)
85
+ : undefined;
86
+ const policyFactory = cmdOptions.freeForAllPolicyFactoryAddress
87
+ ? sdk_1.FreeForAllPolicyFactory__factory.connect(cmdOptions.freeForAllPolicyFactoryAddress, signer)
88
+ : undefined;
89
+ const [contract] = await (0, sdk_1.deployFreeForAllSignUpPolicy)({ checker: checkerFactory, policy: policyFactory }, signer, true);
90
+ signupPolicyContractAddress = await contract.getAddress();
91
+ }
92
+ // deploy a verifier contract
93
+ const verifierContract = await (0, sdk_1.deployVerifier)(signer, true);
94
+ const verifierContractAddress = await verifierContract.getAddress();
95
+ // deploy MACI, PollFactory and poseidon
96
+ const { maciContractAddress, pollFactoryContractAddress, tallyFactoryContractAddress, messageProcessorFactoryContractAddress, poseidonAddresses, } = await (0, sdk_1.deployMaci)({
97
+ signupPolicyAddress: signupPolicyContractAddress,
98
+ poseidonAddresses: {
99
+ poseidonT3,
100
+ poseidonT4,
101
+ poseidonT5,
102
+ poseidonT6,
103
+ },
104
+ signer,
105
+ stateTreeDepth: cmdOptions.stateTreeDepth,
106
+ });
107
+ const emptyBallotRoots = (0, sdk_1.genEmptyBallotRoots)(cmdOptions.stateTreeDepth);
108
+ // save to the JSON File
109
+ await (0, utils_1.storeContractAddresses)({
110
+ data: {
111
+ [cmdOptions.signupPolicyContractName]: { address: signupPolicyContractAddress, args: [] },
112
+ [sdk_1.EContracts.Verifier]: { address: verifierContractAddress, args: [] },
113
+ [sdk_1.EContracts.MACI]: {
114
+ address: maciContractAddress,
115
+ args: [
116
+ pollFactoryContractAddress,
117
+ messageProcessorFactoryContractAddress,
118
+ tallyFactoryContractAddress,
119
+ signupPolicyContractAddress,
120
+ cmdOptions.stateTreeDepth,
121
+ emptyBallotRoots.map((root) => root.toString()),
122
+ ],
123
+ },
124
+ [sdk_1.EContracts.MessageProcessorFactory]: { address: messageProcessorFactoryContractAddress, args: [] },
125
+ [sdk_1.EContracts.TallyFactory]: { address: tallyFactoryContractAddress, args: [] },
126
+ [sdk_1.EContracts.PollFactory]: { address: pollFactoryContractAddress, args: [] },
127
+ [sdk_1.EContracts.PoseidonT3]: { address: poseidonAddresses.poseidonT3, args: [] },
128
+ [sdk_1.EContracts.PoseidonT4]: { address: poseidonAddresses.poseidonT4, args: [] },
129
+ [sdk_1.EContracts.PoseidonT5]: { address: poseidonAddresses.poseidonT5, args: [] },
130
+ [sdk_1.EContracts.PoseidonT6]: { address: poseidonAddresses.poseidonT6, args: [] },
131
+ },
132
+ signer,
133
+ });
134
+ (0, sdk_1.logGreen)({ quiet: cmdOptions.quiet, text: (0, sdk_1.success)(`MACI deployed at: ${maciContractAddress}`) });
135
+ }
136
+ catch (error) {
137
+ program.error(error.message, { exitCode: 1 });
138
+ }
139
+ });
140
+ program
141
+ .command("checkVerifyingKeys")
142
+ .description("check that the verifying keys in the contract match the local ones")
143
+ .option("-u, --use-quadratic-voting <useQuadraticVoting>", "whether to use quadratic voting", (value) => value === "true", true)
144
+ .option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
145
+ .option("-r, --rpc-provider <provider>", "the rpc provider URL")
146
+ .option("-k, --vk-contract <vkContract>", "the VkRegistry contract address")
147
+ .requiredOption("-s, --state-tree-depth <stateTreeDepth>", "the state tree depth", parseInt)
148
+ .requiredOption("-i, --int-state-tree-depth <intStateTreeDepth>", "the intermediate state tree depth", parseInt)
149
+ .requiredOption("-v, --vote-option-tree-depth <voteOptionTreeDepth>", "the vote option tree depth", parseInt)
150
+ .requiredOption("-b, --msg-batch-size <messageBatchSize>", "the message batch size", parseInt)
151
+ .requiredOption("-p, --process-messages-zkey <processMessagesZkeyPath>", "the process messages zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)")
152
+ .requiredOption("-t, --tally-votes-zkey <tallyVotesZkeyPath>", "the tally votes zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)")
153
+ .requiredOption("--poll-joining-zkey <pollJoiningZkey>", "the poll joining zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)")
154
+ .requiredOption("--poll-joined-zkey <pollJoinedZkey>", "the poll joined zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)")
155
+ .action(async (cmdOptions) => {
156
+ try {
157
+ const signer = await getSigner();
158
+ const network = await signer.provider?.getNetwork();
159
+ const [vkContractAddress] = (0, utils_1.readContractAddresses)({
160
+ contractNames: [sdk_1.EContracts.VkRegistry],
161
+ network: network?.name,
162
+ defaultAddresses: [cmdOptions.vkContract],
163
+ });
164
+ (0, sdk_1.logYellow)({ quiet: cmdOptions.quiet, text: (0, sdk_1.info)("Retrieving verifying keys from the contract...") });
165
+ await (0, sdk_1.checkVerifyingKeys)({
166
+ stateTreeDepth: cmdOptions.stateTreeDepth,
167
+ intStateTreeDepth: cmdOptions.intStateTreeDepth,
168
+ voteOptionTreeDepth: cmdOptions.voteOptionTreeDepth,
169
+ messageBatchSize: cmdOptions.msgBatchSize,
170
+ processMessagesZkeyPath: cmdOptions.processMessagesZkey,
171
+ tallyVotesZkeyPath: cmdOptions.tallyVotesZkey,
172
+ pollJoiningZkeyPath: cmdOptions.pollJoiningZkey,
173
+ pollJoinedZkeyPath: cmdOptions.pollJoinedZkey,
174
+ vkRegistry: vkContractAddress,
175
+ useQuadraticVoting: cmdOptions.useQuadraticVoting,
176
+ signer,
177
+ });
178
+ (0, sdk_1.logGreen)({ quiet: cmdOptions.quiet, text: (0, sdk_1.success)("Verifying keys match") });
179
+ }
180
+ catch (error) {
181
+ program.error(error.message, { exitCode: 1 });
182
+ }
183
+ });
184
+ program
185
+ .command("genMaciPubKey")
186
+ .description("generate a new MACI public key")
187
+ .requiredOption("-k, --privkey <privkey>", "the private key")
188
+ .option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
189
+ .option("-r, --rpc-provider <provider>", "the rpc provider URL")
190
+ .action((cmdObj) => {
191
+ const publicKey = (0, sdk_1.generateMaciPublicKey)(cmdObj.privkey);
192
+ (0, sdk_1.logGreen)({ quiet: cmdObj.quiet, text: (0, sdk_1.success)(`Public key: ${publicKey}`) });
193
+ });
194
+ program
195
+ .command("genMaciKeyPair")
196
+ .description("generate a new MACI key pair")
197
+ .option("-s, --seed <seed>", "seed value for keypair", (value) => (value ? BigInt(value) : undefined), undefined)
198
+ .option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
199
+ .action((cmdObj) => {
200
+ const { publicKey, privateKey } = (0, sdk_1.generateKeypair)({ seed: cmdObj.seed });
201
+ (0, sdk_1.logGreen)({ quiet: cmdObj.quiet, text: (0, sdk_1.success)(`Public key: ${publicKey}`) });
202
+ (0, sdk_1.logGreen)({ quiet: cmdObj.quiet, text: (0, sdk_1.success)(`Private key: ${privateKey}`) });
203
+ });
204
+ program
205
+ .command("deployVkRegistry")
206
+ .description("deploy a new verification key registry contract")
207
+ .option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
208
+ .option("-r, --rpc-provider <provider>", "the rpc provider URL")
209
+ .action(async (cmdObj) => {
210
+ try {
211
+ (0, utils_1.banner)(cmdObj.quiet);
212
+ const signer = await getSigner();
213
+ // assume that the vkRegistry contract is the first one to be deployed
214
+ const isContractAddressesStoreExists = fs_1.default.existsSync(utils_1.contractAddressesStorePath);
215
+ if (isContractAddressesStoreExists) {
216
+ const network = await signer.provider?.getNetwork();
217
+ (0, utils_1.resetContractAddresses)(network?.name);
218
+ }
219
+ // deploy and store the address
220
+ const vkRegistryAddress = await (0, sdk_1.deployVkRegistryContract)({ signer });
221
+ await (0, utils_1.storeContractAddresses)({
222
+ data: { [sdk_1.EContracts.VkRegistry]: { address: vkRegistryAddress, args: [] } },
223
+ signer,
224
+ });
225
+ (0, sdk_1.logGreen)({ quiet: cmdObj.quiet, text: (0, sdk_1.success)(`VkRegistry deployed at: ${vkRegistryAddress}`) });
226
+ }
227
+ catch (error) {
228
+ program.error(error.message, { exitCode: 1 });
229
+ }
230
+ });
231
+ program
232
+ .command("show")
233
+ .description("show the deployed contract addresses")
234
+ .action(async () => {
235
+ try {
236
+ (0, utils_1.banner)(false);
237
+ if (!fs_1.default.existsSync(utils_1.contractAddressesStorePath)) {
238
+ throw new Error("No contracts have been deployed yet");
239
+ }
240
+ const signer = await getSigner();
241
+ const [address, network] = await Promise.all([signer.getAddress(), signer.provider?.getNetwork()]);
242
+ const contractStorage = sdk_1.ContractStorage.getInstance();
243
+ contractStorage.printContracts(address, network?.name ?? "hardhat");
244
+ }
245
+ catch (error) {
246
+ program.error(error.message, { exitCode: 1 });
247
+ }
248
+ });
249
+ program
250
+ .command("deployPoll")
251
+ .description("deploy a new poll")
252
+ .option("-k, --vkRegistryAddress <vkRegistryAddress>", "the vk registry contract address")
253
+ .requiredOption("-s, --start <pollStartDate>", "the poll start date", parseInt)
254
+ .requiredOption("-e, --end <pollEndDate>", "the poll end date", parseInt)
255
+ .requiredOption("-i, --int-state-tree-depth <intStateTreeDepth>", "the int state tree depth", parseInt)
256
+ .requiredOption("-b, --msg-batch-size <messageBatchSize>", "the message batch size", parseInt)
257
+ .requiredOption("-s, --state-tree-depth <stateTreeDepth>", "the state tree depth", parseInt)
258
+ .requiredOption("-v, --vote-option-tree-depth <voteOptionTreeDepth>", "the vote option tree depth", parseInt)
259
+ .requiredOption("-p, --pubkey <coordinatorPubkey>", "the coordinator public key")
260
+ .option("-u, --use-quadratic-voting <useQuadraticVoting>", "whether to use quadratic voting", (value) => value === "true", true)
261
+ .option("-x, --maci-address <maciAddress>", "the MACI contract address")
262
+ .option("-m, --relayers <relayers>", "the relayer addresses", (value) => value.split(",").map((item) => item.trim()))
263
+ .option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
264
+ .option("-r, --rpc-provider <provider>", "the rpc provider URL")
265
+ .option("-o, --vote-options <voteOptions>", "the number of vote options", parseInt)
266
+ .option("--initial-voice-credits <initialVoiceCredits>", "the initial voice credits", parseInt)
267
+ .option("--initial-voice-credits-proxy <initialVoiceCreditsProxy>", "the initial voice credits proxy address")
268
+ .option("--signup-policy <signupPolicy>", "the signup policy contract address")
269
+ .action(async (cmdObj) => {
270
+ try {
271
+ (0, utils_1.banner)(cmdObj.quiet);
272
+ const signer = await getSigner();
273
+ const network = await signer.provider?.getNetwork();
274
+ const [vkRegistryAddress, maciAddress, initialVoiceCreditProxyAddress, verifierContractAddress] = (0, utils_1.readContractAddresses)({
275
+ contractNames: [
276
+ sdk_1.EContracts.VkRegistry,
277
+ sdk_1.EContracts.MACI,
278
+ sdk_1.EContracts.ConstantInitialVoiceCreditProxy,
279
+ sdk_1.EContracts.Verifier,
280
+ ],
281
+ network: network?.name,
282
+ defaultAddresses: [cmdObj.vkRegistryAddress, cmdObj.maciAddress, cmdObj.initialVoiceCreditsProxy],
283
+ });
284
+ const maciContract = sdk_1.MACI__factory.connect(maciAddress, signer);
285
+ const nextPollId = await maciContract.nextPollId();
286
+ const policyTrait = await (0, sdk_1.getPolicyTrait)({ maciAddress, signer });
287
+ const policyContractName = (0, sdk_1.getPolicyContractNamesByTrait)(policyTrait);
288
+ const [signupPolicyContractAddress] = (0, utils_1.readContractAddresses)({
289
+ contractNames: [policyContractName.toString()],
290
+ keys: [nextPollId.toString()],
291
+ network: network?.name,
292
+ defaultAddresses: [cmdObj.signupPolicy],
293
+ });
294
+ const { pollId, pollContractAddress, tallyContractAddress, messageProcessorContractAddress, initialVoiceCreditProxyContractAddress, policyContractAddress, } = await (0, sdk_1.deployPoll)({
295
+ initialVoiceCredits: cmdObj.initialVoiceCredits || defaults_1.DEFAULT_INITIAL_VOICE_CREDITS,
296
+ pollStartTimestamp: cmdObj.start,
297
+ pollEndTimestamp: cmdObj.end,
298
+ intStateTreeDepth: cmdObj.intStateTreeDepth,
299
+ messageBatchSize: cmdObj.msgBatchSize,
300
+ stateTreeDepth: cmdObj.stateTreeDepth,
301
+ voteOptionTreeDepth: cmdObj.voteOptionTreeDepth,
302
+ coordinatorPubKey: domainobjs_1.PubKey.deserialize(cmdObj.pubkey),
303
+ maciAddress,
304
+ vkRegistryContractAddress: vkRegistryAddress,
305
+ relayers: cmdObj.relayers ?? [ethers_1.ZeroAddress],
306
+ mode: cmdObj.useQuadraticVoting ? sdk_1.EMode.QV : sdk_1.EMode.NON_QV,
307
+ signer,
308
+ voteOptions: cmdObj.voteOptions ?? defaults_1.DEFAULT_VOTE_OPTIONS,
309
+ verifierContractAddress,
310
+ policyContractAddress: signupPolicyContractAddress,
311
+ initialVoiceCreditProxyContractAddress: initialVoiceCreditProxyAddress,
312
+ });
313
+ (0, sdk_1.logGreen)({ quiet: cmdObj.quiet, text: (0, sdk_1.success)(`Poll ID: ${pollId}`) });
314
+ (0, sdk_1.logGreen)({ quiet: cmdObj.quiet, text: (0, sdk_1.success)(`Poll contract address: ${pollContractAddress}`) });
315
+ (0, sdk_1.logGreen)({ quiet: cmdObj.quiet, text: (0, sdk_1.success)(`Tally contract address: ${tallyContractAddress}`) });
316
+ (0, sdk_1.logGreen)({
317
+ quiet: cmdObj.quiet,
318
+ text: (0, sdk_1.success)(`Message processor contract address: ${messageProcessorContractAddress}`),
319
+ });
320
+ (0, sdk_1.logGreen)({
321
+ quiet: cmdObj.quiet,
322
+ text: (0, sdk_1.success)(`Initial voice credit proxy contract address: ${initialVoiceCreditProxyContractAddress}`),
323
+ });
324
+ (0, sdk_1.logGreen)({
325
+ quiet: cmdObj.quiet,
326
+ text: (0, sdk_1.success)(`Signup policy contract address: ${policyContractAddress}`),
327
+ });
328
+ }
329
+ catch (error) {
330
+ program.error(error.message, { exitCode: 1 });
331
+ }
332
+ });
333
+ program
334
+ .command("joinPoll")
335
+ .description("join the poll")
336
+ .requiredOption("-k, --priv-key <privKey>", "the private key")
337
+ .option("-i, --state-index <stateIndex>", "the user's state index", BigInt)
338
+ .option("-s, --sg-data <sgData>", "the signup policy data")
339
+ .option("-v, --ivcp-data <ivcpData>", "the initial voice credit proxy data")
340
+ .option("-n, --new-voice-credit-balance <newVoiceCreditBalance>", "the voice credit balance of the user for the poll", BigInt)
341
+ .requiredOption("-p, --poll-id <pollId>", "the id of the poll", BigInt)
342
+ .option("-x, --maci-address <maciAddress>", "the MACI contract address")
343
+ .option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
344
+ .option("--state-file <stateFile>", "the path to the state file containing the serialized maci state")
345
+ .option("--start-block <startBlock>", "the block number to start looking for events from", parseInt)
346
+ .option("--end-block <endBlock>", "the block number to end looking for events from", parseInt)
347
+ .option("--blocks-per-batch <blockPerBatch>", "the number of blocks to process per batch", parseInt)
348
+ .option("--transaction-hash <transactionHash>", "transaction hash of MACI contract creation")
349
+ .option("--poll-wasm <pollWasm>", "the path to the poll witness generation wasm binary")
350
+ .requiredOption("--poll-joining-zkey <pollZkeyPath>", "the poll join zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)")
351
+ .option("-w, --wasm", "whether to use the wasm binaries")
352
+ .option("-r, --rapidsnark <rapidsnark>", "the path to the rapidsnark binary")
353
+ .option("-g, --poll-witnessgen <pollWitnessgen>", "the path to the poll witness generation binary")
354
+ .action(async (cmdObj) => {
355
+ try {
356
+ const signer = await getSigner();
357
+ const network = await signer.provider?.getNetwork();
358
+ const [maciAddress] = (0, utils_1.readContractAddresses)({
359
+ contractNames: [sdk_1.EContracts.MACI],
360
+ network: network?.name,
361
+ defaultAddresses: [cmdObj.maciAddress],
362
+ });
363
+ const privateKey = cmdObj.privKey || (await (0, utils_1.promptSensitiveValue)("Insert your MACI private key"));
364
+ const data = await (0, sdk_1.joinPoll)({
365
+ maciAddress,
366
+ privateKey,
367
+ stateIndex: cmdObj.stateIndex,
368
+ stateFile: cmdObj.stateFile,
369
+ pollId: cmdObj.pollId,
370
+ signer,
371
+ startBlock: cmdObj.startBlock,
372
+ endBlock: cmdObj.endBlock,
373
+ blocksPerBatch: cmdObj.blocksPerBatch,
374
+ pollJoiningZkey: cmdObj.pollJoiningZkey,
375
+ pollWasm: cmdObj.pollWasm,
376
+ useWasm: cmdObj.wasm,
377
+ rapidsnark: cmdObj.rapidsnark,
378
+ pollWitgen: cmdObj.pollWitnessgen,
379
+ sgDataArg: cmdObj.sgData ?? utils_1.DEFAULT_SG_DATA,
380
+ ivcpDataArg: cmdObj.ivcpData ?? utils_1.DEFAULT_IVCP_DATA,
381
+ });
382
+ (0, sdk_1.logGreen)({ quiet: cmdObj.quiet, text: (0, sdk_1.info)(`User joined poll with nullifier: ${data.nullifier}`) });
383
+ (0, sdk_1.logGreen)({ quiet: cmdObj.quiet, text: (0, sdk_1.info)(`User joined poll with state index: ${data.pollStateIndex}`) });
384
+ (0, sdk_1.logGreen)({ quiet: cmdObj.quiet, text: (0, sdk_1.info)(`User joined poll with ${data.voiceCredits} voice credits`) });
385
+ }
386
+ catch (error) {
387
+ program.error(error.message, { exitCode: 1 });
388
+ }
389
+ });
390
+ program
391
+ .command("setVerifyingKeys")
392
+ .description("set the verifying keys")
393
+ .requiredOption("-s, --state-tree-depth <stateTreeDepth>", "the state tree depth", parseInt)
394
+ .requiredOption("-i, --int-state-tree-depth <intStateTreeDepth>", "the intermediate state tree depth", parseInt)
395
+ .requiredOption("-v, --vote-option-tree-depth <voteOptionTreeDepth>", "the vote option tree depth", parseInt)
396
+ .requiredOption("-b, --msg-batch-size <messageBatchSize>", "the message batch size", parseInt)
397
+ .option("--poll-state-tree-depth <pollStateTreeDepth>", "the poll state tree depth", parseInt)
398
+ .option("--poll-joining-zkey <pollJoiningZkeyPath>", "the poll joining zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)")
399
+ .option("--poll-joined-zkey <pollJoinedZkeyPath>", "the poll joined zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)")
400
+ .option("--process-messages-zkey-qv <processMessagesZkeyPathQv>", "the process messages qv zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)")
401
+ .option("--tally-votes-zkey-qv <tallyVotesZkeyPathQv>", "the tally votes qv zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)")
402
+ .option("--process-messages-zkey-non-qv <processMessagesZkeyPathNonQv>", "the process messages non-qv zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)")
403
+ .option("--tally-votes-zkey-non-qv <tallyVotesZkeyPathNonQv>", "the tally votes non-qv zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)")
404
+ .option("-u, --use-quadratic-voting <useQuadraticVoting>", "whether to use quadratic voting", (value) => value === "true", true)
405
+ .option("-k, --vk-registry <vkRegistry>", "the vk registry contract address")
406
+ .option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
407
+ .option("-r, --rpc-provider <provider>", "the rpc provider URL")
408
+ .action(async (cmdObj) => {
409
+ try {
410
+ const signer = await getSigner();
411
+ const network = await signer.provider?.getNetwork();
412
+ const [vkRegistryAddress] = (0, utils_1.readContractAddresses)({
413
+ contractNames: [sdk_1.EContracts.VkRegistry],
414
+ network: network?.name,
415
+ defaultAddresses: [cmdObj.vkRegistry],
416
+ });
417
+ const { pollJoiningVk, pollJoinedVk, processVk, tallyVk } = await (0, sdk_1.extractAllVks)({
418
+ pollJoiningZkeyPath: cmdObj.pollJoiningZkey,
419
+ pollJoinedZkeyPath: cmdObj.pollJoinedZkey,
420
+ processMessagesZkeyPath: cmdObj.useQuadraticVoting
421
+ ? cmdObj.processMessagesZkeyQv
422
+ : cmdObj.processMessagesZkeyNonQv,
423
+ tallyVotesZkeyPath: cmdObj.useQuadraticVoting ? cmdObj.tallyVotesZkeyQv : cmdObj.tallyVotesZkeyQv,
424
+ });
425
+ await (0, sdk_1.setVerifyingKeys)({
426
+ stateTreeDepth: cmdObj.stateTreeDepth,
427
+ intStateTreeDepth: cmdObj.intStateTreeDepth,
428
+ voteOptionTreeDepth: cmdObj.voteOptionTreeDepth,
429
+ messageBatchSize: cmdObj.msgBatchSize,
430
+ pollStateTreeDepth: cmdObj.pollStateTreeDepth || cmdObj.stateTreeDepth,
431
+ pollJoiningVk: pollJoiningVk,
432
+ pollJoinedVk: pollJoinedVk,
433
+ processMessagesVk: processVk,
434
+ tallyVotesVk: tallyVk,
435
+ vkRegistryAddress,
436
+ mode: cmdObj.useQuadraticVoting ? sdk_1.EMode.QV : sdk_1.EMode.NON_QV,
437
+ signer,
438
+ });
439
+ }
440
+ catch (error) {
441
+ program.error(error.message, { exitCode: 1 });
442
+ }
443
+ });
444
+ program
445
+ .command("publish")
446
+ .description("publish a new message to a MACI Poll contract")
447
+ .requiredOption("-p, --pubkey <pubkey>", "the MACI public key which should replace the user's public key in the state tree")
448
+ .option("-x, --maci-address <maciAddress>", "the MACI contract address")
449
+ .option("-k, --privkey <privkey>", "your serialized MACI private key")
450
+ .requiredOption("-i, --state-index <stateIndex>", "the user's state index", BigInt)
451
+ .requiredOption("-v, --vote-option-index <voteOptionIndex>", "the vote option index", BigInt)
452
+ .requiredOption("-n, --nonce <nonce>", "the message nonce", BigInt)
453
+ .option("-s, --salt <salt>", "the message salt", BigInt)
454
+ .requiredOption("-o, --poll-id <pollId>", "the poll id", BigInt)
455
+ .requiredOption("-w, --new-vote-weight <newVoteWeight>", "the new vote weight", BigInt)
456
+ .option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
457
+ .option("-r, --rpc-provider <provider>", "the rpc provider URL")
458
+ .action(async (cmdObj) => {
459
+ try {
460
+ const signer = await getSigner();
461
+ const network = await signer.provider?.getNetwork();
462
+ const [maciAddress] = (0, utils_1.readContractAddresses)({
463
+ contractNames: [sdk_1.EContracts.MACI],
464
+ network: network?.name,
465
+ defaultAddresses: [cmdObj.maciAddress],
466
+ });
467
+ const privateKey = cmdObj.privkey || (await (0, utils_1.promptSensitiveValue)("Insert your MACI private key"));
468
+ await (0, sdk_1.publish)({
469
+ pubkey: cmdObj.pubkey,
470
+ stateIndex: cmdObj.stateIndex,
471
+ voteOptionIndex: cmdObj.voteOptionIndex,
472
+ nonce: cmdObj.nonce,
473
+ pollId: cmdObj.pollId,
474
+ newVoteWeight: cmdObj.newVoteWeight,
475
+ maciAddress,
476
+ salt: cmdObj.salt,
477
+ privateKey,
478
+ signer,
479
+ });
480
+ }
481
+ catch (error) {
482
+ program.error(error.message, { exitCode: 1 });
483
+ }
484
+ });
485
+ program
486
+ .command("mergeSignups")
487
+ .description("merge the signups accumulator queue")
488
+ .option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
489
+ .option("-x, --maci-address <maciAddress>", "the MACI contract address")
490
+ .requiredOption("-p, --poll-id <pollId>", "the poll id", BigInt)
491
+ .action(async (cmdObj) => {
492
+ try {
493
+ const signer = await getSigner();
494
+ const network = await signer.provider?.getNetwork();
495
+ const [maciAddress] = (0, utils_1.readContractAddresses)({
496
+ contractNames: [sdk_1.EContracts.MACI],
497
+ network: network?.name,
498
+ defaultAddresses: [cmdObj.maciAddress],
499
+ });
500
+ const receipt = await (0, sdk_1.mergeSignups)({
501
+ pollId: cmdObj.pollId,
502
+ maciAddress,
503
+ signer,
504
+ });
505
+ (0, sdk_1.logGreen)({ quiet: cmdObj.quiet, text: (0, sdk_1.info)(`Transaction hash: ${receipt.hash}`) });
506
+ (0, sdk_1.logGreen)({
507
+ quiet: cmdObj.quiet,
508
+ text: (0, sdk_1.success)(`Executed mergeSignups(); gas used: ${receipt.gasUsed.toString()}`),
509
+ });
510
+ }
511
+ catch (error) {
512
+ program.error(error.message, { exitCode: 1 });
513
+ }
514
+ });
515
+ program
516
+ .command("timeTravel")
517
+ .description("fast-forward the time (only works for local hardhat testing")
518
+ .requiredOption("-s, --seconds <seconds>", "the number of seconds to fast-forward", parseInt)
519
+ .option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
520
+ .option("-r, --rpc-provider <provider>", "the rpc provider URL")
521
+ .action(async (cmdObj) => {
522
+ try {
523
+ (0, utils_1.banner)(cmdObj.quiet);
524
+ const signer = await getSigner();
525
+ await (0, sdk_1.timeTravel)({ seconds: cmdObj.seconds, signer });
526
+ (0, sdk_1.logGreen)({ quiet: cmdObj.quiet, text: (0, sdk_1.success)(`Fast-forwarded ${cmdObj.seconds} seconds`) });
527
+ }
528
+ catch (error) {
529
+ program.error(error.message, { exitCode: 1 });
530
+ }
531
+ });
532
+ program
533
+ .command("extractVkToFile")
534
+ .description("extract vkey to json file")
535
+ .requiredOption("--poll-joining-zkey <pollJoiningZkey>", "the poll joining zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)")
536
+ .requiredOption("--poll-joined-zkey <pollJoinedZkey>", "the poll joined zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)")
537
+ .requiredOption("--process-messages-zkey-qv <processMessagesZkeyPathQv>", "the process messages qv zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)")
538
+ .requiredOption("--tally-votes-zkey-qv <tallyVotesZkeyPathQv>", "the tally votes qv zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)")
539
+ .requiredOption("--process-messages-zkey-non-qv <processMessagesZkeyPathNonQv>", "the process messages non-qv zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)")
540
+ .requiredOption("--tally-votes-zkey-non-qv <tallyVotesZkeyPathNonQv>", "the tally votes non-qv zkey path (see different options for zkey files to use specific circuits https://maci.pse.dev/docs/trusted-setup, https://maci.pse.dev/docs/testing/#pre-compiled-artifacts-for-testing)")
541
+ .requiredOption("-o, --output-file <outputFile>", "the output file path of extracted vkeys")
542
+ .action(async (cmdObj) => {
543
+ try {
544
+ await (0, sdk_1.extractVkToFile)({
545
+ processMessagesZkeyPathQv: cmdObj.processMessagesZkeyQv,
546
+ tallyVotesZkeyPathQv: cmdObj.tallyVotesZkeyQv,
547
+ processMessagesZkeyPathNonQv: cmdObj.processMessagesZkeyNonQv,
548
+ tallyVotesZkeyPathNonQv: cmdObj.tallyVotesZkeyNonQv,
549
+ pollJoiningZkeyPath: cmdObj.pollJoiningZkey,
550
+ pollJoinedZkeyPath: cmdObj.pollJoinedZkey,
551
+ outputFilePath: cmdObj.outputFile,
552
+ });
553
+ }
554
+ catch (error) {
555
+ program.error(error.message, { exitCode: 1 });
556
+ }
557
+ });
558
+ program
559
+ .command("signup")
560
+ .description("Sign up to a MACI contract")
561
+ .requiredOption("-p, --pubkey <maciPubKey>", "the MACI public key")
562
+ .option("-x, --maci-address <maciAddress>", "the MACI contract address")
563
+ .option("-s, --sg-data <sgData>", "the signup gateway data")
564
+ .option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
565
+ .option("-r, --rpc-provider <provider>", "the rpc provider URL")
566
+ .action(async (cmdObj) => {
567
+ try {
568
+ const signer = await getSigner();
569
+ const network = await signer.provider?.getNetwork();
570
+ const [maciAddress] = (0, utils_1.readContractAddresses)({
571
+ contractNames: [sdk_1.EContracts.MACI],
572
+ network: network?.name,
573
+ defaultAddresses: [cmdObj.maciAddress],
574
+ });
575
+ const data = await (0, sdk_1.signup)({
576
+ maciPubKey: cmdObj.pubkey,
577
+ maciAddress,
578
+ sgData: cmdObj.sgData ?? utils_1.DEFAULT_SG_DATA,
579
+ signer,
580
+ });
581
+ (0, sdk_1.logGreen)({
582
+ quiet: cmdObj.quiet,
583
+ text: (0, sdk_1.success)(`State index: ${data.stateIndex.toString()}\n Transaction hash: ${data.transactionHash}`),
584
+ });
585
+ }
586
+ catch (error) {
587
+ program.error(error.message, { exitCode: 1 });
588
+ }
589
+ });
590
+ program
591
+ .command("isRegisteredUser")
592
+ .description("Checks if user is registered with their public key and get their data")
593
+ .requiredOption("-p, --pubkey <maciPubKey>", "the MACI public key")
594
+ .option("-x, --maci-address <maciAddress>", "the MACI contract address")
595
+ .option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
596
+ .action(async (cmdObj) => {
597
+ try {
598
+ const signer = await getSigner();
599
+ const network = await signer.provider?.getNetwork();
600
+ const [maciAddress] = (0, utils_1.readContractAddresses)({
601
+ contractNames: [sdk_1.EContracts.MACI],
602
+ network: network?.name,
603
+ defaultAddresses: [cmdObj.maciAddress],
604
+ });
605
+ const data = await (0, sdk_1.getSignedupUserData)({
606
+ maciPubKey: cmdObj.pubkey,
607
+ maciAddress,
608
+ signer,
609
+ });
610
+ if (data.isRegistered) {
611
+ (0, sdk_1.logGreen)({ quiet: cmdObj.quiet, text: (0, sdk_1.success)(`State index: ${data.stateIndex?.toString()}`) });
612
+ }
613
+ else {
614
+ (0, sdk_1.logRed)({ quiet: cmdObj.quiet, text: "User is not registered" });
615
+ }
616
+ }
617
+ catch (error) {
618
+ program.error(error.message, { exitCode: 1 });
619
+ }
620
+ });
621
+ program
622
+ .command("isJoinedUser")
623
+ .description("Checks if user is joined to the poll with public key")
624
+ .requiredOption("-p, --pubkey <pubkey>", "the MACI public key")
625
+ .option("-x, --maci-address <maciAddress>", "the MACI contract address")
626
+ .requiredOption("-o, --poll-id <pollId>", "the poll id", BigInt)
627
+ .option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
628
+ .option("--start-block <startBlock>", "the block number to start looking for events from", parseInt)
629
+ .option("--end-block <endBlock>", "the block number to end looking for events from", parseInt)
630
+ .option("--blocks-per-batch <blockPerBatch>", "the number of blocks to process per batch", parseInt)
631
+ .action(async (cmdObj) => {
632
+ try {
633
+ const signer = await getSigner();
634
+ const network = await signer.provider?.getNetwork();
635
+ const [maciAddress] = (0, utils_1.readContractAddresses)({
636
+ contractNames: [sdk_1.EContracts.MACI],
637
+ network: network?.name,
638
+ defaultAddresses: [cmdObj.maciAddress],
639
+ });
640
+ const data = await (0, sdk_1.getJoinedUserData)({
641
+ pollPubKey: cmdObj.pubkey,
642
+ startBlock: cmdObj.startBlock,
643
+ maciAddress,
644
+ pollId: cmdObj.pollId,
645
+ signer,
646
+ });
647
+ if (data.isJoined) {
648
+ (0, sdk_1.logGreen)({
649
+ quiet: cmdObj.quiet,
650
+ text: (0, sdk_1.success)([
651
+ `Poll state index: ${data.pollStateIndex?.toString()}, registered: ${data.isJoined}`,
652
+ `Voice credits: ${data.voiceCredits?.toString()}`,
653
+ ].join("\n")),
654
+ });
655
+ }
656
+ else {
657
+ (0, sdk_1.logRed)({ quiet: cmdObj.quiet, text: "User has not joined the poll" });
658
+ }
659
+ }
660
+ catch (error) {
661
+ program.error(error.message, { exitCode: 1 });
662
+ }
663
+ });
664
+ program
665
+ .command("getPoll")
666
+ .description("Get deployed poll from MACI contract")
667
+ .option("-p, --poll <poll>", "the poll id")
668
+ .option("-x, --maci-address <maciAddress>", "the MACI contract address")
669
+ .action(async (cmdObj) => {
670
+ try {
671
+ const signer = await getSigner();
672
+ const network = await signer.provider?.getNetwork();
673
+ const [maciAddress] = (0, utils_1.readContractAddresses)({
674
+ contractNames: [sdk_1.EContracts.MACI],
675
+ network: network?.name,
676
+ defaultAddresses: [cmdObj.maciAddress],
677
+ });
678
+ const details = await (0, sdk_1.getPoll)({
679
+ pollId: cmdObj.poll,
680
+ maciAddress,
681
+ signer,
682
+ });
683
+ (0, sdk_1.logGreen)({
684
+ quiet: true,
685
+ text: (0, sdk_1.success)([
686
+ `ID: ${details.id}`,
687
+ `Start time: ${new Date(Number(details.startDate) * 1000).toString()}`,
688
+ `End time: ${new Date(Number(details.endDate) * 1000).toString()}`,
689
+ `Number of signups ${details.numSignups}`,
690
+ `State tree merged: ${details.isMerged}`,
691
+ `Mode: ${details.mode === 0n ? "Quadratic Voting" : "Non-Quadratic Voting"}`,
692
+ ].join("\n")),
693
+ });
694
+ }
695
+ catch (error) {
696
+ program.error(error.message, { exitCode: 1 });
697
+ }
698
+ });
699
+ program
700
+ .command("fundWallet")
701
+ .description("Fund a wallet with Ether")
702
+ .requiredOption("-a, --amount <amount>", "the amount of Ether", parseInt)
703
+ .requiredOption("-w, --address <address>", "the address to fund")
704
+ .option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
705
+ .option("-r, --rpc-provider <provider>", "the rpc provider URL")
706
+ .action(async (cmdObj) => {
707
+ try {
708
+ (0, utils_1.banner)(cmdObj.quiet);
709
+ const signer = await getSigner();
710
+ const hash = await (0, sdk_1.fundWallet)({ amount: cmdObj.amount, address: cmdObj.address, signer });
711
+ (0, sdk_1.logYellow)({ quiet: cmdObj.quiet, text: (0, sdk_1.info)(`Transaction hash: ${hash}`) });
712
+ (0, sdk_1.logGreen)({
713
+ quiet: cmdObj.quiet,
714
+ text: (0, sdk_1.success)(`Successfully funded ${cmdObj.address} with ${cmdObj.amount} wei`),
715
+ });
716
+ }
717
+ catch (error) {
718
+ program.error(error.message, { exitCode: 1 });
719
+ }
720
+ });
721
+ program
722
+ .command("verify")
723
+ .description("verify the results of a poll")
724
+ .requiredOption("-o, --poll-id <pollId>", "the poll id", BigInt)
725
+ .requiredOption("-t, --tally-file <tallyFile>", "the tally file with results, per vote option spent credits, spent voice credits total")
726
+ .option("-x, --maci-address <maciAddress>", "the MACI contract address")
727
+ .option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
728
+ .option("-r, --rpc-provider <provider>", "the rpc provider URL")
729
+ .action(async (cmdObj) => {
730
+ try {
731
+ (0, utils_1.banner)(cmdObj.quiet);
732
+ const signer = await getSigner();
733
+ const network = await signer.provider?.getNetwork();
734
+ // read the tally file
735
+ const isTallyFileExists = fs_1.default.existsSync(cmdObj.tallyFile);
736
+ if (!cmdObj.tallyFile || !isTallyFileExists) {
737
+ throw new Error(`Unable to open ${cmdObj.tallyFile}`);
738
+ }
739
+ const tallyData = await (0, utils_1.readJSONFile)(cmdObj.tallyFile);
740
+ const [maciAddress] = (0, utils_1.readContractAddresses)({
741
+ contractNames: [sdk_1.EContracts.MACI],
742
+ network: network?.name,
743
+ defaultAddresses: [cmdObj.maciAddress],
744
+ });
745
+ const pollParams = await (0, sdk_1.getPollParams)({ pollId: cmdObj.pollId, maciContractAddress: maciAddress, signer });
746
+ const tallyCommitments = (0, sdk_1.generateTallyCommitments)({
747
+ tallyData,
748
+ voteOptionTreeDepth: pollParams.voteOptionTreeDepth,
749
+ });
750
+ await (0, sdk_1.verify)({
751
+ tallyData,
752
+ pollId: cmdObj.pollId,
753
+ maciAddress,
754
+ signer,
755
+ tallyCommitments,
756
+ numVoteOptions: pollParams.numVoteOptions,
757
+ voteOptionTreeDepth: pollParams.voteOptionTreeDepth,
758
+ });
759
+ }
760
+ catch (error) {
761
+ program.error(error.message, { exitCode: 1 });
762
+ }
763
+ });
764
+ program
765
+ .command("genProofs")
766
+ .description("generate the proofs for a poll")
767
+ .option("-k, --privkey <privkey>", "your serialized MACI private key")
768
+ .option("-x, --maci-address <maciAddress>", "the MACI contract address")
769
+ .requiredOption("-o, --poll-id <pollId>", "the poll id", BigInt)
770
+ .requiredOption("-t, --tally-file <tallyFile>", "the tally file with results, per vote option spent credits, spent voice credits total")
771
+ .option("-r, --rapidsnark <rapidsnark>", "the path to the rapidsnark binary")
772
+ .option("-g, --process-witnessgen <processWitnessgen>", "the path to the process witness generation binary")
773
+ .option("--process-witnessdat <processWitnessdat>", "the path to the process witness dat file")
774
+ .option("--tally-witnessgen <tallyWitnessgen>", "the path to the tally witness generation binary")
775
+ .option("--tally-witnessdat <tallyWitnessdat>", "the path to the tally witness dat file")
776
+ .requiredOption("--poll-joining-zkey <processJoinZkey>", "the path to the poll join zkey")
777
+ .requiredOption("--process-zkey <processZkey>", "the path to the process zkey")
778
+ .requiredOption("--tally-zkey <tallyZkey>", "the path to the tally zkey")
779
+ .option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
780
+ .option("-p, --rpc-provider <provider>", "the rpc provider URL")
781
+ .requiredOption("-f, --output <outputDir>", "the output directory for proofs")
782
+ .option("--transaction-hash <transactionHash>", "transaction hash of MACI contract creation")
783
+ .option("-w, --wasm", "whether to use the wasm binaries")
784
+ .option("--process-wasm <processWasm>", "the path to the process witness generation wasm binary")
785
+ .option("--tally-wasm <tallyWasm>", "the path to the tally witness generation wasm binary")
786
+ .option("--state-file <stateFile>", "the path to the state file containing the serialized maci state")
787
+ .option("--start-block <startBlock>", "the block number to start looking for events from", parseInt)
788
+ .option("--end-block <endBlock>", "the block number to end looking for events from", parseInt)
789
+ .option("--blocks-per-batch <blockPerBatch>", "the number of blocks to process per batch", parseInt)
790
+ .option("-u, --use-quadratic-voting <useQuadraticVoting>", "whether to use quadratic voting", (value) => value === "true", true)
791
+ .option("-b, --ipfs-message-backup-files <ipfsMessageBackupFiles>", "Backup files for ipfs messages (name format: ipfsHash1.json, ipfsHash2.json, ..., ipfsHashN.json)", (value) => value?.split(/\s*,\s*/))
792
+ .action(async ({ quiet, maciAddress, pollId, ipfsMessageBackupFiles, stateFile, startBlock, endBlock, blocksPerBatch, privkey, transactionHash, output, tallyFile, tallyZkey, tallyWitnessgen, tallyWasm, processZkey, processWitnessgen, processWasm, useQuadraticVoting, tallyWitnessdat, processWitnessdat, wasm, rapidsnark, }) => {
793
+ try {
794
+ (0, utils_1.banner)(quiet);
795
+ const signer = await getSigner();
796
+ const network = await signer.provider?.getNetwork();
797
+ const [maciContractAddress] = (0, utils_1.readContractAddresses)({
798
+ contractNames: [sdk_1.EContracts.MACI],
799
+ network: network?.name,
800
+ defaultAddresses: [maciAddress],
801
+ });
802
+ const coordinatorPrivateKey = privkey || (await (0, utils_1.promptSensitiveValue)("Insert your MACI private key"));
803
+ await (0, sdk_1.generateProofs)({
804
+ maciAddress: maciContractAddress,
805
+ coordinatorPrivateKey,
806
+ pollId: Number(pollId),
807
+ ipfsMessageBackupFiles,
808
+ stateFile: stateFile || "",
809
+ transactionHash: transactionHash || "",
810
+ startBlock,
811
+ endBlock,
812
+ blocksPerBatch,
813
+ signer,
814
+ outputDir: output,
815
+ tallyFile,
816
+ tallyZkey,
817
+ tallyWitgen: tallyWitnessgen,
818
+ tallyWasm,
819
+ processZkey,
820
+ processWitgen: processWitnessgen,
821
+ processWasm,
822
+ useQuadraticVoting,
823
+ tallyDatFile: tallyWitnessdat,
824
+ processDatFile: processWitnessdat,
825
+ useWasm: wasm,
826
+ rapidsnark,
827
+ });
828
+ }
829
+ catch (error) {
830
+ program.error(error.message, { exitCode: 1 });
831
+ }
832
+ });
833
+ program
834
+ .command("genLocalState")
835
+ .description("generate a local MACI state from the smart contracts events")
836
+ .requiredOption("-o, --output <outputPath>", "the path where to write the state")
837
+ .requiredOption("-p, --poll-id <pollId>", "the id of the poll", BigInt)
838
+ .option("-x, --maci-address <maciAddress>", "the MACI contract address")
839
+ .option("-k, --privkey <privkey>", "your serialized MACI private key")
840
+ .option("--start-block <startBlock>", "the start block number", parseInt)
841
+ .option("--end-block <endBlock>", "the end block number", parseInt)
842
+ .option("--blocks-per-batch <blockPerBatch>", "the blocks per batch", parseInt)
843
+ .option("--transaction-hash <transactionHash>", "the transaction hash")
844
+ .option("-s, --sleep <sleep>", "the sleep time between batches", parseInt)
845
+ .option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
846
+ .option("-r, --rpc-provider <provider>", "the rpc provider URL")
847
+ .option("-b, --ipfs-message-backup-files <ipfsMessageBackupFiles>", "Backup files for ipfs messages (name format: ipfsHash1.json, ipfsHash2.json, ..., ipfsHashN.json)", (value) => value?.split(/\s*,\s*/))
848
+ .option("-l, --logs-output <logsOutputPath>", "the path where to save the logs for debugging and auditing purposes")
849
+ .action(async (cmdObj) => {
850
+ try {
851
+ const signer = await getSigner();
852
+ const network = await signer.provider?.getNetwork();
853
+ const [maciAddress] = (0, utils_1.readContractAddresses)({
854
+ contractNames: [sdk_1.EContracts.MACI],
855
+ network: network?.name,
856
+ defaultAddresses: [cmdObj.maciAddress],
857
+ });
858
+ const coordinatorPrivateKey = cmdObj.privkey || (await (0, utils_1.promptSensitiveValue)("Insert your MACI private key"));
859
+ await (0, sdk_1.generateMaciState)({
860
+ outputPath: cmdObj.output.toString(),
861
+ pollId: cmdObj.pollId,
862
+ maciAddress,
863
+ coordinatorPrivateKey,
864
+ provider: cmdObj.rpcProvider,
865
+ endBlock: cmdObj.endBlock,
866
+ startBlock: cmdObj.startBlock,
867
+ blockPerBatch: cmdObj.blocksPerBatch,
868
+ transactionHash: cmdObj.transactionHash,
869
+ ipfsMessageBackupFiles: cmdObj.ipfsMessageBackupFiles,
870
+ sleep: cmdObj.sleep,
871
+ signer,
872
+ logsOutputPath: cmdObj.logsOutput,
873
+ });
874
+ }
875
+ catch (error) {
876
+ program.error(error.message, { exitCode: 1 });
877
+ }
878
+ });
879
+ program
880
+ .command("proveOnChain")
881
+ .description("prove the results of a poll on chain")
882
+ .requiredOption("-o, --poll-id <pollId>", "the poll id", BigInt)
883
+ .option("-t, --tally-file <tallyFile>", "the tally file with results, per vote option spent credits, spent voice credits total")
884
+ .option("-q, --quiet <quiet>", "whether to print values to the console", (value) => value === "true", false)
885
+ .option("-r, --rpc-provider <provider>", "the rpc provider URL")
886
+ .option("-x, --maci-address <maciAddress>", "the MACI contract address")
887
+ .requiredOption("-f, --proof-dir <proofDir>", "the proof output directory from the genProofs subcommand")
888
+ .action(async (cmdObj) => {
889
+ try {
890
+ const signer = await getSigner();
891
+ const network = await signer.provider?.getNetwork();
892
+ const [maciAddress] = (0, utils_1.readContractAddresses)({
893
+ contractNames: [sdk_1.EContracts.MACI],
894
+ network: network?.name,
895
+ defaultAddresses: [cmdObj.maciAddress],
896
+ });
897
+ await (0, sdk_1.proveOnChain)({
898
+ pollId: cmdObj.pollId,
899
+ tallyFile: cmdObj.tallyFile,
900
+ proofDir: cmdObj.proofDir,
901
+ maciAddress,
902
+ signer,
903
+ });
904
+ }
905
+ catch (error) {
906
+ program.error(error.message, { exitCode: 1 });
907
+ }
908
+ });
909
+ if (require.main === module) {
910
+ program.parseAsync(process.argv);
911
+ }
912
+ //# sourceMappingURL=index.js.map