@maci-protocol/coordinator 0.0.0-ci.6ccbb3c → 0.0.0-ci.70ceb0a

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 (85) hide show
  1. package/README.md +13 -6
  2. package/build/hardhat.config.cjs +3 -0
  3. package/build/hardhat.config.cjs.map +1 -1
  4. package/build/hardhat.config.d.cts +3 -0
  5. package/build/tests/constants.d.ts +0 -1
  6. package/build/tests/constants.d.ts.map +1 -1
  7. package/build/tests/constants.js +0 -1
  8. package/build/tests/constants.js.map +1 -1
  9. package/build/tests/e2e.aa.test.js +17 -14
  10. package/build/tests/e2e.aa.test.js.map +1 -1
  11. package/build/tests/e2e.deploy.test.js +112 -66
  12. package/build/tests/e2e.deploy.test.js.map +1 -1
  13. package/build/tests/utils.d.ts +6 -0
  14. package/build/tests/utils.d.ts.map +1 -1
  15. package/build/tests/utils.js +12 -3
  16. package/build/tests/utils.js.map +1 -1
  17. package/build/ts/common/__tests__/common.test.js +2 -6
  18. package/build/ts/common/__tests__/common.test.js.map +1 -1
  19. package/build/ts/common/accountAbstraction.d.ts +2 -19
  20. package/build/ts/common/accountAbstraction.d.ts.map +1 -1
  21. package/build/ts/common/accountAbstraction.js +14 -43
  22. package/build/ts/common/accountAbstraction.js.map +1 -1
  23. package/build/ts/common/chain.d.ts +16 -0
  24. package/build/ts/common/chain.d.ts.map +1 -0
  25. package/build/ts/common/chain.js +35 -0
  26. package/build/ts/common/chain.js.map +1 -0
  27. package/build/ts/common/errors.d.ts +17 -18
  28. package/build/ts/common/errors.d.ts.map +1 -1
  29. package/build/ts/common/errors.js +17 -18
  30. package/build/ts/common/errors.js.map +1 -1
  31. package/build/ts/common/index.d.ts +2 -0
  32. package/build/ts/common/index.d.ts.map +1 -1
  33. package/build/ts/common/index.js +2 -0
  34. package/build/ts/common/index.js.map +1 -1
  35. package/build/ts/common/types.d.ts +2 -3
  36. package/build/ts/common/types.d.ts.map +1 -1
  37. package/build/ts/deployer/__tests__/deployer.service.test.js +28 -287
  38. package/build/ts/deployer/__tests__/deployer.service.test.js.map +1 -1
  39. package/build/ts/deployer/__tests__/utils.d.ts +30 -1
  40. package/build/ts/deployer/__tests__/utils.d.ts.map +1 -1
  41. package/build/ts/deployer/__tests__/utils.js +39 -6
  42. package/build/ts/deployer/__tests__/utils.js.map +1 -1
  43. package/build/ts/deployer/deployer.service.d.ts +15 -51
  44. package/build/ts/deployer/deployer.service.d.ts.map +1 -1
  45. package/build/ts/deployer/deployer.service.js +149 -448
  46. package/build/ts/deployer/deployer.service.js.map +1 -1
  47. package/build/ts/deployer/dto.d.ts +4 -4
  48. package/build/ts/deployer/dto.d.ts.map +1 -1
  49. package/build/ts/deployer/dto.js +9 -1
  50. package/build/ts/deployer/dto.js.map +1 -1
  51. package/build/ts/deployer/types.d.ts +42 -12
  52. package/build/ts/deployer/types.d.ts.map +1 -1
  53. package/build/ts/proof/__tests__/proof.controller.test.js +3 -1
  54. package/build/ts/proof/__tests__/proof.controller.test.js.map +1 -1
  55. package/build/ts/proof/__tests__/proof.gateway.test.js +4 -1
  56. package/build/ts/proof/__tests__/proof.gateway.test.js.map +1 -1
  57. package/build/ts/proof/__tests__/proof.service.test.js +4 -2
  58. package/build/ts/proof/__tests__/proof.service.test.js.map +1 -1
  59. package/build/ts/proof/dto.d.ts +10 -9
  60. package/build/ts/proof/dto.d.ts.map +1 -1
  61. package/build/ts/proof/dto.js +42 -21
  62. package/build/ts/proof/dto.js.map +1 -1
  63. package/build/ts/proof/proof.controller.d.ts +3 -2
  64. package/build/ts/proof/proof.controller.d.ts.map +1 -1
  65. package/build/ts/proof/proof.controller.js.map +1 -1
  66. package/build/ts/proof/proof.service.d.ts +3 -3
  67. package/build/ts/proof/proof.service.d.ts.map +1 -1
  68. package/build/ts/proof/proof.service.js +34 -115
  69. package/build/ts/proof/proof.service.js.map +1 -1
  70. package/build/ts/proof/types.d.ts +16 -8
  71. package/build/ts/proof/types.d.ts.map +1 -1
  72. package/build/ts/sessionKeys/provider/KernelEIP1193Provider.d.ts +53 -0
  73. package/build/ts/sessionKeys/provider/KernelEIP1193Provider.d.ts.map +1 -0
  74. package/build/ts/sessionKeys/provider/KernelEIP1193Provider.js +105 -0
  75. package/build/ts/sessionKeys/provider/KernelEIP1193Provider.js.map +1 -0
  76. package/build/ts/sessionKeys/sessionKeys.service.d.ts +13 -2
  77. package/build/ts/sessionKeys/sessionKeys.service.d.ts.map +1 -1
  78. package/build/ts/sessionKeys/sessionKeys.service.js +22 -4
  79. package/build/ts/sessionKeys/sessionKeys.service.js.map +1 -1
  80. package/build/tsconfig.build.tsbuildinfo +1 -1
  81. package/package.json +11 -9
  82. package/build/ts/deployer/utils.d.ts +0 -8
  83. package/build/ts/deployer/utils.d.ts.map +0 -1
  84. package/build/ts/deployer/utils.js +0 -9
  85. package/build/ts/deployer/utils.js.map +0 -1
@@ -7,29 +7,21 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  var __metadata = (this && this.__metadata) || function (k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
- var DeployerService_1;
11
- import { PublicKey, VerifyingKey } from "@maci-protocol/domainobjs";
12
- import { ConstantInitialVoiceCreditProxy__factory as ConstantInitialVoiceCreditProxyFactory, ContractStorage, EPolicies, FreeForAllPolicy__factory as FreeForAllPolicyFactory, EASPolicy__factory as EASPolicyFactory, ZupassPolicy__factory as ZupassPolicyFactory, HatsPolicy__factory as HatsPolicyFactory, SemaphorePolicy__factory as SemaphorePolicyFactory, GitcoinPassportPolicy__factory as GitcoinPassportPolicyFactory, Verifier__factory as VerifierFactory, PoseidonT3__factory as PoseidonT3Factory, PoseidonT4__factory as PoseidonT4Factory, PoseidonT5__factory as PoseidonT5Factory, PoseidonT6__factory as PoseidonT6Factory, VerifyingKeysRegistry__factory as VerifyingKeysRegistryFactory, TallyFactory__factory as TallyFactoryFactory, PollFactory__factory as PollFactoryFactory, MessageProcessorFactory__factory as MessageProcessorFactoryFactory, MessageProcessor__factory as MessageProcessorFactory, ERC20VotesPolicy__factory as ERC20VotesPolicyFactory, ERC20Policy__factory as ERC20PolicyFactory, Tally__factory as TallyFactory, Poll__factory as PollFactory, MACI__factory as MACIFactory, EContracts, EInitialVoiceCreditProxies, EMode, deployPoll, extractAllVerifyingKeys, extractVerifyingKey, generateEmptyBallotRoots, } from "@maci-protocol/sdk";
13
- import { Injectable, Logger } from "@nestjs/common";
10
+ import { deployVerifier } from "@maci-protocol/contracts";
11
+ import { PublicKey } from "@maci-protocol/domainobjs";
12
+ import { ContractStorage, EPolicies, VerifyingKeysRegistry__factory as VerifyingKeysRegistryFactory, MessageProcessor__factory as MessageProcessorFactory, Tally__factory as TallyFactory, Poll__factory as PollFactory, MACI__factory as MACIFactory, EContracts, EInitialVoiceCreditProxies, EMode, deployPoll, extractAllVerifyingKeys, deployConstantInitialVoiceCreditProxy, deployFreeForAllSignUpPolicy, deployERC20VotesPolicy, deployAnonAadhaarPolicy, deploySignupTokenPolicy, deployMerkleProofPolicy, deploySemaphoreSignupPolicy, deployZupassSignUpPolicy, deployGitcoinPassportPolicy, deployEASSignUpPolicy, deployHatsSignupPolicy, deployMaci, setVerifyingKeys, deployVerifyingKeysRegistryContract, generateEmptyBallotRoots, } from "@maci-protocol/sdk";
13
+ import { Injectable } from "@nestjs/common";
14
14
  import { BaseContract } from "ethers";
15
- import { encodeFunctionData } from "viem";
16
15
  import path from "path";
17
16
  import { ErrorCodes } from "../common";
18
- import { getBundlerClient, getDeployedContractAddress, getPublicClient } from "../common/accountAbstraction";
19
17
  import { FileService } from "../file/file.service";
20
18
  import { SessionKeysService } from "../sessionKeys/sessionKeys.service";
21
- import { MAX_GAS_LIMIT } from "./constants";
22
- import { estimateExtraGasLimit } from "./utils";
23
19
  /**
24
20
  * DeployerService is responsible for deploying contracts.
25
21
  */
26
- let DeployerService = DeployerService_1 = class DeployerService {
22
+ let DeployerService = class DeployerService {
27
23
  sessionKeysService;
28
24
  fileService;
29
- /**
30
- * Logger
31
- */
32
- logger = new Logger(DeployerService_1.name);
33
25
  /**
34
26
  * Contract storage instance
35
27
  */
@@ -42,280 +34,131 @@ let DeployerService = DeployerService_1 = class DeployerService {
42
34
  constructor(sessionKeysService, fileService) {
43
35
  this.sessionKeysService = sessionKeysService;
44
36
  this.fileService = fileService;
45
- this.logger = new Logger(DeployerService_1.name);
46
37
  this.storage = ContractStorage.getInstance(path.join(process.cwd(), "deployed-contracts.json"));
47
38
  }
48
39
  /**
49
- * Get the policy abi and bytecode based on the policy type
50
- * and also check if there is already an instance deployed
40
+ * Get the policy contract object
41
+ * always deploy and save it
51
42
  *
43
+ * @param signer - the signer
52
44
  * @param policyType - the policy type
53
45
  * @param network - the network
54
46
  * @param args - the policy args
55
- * @returns - the policy abi and bytecode
47
+ * @returns - the policy contract
56
48
  */
57
- getPolicyData(policyType, network, args) {
58
- const address = this.storage.getAddress(policyType, network);
59
- let storedArgs;
60
- let isAlreadyDeployed;
49
+ async deployAndSavePolicy(signer, policyType, network, args) {
50
+ let contract;
61
51
  // based on the policy type, we need to deploy the correct policy
62
52
  switch (policyType) {
63
53
  case EPolicies.FreeForAll: {
64
- return {
65
- address,
66
- abi: FreeForAllPolicyFactory.abi,
67
- bytecode: FreeForAllPolicyFactory.bytecode,
68
- alreadyDeployed: !!address,
69
- };
54
+ [contract] = await deployFreeForAllSignUpPolicy({}, signer, true);
55
+ break;
70
56
  }
71
57
  case EPolicies.EAS: {
72
- storedArgs = this.storage.getContractArgs(policyType, network);
73
- isAlreadyDeployed =
74
- !!storedArgs &&
75
- storedArgs.length === 3 &&
76
- storedArgs[0] === args.easAddress &&
77
- storedArgs[1] === args.schema &&
78
- storedArgs[2] === args.attester;
79
- return {
80
- address: isAlreadyDeployed ? address : undefined,
81
- abi: EASPolicyFactory.abi,
82
- bytecode: EASPolicyFactory.bytecode,
83
- alreadyDeployed: isAlreadyDeployed,
84
- };
58
+ [contract] = await deployEASSignUpPolicy({
59
+ eas: args.easAddress,
60
+ attester: args.attester,
61
+ schema: args.schema,
62
+ }, {}, signer, true);
63
+ break;
85
64
  }
86
- case EPolicies.Zupass: {
87
- storedArgs = this.storage.getContractArgs(policyType, network);
88
- isAlreadyDeployed =
89
- !!storedArgs &&
90
- storedArgs.length === 4 &&
91
- storedArgs[0] === args.signer1 &&
92
- storedArgs[1] === args.signer2 &&
93
- storedArgs[2] === args.eventId &&
94
- storedArgs[3] === args.zupassVerifier;
95
- return {
96
- address: isAlreadyDeployed ? address : undefined,
97
- abi: ZupassPolicyFactory.abi,
98
- bytecode: ZupassPolicyFactory.bytecode,
99
- alreadyDeployed: isAlreadyDeployed,
100
- };
65
+ case EPolicies.GitcoinPassport: {
66
+ [contract] = await deployGitcoinPassportPolicy({
67
+ decoderAddress: args.decoderAddress,
68
+ minimumScore: Number(args.passingScore),
69
+ }, {}, signer, true);
70
+ break;
101
71
  }
102
72
  case EPolicies.Hats: {
103
- storedArgs = this.storage.getContractArgs(policyType, network);
104
- isAlreadyDeployed =
105
- !!storedArgs &&
106
- storedArgs.length === 2 &&
107
- storedArgs[0] === args.hatsProtocolAddress &&
108
- JSON.stringify(storedArgs[1]) === JSON.stringify(args.critrionHats);
109
- return {
110
- address: isAlreadyDeployed ? address : undefined,
111
- abi: HatsPolicyFactory.abi,
112
- bytecode: HatsPolicyFactory.bytecode,
113
- alreadyDeployed: isAlreadyDeployed,
114
- };
73
+ [contract] = await deployHatsSignupPolicy({
74
+ hats: args.hatsProtocolAddress,
75
+ criterionHats: args.critrionHats.map((c) => BigInt(c)),
76
+ }, {}, signer, true);
77
+ break;
78
+ }
79
+ case EPolicies.Zupass: {
80
+ [contract] = await deployZupassSignUpPolicy({
81
+ eventId: args.eventId,
82
+ signer1: args.signer1,
83
+ signer2: args.signer2,
84
+ verifier: args.zupassVerifier,
85
+ }, {}, signer, true);
86
+ break;
115
87
  }
116
88
  case EPolicies.Semaphore: {
117
- storedArgs = this.storage.getContractArgs(policyType, network);
118
- isAlreadyDeployed =
119
- !!storedArgs &&
120
- storedArgs.length === 2 &&
121
- storedArgs[0] === args.semaphoreContract &&
122
- storedArgs[1] === args.groupId;
123
- return {
124
- address: isAlreadyDeployed ? address : undefined,
125
- abi: SemaphorePolicyFactory.abi,
126
- bytecode: SemaphorePolicyFactory.bytecode,
127
- alreadyDeployed: isAlreadyDeployed,
128
- };
89
+ [contract] = await deploySemaphoreSignupPolicy({
90
+ semaphore: args.semaphoreContract,
91
+ groupId: BigInt(args.groupId),
92
+ }, {}, signer, true);
93
+ break;
129
94
  }
130
- case EPolicies.GitcoinPassport: {
131
- storedArgs = this.storage.getContractArgs(policyType, network);
132
- isAlreadyDeployed =
133
- !!storedArgs &&
134
- storedArgs.length === 2 &&
135
- storedArgs[0] === args.decoderAddress &&
136
- storedArgs[1] === args.passingScore;
137
- return {
138
- address: isAlreadyDeployed ? address : undefined,
139
- abi: GitcoinPassportPolicyFactory.abi,
140
- bytecode: GitcoinPassportPolicyFactory.bytecode,
141
- alreadyDeployed: isAlreadyDeployed,
142
- };
95
+ case EPolicies.MerkleProof: {
96
+ [contract] = await deployMerkleProofPolicy({
97
+ root: args.root,
98
+ }, {}, signer, true);
99
+ break;
143
100
  }
144
- case EPolicies.ERC20Votes: {
145
- storedArgs = this.storage.getContractArgs(policyType, network);
146
- isAlreadyDeployed =
147
- !!storedArgs &&
148
- storedArgs.length === 3 &&
149
- storedArgs[0] === args.token &&
150
- storedArgs[1] === args.factor &&
151
- storedArgs[2] === args.snapshotBlock;
152
- return {
153
- address: isAlreadyDeployed ? address : undefined,
154
- abi: ERC20VotesPolicyFactory.abi,
155
- bytecode: ERC20VotesPolicyFactory.bytecode,
156
- alreadyDeployed: isAlreadyDeployed,
157
- };
101
+ case EPolicies.Token: {
102
+ [contract] = await deploySignupTokenPolicy({
103
+ token: args.token,
104
+ }, {}, signer, true);
105
+ break;
158
106
  }
159
- case EPolicies.ERC20: {
160
- storedArgs = this.storage.getContractArgs(policyType, network);
161
- isAlreadyDeployed =
162
- !!storedArgs &&
163
- storedArgs.length === 2 &&
164
- storedArgs[0] === args.token &&
165
- storedArgs[1] === args.threshold;
166
- return {
167
- address: isAlreadyDeployed ? address : undefined,
168
- abi: ERC20PolicyFactory.abi,
169
- bytecode: ERC20PolicyFactory.bytecode,
170
- alreadyDeployed: isAlreadyDeployed,
171
- };
107
+ case EPolicies.AnonAadhaar: {
108
+ [contract] = await deployAnonAadhaarPolicy({
109
+ verifierAddress: args.verifier,
110
+ nullifierSeed: args.nullifierSeed,
111
+ }, {}, signer, true);
112
+ break;
113
+ }
114
+ case EPolicies.ERC20Votes: {
115
+ [contract] = await deployERC20VotesPolicy({
116
+ snapshotBlock: BigInt(args.snapshotBlock),
117
+ threshold: BigInt(args.threshold),
118
+ token: args.token,
119
+ }, {}, signer, true);
120
+ break;
172
121
  }
173
122
  default:
174
123
  throw new Error(ErrorCodes.UNSUPPORTED_POLICY.toString());
175
124
  }
125
+ await this.storage.register({
126
+ id: policyType,
127
+ contract,
128
+ args: args ? Object.values(args).map((arg) => String(arg)) : [],
129
+ network,
130
+ });
131
+ return contract;
176
132
  }
177
133
  /**
178
- * Get the voice credit proxy abi and bytecode based on the voice credit proxy type
179
- * and also check if there is already an instance deployed
134
+ * Get the voice credit proxy contract object
135
+ * always deploy and save it
180
136
  *
137
+ * @param signer - the signer
181
138
  * @param voiceCreditProxyType - the voice credit proxy type
182
139
  * @param network - the network
183
- * @param args - the voice credit proxy args
184
- * @returns - the voice credit proxy abi and bytecode
140
+ * @param args - the args
141
+ * @returns - the voice credit proxy contract
185
142
  */
186
- getVoiceCreditProxyData(voiceCreditProxyType, network, args) {
187
- let storedArgs;
188
- let isAlreadyDeployed;
189
- const address = this.storage.getAddress(voiceCreditProxyType, network);
143
+ async deployAndSaveVoiceCreditProxy(signer, voiceCreditProxyType, network, args) {
144
+ let contract;
190
145
  switch (voiceCreditProxyType) {
191
146
  case EInitialVoiceCreditProxies.Constant: {
192
- storedArgs = this.storage.getContractArgs(voiceCreditProxyType, network);
193
- isAlreadyDeployed = !!storedArgs && storedArgs[0] === args.amount;
194
- return {
195
- address: isAlreadyDeployed ? address : undefined,
196
- abi: ConstantInitialVoiceCreditProxyFactory.abi,
197
- bytecode: ConstantInitialVoiceCreditProxyFactory.bytecode,
198
- alreadyDeployed: isAlreadyDeployed,
199
- };
147
+ [contract] = await deployConstantInitialVoiceCreditProxy({
148
+ amount: args.amount,
149
+ }, signer, undefined, true);
150
+ break;
200
151
  }
201
152
  default:
202
153
  throw new Error(ErrorCodes.UNSUPPORTED_VOICE_CREDIT_PROXY.toString());
203
154
  }
204
- }
205
- /**
206
- * @param abi - the abi
207
- * @param bytecode - the bytecode
208
- * @param args - the args
209
- * @param publicClient - the public client
210
- * @returns - the address
211
- */
212
- async deployAndGetAddress(kernelClient, abi, bytecode, args, bundlerClient, publicClient) {
213
- const deployCallData = await kernelClient.account.encodeDeployCallData({
214
- abi,
215
- args,
216
- bytecode,
217
- });
218
- const gasPrice = await kernelClient.getUserOperationGasPrice();
219
- const opEstimate = await kernelClient.prepareUserOperation({
220
- callData: deployCallData,
221
- sender: kernelClient.account.address,
222
- maxFeePerGas: gasPrice.maxFeePerGas,
223
- maxPriorityFeePerGas: gasPrice.maxPriorityFeePerGas,
224
- });
225
- const callGasLimitMultiplier = estimateExtraGasLimit(opEstimate.callGasLimit);
226
- const tx = await kernelClient.sendUserOperation({
227
- callData: deployCallData,
228
- sender: kernelClient.account.address,
229
- maxFeePerGas: gasPrice.maxFeePerGas,
230
- maxPriorityFeePerGas: gasPrice.maxPriorityFeePerGas,
231
- callGasLimit: opEstimate.callGasLimit + callGasLimitMultiplier < MAX_GAS_LIMIT
232
- ? opEstimate.callGasLimit + callGasLimitMultiplier
233
- : MAX_GAS_LIMIT,
234
- });
235
- const receipt = await bundlerClient.waitForUserOperationReceipt({
236
- hash: tx,
155
+ await this.storage.register({
156
+ id: voiceCreditProxyType,
157
+ contract,
158
+ args: args ? Object.values(args).map((arg) => String(arg)) : [],
159
+ network,
237
160
  });
238
- const txReceipt = await publicClient.getTransactionReceipt({
239
- hash: receipt.receipt.transactionHash,
240
- });
241
- return getDeployedContractAddress(txReceipt);
242
- }
243
- /**
244
- * Deploy a contract and store the address
245
- *
246
- * @param contract - the contract to deploy
247
- * @param args - the args
248
- * @param abi - the abi
249
- * @param bytecode - the bytecode
250
- * @param kernelClient - the kernel client
251
- * @param publicClient - the public client
252
- * @param chain - the chain
253
- * @returns - the address of the deployed contract
254
- */
255
- async deployAndStore(contract, args, abi, bytecode, kernelClient, bundlerClient, publicClient, chain) {
256
- let address = this.storage.getAddress(contract, chain);
257
- if (!address) {
258
- address = await this.deployAndGetAddress(kernelClient, abi, bytecode, args, bundlerClient, publicClient);
259
- if (!address) {
260
- this.logger.error(`Failed to deploy contract: ${contract}`);
261
- throw new Error(`${ErrorCodes.FAILED_TO_DEPLOY_CONTRACT} ${contract}`);
262
- }
263
- await this.storage.register({
264
- id: contract,
265
- contract: new BaseContract(address, abi),
266
- args: args.map((arg) => {
267
- if (Array.isArray(arg)) {
268
- return arg.map((a) => String(a));
269
- }
270
- return String(arg);
271
- }),
272
- network: chain,
273
- });
274
- }
275
- return address;
276
- }
277
- /**
278
- * Estimate gas, add a bit extra and send the user operation (aka. transaction)
279
- * @param to - the to address of the user operation
280
- * @param value - the value of the user operation
281
- * @param abi - the abi
282
- * @param functionName - the function name
283
- * @param args - the args
284
- * @param errorMessage - the error message
285
- * @param kernelClient - the kernel client
286
- * @param bundlerClient - the bundler client
287
- */
288
- async estimateGasAndSend(to, value, abi, functionName, args, errorMessage, kernelClient, bundlerClient) {
289
- const gasEstimates = await kernelClient.getUserOperationGasPrice();
290
- const userOperation = {
291
- sender: kernelClient.account.address,
292
- maxFeePerGas: gasEstimates.maxFeePerGas,
293
- maxPriorityFeePerGas: gasEstimates.maxPriorityFeePerGas,
294
- callData: await kernelClient.account.encodeCalls([
295
- {
296
- to,
297
- value,
298
- data: encodeFunctionData({
299
- abi,
300
- functionName,
301
- args,
302
- }),
303
- },
304
- ]),
305
- };
306
- const opEstimate = await kernelClient.prepareUserOperation(userOperation);
307
- const callGasLimitMultiplier = estimateExtraGasLimit(opEstimate.callGasLimit);
308
- const userOperationHash = await kernelClient.sendUserOperation({
309
- ...userOperation,
310
- callGasLimit: opEstimate.callGasLimit + callGasLimitMultiplier < MAX_GAS_LIMIT
311
- ? opEstimate.callGasLimit + callGasLimitMultiplier
312
- : MAX_GAS_LIMIT,
313
- });
314
- const receipt = await bundlerClient.waitForUserOperationReceipt({ hash: userOperationHash });
315
- if (!receipt.success) {
316
- throw new Error(errorMessage);
317
- }
318
- return receipt;
161
+ return contract;
319
162
  }
320
163
  /**
321
164
  * Get verifying keys arguments (specially zkey paths)
@@ -325,7 +168,7 @@ let DeployerService = DeployerService_1 = class DeployerService {
325
168
  * @param mode - use QV or NON_QV
326
169
  * @returns SetVerifyingKeysArgs
327
170
  */
328
- async getVerifyingKeysArgs(signer, verifyingKeysRegistryContract, verifyingKeysRegistryArgs, mode) {
171
+ async getVerifyingKeysArgs(signer, verifyingKeysRegistryAddress, verifyingKeysRegistryArgs, mode) {
329
172
  const pollJoiningZkeyPath = this.fileService.getZkeyFilePaths(process.env.COORDINATOR_POLL_JOINING_ZKEY_NAME, true).zkey;
330
173
  const pollJoinedZkeyPath = this.fileService.getZkeyFilePaths(process.env.COORDINATOR_POLL_JOINED_ZKEY_NAME, true).zkey;
331
174
  const processMessagesZkeyPath = this.fileService.getZkeyFilePaths(process.env.COORDINATOR_MESSAGE_PROCESS_ZKEY_NAME, mode === EMode.QV).zkey;
@@ -336,7 +179,7 @@ let DeployerService = DeployerService_1 = class DeployerService {
336
179
  processMessagesZkeyPath,
337
180
  tallyVotesZkeyPath,
338
181
  });
339
- const { stateTreeDepth, intStateTreeDepth, voteOptionTreeDepth, pollStateTreeDepth, messageBatchSize } = verifyingKeysRegistryArgs;
182
+ const { stateTreeDepth, pollStateTreeDepth, intStateTreeDepth, voteOptionTreeDepth, messageBatchSize } = verifyingKeysRegistryArgs;
340
183
  return {
341
184
  pollJoiningVerifyingKey: pollJoiningVerifyingKey,
342
185
  pollJoinedVerifyingKey: pollJoinedVerifyingKey,
@@ -349,7 +192,7 @@ let DeployerService = DeployerService_1 = class DeployerService {
349
192
  pollStateTreeDepth: Number(pollStateTreeDepth),
350
193
  signer,
351
194
  mode,
352
- verifyingKeysRegistryAddress: await verifyingKeysRegistryContract.getAddress(),
195
+ verifyingKeysRegistryAddress,
353
196
  };
354
197
  }
355
198
  /**
@@ -361,165 +204,46 @@ let DeployerService = DeployerService_1 = class DeployerService {
361
204
  * @returns the address of the deployed maci contract
362
205
  */
363
206
  async deployMaci({ approval, sessionKeyAddress, chain, config }) {
364
- const publicClient = getPublicClient(chain);
365
- const bundlerClient = getBundlerClient(chain);
366
- const kernelClient = await this.sessionKeysService.generateClientFromSessionKey(sessionKeyAddress, approval, chain);
367
- let policyAddress = this.storage.getAddress(config.policy.type, chain);
368
- const policyData = this.getPolicyData(config.policy.type, chain, config.policy.args);
369
- // if the policy is not already deployed, we need to deploy it
370
- if (!policyData.alreadyDeployed) {
371
- policyAddress = await this.deployAndStore(config.policy.type, config.policy.args ? Object.values(config.policy.args) : [], policyData.abi, policyData.bytecode, kernelClient, bundlerClient, publicClient, chain);
372
- }
373
- // deploy all maci contracts
374
- // (we are not using Promise.all because the write tx nonce should be sequential)
375
- // 1. verifier
376
- await this.deployAndStore(EContracts.Verifier, [], VerifierFactory.abi, VerifierFactory.bytecode, kernelClient, bundlerClient, publicClient, chain);
377
- // 2. poseidon
378
- let poseidonT3Address;
379
- let poseidonT4Address;
380
- let poseidonT5Address;
381
- let poseidonT6Address;
382
- if (config.Poseidon) {
383
- // Some times the poseidon contracts are already deployed so we don't need to deploy them again
384
- poseidonT3Address = config.Poseidon.poseidonT3;
385
- poseidonT4Address = config.Poseidon.poseidonT4;
386
- poseidonT5Address = config.Poseidon.poseidonT5;
387
- poseidonT6Address = config.Poseidon.poseidonT6;
388
- }
389
- else {
390
- poseidonT3Address = await this.deployAndStore(EContracts.PoseidonT3, [], PoseidonT3Factory.abi, PoseidonT3Factory.bytecode, kernelClient, bundlerClient, publicClient, chain);
391
- poseidonT4Address = await this.deployAndStore(EContracts.PoseidonT4, [], PoseidonT4Factory.abi, PoseidonT4Factory.bytecode, kernelClient, bundlerClient, publicClient, chain);
392
- poseidonT5Address = await this.deployAndStore(EContracts.PoseidonT5, [], PoseidonT5Factory.abi, PoseidonT5Factory.bytecode, kernelClient, bundlerClient, publicClient, chain);
393
- poseidonT6Address = await this.deployAndStore(EContracts.PoseidonT6, [], PoseidonT6Factory.abi, PoseidonT6Factory.bytecode, kernelClient, bundlerClient, publicClient, chain);
394
- }
395
- // 3. factories
396
- const pollFactoryAddress = await this.deployAndStore(EContracts.PollFactory, [], PollFactoryFactory.abi, PollFactoryFactory.linkBytecode({
397
- "contracts/crypto/PoseidonT3.sol:PoseidonT3": poseidonT3Address,
398
- "contracts/crypto/PoseidonT4.sol:PoseidonT4": poseidonT4Address,
399
- "contracts/crypto/PoseidonT5.sol:PoseidonT5": poseidonT5Address,
400
- "contracts/crypto/PoseidonT6.sol:PoseidonT6": poseidonT6Address,
401
- }), kernelClient, bundlerClient, publicClient, chain);
402
- const tallyFactoryAddress = await this.deployAndStore(EContracts.TallyFactory, [], TallyFactoryFactory.abi, TallyFactoryFactory.linkBytecode({
403
- "contracts/crypto/PoseidonT3.sol:PoseidonT3": poseidonT3Address,
404
- "contracts/crypto/PoseidonT4.sol:PoseidonT4": poseidonT4Address,
405
- "contracts/crypto/PoseidonT5.sol:PoseidonT5": poseidonT5Address,
406
- "contracts/crypto/PoseidonT6.sol:PoseidonT6": poseidonT6Address,
407
- }), kernelClient, bundlerClient, publicClient, chain);
408
- const messageProcessorFactoryAddress = await this.deployAndStore(EContracts.MessageProcessorFactory, [], MessageProcessorFactoryFactory.abi, MessageProcessorFactoryFactory.linkBytecode({
409
- "contracts/crypto/PoseidonT3.sol:PoseidonT3": poseidonT3Address,
410
- "contracts/crypto/PoseidonT4.sol:PoseidonT4": poseidonT4Address,
411
- "contracts/crypto/PoseidonT5.sol:PoseidonT5": poseidonT5Address,
412
- "contracts/crypto/PoseidonT6.sol:PoseidonT6": poseidonT6Address,
413
- }), kernelClient, bundlerClient, publicClient, chain);
414
- // 4. VerifyingKeysRegistry
415
- const verifyingKeysRegistryAddress = await this.deployAndStore(EContracts.VerifyingKeysRegistry, [], VerifyingKeysRegistryFactory.abi, VerifyingKeysRegistryFactory.bytecode, kernelClient, bundlerClient, publicClient, chain);
416
- try {
417
- const processMessagesZkeyPathQv = this.fileService.getZkeyFilePaths(process.env.COORDINATOR_MESSAGE_PROCESS_ZKEY_NAME, true);
418
- const tallyVotesZkeyPathQv = this.fileService.getZkeyFilePaths(process.env.COORDINATOR_TALLY_ZKEY_NAME, true);
419
- const processMessagesZkeyPathNonQv = this.fileService.getZkeyFilePaths(process.env.COORDINATOR_MESSAGE_PROCESS_ZKEY_NAME, false);
420
- const tallyVotesZkeyPathNonQv = this.fileService.getZkeyFilePaths(process.env.COORDINATOR_TALLY_ZKEY_NAME, false);
421
- const pollJoiningZkeyPath = this.fileService.getZkeyFilePaths(process.env.COORDINATOR_POLL_JOINING_ZKEY_NAME, true);
422
- const pollJoinedZkeyPath = this.fileService.getZkeyFilePaths(process.env.COORDINATOR_POLL_JOINED_ZKEY_NAME, true);
423
- const [qvProcessVerifyingKey, qvTallyVerifyingKey, nonQvProcessVerifyingKey, nonQvTallyVerifyingKey, pollJoiningVerifyingKey, pollJoinedVerifyingKey,] = await Promise.all([
424
- extractVerifyingKey(processMessagesZkeyPathQv.zkey),
425
- extractVerifyingKey(tallyVotesZkeyPathQv.zkey),
426
- extractVerifyingKey(processMessagesZkeyPathNonQv.zkey),
427
- extractVerifyingKey(tallyVotesZkeyPathNonQv.zkey),
428
- extractVerifyingKey(pollJoiningZkeyPath.zkey),
429
- extractVerifyingKey(pollJoinedZkeyPath.zkey),
430
- ]).then((verifyingKeys) => verifyingKeys.map((verifyingKey) => verifyingKey && VerifyingKey.fromObj(verifyingKey).asContractParam()));
431
- const processZkeys = [qvProcessVerifyingKey, nonQvProcessVerifyingKey].filter(Boolean);
432
- const tallyZkeys = [qvTallyVerifyingKey, nonQvTallyVerifyingKey].filter(Boolean);
433
- // check if the keys are already set
434
- const [isProcessVerifyingKeySet, isProcessNonQvVerifyingKeySet, isTallyVerifyingKeySet, isTallyNonQvVerifyingKeySet,] = await Promise.all([
435
- publicClient.readContract({
436
- address: verifyingKeysRegistryAddress,
437
- abi: VerifyingKeysRegistryFactory.abi,
438
- functionName: "hasProcessVerifyingKey",
439
- args: [
440
- config.VerifyingKeysRegistry.args.stateTreeDepth,
441
- config.VerifyingKeysRegistry.args.voteOptionTreeDepth,
442
- config.VerifyingKeysRegistry.args.messageBatchSize,
443
- EMode.QV,
444
- ],
445
- }),
446
- publicClient.readContract({
447
- address: verifyingKeysRegistryAddress,
448
- abi: VerifyingKeysRegistryFactory.abi,
449
- functionName: "hasProcessVerifyingKey",
450
- args: [
451
- config.VerifyingKeysRegistry.args.stateTreeDepth,
452
- config.VerifyingKeysRegistry.args.voteOptionTreeDepth,
453
- config.VerifyingKeysRegistry.args.messageBatchSize,
454
- EMode.NON_QV,
455
- ],
456
- }),
457
- publicClient.readContract({
458
- address: verifyingKeysRegistryAddress,
459
- abi: VerifyingKeysRegistryFactory.abi,
460
- functionName: "hasTallyVerifyingKey",
461
- args: [
462
- config.VerifyingKeysRegistry.args.stateTreeDepth,
463
- config.VerifyingKeysRegistry.args.intStateTreeDepth,
464
- config.VerifyingKeysRegistry.args.voteOptionTreeDepth,
465
- EMode.QV,
466
- ],
467
- }),
468
- publicClient.readContract({
469
- address: verifyingKeysRegistryAddress,
470
- abi: VerifyingKeysRegistryFactory.abi,
471
- functionName: "hasTallyVerifyingKey",
472
- args: [
473
- config.VerifyingKeysRegistry.args.stateTreeDepth,
474
- config.VerifyingKeysRegistry.args.intStateTreeDepth,
475
- config.VerifyingKeysRegistry.args.voteOptionTreeDepth,
476
- EMode.NON_QV,
477
- ],
478
- }),
479
- ]);
480
- if (isProcessVerifyingKeySet &&
481
- isProcessNonQvVerifyingKeySet &&
482
- isTallyVerifyingKeySet &&
483
- isTallyNonQvVerifyingKeySet) {
484
- this.logger.debug("Verifying keys are already set on the verifyingKey registry");
485
- }
486
- else {
487
- await this.estimateGasAndSend(verifyingKeysRegistryAddress, 0n, VerifyingKeysRegistryFactory.abi, "setVerifyingKeysBatch", [
488
- config.VerifyingKeysRegistry.args.stateTreeDepth,
489
- config.VerifyingKeysRegistry.args.pollStateTreeDepth,
490
- config.VerifyingKeysRegistry.args.intStateTreeDepth,
491
- config.VerifyingKeysRegistry.args.voteOptionTreeDepth,
492
- config.VerifyingKeysRegistry.args.messageBatchSize,
493
- [EMode.QV, EMode.NON_QV],
494
- pollJoiningVerifyingKey,
495
- pollJoinedVerifyingKey,
496
- processZkeys,
497
- tallyZkeys,
498
- ], ErrorCodes.FAILED_TO_SET_VERIFYING_KEYS.toString(), kernelClient, bundlerClient);
499
- }
500
- }
501
- catch (error) {
502
- this.logger.error("Failed to set verifying keys on verifyingKey registry: ", error);
503
- throw error;
504
- }
505
- // 5. maci (here we don't check whether one is already deployed, we just deploy it)
506
- const emptyBallotRoots = generateEmptyBallotRoots(config.MACI.stateTreeDepth);
507
- const maciAddress = await this.deployAndStore(EContracts.MACI, [
508
- pollFactoryAddress,
509
- messageProcessorFactoryAddress,
510
- tallyFactoryAddress,
511
- policyAddress,
512
- config.MACI.stateTreeDepth,
513
- emptyBallotRoots,
514
- ], MACIFactory.abi, MACIFactory.linkBytecode({
515
- "contracts/crypto/PoseidonT3.sol:PoseidonT3": "0x07490eba00dc4ACA6721D052Fa4C5002Aa077233",
516
- "contracts/crypto/PoseidonT4.sol:PoseidonT4": "0xbb0e724CE02e5E7eDd31e632dc6e59F229a1126d",
517
- "contracts/crypto/PoseidonT5.sol:PoseidonT5": "0xE0398F7DFAC494c530F6404AfEaC8669ABeD2679",
518
- "contracts/crypto/PoseidonT6.sol:PoseidonT6": "0xfD77833F10a29c76A6a0ede235Eb651D744d0E2F",
519
- }), kernelClient, bundlerClient, publicClient, chain);
520
- // set the gate on the policy
521
- await this.estimateGasAndSend(policyAddress, 0n, policyData.abi, "setTarget", [maciAddress], ErrorCodes.FAILED_TO_SET_MACI_INSTANCE_ON_POLICY.toString(), kernelClient, bundlerClient);
522
- return { address: maciAddress };
207
+ const signer = await this.sessionKeysService.getCoordinatorSigner(chain, sessionKeyAddress, approval);
208
+ const policyContract = await this.deployAndSavePolicy(signer, config.policy.type, chain, config.policy.args);
209
+ const policyAddress = await policyContract.getAddress();
210
+ const verifierContract = await deployVerifier(signer, true);
211
+ const verifyingKeysRegistryAddress = await deployVerifyingKeysRegistryContract({ signer });
212
+ const verifyingKeysArgs = await this.getVerifyingKeysArgs(signer, verifyingKeysRegistryAddress, config.VerifyingKeysRegistry.args, EMode.QV);
213
+ await setVerifyingKeys(verifyingKeysArgs);
214
+ // deploy the smart contracts
215
+ const maciAddresses = await deployMaci({
216
+ stateTreeDepth: config.MACI.stateTreeDepth,
217
+ signer,
218
+ signupPolicyAddress: policyAddress,
219
+ });
220
+ // store the contracts
221
+ await Promise.all([
222
+ this.storage.register({
223
+ id: EContracts.Verifier,
224
+ contract: verifierContract,
225
+ network: chain,
226
+ }),
227
+ this.storage.register({
228
+ id: EContracts.VerifyingKeysRegistry,
229
+ contract: new BaseContract(verifyingKeysRegistryAddress, VerifyingKeysRegistryFactory.abi),
230
+ network: chain,
231
+ }),
232
+ this.storage.register({
233
+ id: EContracts.MACI,
234
+ contract: new BaseContract(maciAddresses.maciContractAddress, MACIFactory.abi),
235
+ args: [
236
+ maciAddresses.pollFactoryContractAddress,
237
+ maciAddresses.messageProcessorFactoryContractAddress,
238
+ maciAddresses.tallyFactoryContractAddress,
239
+ policyAddress,
240
+ config.MACI.stateTreeDepth,
241
+ generateEmptyBallotRoots(config.MACI.stateTreeDepth).map((root) => root.toString()),
242
+ ],
243
+ network: chain,
244
+ }),
245
+ ]);
246
+ return { address: maciAddresses.maciContractAddress };
523
247
  }
524
248
  /**
525
249
  * Deploy a poll
@@ -528,10 +252,7 @@ let DeployerService = DeployerService_1 = class DeployerService {
528
252
  * @returns poll id
529
253
  */
530
254
  async deployPoll({ approval, sessionKeyAddress, chain, config }) {
531
- const publicClient = getPublicClient(chain);
532
- const bundlerClient = getBundlerClient(chain);
533
- const kernelClient = await this.sessionKeysService.generateClientFromSessionKey(sessionKeyAddress, approval, chain);
534
- const signer = await this.sessionKeysService.getKernelClientSigner(kernelClient);
255
+ const signer = await this.sessionKeysService.getCoordinatorSigner(chain, sessionKeyAddress, approval);
535
256
  // check if there is a maci contract deployed on this chain
536
257
  const maciAddress = this.storage.getAddress(EContracts.MACI, chain);
537
258
  if (!maciAddress) {
@@ -550,22 +271,14 @@ let DeployerService = DeployerService_1 = class DeployerService {
550
271
  // check if policy address was given
551
272
  let policyAddress = config.policy.address;
552
273
  if (!policyAddress) {
553
- const policyData = this.getPolicyData(config.policy.type, chain, config.policy.args);
554
- policyAddress = policyData.address;
555
- // if the policy is not already deployed, we need to deploy it
556
- if (!policyData.alreadyDeployed) {
557
- policyAddress = await this.deployAndStore(config.policy.type, config.policy.args ? Object.values(config.policy.args) : [], policyData.abi, policyData.bytecode, kernelClient, bundlerClient, publicClient, chain);
558
- }
274
+ const policyContract = await this.deployAndSavePolicy(signer, config.policy.type, chain, config.policy.args);
275
+ policyAddress = (await policyContract.getAddress());
559
276
  }
560
277
  // check if initial voice credit proxy address was given
561
278
  let initialVoiceCreditProxyAddress = config.initialVoiceCreditsProxy.address;
562
279
  if (!initialVoiceCreditProxyAddress) {
563
- const voiceCreditProxyData = this.getVoiceCreditProxyData(config.initialVoiceCreditsProxy.type, chain, config.initialVoiceCreditsProxy.args);
564
- initialVoiceCreditProxyAddress = voiceCreditProxyData.address;
565
- // if the voice credit proxy is not already deployed, we need to deploy it
566
- if (!voiceCreditProxyData.alreadyDeployed) {
567
- initialVoiceCreditProxyAddress = await this.deployAndStore(config.initialVoiceCreditsProxy.type, Object.values(config.initialVoiceCreditsProxy.args), voiceCreditProxyData.abi, voiceCreditProxyData.bytecode, kernelClient, bundlerClient, publicClient, chain);
568
- }
280
+ const initialVoiceCreditProxyContract = await this.deployAndSaveVoiceCreditProxy(signer, config.initialVoiceCreditsProxy.type, chain, config.initialVoiceCreditsProxy.args);
281
+ initialVoiceCreditProxyAddress = (await initialVoiceCreditProxyContract.getAddress());
569
282
  }
570
283
  const mode = config.useQuadraticVoting ? EMode.QV : EMode.NON_QV;
571
284
  const deployPollArgs = {
@@ -589,49 +302,37 @@ let DeployerService = DeployerService_1 = class DeployerService {
589
302
  };
590
303
  const { pollContractAddress, messageProcessorContractAddress, tallyContractAddress, pollId } = await deployPoll(deployPollArgs);
591
304
  const poll = PollFactory.connect(pollContractAddress, signer);
592
- // read the emptyBallotRoot and extContracts
593
- const emptyBallotRoot = await poll.emptyBallotRoot();
594
- const extContracts = await poll.extContracts();
595
305
  // store to storage
596
306
  await Promise.all([
597
307
  this.storage.register({
598
308
  id: EContracts.Poll,
599
309
  key: `poll-${pollId}`,
600
310
  contract: poll,
601
- args: [
602
- {
603
- ...deployPollArgs,
604
- extContracts,
605
- emptyBallotRoot: emptyBallotRoot.toString(),
606
- },
607
- ],
311
+ // clones do not have args for verification
312
+ args: [],
608
313
  network: chain,
609
314
  }),
610
315
  this.storage.register({
611
316
  id: EContracts.MessageProcessor,
612
317
  key: `poll-${pollId}`,
613
- contract: new BaseContract(messageProcessorContractAddress, MessageProcessorFactory.abi),
614
- args: [verifierAddress, verifyingKeysRegistryAddress, pollContractAddress, mode],
318
+ contract: MessageProcessorFactory.connect(messageProcessorContractAddress, signer),
319
+ // clones do not have args for verification
320
+ args: [],
615
321
  network: chain,
616
322
  }),
617
323
  this.storage.register({
618
324
  id: EContracts.Tally,
619
325
  key: `poll-${pollId}`,
620
- contract: new BaseContract(tallyContractAddress, TallyFactory.abi),
621
- args: [
622
- verifierAddress,
623
- verifyingKeysRegistryAddress,
624
- pollContractAddress,
625
- messageProcessorContractAddress,
626
- mode,
627
- ],
326
+ contract: TallyFactory.connect(tallyContractAddress, signer),
327
+ // clones do not have args for verification
328
+ args: [],
628
329
  network: chain,
629
330
  }),
630
331
  ]);
631
332
  return { pollId: pollId.toString() };
632
333
  }
633
334
  };
634
- DeployerService = DeployerService_1 = __decorate([
335
+ DeployerService = __decorate([
635
336
  Injectable(),
636
337
  __metadata("design:paramtypes", [SessionKeysService,
637
338
  FileService])