@dorafactory/maci-sdk 0.1.3-pre.46.beta.7 → 0.1.3-pre.46.beta.8
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 +288 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +288 -14
- package/dist/index.mjs.map +1 -1
- package/dist/libs/maci/config.d.ts +1 -1
- package/dist/voter.d.ts +113 -8
- package/package.json +1 -1
- package/src/libs/contract/utils.ts +9 -9
- package/src/libs/maci/config.ts +2 -2
- package/src/operator.ts +19 -0
- package/src/voter.ts +430 -19
package/dist/index.js
CHANGED
|
@@ -4478,11 +4478,11 @@ function getAMaciRoundCircuitFee(network, maxVoter, maxOption) {
|
|
|
4478
4478
|
amount: "0"
|
|
4479
4479
|
};
|
|
4480
4480
|
if (maxVoter <= 25 && maxOption <= 5) {
|
|
4481
|
-
requiredFee.amount = "
|
|
4481
|
+
requiredFee.amount = "5000000000000000000";
|
|
4482
4482
|
} else if (maxVoter <= 625 && maxOption <= 25) {
|
|
4483
|
-
requiredFee.amount = "
|
|
4483
|
+
requiredFee.amount = "27000000000000000000";
|
|
4484
4484
|
} else if (maxVoter <= 15625 && maxOption <= 125) {
|
|
4485
|
-
requiredFee.amount = "
|
|
4485
|
+
requiredFee.amount = "208000000000000000000";
|
|
4486
4486
|
} else {
|
|
4487
4487
|
throw new Error("Number of voters or options is too large.");
|
|
4488
4488
|
}
|
|
@@ -5186,7 +5186,7 @@ var import_tx = require("cosmjs-types/cosmwasm/wasm/v1/tx.js");
|
|
|
5186
5186
|
// src/libs/maci/config.ts
|
|
5187
5187
|
var FEE_DENOM = "peaka";
|
|
5188
5188
|
var DEACTIVATE_FEE = "10000000000000000000";
|
|
5189
|
-
var MESSAGE_FEE = "
|
|
5189
|
+
var MESSAGE_FEE = "60000000000000000";
|
|
5190
5190
|
|
|
5191
5191
|
// src/libs/maci/maci.ts
|
|
5192
5192
|
function isErrorResponse(response) {
|
|
@@ -7901,7 +7901,7 @@ var VoterClient = class _VoterClient {
|
|
|
7901
7901
|
derivePathParams
|
|
7902
7902
|
}) {
|
|
7903
7903
|
const plan = this.normalizeVoteOptions(selectedOptions);
|
|
7904
|
-
const payload = this.batchGenMessage(stateIdx, operatorPubkey, pollId, plan, derivePathParams);
|
|
7904
|
+
const payload = pollId !== void 0 ? this.batchGenMessage(stateIdx, operatorPubkey, pollId, plan, derivePathParams) : this.legacyBatchGenMessage(stateIdx, operatorPubkey, plan, derivePathParams);
|
|
7905
7905
|
return stringizing(payload);
|
|
7906
7906
|
}
|
|
7907
7907
|
/**
|
|
@@ -8009,13 +8009,25 @@ var VoterClient = class _VoterClient {
|
|
|
8009
8009
|
derivePathParams
|
|
8010
8010
|
}) {
|
|
8011
8011
|
const [coordPubkeyX, coordPubkeyY] = this.unpackMaciPubkey(operatorPubkey);
|
|
8012
|
-
|
|
8013
|
-
|
|
8014
|
-
|
|
8015
|
-
|
|
8016
|
-
|
|
8017
|
-
|
|
8018
|
-
|
|
8012
|
+
let addKeyInput;
|
|
8013
|
+
if (pollId !== void 0) {
|
|
8014
|
+
if (!newPubkey) {
|
|
8015
|
+
throw new Error("buildAddNewKeyPayload: `newPubkey` is required when `pollId` is provided");
|
|
8016
|
+
}
|
|
8017
|
+
addKeyInput = await this.genAddKeyInput(stateTreeDepth + 2, {
|
|
8018
|
+
coordPubKey: [coordPubkeyX, coordPubkeyY],
|
|
8019
|
+
deactivates: deactivates.map((d) => d.map(BigInt)),
|
|
8020
|
+
newPubKey: newPubkey,
|
|
8021
|
+
pollId,
|
|
8022
|
+
derivePathParams
|
|
8023
|
+
});
|
|
8024
|
+
} else {
|
|
8025
|
+
addKeyInput = await this.legacyGenAddKeyInput(stateTreeDepth + 2, {
|
|
8026
|
+
coordPubKey: [coordPubkeyX, coordPubkeyY],
|
|
8027
|
+
deactivates: deactivates.map((d) => d.map(BigInt)),
|
|
8028
|
+
derivePathParams
|
|
8029
|
+
});
|
|
8030
|
+
}
|
|
8019
8031
|
if (addKeyInput === null) {
|
|
8020
8032
|
throw Error("genAddKeyInput failed");
|
|
8021
8033
|
}
|
|
@@ -8046,6 +8058,36 @@ var VoterClient = class _VoterClient {
|
|
|
8046
8058
|
derivePathParams
|
|
8047
8059
|
}) {
|
|
8048
8060
|
const [coordPubkeyX, coordPubkeyY] = this.unpackMaciPubkey(coordinatorPubkey);
|
|
8061
|
+
if (pollId === void 0) {
|
|
8062
|
+
if (!deactivates || deactivates.length === 0) {
|
|
8063
|
+
throw new Error(
|
|
8064
|
+
"buildPreAddNewKeyPayload: `deactivates` is required in legacy mode (pollId omitted)"
|
|
8065
|
+
);
|
|
8066
|
+
}
|
|
8067
|
+
const addKeyInput2 = await this.legacyGenPreAddKeyInput(stateTreeDepth + 2, {
|
|
8068
|
+
coordPubKey: [coordPubkeyX, coordPubkeyY],
|
|
8069
|
+
deactivates: deactivates.map((d) => d.map(BigInt)),
|
|
8070
|
+
derivePathParams
|
|
8071
|
+
});
|
|
8072
|
+
if (addKeyInput2 === null) {
|
|
8073
|
+
throw Error("legacyGenPreAddKeyInput failed, cannot find deactivate idx");
|
|
8074
|
+
}
|
|
8075
|
+
const { proof: proof2 } = await import_snarkjs.groth16.fullProve(addKeyInput2, wasmFile, zkeyFile);
|
|
8076
|
+
const proofHex2 = await adaptToUncompressed(proof2);
|
|
8077
|
+
return {
|
|
8078
|
+
proof: proofHex2,
|
|
8079
|
+
d: [
|
|
8080
|
+
addKeyInput2.d1[0].toString(),
|
|
8081
|
+
addKeyInput2.d1[1].toString(),
|
|
8082
|
+
addKeyInput2.d2[0].toString(),
|
|
8083
|
+
addKeyInput2.d2[1].toString()
|
|
8084
|
+
],
|
|
8085
|
+
nullifier: addKeyInput2.nullifier.toString()
|
|
8086
|
+
};
|
|
8087
|
+
}
|
|
8088
|
+
if (!newPubkey) {
|
|
8089
|
+
throw new Error("buildPreAddNewKeyPayload: `newPubkey` is required when `pollId` is provided");
|
|
8090
|
+
}
|
|
8049
8091
|
const coordPubKey = [coordPubkeyX, coordPubkeyY];
|
|
8050
8092
|
let resolvedDeactivates;
|
|
8051
8093
|
let preComputedTreeProof;
|
|
@@ -8282,7 +8324,7 @@ var VoterClient = class _VoterClient {
|
|
|
8282
8324
|
nonce = 0,
|
|
8283
8325
|
derivePathParams
|
|
8284
8326
|
}) {
|
|
8285
|
-
const genMessage = this.genMessageFactory(stateIdx, operatorPubkey, pollId, derivePathParams);
|
|
8327
|
+
const genMessage = pollId !== void 0 ? this.genMessageFactory(stateIdx, operatorPubkey, pollId, derivePathParams) : this.legacyGenMessageFactory(stateIdx, operatorPubkey, derivePathParams);
|
|
8286
8328
|
const encAccount = genKeypair();
|
|
8287
8329
|
const msg = genMessage(BigInt(encAccount.privKey), nonce, 0, 0, true);
|
|
8288
8330
|
return stringizing({
|
|
@@ -8290,6 +8332,225 @@ var VoterClient = class _VoterClient {
|
|
|
8290
8332
|
encPubkeys: encAccount.pubKey
|
|
8291
8333
|
});
|
|
8292
8334
|
}
|
|
8335
|
+
// ==================== Legacy Methods (backward-compat, no pollId) ====================
|
|
8336
|
+
legacyGenMessageFactory(stateIdx, operatorPubkey, derivePathParams) {
|
|
8337
|
+
return (encPriKey, nonce, voIdx, newVotes, isLastCmd, salt) => {
|
|
8338
|
+
if (salt === void 0) {
|
|
8339
|
+
salt = BigInt(`0x${import_crypto_js3.default.lib.WordArray.random(7).toString(import_crypto_js3.default.enc.Hex)}`);
|
|
8340
|
+
}
|
|
8341
|
+
const packaged = BigInt(nonce) + (BigInt(stateIdx) << 32n) + (BigInt(voIdx) << 64n) + (BigInt(newVotes) << 96n) + (BigInt(salt) << 192n);
|
|
8342
|
+
const signer = this.getSigner(derivePathParams);
|
|
8343
|
+
let newPubKey;
|
|
8344
|
+
if (isLastCmd) {
|
|
8345
|
+
newPubKey = [0n, 0n];
|
|
8346
|
+
} else {
|
|
8347
|
+
newPubKey = [...signer.getPublicKey().toPoints()];
|
|
8348
|
+
}
|
|
8349
|
+
const hash = poseidon([packaged, ...newPubKey]);
|
|
8350
|
+
const signature = signer.sign(hash);
|
|
8351
|
+
const command = [packaged, ...newPubKey, ...signature.R8, signature.S];
|
|
8352
|
+
const coordPubkey = this.unpackMaciPubkey(operatorPubkey);
|
|
8353
|
+
const message = (0, import_poseidon_cipher3.poseidonEncrypt)(command, genEcdhSharedKey(encPriKey, coordPubkey), 0n);
|
|
8354
|
+
return message;
|
|
8355
|
+
};
|
|
8356
|
+
}
|
|
8357
|
+
legacyBatchGenMessage(stateIdx, operatorPubkey, plan, derivePathParams) {
|
|
8358
|
+
const genMessage = this.legacyGenMessageFactory(stateIdx, operatorPubkey, derivePathParams);
|
|
8359
|
+
const payload = [];
|
|
8360
|
+
for (let i = plan.length - 1; i >= 0; i--) {
|
|
8361
|
+
const p = plan[i];
|
|
8362
|
+
const encAccount = genKeypair();
|
|
8363
|
+
const isLastCmd = i === plan.length - 1;
|
|
8364
|
+
const msg = genMessage(BigInt(encAccount.privKey), i + 1, p[0], p[1], isLastCmd);
|
|
8365
|
+
payload.push({
|
|
8366
|
+
msg,
|
|
8367
|
+
encPubkeys: encAccount.pubKey
|
|
8368
|
+
});
|
|
8369
|
+
}
|
|
8370
|
+
return payload;
|
|
8371
|
+
}
|
|
8372
|
+
legacyBuildVotePayload({
|
|
8373
|
+
stateIdx,
|
|
8374
|
+
operatorPubkey,
|
|
8375
|
+
selectedOptions,
|
|
8376
|
+
derivePathParams
|
|
8377
|
+
}) {
|
|
8378
|
+
const plan = this.normalizeVoteOptions(selectedOptions);
|
|
8379
|
+
const payload = this.legacyBatchGenMessage(stateIdx, operatorPubkey, plan, derivePathParams);
|
|
8380
|
+
return stringizing(payload);
|
|
8381
|
+
}
|
|
8382
|
+
legacyBuildDeactivatePayload({
|
|
8383
|
+
stateIdx,
|
|
8384
|
+
operatorPubkey,
|
|
8385
|
+
nonce = 0,
|
|
8386
|
+
derivePathParams
|
|
8387
|
+
}) {
|
|
8388
|
+
const genMessage = this.legacyGenMessageFactory(stateIdx, operatorPubkey, derivePathParams);
|
|
8389
|
+
const encAccount = genKeypair();
|
|
8390
|
+
const msg = genMessage(BigInt(encAccount.privKey), nonce, 0, 0, true);
|
|
8391
|
+
return stringizing({
|
|
8392
|
+
msg,
|
|
8393
|
+
encPubkeys: encAccount.pubKey
|
|
8394
|
+
});
|
|
8395
|
+
}
|
|
8396
|
+
async legacyGenAddKeyInput(depth, {
|
|
8397
|
+
coordPubKey,
|
|
8398
|
+
deactivates,
|
|
8399
|
+
derivePathParams
|
|
8400
|
+
}) {
|
|
8401
|
+
const signer = this.getSigner(derivePathParams);
|
|
8402
|
+
const sharedKeyHash = poseidon(signer.genEcdhSharedKey(coordPubKey));
|
|
8403
|
+
const randomVal = genRandomSalt();
|
|
8404
|
+
const deactivateIdx = deactivates.findIndex((d) => d[4] === sharedKeyHash);
|
|
8405
|
+
if (deactivateIdx < 0) {
|
|
8406
|
+
return null;
|
|
8407
|
+
}
|
|
8408
|
+
const deactivateLeaf = deactivates[deactivateIdx];
|
|
8409
|
+
const c1 = [deactivateLeaf[0], deactivateLeaf[1]];
|
|
8410
|
+
const c2 = [deactivateLeaf[2], deactivateLeaf[3]];
|
|
8411
|
+
const { d1, d2 } = rerandomize(coordPubKey, { c1, c2 }, randomVal);
|
|
8412
|
+
const nullifier = poseidon([signer.getFormatedPrivKey(), 1444992409218394441042n]);
|
|
8413
|
+
const tree = new Tree(5, depth, 0n);
|
|
8414
|
+
const leaves = deactivates.map((d) => poseidon(d));
|
|
8415
|
+
tree.initLeaves(leaves);
|
|
8416
|
+
const deactivateRoot = tree.root;
|
|
8417
|
+
const deactivateLeafPathElements = tree.pathElementOf(deactivateIdx);
|
|
8418
|
+
const inputHash = computeInputHash([
|
|
8419
|
+
deactivateRoot,
|
|
8420
|
+
poseidon(coordPubKey),
|
|
8421
|
+
nullifier,
|
|
8422
|
+
d1[0],
|
|
8423
|
+
d1[1],
|
|
8424
|
+
d2[0],
|
|
8425
|
+
d2[1]
|
|
8426
|
+
]);
|
|
8427
|
+
return {
|
|
8428
|
+
inputHash,
|
|
8429
|
+
coordPubKey,
|
|
8430
|
+
deactivateRoot,
|
|
8431
|
+
deactivateIndex: deactivateIdx,
|
|
8432
|
+
deactivateLeaf: poseidon(deactivateLeaf),
|
|
8433
|
+
c1,
|
|
8434
|
+
c2,
|
|
8435
|
+
randomVal,
|
|
8436
|
+
d1,
|
|
8437
|
+
d2,
|
|
8438
|
+
deactivateLeafPathElements,
|
|
8439
|
+
nullifier,
|
|
8440
|
+
oldPrivateKey: signer.getFormatedPrivKey()
|
|
8441
|
+
};
|
|
8442
|
+
}
|
|
8443
|
+
async legacyGenPreAddKeyInput(depth, {
|
|
8444
|
+
coordPubKey,
|
|
8445
|
+
deactivates,
|
|
8446
|
+
derivePathParams
|
|
8447
|
+
}) {
|
|
8448
|
+
const signer = this.getSigner(derivePathParams);
|
|
8449
|
+
const sharedKeyHash = poseidon(signer.genEcdhSharedKey(coordPubKey));
|
|
8450
|
+
const randomVal = genRandomSalt();
|
|
8451
|
+
const deactivateIdx = deactivates.findIndex((d) => d[4] === sharedKeyHash);
|
|
8452
|
+
if (deactivateIdx < 0) {
|
|
8453
|
+
return null;
|
|
8454
|
+
}
|
|
8455
|
+
const deactivateLeaf = deactivates[deactivateIdx];
|
|
8456
|
+
const c1 = [deactivateLeaf[0], deactivateLeaf[1]];
|
|
8457
|
+
const c2 = [deactivateLeaf[2], deactivateLeaf[3]];
|
|
8458
|
+
const { d1, d2 } = rerandomize(coordPubKey, { c1, c2 }, randomVal);
|
|
8459
|
+
const nullifier = poseidon([signer.getFormatedPrivKey(), 1444992409218394441042n]);
|
|
8460
|
+
const tree = new Tree(5, depth, 0n);
|
|
8461
|
+
const leaves = deactivates.map((d) => poseidon(d));
|
|
8462
|
+
tree.initLeaves(leaves);
|
|
8463
|
+
const deactivateRoot = tree.root;
|
|
8464
|
+
const deactivateLeafPathElements = tree.pathElementOf(deactivateIdx);
|
|
8465
|
+
const inputHash = computeInputHash([
|
|
8466
|
+
deactivateRoot,
|
|
8467
|
+
poseidon(coordPubKey),
|
|
8468
|
+
nullifier,
|
|
8469
|
+
d1[0],
|
|
8470
|
+
d1[1],
|
|
8471
|
+
d2[0],
|
|
8472
|
+
d2[1]
|
|
8473
|
+
]);
|
|
8474
|
+
return {
|
|
8475
|
+
inputHash,
|
|
8476
|
+
coordPubKey,
|
|
8477
|
+
deactivateRoot,
|
|
8478
|
+
deactivateIndex: deactivateIdx,
|
|
8479
|
+
deactivateLeaf: poseidon(deactivateLeaf),
|
|
8480
|
+
c1,
|
|
8481
|
+
c2,
|
|
8482
|
+
randomVal,
|
|
8483
|
+
d1,
|
|
8484
|
+
d2,
|
|
8485
|
+
deactivateLeafPathElements,
|
|
8486
|
+
nullifier,
|
|
8487
|
+
oldPrivateKey: signer.getFormatedPrivKey()
|
|
8488
|
+
};
|
|
8489
|
+
}
|
|
8490
|
+
/**
|
|
8491
|
+
* Legacy `buildAddNewKeyPayload` — old deactivate+addNewKey flow without `pollId` / `newPubKey`
|
|
8492
|
+
* in the ZK circuit. Use when interacting with contracts that predate the poll-ID upgrade.
|
|
8493
|
+
*/
|
|
8494
|
+
async legacyBuildAddNewKeyPayload({
|
|
8495
|
+
stateTreeDepth,
|
|
8496
|
+
operatorPubkey,
|
|
8497
|
+
deactivates,
|
|
8498
|
+
wasmFile,
|
|
8499
|
+
zkeyFile,
|
|
8500
|
+
derivePathParams
|
|
8501
|
+
}) {
|
|
8502
|
+
const [coordPubkeyX, coordPubkeyY] = this.unpackMaciPubkey(operatorPubkey);
|
|
8503
|
+
const addKeyInput = await this.legacyGenAddKeyInput(stateTreeDepth + 2, {
|
|
8504
|
+
coordPubKey: [coordPubkeyX, coordPubkeyY],
|
|
8505
|
+
deactivates: deactivates.map((d) => d.map(BigInt)),
|
|
8506
|
+
derivePathParams
|
|
8507
|
+
});
|
|
8508
|
+
if (addKeyInput === null) {
|
|
8509
|
+
throw Error("legacyGenAddKeyInput failed, cannot find deactivate idx");
|
|
8510
|
+
}
|
|
8511
|
+
const { proof } = await import_snarkjs.groth16.fullProve(addKeyInput, wasmFile, zkeyFile);
|
|
8512
|
+
const proofHex = await adaptToUncompressed(proof);
|
|
8513
|
+
return {
|
|
8514
|
+
proof: proofHex,
|
|
8515
|
+
d: [
|
|
8516
|
+
addKeyInput.d1[0].toString(),
|
|
8517
|
+
addKeyInput.d1[1].toString(),
|
|
8518
|
+
addKeyInput.d2[0].toString(),
|
|
8519
|
+
addKeyInput.d2[1].toString()
|
|
8520
|
+
],
|
|
8521
|
+
nullifier: addKeyInput.nullifier.toString()
|
|
8522
|
+
};
|
|
8523
|
+
}
|
|
8524
|
+
async legacyBuildPreAddNewKeyPayload({
|
|
8525
|
+
stateTreeDepth,
|
|
8526
|
+
coordinatorPubkey,
|
|
8527
|
+
deactivates,
|
|
8528
|
+
wasmFile,
|
|
8529
|
+
zkeyFile,
|
|
8530
|
+
derivePathParams
|
|
8531
|
+
}) {
|
|
8532
|
+
const [coordPubkeyX, coordPubkeyY] = this.unpackMaciPubkey(coordinatorPubkey);
|
|
8533
|
+
const addKeyInput = await this.legacyGenPreAddKeyInput(stateTreeDepth + 2, {
|
|
8534
|
+
coordPubKey: [coordPubkeyX, coordPubkeyY],
|
|
8535
|
+
deactivates: deactivates.map((d) => d.map(BigInt)),
|
|
8536
|
+
derivePathParams
|
|
8537
|
+
});
|
|
8538
|
+
if (addKeyInput === null) {
|
|
8539
|
+
throw Error("legacyGenPreAddKeyInput failed, cannot find deactivate idx");
|
|
8540
|
+
}
|
|
8541
|
+
const { proof } = await import_snarkjs.groth16.fullProve(addKeyInput, wasmFile, zkeyFile);
|
|
8542
|
+
const proofHex = await adaptToUncompressed(proof);
|
|
8543
|
+
return {
|
|
8544
|
+
proof: proofHex,
|
|
8545
|
+
d: [
|
|
8546
|
+
addKeyInput.d1[0].toString(),
|
|
8547
|
+
addKeyInput.d1[1].toString(),
|
|
8548
|
+
addKeyInput.d2[0].toString(),
|
|
8549
|
+
addKeyInput.d2[1].toString()
|
|
8550
|
+
],
|
|
8551
|
+
nullifier: addKeyInput.nullifier.toString()
|
|
8552
|
+
};
|
|
8553
|
+
}
|
|
8293
8554
|
// ==================== SaaS API Client Methods ====================
|
|
8294
8555
|
/**
|
|
8295
8556
|
* Create a MACI round via SaaS API
|
|
@@ -8419,7 +8680,7 @@ var VoterClient = class _VoterClient {
|
|
|
8419
8680
|
deactivateIdx,
|
|
8420
8681
|
voterScale,
|
|
8421
8682
|
newPubkey,
|
|
8422
|
-
pollId: BigInt(pollId),
|
|
8683
|
+
pollId: pollId !== void 0 ? BigInt(pollId) : void 0,
|
|
8423
8684
|
wasmFile,
|
|
8424
8685
|
zkeyFile,
|
|
8425
8686
|
derivePathParams
|
|
@@ -9372,6 +9633,19 @@ var OperatorClient = class {
|
|
|
9372
9633
|
throw new Error("Poll ID not set. Ensure initRound was called with pollId parameter.");
|
|
9373
9634
|
}
|
|
9374
9635
|
const batchSize = this.batchSize;
|
|
9636
|
+
if (this.msgEndIdx === 0) {
|
|
9637
|
+
this.endProcessingPeriod();
|
|
9638
|
+
const newStateRoot2 = this.stateTree.root;
|
|
9639
|
+
const newStateCommitment2 = poseidon([newStateRoot2, newStateSalt]);
|
|
9640
|
+
this.stateCommitment = newStateCommitment2;
|
|
9641
|
+
return {
|
|
9642
|
+
input: {
|
|
9643
|
+
newStateCommitment: newStateCommitment2,
|
|
9644
|
+
packedVals: BigInt(this.maxVoteOptions) + (BigInt(this.numSignUps) << 32n) + (this.isQuadraticCost ? 1n << 64n : 0n)
|
|
9645
|
+
},
|
|
9646
|
+
proof: null
|
|
9647
|
+
};
|
|
9648
|
+
}
|
|
9375
9649
|
const batchStartIdx = Math.floor((this.msgEndIdx - 1) / batchSize) * batchSize;
|
|
9376
9650
|
const batchEndIdx = Math.min(batchStartIdx + batchSize, this.msgEndIdx);
|
|
9377
9651
|
console.log(`Process messages [${batchStartIdx}, ${batchEndIdx})`);
|