@dorafactory/maci-sdk 0.1.3-pre.46.beta.1 → 0.1.3-pre.46.beta.11
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.
- package/dist/index.js +854 -87
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +854 -87
- package/dist/index.mjs.map +1 -1
- package/dist/libs/api/client.d.ts +23 -0
- package/dist/libs/api/types.d.ts +434 -9
- package/dist/libs/contract/contract.d.ts +28 -0
- package/dist/libs/contract/ts/ApiSaas.client.d.ts +21 -1
- package/dist/libs/contract/ts/ApiSaas.types.d.ts +19 -0
- package/dist/libs/crypto/keys.d.ts +5 -1
- package/dist/libs/maci/config.d.ts +1 -1
- package/dist/libs/maci/maci.d.ts +17 -2
- package/dist/maci.d.ts +43 -2
- package/dist/operator.d.ts +16 -4
- package/dist/voter.d.ts +251 -14
- package/package.json +1 -1
- package/src/libs/api/client.ts +55 -0
- package/src/libs/api/types.ts +434 -9
- package/src/libs/contract/config.ts +0 -1
- package/src/libs/contract/contract.ts +158 -2
- package/src/libs/contract/ts/ApiSaas.client.ts +90 -0
- package/src/libs/contract/ts/ApiSaas.types.ts +21 -0
- package/src/libs/contract/utils.ts +9 -9
- package/src/libs/crypto/keys.ts +13 -4
- package/src/libs/maci/config.ts +2 -2
- package/src/libs/maci/maci.ts +136 -53
- package/src/maci.ts +18 -1
- package/src/operator.ts +70 -17
- package/src/voter.ts +732 -63
- package/dist/libs/contract/ts/Maci.client.d.ts +0 -196
- package/dist/libs/contract/ts/Maci.types.d.ts +0 -208
- package/dist/libs/contract/ts/Saas.client.d.ts +0 -150
- package/dist/libs/contract/ts/Saas.types.d.ts +0 -128
package/dist/index.js
CHANGED
|
@@ -1247,7 +1247,9 @@ var rerandomize = (pubKey, ciphertext, randomVal = genRandomSalt()) => {
|
|
|
1247
1247
|
var genAddKeyInput = (depth, {
|
|
1248
1248
|
coordPubKey,
|
|
1249
1249
|
oldKey,
|
|
1250
|
-
deactivates
|
|
1250
|
+
deactivates,
|
|
1251
|
+
newPubKey,
|
|
1252
|
+
pollId
|
|
1251
1253
|
}) => {
|
|
1252
1254
|
const sharedKeyHash = poseidon(genEcdhSharedKey(oldKey.privKey, coordPubKey));
|
|
1253
1255
|
const randomVal = genRandomSalt();
|
|
@@ -1259,7 +1261,7 @@ var genAddKeyInput = (depth, {
|
|
|
1259
1261
|
const c1 = [deactivateLeaf[0], deactivateLeaf[1]];
|
|
1260
1262
|
const c2 = [deactivateLeaf[2], deactivateLeaf[3]];
|
|
1261
1263
|
const { d1, d2 } = rerandomize(coordPubKey, { c1, c2 }, randomVal);
|
|
1262
|
-
const nullifier = poseidon([BigInt(oldKey.formatedPrivKey),
|
|
1264
|
+
const nullifier = poseidon([BigInt(oldKey.formatedPrivKey), pollId]);
|
|
1263
1265
|
const tree = new Tree(5, depth, 0n);
|
|
1264
1266
|
const leaves = deactivates.map((d) => poseidon(d));
|
|
1265
1267
|
tree.initLeaves(leaves);
|
|
@@ -1272,7 +1274,9 @@ var genAddKeyInput = (depth, {
|
|
|
1272
1274
|
d1[0],
|
|
1273
1275
|
d1[1],
|
|
1274
1276
|
d2[0],
|
|
1275
|
-
d2[1]
|
|
1277
|
+
d2[1],
|
|
1278
|
+
poseidon(newPubKey),
|
|
1279
|
+
pollId
|
|
1276
1280
|
]);
|
|
1277
1281
|
const input = {
|
|
1278
1282
|
inputHash,
|
|
@@ -1287,7 +1291,9 @@ var genAddKeyInput = (depth, {
|
|
|
1287
1291
|
d2,
|
|
1288
1292
|
deactivateLeafPathElements,
|
|
1289
1293
|
nullifier,
|
|
1290
|
-
oldPrivateKey: oldKey.formatedPrivKey
|
|
1294
|
+
oldPrivateKey: oldKey.formatedPrivKey,
|
|
1295
|
+
newPubKey,
|
|
1296
|
+
pollId
|
|
1291
1297
|
};
|
|
1292
1298
|
return input;
|
|
1293
1299
|
};
|
|
@@ -4342,6 +4348,46 @@ var ApiSaasClient = class extends ApiSaasQueryClient {
|
|
|
4342
4348
|
_funds
|
|
4343
4349
|
);
|
|
4344
4350
|
};
|
|
4351
|
+
this.publishMessage = async ({
|
|
4352
|
+
contractAddr,
|
|
4353
|
+
encPubKeys,
|
|
4354
|
+
messages
|
|
4355
|
+
}, fee = "auto", memo, _funds) => {
|
|
4356
|
+
return await this.client.execute(
|
|
4357
|
+
this.sender,
|
|
4358
|
+
this.contractAddress,
|
|
4359
|
+
{
|
|
4360
|
+
publish_message: {
|
|
4361
|
+
contract_addr: contractAddr,
|
|
4362
|
+
enc_pub_keys: encPubKeys,
|
|
4363
|
+
messages
|
|
4364
|
+
}
|
|
4365
|
+
},
|
|
4366
|
+
fee,
|
|
4367
|
+
memo,
|
|
4368
|
+
_funds
|
|
4369
|
+
);
|
|
4370
|
+
};
|
|
4371
|
+
this.publishDeactivateMessage = async ({
|
|
4372
|
+
contractAddr,
|
|
4373
|
+
encPubKey,
|
|
4374
|
+
message
|
|
4375
|
+
}, fee = "auto", memo, _funds) => {
|
|
4376
|
+
return await this.client.execute(
|
|
4377
|
+
this.sender,
|
|
4378
|
+
this.contractAddress,
|
|
4379
|
+
{
|
|
4380
|
+
publish_deactivate_message: {
|
|
4381
|
+
contract_addr: contractAddr,
|
|
4382
|
+
enc_pub_key: encPubKey,
|
|
4383
|
+
message
|
|
4384
|
+
}
|
|
4385
|
+
},
|
|
4386
|
+
fee,
|
|
4387
|
+
memo,
|
|
4388
|
+
_funds
|
|
4389
|
+
);
|
|
4390
|
+
};
|
|
4345
4391
|
this.client = client;
|
|
4346
4392
|
this.sender = sender;
|
|
4347
4393
|
this.contractAddress = contractAddress;
|
|
@@ -4354,6 +4400,8 @@ var ApiSaasClient = class extends ApiSaasQueryClient {
|
|
|
4354
4400
|
this.createAmaciRound = this.createAmaciRound.bind(this);
|
|
4355
4401
|
this.setRoundInfo = this.setRoundInfo.bind(this);
|
|
4356
4402
|
this.setVoteOptionsMap = this.setVoteOptionsMap.bind(this);
|
|
4403
|
+
this.publishMessage = this.publishMessage.bind(this);
|
|
4404
|
+
this.publishDeactivateMessage = this.publishDeactivateMessage.bind(this);
|
|
4357
4405
|
}
|
|
4358
4406
|
};
|
|
4359
4407
|
|
|
@@ -4399,7 +4447,6 @@ async function createApiSaasClientBy({
|
|
|
4399
4447
|
return new ApiSaasClient(signingCosmWasmClient, address, contractAddress);
|
|
4400
4448
|
}
|
|
4401
4449
|
async function createContractClientByWallet(rpcEndpoint, wallet) {
|
|
4402
|
-
console.log("rpcEndpoint", rpcEndpoint);
|
|
4403
4450
|
const client = await import_cosmwasm_stargate.SigningCosmWasmClient.connectWithSigner(rpcEndpoint, wallet, {
|
|
4404
4451
|
...defaultSigningClientOptions
|
|
4405
4452
|
});
|
|
@@ -4431,11 +4478,11 @@ function getAMaciRoundCircuitFee(network, maxVoter, maxOption) {
|
|
|
4431
4478
|
amount: "0"
|
|
4432
4479
|
};
|
|
4433
4480
|
if (maxVoter <= 25 && maxOption <= 5) {
|
|
4434
|
-
requiredFee.amount = "
|
|
4481
|
+
requiredFee.amount = "5000000000000000000";
|
|
4435
4482
|
} else if (maxVoter <= 625 && maxOption <= 25) {
|
|
4436
|
-
requiredFee.amount = "
|
|
4483
|
+
requiredFee.amount = "27000000000000000000";
|
|
4437
4484
|
} else if (maxVoter <= 15625 && maxOption <= 125) {
|
|
4438
|
-
requiredFee.amount = "
|
|
4485
|
+
requiredFee.amount = "208000000000000000000";
|
|
4439
4486
|
} else {
|
|
4440
4487
|
throw new Error("Number of voters or options is too large.");
|
|
4441
4488
|
}
|
|
@@ -4515,6 +4562,7 @@ var Contract = class {
|
|
|
4515
4562
|
[requiredFee]
|
|
4516
4563
|
);
|
|
4517
4564
|
let contractAddress = "";
|
|
4565
|
+
let pollId = "";
|
|
4518
4566
|
for (const event of res.events) {
|
|
4519
4567
|
if (event.type === "wasm") {
|
|
4520
4568
|
const actionEvent = event.attributes.find(
|
|
@@ -4524,8 +4572,16 @@ var Contract = class {
|
|
|
4524
4572
|
const roundAddrEvent = event.attributes.find(
|
|
4525
4573
|
(attr) => attr.key === "round_addr"
|
|
4526
4574
|
);
|
|
4575
|
+
const pollIdEvent = event.attributes.find(
|
|
4576
|
+
(attr) => attr.key === "poll_id"
|
|
4577
|
+
);
|
|
4527
4578
|
if (roundAddrEvent) {
|
|
4528
4579
|
contractAddress = roundAddrEvent.value.toString();
|
|
4580
|
+
}
|
|
4581
|
+
if (pollIdEvent) {
|
|
4582
|
+
pollId = pollIdEvent.value.toString();
|
|
4583
|
+
}
|
|
4584
|
+
if (contractAddress) {
|
|
4529
4585
|
break;
|
|
4530
4586
|
}
|
|
4531
4587
|
}
|
|
@@ -4533,7 +4589,8 @@ var Contract = class {
|
|
|
4533
4589
|
}
|
|
4534
4590
|
return {
|
|
4535
4591
|
...res,
|
|
4536
|
-
contractAddress
|
|
4592
|
+
contractAddress,
|
|
4593
|
+
pollId
|
|
4537
4594
|
};
|
|
4538
4595
|
}
|
|
4539
4596
|
async queryRoundInfo({ signer, roundAddress }) {
|
|
@@ -4944,6 +5001,7 @@ var Contract = class {
|
|
|
4944
5001
|
createResponse = await client.createAmaciRound(roundParams, fee);
|
|
4945
5002
|
}
|
|
4946
5003
|
let contractAddress = "";
|
|
5004
|
+
let pollId = "";
|
|
4947
5005
|
for (const event of createResponse.events) {
|
|
4948
5006
|
if (event.type === "wasm") {
|
|
4949
5007
|
const actionEvent = event.attributes.find(
|
|
@@ -4953,8 +5011,16 @@ var Contract = class {
|
|
|
4953
5011
|
const roundAddrEvent = event.attributes.find(
|
|
4954
5012
|
(attr) => attr.key === "round_addr"
|
|
4955
5013
|
);
|
|
5014
|
+
const pollIdEvent = event.attributes.find(
|
|
5015
|
+
(attr) => attr.key === "poll_id"
|
|
5016
|
+
);
|
|
4956
5017
|
if (roundAddrEvent) {
|
|
4957
5018
|
contractAddress = roundAddrEvent.value.toString();
|
|
5019
|
+
}
|
|
5020
|
+
if (pollIdEvent) {
|
|
5021
|
+
pollId = pollIdEvent.value.toString();
|
|
5022
|
+
}
|
|
5023
|
+
if (contractAddress) {
|
|
4958
5024
|
break;
|
|
4959
5025
|
}
|
|
4960
5026
|
}
|
|
@@ -4962,9 +5028,126 @@ var Contract = class {
|
|
|
4962
5028
|
}
|
|
4963
5029
|
return {
|
|
4964
5030
|
...createResponse,
|
|
4965
|
-
contractAddress
|
|
5031
|
+
contractAddress,
|
|
5032
|
+
pollId
|
|
4966
5033
|
};
|
|
4967
5034
|
}
|
|
5035
|
+
async publishMessageViaSaas({
|
|
5036
|
+
signer,
|
|
5037
|
+
contractAddress,
|
|
5038
|
+
encPubKeys,
|
|
5039
|
+
messages,
|
|
5040
|
+
granter,
|
|
5041
|
+
fee = 1.8
|
|
5042
|
+
}) {
|
|
5043
|
+
const client = await createApiSaasClientBy({
|
|
5044
|
+
rpcEndpoint: this.rpcEndpoint,
|
|
5045
|
+
wallet: signer,
|
|
5046
|
+
contractAddress: this.apiSaasAddress
|
|
5047
|
+
});
|
|
5048
|
+
const saasGranter = granter || this.apiSaasAddress;
|
|
5049
|
+
if (typeof fee !== "object") {
|
|
5050
|
+
const [{ address }] = await signer.getAccounts();
|
|
5051
|
+
const contractClient = await this.contractClient({ signer });
|
|
5052
|
+
const msg = {
|
|
5053
|
+
publish_message: {
|
|
5054
|
+
contract_addr: contractAddress,
|
|
5055
|
+
enc_pub_keys: encPubKeys,
|
|
5056
|
+
messages
|
|
5057
|
+
}
|
|
5058
|
+
};
|
|
5059
|
+
const gasEstimation = await contractClient.simulate(
|
|
5060
|
+
address,
|
|
5061
|
+
[
|
|
5062
|
+
{
|
|
5063
|
+
typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
|
|
5064
|
+
value: {
|
|
5065
|
+
sender: address,
|
|
5066
|
+
contract: this.apiSaasAddress,
|
|
5067
|
+
msg: new TextEncoder().encode(JSON.stringify(msg))
|
|
5068
|
+
}
|
|
5069
|
+
}
|
|
5070
|
+
],
|
|
5071
|
+
""
|
|
5072
|
+
);
|
|
5073
|
+
const multiplier = typeof fee === "number" ? fee : 1.8;
|
|
5074
|
+
const gasPrice = import_stargate2.GasPrice.fromString("10000000000peaka");
|
|
5075
|
+
const calculatedFee = (0, import_stargate2.calculateFee)(Math.round(gasEstimation * multiplier), gasPrice);
|
|
5076
|
+
const grantFee = {
|
|
5077
|
+
amount: calculatedFee.amount,
|
|
5078
|
+
gas: calculatedFee.gas,
|
|
5079
|
+
granter: saasGranter
|
|
5080
|
+
};
|
|
5081
|
+
return client.publishMessage({ contractAddr: contractAddress, encPubKeys, messages }, grantFee);
|
|
5082
|
+
} else {
|
|
5083
|
+
const grantFee = {
|
|
5084
|
+
...fee,
|
|
5085
|
+
granter: saasGranter
|
|
5086
|
+
};
|
|
5087
|
+
return client.publishMessage({ contractAddr: contractAddress, encPubKeys, messages }, grantFee);
|
|
5088
|
+
}
|
|
5089
|
+
}
|
|
5090
|
+
async publishDeactivateMessageViaSaas({
|
|
5091
|
+
signer,
|
|
5092
|
+
contractAddress,
|
|
5093
|
+
encPubKey,
|
|
5094
|
+
message,
|
|
5095
|
+
granter,
|
|
5096
|
+
fee = 1.8
|
|
5097
|
+
}) {
|
|
5098
|
+
const client = await createApiSaasClientBy({
|
|
5099
|
+
rpcEndpoint: this.rpcEndpoint,
|
|
5100
|
+
wallet: signer,
|
|
5101
|
+
contractAddress: this.apiSaasAddress
|
|
5102
|
+
});
|
|
5103
|
+
const saasGranter = granter || this.apiSaasAddress;
|
|
5104
|
+
if (typeof fee !== "object") {
|
|
5105
|
+
const [{ address }] = await signer.getAccounts();
|
|
5106
|
+
const contractClient = await this.contractClient({ signer });
|
|
5107
|
+
const msg = {
|
|
5108
|
+
publish_deactivate_message: {
|
|
5109
|
+
contract_addr: contractAddress,
|
|
5110
|
+
enc_pub_key: encPubKey,
|
|
5111
|
+
message
|
|
5112
|
+
}
|
|
5113
|
+
};
|
|
5114
|
+
const gasEstimation = await contractClient.simulate(
|
|
5115
|
+
address,
|
|
5116
|
+
[
|
|
5117
|
+
{
|
|
5118
|
+
typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
|
|
5119
|
+
value: {
|
|
5120
|
+
sender: address,
|
|
5121
|
+
contract: this.apiSaasAddress,
|
|
5122
|
+
msg: new TextEncoder().encode(JSON.stringify(msg))
|
|
5123
|
+
}
|
|
5124
|
+
}
|
|
5125
|
+
],
|
|
5126
|
+
""
|
|
5127
|
+
);
|
|
5128
|
+
const multiplier = typeof fee === "number" ? fee : 1.8;
|
|
5129
|
+
const gasPrice = import_stargate2.GasPrice.fromString("10000000000peaka");
|
|
5130
|
+
const calculatedFee = (0, import_stargate2.calculateFee)(Math.round(gasEstimation * multiplier), gasPrice);
|
|
5131
|
+
const grantFee = {
|
|
5132
|
+
amount: calculatedFee.amount,
|
|
5133
|
+
gas: calculatedFee.gas,
|
|
5134
|
+
granter: saasGranter
|
|
5135
|
+
};
|
|
5136
|
+
return client.publishDeactivateMessage(
|
|
5137
|
+
{ contractAddr: contractAddress, encPubKey, message },
|
|
5138
|
+
grantFee
|
|
5139
|
+
);
|
|
5140
|
+
} else {
|
|
5141
|
+
const grantFee = {
|
|
5142
|
+
...fee,
|
|
5143
|
+
granter: saasGranter
|
|
5144
|
+
};
|
|
5145
|
+
return client.publishDeactivateMessage(
|
|
5146
|
+
{ contractAddr: contractAddress, encPubKey, message },
|
|
5147
|
+
grantFee
|
|
5148
|
+
);
|
|
5149
|
+
}
|
|
5150
|
+
}
|
|
4968
5151
|
};
|
|
4969
5152
|
|
|
4970
5153
|
// src/libs/oracle-certificate/oracle-certificate.ts
|
|
@@ -5023,7 +5206,7 @@ var import_tx = require("cosmjs-types/cosmwasm/wasm/v1/tx.js");
|
|
|
5023
5206
|
// src/libs/maci/config.ts
|
|
5024
5207
|
var FEE_DENOM = "peaka";
|
|
5025
5208
|
var DEACTIVATE_FEE = "10000000000000000000";
|
|
5026
|
-
var MESSAGE_FEE = "
|
|
5209
|
+
var MESSAGE_FEE = "60000000000000000";
|
|
5027
5210
|
|
|
5028
5211
|
// src/libs/maci/maci.ts
|
|
5029
5212
|
function isErrorResponse(response) {
|
|
@@ -5486,6 +5669,18 @@ var MACI = class {
|
|
|
5486
5669
|
if (!address) {
|
|
5487
5670
|
address = (await signer.getAccounts())[0].address;
|
|
5488
5671
|
}
|
|
5672
|
+
const msgLength = payload[0]?.msg.length ?? 0;
|
|
5673
|
+
if (msgLength === 7) {
|
|
5674
|
+
return await this.publishMessageBatchLegacy({
|
|
5675
|
+
signer,
|
|
5676
|
+
address,
|
|
5677
|
+
payload,
|
|
5678
|
+
contractAddress,
|
|
5679
|
+
gasStation,
|
|
5680
|
+
granter,
|
|
5681
|
+
fee
|
|
5682
|
+
});
|
|
5683
|
+
}
|
|
5489
5684
|
return await this.publishMessageBatch({
|
|
5490
5685
|
signer,
|
|
5491
5686
|
address,
|
|
@@ -5571,34 +5766,29 @@ var MACI = class {
|
|
|
5571
5766
|
}));
|
|
5572
5767
|
const totalFee = (BigInt(MESSAGE_FEE) * BigInt(payload.length)).toString();
|
|
5573
5768
|
const batchFunds = [{ denom: FEE_DENOM, amount: totalFee }];
|
|
5574
|
-
if (gasStation &&
|
|
5769
|
+
if (gasStation && granter === this.contract.apiSaasAddress) {
|
|
5770
|
+
return this.contract.publishMessageViaSaas({
|
|
5771
|
+
signer,
|
|
5772
|
+
contractAddress,
|
|
5773
|
+
encPubKeys,
|
|
5774
|
+
messages,
|
|
5775
|
+
granter,
|
|
5776
|
+
fee
|
|
5777
|
+
});
|
|
5778
|
+
} else if (gasStation && typeof fee !== "object") {
|
|
5575
5779
|
const client = await this.contract.contractClient({ signer });
|
|
5576
|
-
const
|
|
5577
|
-
x: p.encPubkeys[0],
|
|
5578
|
-
y: p.encPubkeys[1]
|
|
5579
|
-
}));
|
|
5580
|
-
const messagesBigInt = payload.map((p) => ({
|
|
5581
|
-
data: p.msg
|
|
5582
|
-
}));
|
|
5583
|
-
const msg = {
|
|
5780
|
+
const msgForSimulate = {
|
|
5584
5781
|
typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
|
|
5585
5782
|
value: import_tx.MsgExecuteContract.fromPartial({
|
|
5586
5783
|
sender: address,
|
|
5587
5784
|
contract: contractAddress,
|
|
5588
5785
|
msg: new TextEncoder().encode(
|
|
5589
|
-
JSON.stringify(
|
|
5590
|
-
stringizing({
|
|
5591
|
-
publish_message: {
|
|
5592
|
-
enc_pub_keys: encPubKeysBigInt,
|
|
5593
|
-
messages: messagesBigInt
|
|
5594
|
-
}
|
|
5595
|
-
})
|
|
5596
|
-
)
|
|
5786
|
+
JSON.stringify({ publish_message: { enc_pub_keys: encPubKeys, messages } })
|
|
5597
5787
|
),
|
|
5598
5788
|
funds: batchFunds
|
|
5599
5789
|
})
|
|
5600
5790
|
};
|
|
5601
|
-
const gasEstimation = await client.simulate(address, [
|
|
5791
|
+
const gasEstimation = await client.simulate(address, [msgForSimulate], "");
|
|
5602
5792
|
const multiplier = typeof fee === "number" ? fee : 1.8;
|
|
5603
5793
|
const gasPrice = import_stargate3.GasPrice.fromString("10000000000peaka");
|
|
5604
5794
|
const calculatedFee = (0, import_stargate3.calculateFee)(Math.round(gasEstimation * multiplier), gasPrice);
|
|
@@ -5617,6 +5807,63 @@ var MACI = class {
|
|
|
5617
5807
|
}
|
|
5618
5808
|
return amaciClient.publishMessage({ encPubKeys, messages }, fee, void 0, batchFunds);
|
|
5619
5809
|
}
|
|
5810
|
+
async publishMessageBatchLegacy({
|
|
5811
|
+
signer,
|
|
5812
|
+
address,
|
|
5813
|
+
payload,
|
|
5814
|
+
contractAddress,
|
|
5815
|
+
gasStation,
|
|
5816
|
+
granter,
|
|
5817
|
+
fee = 1.8
|
|
5818
|
+
}) {
|
|
5819
|
+
if (!address) {
|
|
5820
|
+
address = (await signer.getAccounts())[0].address;
|
|
5821
|
+
}
|
|
5822
|
+
const client = await this.contract.contractClient({ signer });
|
|
5823
|
+
const messages = payload.map((p) => ({
|
|
5824
|
+
data: p.msg
|
|
5825
|
+
}));
|
|
5826
|
+
const encPubKeys = payload.map((p) => ({
|
|
5827
|
+
x: p.encPubkeys[0],
|
|
5828
|
+
y: p.encPubkeys[1]
|
|
5829
|
+
}));
|
|
5830
|
+
const msg = {
|
|
5831
|
+
typeUrl: "/cosmwasm.wasm.v1.MsgExecuteContract",
|
|
5832
|
+
value: import_tx.MsgExecuteContract.fromPartial({
|
|
5833
|
+
sender: address,
|
|
5834
|
+
contract: contractAddress,
|
|
5835
|
+
msg: new TextEncoder().encode(
|
|
5836
|
+
JSON.stringify(
|
|
5837
|
+
stringizing({
|
|
5838
|
+
publish_message_batch: {
|
|
5839
|
+
enc_pub_keys: encPubKeys,
|
|
5840
|
+
messages
|
|
5841
|
+
}
|
|
5842
|
+
})
|
|
5843
|
+
)
|
|
5844
|
+
)
|
|
5845
|
+
})
|
|
5846
|
+
};
|
|
5847
|
+
if (gasStation && typeof fee !== "object") {
|
|
5848
|
+
const gasEstimation = await client.simulate(address, [msg], "");
|
|
5849
|
+
const multiplier = typeof fee === "number" ? fee : 1.8;
|
|
5850
|
+
const gasPrice = import_stargate3.GasPrice.fromString("10000000000peaka");
|
|
5851
|
+
const calculatedFee = (0, import_stargate3.calculateFee)(Math.round(gasEstimation * multiplier), gasPrice);
|
|
5852
|
+
const grantFee = {
|
|
5853
|
+
amount: calculatedFee.amount,
|
|
5854
|
+
gas: calculatedFee.gas,
|
|
5855
|
+
granter: granter || contractAddress
|
|
5856
|
+
};
|
|
5857
|
+
return client.signAndBroadcast(address, [msg], grantFee);
|
|
5858
|
+
} else if (gasStation && typeof fee === "object") {
|
|
5859
|
+
const grantFee = {
|
|
5860
|
+
...fee,
|
|
5861
|
+
granter: granter || contractAddress
|
|
5862
|
+
};
|
|
5863
|
+
return client.signAndBroadcast(address, [msg], grantFee);
|
|
5864
|
+
}
|
|
5865
|
+
return client.signAndBroadcast(address, [msg], fee);
|
|
5866
|
+
}
|
|
5620
5867
|
async deactivate({
|
|
5621
5868
|
signer,
|
|
5622
5869
|
address,
|
|
@@ -5712,10 +5959,23 @@ var MACI = class {
|
|
|
5712
5959
|
}) {
|
|
5713
5960
|
try {
|
|
5714
5961
|
address = address || (await signer.getAccounts())[0].address;
|
|
5715
|
-
const client = await this.contract.contractClient({
|
|
5716
|
-
signer
|
|
5717
|
-
});
|
|
5718
5962
|
const { msg, encPubkeys } = payload;
|
|
5963
|
+
if (gasStation === true && granter === this.contract.apiSaasAddress) {
|
|
5964
|
+
return this.contract.publishDeactivateMessageViaSaas({
|
|
5965
|
+
signer,
|
|
5966
|
+
contractAddress,
|
|
5967
|
+
encPubKey: {
|
|
5968
|
+
x: encPubkeys[0].toString(),
|
|
5969
|
+
y: encPubkeys[1].toString()
|
|
5970
|
+
},
|
|
5971
|
+
message: {
|
|
5972
|
+
data: msg.map((m) => m.toString())
|
|
5973
|
+
},
|
|
5974
|
+
granter,
|
|
5975
|
+
fee
|
|
5976
|
+
});
|
|
5977
|
+
}
|
|
5978
|
+
const client = await this.contract.contractClient({ signer });
|
|
5719
5979
|
const deactivateMsg = stringizing({
|
|
5720
5980
|
publish_deactivate_message: {
|
|
5721
5981
|
enc_pub_key: {
|
|
@@ -5771,6 +6031,7 @@ var MACI = class {
|
|
|
5771
6031
|
}
|
|
5772
6032
|
async genAddKeyInput({
|
|
5773
6033
|
maciKeypair,
|
|
6034
|
+
newMaciKeypair,
|
|
5774
6035
|
contractAddress
|
|
5775
6036
|
}) {
|
|
5776
6037
|
const deactivates = await this.fetchAllDeactivateLogs({
|
|
@@ -5779,12 +6040,15 @@ var MACI = class {
|
|
|
5779
6040
|
const roundInfo = await this.getRoundInfo({
|
|
5780
6041
|
contractAddress
|
|
5781
6042
|
});
|
|
6043
|
+
const pollId = await this.getPollId({ contractAddress });
|
|
5782
6044
|
const circuitPower = roundInfo.circuitPower;
|
|
5783
6045
|
const stateTreeDepth = Number(circuitPower.split("-")[0]);
|
|
5784
6046
|
const inputObj = genAddKeyInput(stateTreeDepth + 2, {
|
|
5785
6047
|
coordPubKey: [BigInt(roundInfo.coordinatorPubkeyX), BigInt(roundInfo.coordinatorPubkeyY)],
|
|
5786
6048
|
oldKey: maciKeypair,
|
|
5787
|
-
deactivates: deactivates.map((d) => d.map(BigInt))
|
|
6049
|
+
deactivates: deactivates.map((d) => d.map(BigInt)),
|
|
6050
|
+
newPubKey: newMaciKeypair.pubKey,
|
|
6051
|
+
pollId: BigInt(pollId)
|
|
5788
6052
|
});
|
|
5789
6053
|
return inputObj;
|
|
5790
6054
|
}
|
|
@@ -6429,6 +6693,47 @@ var MaciApiClient = class {
|
|
|
6429
6693
|
method: "GET"
|
|
6430
6694
|
});
|
|
6431
6695
|
}
|
|
6696
|
+
/**
|
|
6697
|
+
* Get coordinator public key, deactivate root, and voter scale for a round.
|
|
6698
|
+
* Lighter alternative to the full data endpoint when only circuit inputs are needed.
|
|
6699
|
+
*/
|
|
6700
|
+
async getPreDeactivateMeta(params) {
|
|
6701
|
+
return this.fetch(`/v1/pre-deactivate/${params.contractAddress}/meta`, {
|
|
6702
|
+
method: "GET"
|
|
6703
|
+
});
|
|
6704
|
+
}
|
|
6705
|
+
/**
|
|
6706
|
+
* Get K-anonymous Merkle proof packages for the specified leaf indices.
|
|
6707
|
+
* The caller should mix the real leaf index with decoy indices to preserve privacy.
|
|
6708
|
+
*/
|
|
6709
|
+
async getPreDeactivateProof(contractAddress, indices) {
|
|
6710
|
+
return this.fetch(
|
|
6711
|
+
`/v1/pre-deactivate/${contractAddress}/proof?indices=${indices}`,
|
|
6712
|
+
{ method: "GET" }
|
|
6713
|
+
);
|
|
6714
|
+
}
|
|
6715
|
+
// ==================== Claim Key APIs ====================
|
|
6716
|
+
/**
|
|
6717
|
+
* Claim MACI Key
|
|
6718
|
+
* Assign the next available pre-generated MACI key pair for an AMACI round (first-come-first-served).
|
|
6719
|
+
* Returns pubkey, secretKey, and the full deactivate Merkle proof.
|
|
6720
|
+
* WARNING: secretKey is returned only once and cannot be retrieved again.
|
|
6721
|
+
*/
|
|
6722
|
+
async claimMaciKey(params) {
|
|
6723
|
+
return this.fetch(`/v1/rounds/${params.contractAddress}/claim-key`, {
|
|
6724
|
+
method: "POST"
|
|
6725
|
+
});
|
|
6726
|
+
}
|
|
6727
|
+
/**
|
|
6728
|
+
* Get Claim Statistics
|
|
6729
|
+
* Returns total key slots (scale), claimed count, and available count for the round.
|
|
6730
|
+
* Public endpoint — no authentication required.
|
|
6731
|
+
*/
|
|
6732
|
+
async getClaimStats(params) {
|
|
6733
|
+
return this.fetch(`/v1/rounds/${params.contractAddress}/claim-key-stats`, {
|
|
6734
|
+
method: "GET"
|
|
6735
|
+
});
|
|
6736
|
+
}
|
|
6432
6737
|
};
|
|
6433
6738
|
|
|
6434
6739
|
// src/maci.ts
|
|
@@ -6789,10 +7094,12 @@ var MaciClient = class {
|
|
|
6789
7094
|
}
|
|
6790
7095
|
async genAddKeyInput({
|
|
6791
7096
|
contractAddress,
|
|
6792
|
-
maciKeypair
|
|
7097
|
+
maciKeypair,
|
|
7098
|
+
newMaciKeypair
|
|
6793
7099
|
}) {
|
|
6794
7100
|
return await this.maci.genAddKeyInput({
|
|
6795
7101
|
maciKeypair: maciKeypair || this.maciKeypair,
|
|
7102
|
+
newMaciKeypair,
|
|
6796
7103
|
contractAddress
|
|
6797
7104
|
});
|
|
6798
7105
|
}
|
|
@@ -7005,6 +7312,19 @@ var MaciClient = class {
|
|
|
7005
7312
|
}
|
|
7006
7313
|
return await this.saasApiClient.setVoteOptions(params);
|
|
7007
7314
|
}
|
|
7315
|
+
/**
|
|
7316
|
+
* Claim the next available pre-generated MACI key pair for an AMACI round via SaaS API.
|
|
7317
|
+
* The key is assigned on a first-come-first-served basis.
|
|
7318
|
+
* WARNING: secretKey is returned only once — save it immediately, it cannot be retrieved again.
|
|
7319
|
+
* @param contractAddress - Round contract address
|
|
7320
|
+
* @returns Claimed key pair with full deactivate Merkle proof
|
|
7321
|
+
*/
|
|
7322
|
+
async saasClaimKey(contractAddress) {
|
|
7323
|
+
if (!this.saasApiClient) {
|
|
7324
|
+
throw new Error("SaaS API client not initialized");
|
|
7325
|
+
}
|
|
7326
|
+
return await this.saasApiClient.claimMaciKey({ contractAddress });
|
|
7327
|
+
}
|
|
7008
7328
|
};
|
|
7009
7329
|
|
|
7010
7330
|
// src/voter.ts
|
|
@@ -7497,6 +7817,15 @@ var MaciAccount = class {
|
|
|
7497
7817
|
|
|
7498
7818
|
// src/voter.ts
|
|
7499
7819
|
var import_poseidon_cipher3 = require("@zk-kit/poseidon-cipher");
|
|
7820
|
+
function buildKAnonymousIndices(deactivateIdx, voterScale) {
|
|
7821
|
+
const kMax = Math.min(200, Math.floor(voterScale * 0.1) || 1);
|
|
7822
|
+
const pool = Array.from({ length: voterScale }, (_, i) => i).filter((i) => i !== deactivateIdx);
|
|
7823
|
+
for (let i = pool.length - 1; i > 0; i--) {
|
|
7824
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
7825
|
+
[pool[i], pool[j]] = [pool[j], pool[i]];
|
|
7826
|
+
}
|
|
7827
|
+
return [deactivateIdx, ...pool.slice(0, kMax - 1)].sort((a, b) => a - b).join(",");
|
|
7828
|
+
}
|
|
7500
7829
|
var VoterClient = class _VoterClient {
|
|
7501
7830
|
/**
|
|
7502
7831
|
* @constructor
|
|
@@ -7627,7 +7956,7 @@ var VoterClient = class _VoterClient {
|
|
|
7627
7956
|
derivePathParams
|
|
7628
7957
|
}) {
|
|
7629
7958
|
const plan = this.normalizeVoteOptions(selectedOptions);
|
|
7630
|
-
const payload = this.batchGenMessage(stateIdx, operatorPubkey, pollId, plan, derivePathParams);
|
|
7959
|
+
const payload = pollId !== void 0 ? this.batchGenMessage(stateIdx, operatorPubkey, pollId, plan, derivePathParams) : this.legacyBatchGenMessage(stateIdx, operatorPubkey, plan, derivePathParams);
|
|
7631
7960
|
return stringizing(payload);
|
|
7632
7961
|
}
|
|
7633
7962
|
/**
|
|
@@ -7728,16 +8057,32 @@ var VoterClient = class _VoterClient {
|
|
|
7728
8057
|
stateTreeDepth,
|
|
7729
8058
|
operatorPubkey,
|
|
7730
8059
|
deactivates,
|
|
8060
|
+
newPubkey,
|
|
8061
|
+
pollId,
|
|
7731
8062
|
wasmFile,
|
|
7732
8063
|
zkeyFile,
|
|
7733
8064
|
derivePathParams
|
|
7734
8065
|
}) {
|
|
7735
8066
|
const [coordPubkeyX, coordPubkeyY] = this.unpackMaciPubkey(operatorPubkey);
|
|
7736
|
-
|
|
7737
|
-
|
|
7738
|
-
|
|
7739
|
-
|
|
7740
|
-
|
|
8067
|
+
let addKeyInput;
|
|
8068
|
+
if (pollId !== void 0) {
|
|
8069
|
+
if (!newPubkey) {
|
|
8070
|
+
throw new Error("buildAddNewKeyPayload: `newPubkey` is required when `pollId` is provided");
|
|
8071
|
+
}
|
|
8072
|
+
addKeyInput = await this.genAddKeyInput(stateTreeDepth + 2, {
|
|
8073
|
+
coordPubKey: [coordPubkeyX, coordPubkeyY],
|
|
8074
|
+
deactivates: deactivates.map((d) => d.map(BigInt)),
|
|
8075
|
+
newPubKey: newPubkey,
|
|
8076
|
+
pollId,
|
|
8077
|
+
derivePathParams
|
|
8078
|
+
});
|
|
8079
|
+
} else {
|
|
8080
|
+
addKeyInput = await this.legacyGenAddKeyInput(stateTreeDepth + 2, {
|
|
8081
|
+
coordPubKey: [coordPubkeyX, coordPubkeyY],
|
|
8082
|
+
deactivates: deactivates.map((d) => d.map(BigInt)),
|
|
8083
|
+
derivePathParams
|
|
8084
|
+
});
|
|
8085
|
+
}
|
|
7741
8086
|
if (addKeyInput === null) {
|
|
7742
8087
|
throw Error("genAddKeyInput failed");
|
|
7743
8088
|
}
|
|
@@ -7758,20 +8103,117 @@ var VoterClient = class _VoterClient {
|
|
|
7758
8103
|
stateTreeDepth,
|
|
7759
8104
|
coordinatorPubkey,
|
|
7760
8105
|
deactivates,
|
|
8106
|
+
contractAddress,
|
|
8107
|
+
deactivateIdx,
|
|
8108
|
+
voterScale,
|
|
8109
|
+
preComputedProof,
|
|
8110
|
+
newPubkey,
|
|
8111
|
+
pollId,
|
|
7761
8112
|
wasmFile,
|
|
7762
8113
|
zkeyFile,
|
|
7763
8114
|
derivePathParams
|
|
7764
8115
|
}) {
|
|
7765
8116
|
const [coordPubkeyX, coordPubkeyY] = this.unpackMaciPubkey(coordinatorPubkey);
|
|
8117
|
+
if (pollId === void 0) {
|
|
8118
|
+
if (!deactivates || deactivates.length === 0) {
|
|
8119
|
+
throw new Error(
|
|
8120
|
+
"buildPreAddNewKeyPayload: `deactivates` is required in legacy mode (pollId omitted)"
|
|
8121
|
+
);
|
|
8122
|
+
}
|
|
8123
|
+
const addKeyInput2 = await this.legacyGenPreAddKeyInput(stateTreeDepth + 2, {
|
|
8124
|
+
coordPubKey: [coordPubkeyX, coordPubkeyY],
|
|
8125
|
+
deactivates: deactivates.map((d) => d.map(BigInt)),
|
|
8126
|
+
derivePathParams
|
|
8127
|
+
});
|
|
8128
|
+
if (addKeyInput2 === null) {
|
|
8129
|
+
throw Error("legacyGenPreAddKeyInput failed, cannot find deactivate idx");
|
|
8130
|
+
}
|
|
8131
|
+
const { proof: proof2 } = await import_snarkjs.groth16.fullProve(addKeyInput2, wasmFile, zkeyFile);
|
|
8132
|
+
const proofHex2 = await adaptToUncompressed(proof2);
|
|
8133
|
+
return {
|
|
8134
|
+
proof: proofHex2,
|
|
8135
|
+
d: [
|
|
8136
|
+
addKeyInput2.d1[0].toString(),
|
|
8137
|
+
addKeyInput2.d1[1].toString(),
|
|
8138
|
+
addKeyInput2.d2[0].toString(),
|
|
8139
|
+
addKeyInput2.d2[1].toString()
|
|
8140
|
+
],
|
|
8141
|
+
nullifier: addKeyInput2.nullifier.toString()
|
|
8142
|
+
};
|
|
8143
|
+
}
|
|
8144
|
+
if (!newPubkey) {
|
|
8145
|
+
throw new Error("buildPreAddNewKeyPayload: `newPubkey` is required when `pollId` is provided");
|
|
8146
|
+
}
|
|
8147
|
+
const coordPubKey = [coordPubkeyX, coordPubkeyY];
|
|
8148
|
+
let resolvedDeactivates;
|
|
8149
|
+
let preComputedTreeProof;
|
|
8150
|
+
let preComputedLeaf;
|
|
8151
|
+
if (deactivates && deactivates.length > 0) {
|
|
8152
|
+
resolvedDeactivates = deactivates.map((d) => d.map(BigInt));
|
|
8153
|
+
} else if (preComputedProof) {
|
|
8154
|
+
if (deactivateIdx === void 0) {
|
|
8155
|
+
throw new Error(
|
|
8156
|
+
"buildPreAddNewKeyPayload: `deactivateIdx` is required when `preComputedProof` is provided"
|
|
8157
|
+
);
|
|
8158
|
+
}
|
|
8159
|
+
preComputedLeaf = preComputedProof.deactivateLeaf.map(BigInt);
|
|
8160
|
+
preComputedTreeProof = {
|
|
8161
|
+
root: preComputedProof.root,
|
|
8162
|
+
pathElements: preComputedProof.pathElements
|
|
8163
|
+
};
|
|
8164
|
+
resolvedDeactivates = [];
|
|
8165
|
+
} else {
|
|
8166
|
+
if (!contractAddress) {
|
|
8167
|
+
throw new Error(
|
|
8168
|
+
"buildPreAddNewKeyPayload: `contractAddress` is required when `deactivates` is not provided"
|
|
8169
|
+
);
|
|
8170
|
+
}
|
|
8171
|
+
if (deactivateIdx === void 0) {
|
|
8172
|
+
throw new Error(
|
|
8173
|
+
"buildPreAddNewKeyPayload: `deactivateIdx` is required when `deactivates` is not provided"
|
|
8174
|
+
);
|
|
8175
|
+
}
|
|
8176
|
+
if (voterScale === void 0) {
|
|
8177
|
+
throw new Error(
|
|
8178
|
+
"buildPreAddNewKeyPayload: `voterScale` is required for the K-anonymous API path"
|
|
8179
|
+
);
|
|
8180
|
+
}
|
|
8181
|
+
const indicesParam = buildKAnonymousIndices(deactivateIdx, voterScale);
|
|
8182
|
+
const proofResp = await this.saasApiClient.getPreDeactivateProof(
|
|
8183
|
+
contractAddress,
|
|
8184
|
+
indicesParam
|
|
8185
|
+
);
|
|
8186
|
+
const pkg = proofResp.proofs.find((p) => p.leafIndex === deactivateIdx);
|
|
8187
|
+
if (!pkg) {
|
|
8188
|
+
throw new Error(
|
|
8189
|
+
`buildPreAddNewKeyPayload: proof package for leafIndex ${deactivateIdx} not found in API response`
|
|
8190
|
+
);
|
|
8191
|
+
}
|
|
8192
|
+
preComputedLeaf = pkg.deactivateLeaf.map(BigInt);
|
|
8193
|
+
preComputedTreeProof = {
|
|
8194
|
+
root: proofResp.root,
|
|
8195
|
+
pathElements: pkg.pathElements
|
|
8196
|
+
};
|
|
8197
|
+
resolvedDeactivates = [];
|
|
8198
|
+
}
|
|
8199
|
+
const genPreAddKeyInputStart = Date.now();
|
|
7766
8200
|
const addKeyInput = await this.genPreAddKeyInput(stateTreeDepth + 2, {
|
|
7767
|
-
coordPubKey
|
|
7768
|
-
deactivates:
|
|
7769
|
-
|
|
8201
|
+
coordPubKey,
|
|
8202
|
+
deactivates: resolvedDeactivates,
|
|
8203
|
+
newPubKey: newPubkey,
|
|
8204
|
+
pollId,
|
|
8205
|
+
derivePathParams,
|
|
8206
|
+
preComputedTreeProof,
|
|
8207
|
+
preComputedLeaf,
|
|
8208
|
+
deactivateIdx
|
|
7770
8209
|
});
|
|
8210
|
+
console.log(`[genPreAddKeyInput] elapsed: ${Date.now() - genPreAddKeyInputStart}ms`);
|
|
7771
8211
|
if (addKeyInput === null) {
|
|
7772
8212
|
throw Error("genPreAddKeyInput failed, cannot find deactivate idx");
|
|
7773
8213
|
}
|
|
8214
|
+
const fullProveStart = Date.now();
|
|
7774
8215
|
const { proof } = await import_snarkjs.groth16.fullProve(addKeyInput, wasmFile, zkeyFile);
|
|
8216
|
+
console.log(`[fullProve] elapsed: ${Date.now() - fullProveStart}ms`);
|
|
7775
8217
|
const proofHex = await adaptToUncompressed(proof);
|
|
7776
8218
|
return {
|
|
7777
8219
|
proof: proofHex,
|
|
@@ -7787,6 +8229,8 @@ var VoterClient = class _VoterClient {
|
|
|
7787
8229
|
async genAddKeyInput(depth, {
|
|
7788
8230
|
coordPubKey,
|
|
7789
8231
|
deactivates,
|
|
8232
|
+
newPubKey,
|
|
8233
|
+
pollId,
|
|
7790
8234
|
derivePathParams
|
|
7791
8235
|
}) {
|
|
7792
8236
|
const signer = this.getSigner(derivePathParams);
|
|
@@ -7800,7 +8244,7 @@ var VoterClient = class _VoterClient {
|
|
|
7800
8244
|
const c1 = [deactivateLeaf[0], deactivateLeaf[1]];
|
|
7801
8245
|
const c2 = [deactivateLeaf[2], deactivateLeaf[3]];
|
|
7802
8246
|
const { d1, d2 } = rerandomize(coordPubKey, { c1, c2 }, randomVal);
|
|
7803
|
-
const nullifier = poseidon([signer.getFormatedPrivKey(),
|
|
8247
|
+
const nullifier = poseidon([signer.getFormatedPrivKey(), pollId]);
|
|
7804
8248
|
const tree = new Tree(5, depth, 0n);
|
|
7805
8249
|
const leaves = deactivates.map((d) => poseidon(d));
|
|
7806
8250
|
tree.initLeaves(leaves);
|
|
@@ -7813,7 +8257,9 @@ var VoterClient = class _VoterClient {
|
|
|
7813
8257
|
d1[0],
|
|
7814
8258
|
d1[1],
|
|
7815
8259
|
d2[0],
|
|
7816
|
-
d2[1]
|
|
8260
|
+
d2[1],
|
|
8261
|
+
poseidon(newPubKey),
|
|
8262
|
+
pollId
|
|
7817
8263
|
]);
|
|
7818
8264
|
const input = {
|
|
7819
8265
|
inputHash,
|
|
@@ -7828,32 +8274,75 @@ var VoterClient = class _VoterClient {
|
|
|
7828
8274
|
d2,
|
|
7829
8275
|
deactivateLeafPathElements,
|
|
7830
8276
|
nullifier,
|
|
7831
|
-
oldPrivateKey: signer.getFormatedPrivKey()
|
|
8277
|
+
oldPrivateKey: signer.getFormatedPrivKey(),
|
|
8278
|
+
newPubKey,
|
|
8279
|
+
pollId
|
|
7832
8280
|
};
|
|
7833
8281
|
return input;
|
|
7834
8282
|
}
|
|
7835
8283
|
async genPreAddKeyInput(depth, {
|
|
7836
8284
|
coordPubKey,
|
|
7837
8285
|
deactivates,
|
|
7838
|
-
|
|
8286
|
+
newPubKey,
|
|
8287
|
+
pollId,
|
|
8288
|
+
derivePathParams,
|
|
8289
|
+
preComputedTreeProof,
|
|
8290
|
+
preComputedLeaf,
|
|
8291
|
+
deactivateIdx: providedDeactivateIdx
|
|
7839
8292
|
}) {
|
|
8293
|
+
let t0 = Date.now();
|
|
7840
8294
|
const signer = this.getSigner(derivePathParams);
|
|
7841
|
-
|
|
8295
|
+
console.log(`[genPreAddKeyInput] getSigner: ${Date.now() - t0}ms`);
|
|
8296
|
+
t0 = Date.now();
|
|
7842
8297
|
const randomVal = genRandomSalt();
|
|
7843
|
-
|
|
7844
|
-
if (
|
|
8298
|
+
let deactivateIdx;
|
|
8299
|
+
if (providedDeactivateIdx !== void 0) {
|
|
8300
|
+
deactivateIdx = providedDeactivateIdx;
|
|
8301
|
+
console.log(
|
|
8302
|
+
`[genPreAddKeyInput] using provided deactivateIdx=${deactivateIdx} (skip search)`
|
|
8303
|
+
);
|
|
8304
|
+
} else {
|
|
8305
|
+
const sharedKeyHash = poseidon(signer.genEcdhSharedKey(coordPubKey));
|
|
8306
|
+
console.log(`[genPreAddKeyInput] genEcdhSharedKey + poseidon: ${Date.now() - t0}ms`);
|
|
8307
|
+
t0 = Date.now();
|
|
8308
|
+
deactivateIdx = deactivates.findIndex((d) => d[4] === sharedKeyHash);
|
|
8309
|
+
if (deactivateIdx < 0) {
|
|
8310
|
+
return null;
|
|
8311
|
+
}
|
|
8312
|
+
console.log(`[genPreAddKeyInput] genRandomSalt + findDeactivateIdx: ${Date.now() - t0}ms`);
|
|
8313
|
+
t0 = Date.now();
|
|
8314
|
+
}
|
|
8315
|
+
const deactivateLeaf = preComputedLeaf ?? deactivates[deactivateIdx];
|
|
8316
|
+
if (!deactivateLeaf) {
|
|
7845
8317
|
return null;
|
|
7846
8318
|
}
|
|
7847
|
-
const deactivateLeaf = deactivates[deactivateIdx];
|
|
7848
8319
|
const c1 = [deactivateLeaf[0], deactivateLeaf[1]];
|
|
7849
8320
|
const c2 = [deactivateLeaf[2], deactivateLeaf[3]];
|
|
7850
8321
|
const { d1, d2 } = rerandomize(coordPubKey, { c1, c2 }, randomVal);
|
|
7851
|
-
|
|
7852
|
-
|
|
7853
|
-
const
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
|
|
8322
|
+
console.log(`[genPreAddKeyInput] rerandomize: ${Date.now() - t0}ms`);
|
|
8323
|
+
t0 = Date.now();
|
|
8324
|
+
const nullifier = poseidon([signer.getFormatedPrivKey(), pollId]);
|
|
8325
|
+
console.log(`[genPreAddKeyInput] nullifier (poseidon): ${Date.now() - t0}ms`);
|
|
8326
|
+
t0 = Date.now();
|
|
8327
|
+
let deactivateRoot;
|
|
8328
|
+
let deactivateLeafPathElements;
|
|
8329
|
+
if (preComputedTreeProof) {
|
|
8330
|
+
deactivateRoot = BigInt(preComputedTreeProof.root);
|
|
8331
|
+
deactivateLeafPathElements = preComputedTreeProof.pathElements.map(
|
|
8332
|
+
(level) => level.map(BigInt)
|
|
8333
|
+
);
|
|
8334
|
+
console.log(`[genPreAddKeyInput] using preComputedTreeProof (API path)`);
|
|
8335
|
+
} else {
|
|
8336
|
+
const tree = new Tree(5, depth, 0n);
|
|
8337
|
+
const leaves = deactivates.map((d) => poseidon(d));
|
|
8338
|
+
tree.initLeaves(leaves);
|
|
8339
|
+
console.log(`[genPreAddKeyInput] build tree + initLeaves: ${Date.now() - t0}ms`);
|
|
8340
|
+
t0 = Date.now();
|
|
8341
|
+
deactivateRoot = tree.root;
|
|
8342
|
+
deactivateLeafPathElements = tree.pathElementOf(deactivateIdx);
|
|
8343
|
+
console.log(`[genPreAddKeyInput] tree.root + pathElementOf: ${Date.now() - t0}ms`);
|
|
8344
|
+
t0 = Date.now();
|
|
8345
|
+
}
|
|
7857
8346
|
const inputHash = computeInputHash([
|
|
7858
8347
|
deactivateRoot,
|
|
7859
8348
|
poseidon(coordPubKey),
|
|
@@ -7861,8 +8350,12 @@ var VoterClient = class _VoterClient {
|
|
|
7861
8350
|
d1[0],
|
|
7862
8351
|
d1[1],
|
|
7863
8352
|
d2[0],
|
|
7864
|
-
d2[1]
|
|
8353
|
+
d2[1],
|
|
8354
|
+
poseidon(newPubKey),
|
|
8355
|
+
pollId
|
|
7865
8356
|
]);
|
|
8357
|
+
console.log(`[genPreAddKeyInput] computeInputHash: ${Date.now() - t0}ms`);
|
|
8358
|
+
t0 = Date.now();
|
|
7866
8359
|
const input = {
|
|
7867
8360
|
inputHash,
|
|
7868
8361
|
coordPubKey,
|
|
@@ -7876,7 +8369,9 @@ var VoterClient = class _VoterClient {
|
|
|
7876
8369
|
d2,
|
|
7877
8370
|
deactivateLeafPathElements,
|
|
7878
8371
|
nullifier,
|
|
7879
|
-
oldPrivateKey: signer.getFormatedPrivKey()
|
|
8372
|
+
oldPrivateKey: signer.getFormatedPrivKey(),
|
|
8373
|
+
newPubKey,
|
|
8374
|
+
pollId
|
|
7880
8375
|
};
|
|
7881
8376
|
return input;
|
|
7882
8377
|
}
|
|
@@ -7897,7 +8392,68 @@ var VoterClient = class _VoterClient {
|
|
|
7897
8392
|
nonce = 0,
|
|
7898
8393
|
derivePathParams
|
|
7899
8394
|
}) {
|
|
7900
|
-
const genMessage = this.genMessageFactory(stateIdx, operatorPubkey, pollId, derivePathParams);
|
|
8395
|
+
const genMessage = pollId !== void 0 ? this.genMessageFactory(stateIdx, operatorPubkey, pollId, derivePathParams) : this.legacyGenMessageFactory(stateIdx, operatorPubkey, derivePathParams);
|
|
8396
|
+
const encAccount = genKeypair();
|
|
8397
|
+
const msg = genMessage(BigInt(encAccount.privKey), nonce, 0, 0, true);
|
|
8398
|
+
return stringizing({
|
|
8399
|
+
msg,
|
|
8400
|
+
encPubkeys: encAccount.pubKey
|
|
8401
|
+
});
|
|
8402
|
+
}
|
|
8403
|
+
// ==================== Legacy Methods (backward-compat, no pollId) ====================
|
|
8404
|
+
legacyGenMessageFactory(stateIdx, operatorPubkey, derivePathParams) {
|
|
8405
|
+
return (encPriKey, nonce, voIdx, newVotes, isLastCmd, salt) => {
|
|
8406
|
+
if (salt === void 0) {
|
|
8407
|
+
salt = BigInt(`0x${import_crypto_js3.default.lib.WordArray.random(7).toString(import_crypto_js3.default.enc.Hex)}`);
|
|
8408
|
+
}
|
|
8409
|
+
const packaged = BigInt(nonce) + (BigInt(stateIdx) << 32n) + (BigInt(voIdx) << 64n) + (BigInt(newVotes) << 96n) + (BigInt(salt) << 192n);
|
|
8410
|
+
const signer = this.getSigner(derivePathParams);
|
|
8411
|
+
let newPubKey;
|
|
8412
|
+
if (isLastCmd) {
|
|
8413
|
+
newPubKey = [0n, 0n];
|
|
8414
|
+
} else {
|
|
8415
|
+
newPubKey = [...signer.getPublicKey().toPoints()];
|
|
8416
|
+
}
|
|
8417
|
+
const hash = poseidon([packaged, ...newPubKey]);
|
|
8418
|
+
const signature = signer.sign(hash);
|
|
8419
|
+
const command = [packaged, ...newPubKey, ...signature.R8, signature.S];
|
|
8420
|
+
const coordPubkey = this.unpackMaciPubkey(operatorPubkey);
|
|
8421
|
+
const message = (0, import_poseidon_cipher3.poseidonEncrypt)(command, genEcdhSharedKey(encPriKey, coordPubkey), 0n);
|
|
8422
|
+
return message;
|
|
8423
|
+
};
|
|
8424
|
+
}
|
|
8425
|
+
legacyBatchGenMessage(stateIdx, operatorPubkey, plan, derivePathParams) {
|
|
8426
|
+
const genMessage = this.legacyGenMessageFactory(stateIdx, operatorPubkey, derivePathParams);
|
|
8427
|
+
const payload = [];
|
|
8428
|
+
for (let i = plan.length - 1; i >= 0; i--) {
|
|
8429
|
+
const p = plan[i];
|
|
8430
|
+
const encAccount = genKeypair();
|
|
8431
|
+
const isLastCmd = i === plan.length - 1;
|
|
8432
|
+
const msg = genMessage(BigInt(encAccount.privKey), i + 1, p[0], p[1], isLastCmd);
|
|
8433
|
+
payload.push({
|
|
8434
|
+
msg,
|
|
8435
|
+
encPubkeys: encAccount.pubKey
|
|
8436
|
+
});
|
|
8437
|
+
}
|
|
8438
|
+
return payload;
|
|
8439
|
+
}
|
|
8440
|
+
legacyBuildVotePayload({
|
|
8441
|
+
stateIdx,
|
|
8442
|
+
operatorPubkey,
|
|
8443
|
+
selectedOptions,
|
|
8444
|
+
derivePathParams
|
|
8445
|
+
}) {
|
|
8446
|
+
const plan = this.normalizeVoteOptions(selectedOptions);
|
|
8447
|
+
const payload = this.legacyBatchGenMessage(stateIdx, operatorPubkey, plan, derivePathParams);
|
|
8448
|
+
return stringizing(payload);
|
|
8449
|
+
}
|
|
8450
|
+
legacyBuildDeactivatePayload({
|
|
8451
|
+
stateIdx,
|
|
8452
|
+
operatorPubkey,
|
|
8453
|
+
nonce = 0,
|
|
8454
|
+
derivePathParams
|
|
8455
|
+
}) {
|
|
8456
|
+
const genMessage = this.legacyGenMessageFactory(stateIdx, operatorPubkey, derivePathParams);
|
|
7901
8457
|
const encAccount = genKeypair();
|
|
7902
8458
|
const msg = genMessage(BigInt(encAccount.privKey), nonce, 0, 0, true);
|
|
7903
8459
|
return stringizing({
|
|
@@ -7905,6 +8461,164 @@ var VoterClient = class _VoterClient {
|
|
|
7905
8461
|
encPubkeys: encAccount.pubKey
|
|
7906
8462
|
});
|
|
7907
8463
|
}
|
|
8464
|
+
async legacyGenAddKeyInput(depth, {
|
|
8465
|
+
coordPubKey,
|
|
8466
|
+
deactivates,
|
|
8467
|
+
derivePathParams
|
|
8468
|
+
}) {
|
|
8469
|
+
const signer = this.getSigner(derivePathParams);
|
|
8470
|
+
const sharedKeyHash = poseidon(signer.genEcdhSharedKey(coordPubKey));
|
|
8471
|
+
const randomVal = genRandomSalt();
|
|
8472
|
+
const deactivateIdx = deactivates.findIndex((d) => d[4] === sharedKeyHash);
|
|
8473
|
+
if (deactivateIdx < 0) {
|
|
8474
|
+
return null;
|
|
8475
|
+
}
|
|
8476
|
+
const deactivateLeaf = deactivates[deactivateIdx];
|
|
8477
|
+
const c1 = [deactivateLeaf[0], deactivateLeaf[1]];
|
|
8478
|
+
const c2 = [deactivateLeaf[2], deactivateLeaf[3]];
|
|
8479
|
+
const { d1, d2 } = rerandomize(coordPubKey, { c1, c2 }, randomVal);
|
|
8480
|
+
const nullifier = poseidon([signer.getFormatedPrivKey(), 1444992409218394441042n]);
|
|
8481
|
+
const tree = new Tree(5, depth, 0n);
|
|
8482
|
+
const leaves = deactivates.map((d) => poseidon(d));
|
|
8483
|
+
tree.initLeaves(leaves);
|
|
8484
|
+
const deactivateRoot = tree.root;
|
|
8485
|
+
const deactivateLeafPathElements = tree.pathElementOf(deactivateIdx);
|
|
8486
|
+
const inputHash = computeInputHash([
|
|
8487
|
+
deactivateRoot,
|
|
8488
|
+
poseidon(coordPubKey),
|
|
8489
|
+
nullifier,
|
|
8490
|
+
d1[0],
|
|
8491
|
+
d1[1],
|
|
8492
|
+
d2[0],
|
|
8493
|
+
d2[1]
|
|
8494
|
+
]);
|
|
8495
|
+
return {
|
|
8496
|
+
inputHash,
|
|
8497
|
+
coordPubKey,
|
|
8498
|
+
deactivateRoot,
|
|
8499
|
+
deactivateIndex: deactivateIdx,
|
|
8500
|
+
deactivateLeaf: poseidon(deactivateLeaf),
|
|
8501
|
+
c1,
|
|
8502
|
+
c2,
|
|
8503
|
+
randomVal,
|
|
8504
|
+
d1,
|
|
8505
|
+
d2,
|
|
8506
|
+
deactivateLeafPathElements,
|
|
8507
|
+
nullifier,
|
|
8508
|
+
oldPrivateKey: signer.getFormatedPrivKey()
|
|
8509
|
+
};
|
|
8510
|
+
}
|
|
8511
|
+
async legacyGenPreAddKeyInput(depth, {
|
|
8512
|
+
coordPubKey,
|
|
8513
|
+
deactivates,
|
|
8514
|
+
derivePathParams
|
|
8515
|
+
}) {
|
|
8516
|
+
const signer = this.getSigner(derivePathParams);
|
|
8517
|
+
const sharedKeyHash = poseidon(signer.genEcdhSharedKey(coordPubKey));
|
|
8518
|
+
const randomVal = genRandomSalt();
|
|
8519
|
+
const deactivateIdx = deactivates.findIndex((d) => d[4] === sharedKeyHash);
|
|
8520
|
+
if (deactivateIdx < 0) {
|
|
8521
|
+
return null;
|
|
8522
|
+
}
|
|
8523
|
+
const deactivateLeaf = deactivates[deactivateIdx];
|
|
8524
|
+
const c1 = [deactivateLeaf[0], deactivateLeaf[1]];
|
|
8525
|
+
const c2 = [deactivateLeaf[2], deactivateLeaf[3]];
|
|
8526
|
+
const { d1, d2 } = rerandomize(coordPubKey, { c1, c2 }, randomVal);
|
|
8527
|
+
const nullifier = poseidon([signer.getFormatedPrivKey(), 1444992409218394441042n]);
|
|
8528
|
+
const tree = new Tree(5, depth, 0n);
|
|
8529
|
+
const leaves = deactivates.map((d) => poseidon(d));
|
|
8530
|
+
tree.initLeaves(leaves);
|
|
8531
|
+
const deactivateRoot = tree.root;
|
|
8532
|
+
const deactivateLeafPathElements = tree.pathElementOf(deactivateIdx);
|
|
8533
|
+
const inputHash = computeInputHash([
|
|
8534
|
+
deactivateRoot,
|
|
8535
|
+
poseidon(coordPubKey),
|
|
8536
|
+
nullifier,
|
|
8537
|
+
d1[0],
|
|
8538
|
+
d1[1],
|
|
8539
|
+
d2[0],
|
|
8540
|
+
d2[1]
|
|
8541
|
+
]);
|
|
8542
|
+
return {
|
|
8543
|
+
inputHash,
|
|
8544
|
+
coordPubKey,
|
|
8545
|
+
deactivateRoot,
|
|
8546
|
+
deactivateIndex: deactivateIdx,
|
|
8547
|
+
deactivateLeaf: poseidon(deactivateLeaf),
|
|
8548
|
+
c1,
|
|
8549
|
+
c2,
|
|
8550
|
+
randomVal,
|
|
8551
|
+
d1,
|
|
8552
|
+
d2,
|
|
8553
|
+
deactivateLeafPathElements,
|
|
8554
|
+
nullifier,
|
|
8555
|
+
oldPrivateKey: signer.getFormatedPrivKey()
|
|
8556
|
+
};
|
|
8557
|
+
}
|
|
8558
|
+
/**
|
|
8559
|
+
* Legacy `buildAddNewKeyPayload` — old deactivate+addNewKey flow without `pollId` / `newPubKey`
|
|
8560
|
+
* in the ZK circuit. Use when interacting with contracts that predate the poll-ID upgrade.
|
|
8561
|
+
*/
|
|
8562
|
+
async legacyBuildAddNewKeyPayload({
|
|
8563
|
+
stateTreeDepth,
|
|
8564
|
+
operatorPubkey,
|
|
8565
|
+
deactivates,
|
|
8566
|
+
wasmFile,
|
|
8567
|
+
zkeyFile,
|
|
8568
|
+
derivePathParams
|
|
8569
|
+
}) {
|
|
8570
|
+
const [coordPubkeyX, coordPubkeyY] = this.unpackMaciPubkey(operatorPubkey);
|
|
8571
|
+
const addKeyInput = await this.legacyGenAddKeyInput(stateTreeDepth + 2, {
|
|
8572
|
+
coordPubKey: [coordPubkeyX, coordPubkeyY],
|
|
8573
|
+
deactivates: deactivates.map((d) => d.map(BigInt)),
|
|
8574
|
+
derivePathParams
|
|
8575
|
+
});
|
|
8576
|
+
if (addKeyInput === null) {
|
|
8577
|
+
throw Error("legacyGenAddKeyInput failed, cannot find deactivate idx");
|
|
8578
|
+
}
|
|
8579
|
+
const { proof } = await import_snarkjs.groth16.fullProve(addKeyInput, wasmFile, zkeyFile);
|
|
8580
|
+
const proofHex = await adaptToUncompressed(proof);
|
|
8581
|
+
return {
|
|
8582
|
+
proof: proofHex,
|
|
8583
|
+
d: [
|
|
8584
|
+
addKeyInput.d1[0].toString(),
|
|
8585
|
+
addKeyInput.d1[1].toString(),
|
|
8586
|
+
addKeyInput.d2[0].toString(),
|
|
8587
|
+
addKeyInput.d2[1].toString()
|
|
8588
|
+
],
|
|
8589
|
+
nullifier: addKeyInput.nullifier.toString()
|
|
8590
|
+
};
|
|
8591
|
+
}
|
|
8592
|
+
async legacyBuildPreAddNewKeyPayload({
|
|
8593
|
+
stateTreeDepth,
|
|
8594
|
+
coordinatorPubkey,
|
|
8595
|
+
deactivates,
|
|
8596
|
+
wasmFile,
|
|
8597
|
+
zkeyFile,
|
|
8598
|
+
derivePathParams
|
|
8599
|
+
}) {
|
|
8600
|
+
const [coordPubkeyX, coordPubkeyY] = this.unpackMaciPubkey(coordinatorPubkey);
|
|
8601
|
+
const addKeyInput = await this.legacyGenPreAddKeyInput(stateTreeDepth + 2, {
|
|
8602
|
+
coordPubKey: [coordPubkeyX, coordPubkeyY],
|
|
8603
|
+
deactivates: deactivates.map((d) => d.map(BigInt)),
|
|
8604
|
+
derivePathParams
|
|
8605
|
+
});
|
|
8606
|
+
if (addKeyInput === null) {
|
|
8607
|
+
throw Error("legacyGenPreAddKeyInput failed, cannot find deactivate idx");
|
|
8608
|
+
}
|
|
8609
|
+
const { proof } = await import_snarkjs.groth16.fullProve(addKeyInput, wasmFile, zkeyFile);
|
|
8610
|
+
const proofHex = await adaptToUncompressed(proof);
|
|
8611
|
+
return {
|
|
8612
|
+
proof: proofHex,
|
|
8613
|
+
d: [
|
|
8614
|
+
addKeyInput.d1[0].toString(),
|
|
8615
|
+
addKeyInput.d1[1].toString(),
|
|
8616
|
+
addKeyInput.d2[0].toString(),
|
|
8617
|
+
addKeyInput.d2[1].toString()
|
|
8618
|
+
],
|
|
8619
|
+
nullifier: addKeyInput.nullifier.toString()
|
|
8620
|
+
};
|
|
8621
|
+
}
|
|
7908
8622
|
// ==================== SaaS API Client Methods ====================
|
|
7909
8623
|
/**
|
|
7910
8624
|
* Create a MACI round via SaaS API
|
|
@@ -7995,8 +8709,14 @@ var VoterClient = class _VoterClient {
|
|
|
7995
8709
|
}
|
|
7996
8710
|
// ==================== Maci Voter Methods ====================
|
|
7997
8711
|
/**
|
|
7998
|
-
* Pre-create a new account for AMACI voting (pre-deactivate mode)
|
|
7999
|
-
*
|
|
8712
|
+
* Pre-create a new account for AMACI voting (pre-deactivate mode).
|
|
8713
|
+
*
|
|
8714
|
+
* Two modes are supported:
|
|
8715
|
+
* - **Local mode**: pass `deactivates` to build the Merkle tree locally (original behaviour).
|
|
8716
|
+
* - **API mode**: omit `deactivates` and the proof will be fetched from the SaaS API using
|
|
8717
|
+
* `contractAddress` (K-anonymous request).
|
|
8718
|
+
*
|
|
8719
|
+
* @param params - Parameters including contract address, optional deactivates, circuit files, and ticket
|
|
8000
8720
|
* @returns Result with transaction details and new voter account
|
|
8001
8721
|
*/
|
|
8002
8722
|
async saasPreCreateNewAccount({
|
|
@@ -8004,32 +8724,43 @@ var VoterClient = class _VoterClient {
|
|
|
8004
8724
|
stateTreeDepth,
|
|
8005
8725
|
coordinatorPubkey,
|
|
8006
8726
|
deactivates,
|
|
8727
|
+
deactivateIdx,
|
|
8728
|
+
voterScale,
|
|
8729
|
+
preComputedProof,
|
|
8730
|
+
pollId,
|
|
8007
8731
|
wasmFile,
|
|
8008
8732
|
zkeyFile,
|
|
8009
8733
|
ticket,
|
|
8010
8734
|
derivePathParams
|
|
8011
8735
|
}) {
|
|
8736
|
+
const newVoterClient = new _VoterClient({
|
|
8737
|
+
network: this.network,
|
|
8738
|
+
restEndpoint: this.restEndpoint,
|
|
8739
|
+
apiEndpoint: this.apiEndpoint,
|
|
8740
|
+
saasApiEndpoint: this.saasApiEndpoint,
|
|
8741
|
+
registryAddress: this.registryAddress
|
|
8742
|
+
});
|
|
8743
|
+
const newPubkey = newVoterClient.getPubkey().toPoints();
|
|
8012
8744
|
const addNewKeyPayload = await this.buildPreAddNewKeyPayload({
|
|
8013
8745
|
stateTreeDepth,
|
|
8014
8746
|
coordinatorPubkey,
|
|
8015
8747
|
deactivates,
|
|
8748
|
+
contractAddress,
|
|
8749
|
+
deactivateIdx,
|
|
8750
|
+
voterScale,
|
|
8751
|
+
preComputedProof,
|
|
8752
|
+
newPubkey,
|
|
8753
|
+
pollId: pollId !== void 0 ? BigInt(pollId) : void 0,
|
|
8016
8754
|
wasmFile,
|
|
8017
8755
|
zkeyFile,
|
|
8018
8756
|
derivePathParams
|
|
8019
8757
|
});
|
|
8020
|
-
const newVoterClient = new _VoterClient({
|
|
8021
|
-
network: this.network,
|
|
8022
|
-
restEndpoint: this.restEndpoint,
|
|
8023
|
-
apiEndpoint: this.apiEndpoint,
|
|
8024
|
-
saasApiEndpoint: this.saasApiEndpoint,
|
|
8025
|
-
registryAddress: this.registryAddress
|
|
8026
|
-
});
|
|
8027
8758
|
const addNewKeyResult = await newVoterClient.saasSubmitPreAddNewKey({
|
|
8028
8759
|
contractAddress,
|
|
8029
8760
|
proof: addNewKeyPayload.proof,
|
|
8030
8761
|
d: addNewKeyPayload.d,
|
|
8031
8762
|
nullifier: addNewKeyPayload.nullifier,
|
|
8032
|
-
newPubkey:
|
|
8763
|
+
newPubkey: newPubkey.map((p) => p.toString()),
|
|
8033
8764
|
ticket
|
|
8034
8765
|
});
|
|
8035
8766
|
return {
|
|
@@ -8047,22 +8778,19 @@ var VoterClient = class _VoterClient {
|
|
|
8047
8778
|
operatorPubkey,
|
|
8048
8779
|
selectedOptions,
|
|
8049
8780
|
ticket,
|
|
8781
|
+
pollId,
|
|
8782
|
+
stateIdx,
|
|
8050
8783
|
derivePathParams
|
|
8051
8784
|
}) {
|
|
8052
|
-
const
|
|
8053
|
-
|
|
8054
|
-
derivePathParams
|
|
8055
|
-
});
|
|
8056
|
-
if (stateIdx === -1) {
|
|
8785
|
+
const resolvedStateIdx = stateIdx !== void 0 ? stateIdx : await this.getStateIdx({ contractAddress, derivePathParams });
|
|
8786
|
+
if (resolvedStateIdx === -1) {
|
|
8057
8787
|
throw new Error("State index is not set, Please signup or addNewKey first");
|
|
8058
8788
|
}
|
|
8059
|
-
const pollId = await this.getPollId(contractAddress);
|
|
8060
8789
|
const payload = this.buildVotePayload({
|
|
8061
|
-
stateIdx,
|
|
8790
|
+
stateIdx: resolvedStateIdx,
|
|
8062
8791
|
operatorPubkey,
|
|
8063
8792
|
selectedOptions,
|
|
8064
8793
|
pollId,
|
|
8065
|
-
// Pass pollId instead of contractAddress
|
|
8066
8794
|
derivePathParams
|
|
8067
8795
|
});
|
|
8068
8796
|
const voteResult = await this.saasSubmitVote({
|
|
@@ -8278,6 +9006,8 @@ var OperatorClient = class {
|
|
|
8278
9006
|
stateTreeDepth,
|
|
8279
9007
|
operatorPubkey,
|
|
8280
9008
|
deactivates,
|
|
9009
|
+
newPubkey,
|
|
9010
|
+
pollId,
|
|
8281
9011
|
wasmFile,
|
|
8282
9012
|
zkeyFile,
|
|
8283
9013
|
derivePathParams
|
|
@@ -8286,6 +9016,8 @@ var OperatorClient = class {
|
|
|
8286
9016
|
const addKeyInput = await this.genAddKeyInput(stateTreeDepth + 2, {
|
|
8287
9017
|
coordPubKey: [coordPubkeyX, coordPubkeyY],
|
|
8288
9018
|
deactivates: deactivates.map((d) => d.map(BigInt)),
|
|
9019
|
+
newPubKey: newPubkey,
|
|
9020
|
+
pollId,
|
|
8289
9021
|
derivePathParams
|
|
8290
9022
|
});
|
|
8291
9023
|
if (addKeyInput === null) {
|
|
@@ -8308,6 +9040,8 @@ var OperatorClient = class {
|
|
|
8308
9040
|
stateTreeDepth,
|
|
8309
9041
|
coordinatorPubkey,
|
|
8310
9042
|
deactivates,
|
|
9043
|
+
newPubkey,
|
|
9044
|
+
pollId,
|
|
8311
9045
|
wasmFile,
|
|
8312
9046
|
zkeyFile,
|
|
8313
9047
|
derivePathParams
|
|
@@ -8316,6 +9050,8 @@ var OperatorClient = class {
|
|
|
8316
9050
|
const addKeyInput = await this.genPreAddKeyInput(stateTreeDepth + 2, {
|
|
8317
9051
|
coordPubKey: [coordPubkeyX, coordPubkeyY],
|
|
8318
9052
|
deactivates: deactivates.map((d) => d.map(BigInt)),
|
|
9053
|
+
newPubKey: newPubkey,
|
|
9054
|
+
pollId,
|
|
8319
9055
|
derivePathParams
|
|
8320
9056
|
});
|
|
8321
9057
|
if (addKeyInput === null) {
|
|
@@ -8337,6 +9073,8 @@ var OperatorClient = class {
|
|
|
8337
9073
|
async genAddKeyInput(depth, {
|
|
8338
9074
|
coordPubKey,
|
|
8339
9075
|
deactivates,
|
|
9076
|
+
newPubKey,
|
|
9077
|
+
pollId,
|
|
8340
9078
|
derivePathParams
|
|
8341
9079
|
}) {
|
|
8342
9080
|
const signer = this.getSigner(derivePathParams);
|
|
@@ -8350,7 +9088,7 @@ var OperatorClient = class {
|
|
|
8350
9088
|
const c1 = [deactivateLeaf[0], deactivateLeaf[1]];
|
|
8351
9089
|
const c2 = [deactivateLeaf[2], deactivateLeaf[3]];
|
|
8352
9090
|
const { d1, d2 } = rerandomize(coordPubKey, { c1, c2 }, randomVal);
|
|
8353
|
-
const nullifier = poseidon([signer.getFormatedPrivKey(),
|
|
9091
|
+
const nullifier = poseidon([signer.getFormatedPrivKey(), pollId]);
|
|
8354
9092
|
const tree = new Tree(5, depth, 0n);
|
|
8355
9093
|
const leaves = deactivates.map((d) => poseidon(d));
|
|
8356
9094
|
tree.initLeaves(leaves);
|
|
@@ -8363,7 +9101,9 @@ var OperatorClient = class {
|
|
|
8363
9101
|
d1[0],
|
|
8364
9102
|
d1[1],
|
|
8365
9103
|
d2[0],
|
|
8366
|
-
d2[1]
|
|
9104
|
+
d2[1],
|
|
9105
|
+
poseidon(newPubKey),
|
|
9106
|
+
pollId
|
|
8367
9107
|
]);
|
|
8368
9108
|
const input = {
|
|
8369
9109
|
inputHash,
|
|
@@ -8378,13 +9118,17 @@ var OperatorClient = class {
|
|
|
8378
9118
|
d2,
|
|
8379
9119
|
deactivateLeafPathElements,
|
|
8380
9120
|
nullifier,
|
|
8381
|
-
oldPrivateKey: signer.getFormatedPrivKey()
|
|
9121
|
+
oldPrivateKey: signer.getFormatedPrivKey(),
|
|
9122
|
+
newPubKey,
|
|
9123
|
+
pollId
|
|
8382
9124
|
};
|
|
8383
9125
|
return input;
|
|
8384
9126
|
}
|
|
8385
9127
|
async genPreAddKeyInput(depth, {
|
|
8386
9128
|
coordPubKey,
|
|
8387
9129
|
deactivates,
|
|
9130
|
+
newPubKey,
|
|
9131
|
+
pollId,
|
|
8388
9132
|
derivePathParams
|
|
8389
9133
|
}) {
|
|
8390
9134
|
const signer = this.getSigner(derivePathParams);
|
|
@@ -8398,7 +9142,7 @@ var OperatorClient = class {
|
|
|
8398
9142
|
const c1 = [deactivateLeaf[0], deactivateLeaf[1]];
|
|
8399
9143
|
const c2 = [deactivateLeaf[2], deactivateLeaf[3]];
|
|
8400
9144
|
const { d1, d2 } = rerandomize(coordPubKey, { c1, c2 }, randomVal);
|
|
8401
|
-
const nullifier = poseidon([signer.getFormatedPrivKey(),
|
|
9145
|
+
const nullifier = poseidon([signer.getFormatedPrivKey(), pollId]);
|
|
8402
9146
|
const tree = new Tree(5, depth, 0n);
|
|
8403
9147
|
const leaves = deactivates.map((d) => poseidon(d));
|
|
8404
9148
|
tree.initLeaves(leaves);
|
|
@@ -8411,7 +9155,9 @@ var OperatorClient = class {
|
|
|
8411
9155
|
d1[0],
|
|
8412
9156
|
d1[1],
|
|
8413
9157
|
d2[0],
|
|
8414
|
-
d2[1]
|
|
9158
|
+
d2[1],
|
|
9159
|
+
poseidon(newPubKey),
|
|
9160
|
+
pollId
|
|
8415
9161
|
]);
|
|
8416
9162
|
const input = {
|
|
8417
9163
|
inputHash,
|
|
@@ -8426,7 +9172,9 @@ var OperatorClient = class {
|
|
|
8426
9172
|
d2,
|
|
8427
9173
|
deactivateLeafPathElements,
|
|
8428
9174
|
nullifier,
|
|
8429
|
-
oldPrivateKey: signer.getFormatedPrivKey()
|
|
9175
|
+
oldPrivateKey: signer.getFormatedPrivKey(),
|
|
9176
|
+
newPubKey,
|
|
9177
|
+
pollId
|
|
8430
9178
|
};
|
|
8431
9179
|
return input;
|
|
8432
9180
|
}
|
|
@@ -8445,7 +9193,13 @@ var OperatorClient = class {
|
|
|
8445
9193
|
pollId,
|
|
8446
9194
|
derivePathParams
|
|
8447
9195
|
}) {
|
|
8448
|
-
const payload = this.batchGenMessage(
|
|
9196
|
+
const payload = this.batchGenMessage(
|
|
9197
|
+
stateIdx,
|
|
9198
|
+
operatorPubkey,
|
|
9199
|
+
[[0, 0]],
|
|
9200
|
+
pollId,
|
|
9201
|
+
derivePathParams
|
|
9202
|
+
);
|
|
8449
9203
|
return stringizing(payload[0]);
|
|
8450
9204
|
}
|
|
8451
9205
|
/**
|
|
@@ -8549,10 +9303,10 @@ var OperatorClient = class {
|
|
|
8549
9303
|
}
|
|
8550
9304
|
/**
|
|
8551
9305
|
* Decrypt message to command
|
|
8552
|
-
*
|
|
9306
|
+
*
|
|
8553
9307
|
* Message structure after decryption (7 elements):
|
|
8554
9308
|
* [packed_data, newPubKey_x, newPubKey_y, salt, sig_R8_x, sig_R8_y, sig_S]
|
|
8555
|
-
*
|
|
9309
|
+
*
|
|
8556
9310
|
* Packed data contains (from low to high bits):
|
|
8557
9311
|
* - nonce (bits 0-31)
|
|
8558
9312
|
* - stateIdx (bits 32-63)
|
|
@@ -8949,6 +9703,19 @@ var OperatorClient = class {
|
|
|
8949
9703
|
throw new Error("Poll ID not set. Ensure initRound was called with pollId parameter.");
|
|
8950
9704
|
}
|
|
8951
9705
|
const batchSize = this.batchSize;
|
|
9706
|
+
if (this.msgEndIdx === 0) {
|
|
9707
|
+
this.endProcessingPeriod();
|
|
9708
|
+
const newStateRoot2 = this.stateTree.root;
|
|
9709
|
+
const newStateCommitment2 = poseidon([newStateRoot2, newStateSalt]);
|
|
9710
|
+
this.stateCommitment = newStateCommitment2;
|
|
9711
|
+
return {
|
|
9712
|
+
input: {
|
|
9713
|
+
newStateCommitment: newStateCommitment2,
|
|
9714
|
+
packedVals: BigInt(this.maxVoteOptions) + (BigInt(this.numSignUps) << 32n) + (this.isQuadraticCost ? 1n << 64n : 0n)
|
|
9715
|
+
},
|
|
9716
|
+
proof: null
|
|
9717
|
+
};
|
|
9718
|
+
}
|
|
8952
9719
|
const batchStartIdx = Math.floor((this.msgEndIdx - 1) / batchSize) * batchSize;
|
|
8953
9720
|
const batchEndIdx = Math.min(batchStartIdx + batchSize, this.msgEndIdx);
|
|
8954
9721
|
console.log(`Process messages [${batchStartIdx}, ${batchEndIdx})`);
|