@dorafactory/maci-sdk 0.1.3-pre.21 → 0.1.3-pre.23
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.d.ts +7 -2
- package/dist/index.js +1485 -65
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1470 -74
- package/dist/index.mjs.map +1 -1
- package/dist/libs/account/crypto.d.ts +1 -0
- package/dist/libs/account/index.d.ts +35 -0
- package/dist/libs/account/keypair.d.ts +21 -0
- package/dist/libs/account/util.d.ts +25 -0
- package/dist/libs/api/client.d.ts +173 -0
- package/dist/libs/api/index.d.ts +3 -0
- package/dist/libs/const.d.ts +1 -0
- package/dist/libs/crypto/adapter.d.ts +6 -0
- package/dist/libs/crypto/curve.d.ts +3 -0
- package/dist/libs/crypto/index.d.ts +3 -0
- package/dist/libs/crypto/keys.d.ts +8 -1
- package/dist/libs/crypto/rerandomize.d.ts +12 -0
- package/dist/libs/crypto/sign.d.ts +1 -1
- package/dist/libs/cryptography/index.d.ts +0 -0
- package/dist/libs/cryptography/keypair.d.ts +30 -0
- package/dist/libs/cryptography/mnemonics.d.ts +27 -0
- package/dist/libs/cryptography/publickey.d.ts +23 -0
- package/dist/libs/cryptography/signature-scheme.d.ts +1 -0
- package/dist/libs/index.d.ts +1 -0
- package/dist/libs/keypairs/eddsa-poseidon/index.d.ts +2 -0
- package/dist/libs/keypairs/eddsa-poseidon/keypair.d.ts +187 -0
- package/dist/libs/keypairs/eddsa-poseidon/publickey.d.ts +48 -0
- package/dist/maci.d.ts +90 -31
- package/dist/types/index.d.ts +23 -0
- package/dist/utils/base64.d.ts +6 -0
- package/dist/utils/bech32.d.ts +2 -0
- package/dist/utils/decode-address.d.ts +10 -0
- package/dist/utils/fetch.d.ts +1 -0
- package/dist/utils/hex.d.ts +6 -0
- package/dist/utils/index.d.ts +4 -24
- package/dist/utils/validate-address.d.ts +24 -0
- package/dist/voter.d.ts +230 -0
- package/package.json +13 -61
- package/src/index.ts +11 -13
- package/src/libs/account/crypto.ts +7 -0
- package/src/libs/account/index.ts +70 -0
- package/src/libs/account/keypair.ts +29 -0
- package/src/libs/account/util.ts +55 -0
- package/src/libs/api/client.ts +406 -0
- package/src/libs/api/index.ts +3 -0
- package/src/libs/api/types.d.ts +1493 -0
- package/src/libs/const.ts +37 -54
- package/src/libs/crypto/adapter.ts +41 -0
- package/src/libs/crypto/babyjub.ts +4 -7
- package/src/libs/crypto/constants.ts +2 -5
- package/src/libs/crypto/curve.ts +55 -0
- package/src/libs/crypto/hashing.ts +4 -6
- package/src/libs/crypto/index.ts +3 -0
- package/src/libs/crypto/keys.ts +15 -48
- package/src/libs/crypto/rerandomize.ts +77 -0
- package/src/libs/crypto/sign.ts +8 -17
- package/src/libs/crypto/tree.ts +1 -3
- package/src/libs/cryptography/index.ts +0 -0
- package/src/libs/cryptography/keypair.ts +44 -0
- package/src/libs/cryptography/mnemonics.ts +47 -0
- package/src/libs/cryptography/publickey.ts +44 -0
- package/src/libs/cryptography/signature-scheme.ts +1 -0
- package/src/libs/index.ts +1 -0
- package/src/libs/keypairs/eddsa-poseidon/index.ts +6 -0
- package/src/libs/keypairs/eddsa-poseidon/keypair.ts +452 -0
- package/src/libs/keypairs/eddsa-poseidon/publickey.ts +141 -0
- package/src/maci.ts +157 -101
- package/src/types/index.ts +30 -4
- package/src/types/lib.d.ts +7 -0
- package/src/utils/base64.ts +28 -0
- package/src/utils/bech32.ts +29 -0
- package/src/utils/decode-address.ts +35 -0
- package/src/utils/fetch.ts +28 -0
- package/src/utils/hex.ts +23 -0
- package/src/utils/index.ts +15 -79
- package/src/utils/validate-address.ts +82 -0
- package/src/voter.ts +654 -0
package/dist/index.js
CHANGED
|
@@ -31,9 +31,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
Circuit: () => Circuit,
|
|
34
|
+
EdDSAPoseidonKeypair: () => EdDSAPoseidonKeypair,
|
|
35
|
+
EdDSAPoseidonPublicKey: () => EdDSAPoseidonPublicKey,
|
|
34
36
|
G1Point: () => G1Point,
|
|
35
37
|
G2Point: () => G2Point,
|
|
36
38
|
Http: () => Http,
|
|
39
|
+
MaciApiClient: () => MaciApiClient,
|
|
37
40
|
MaciCertSystemType: () => MaciCertSystemType,
|
|
38
41
|
MaciCircuitType: () => MaciCircuitType,
|
|
39
42
|
MaciClient: () => MaciClient2,
|
|
@@ -47,12 +50,23 @@ __export(index_exports, {
|
|
|
47
50
|
Transaction: () => Transaction,
|
|
48
51
|
Tree: () => Tree,
|
|
49
52
|
UserAccount: () => UserAccount,
|
|
53
|
+
VoterClient: () => VoterClient,
|
|
54
|
+
adaptToUncompressed: () => adaptToUncompressed,
|
|
55
|
+
addressToUint256: () => addressToUint256,
|
|
50
56
|
batchGenMessage: () => batchGenMessage,
|
|
51
57
|
bigInt2Buffer: () => bigInt2Buffer,
|
|
58
|
+
bigintToHex: () => bigintToHex,
|
|
52
59
|
buffer2Bigint: () => buffer2Bigint,
|
|
53
60
|
circuits: () => circuits,
|
|
61
|
+
compressPublicKey: () => compressPublicKey,
|
|
62
|
+
decompressPublicKey: () => decompressPublicKey,
|
|
54
63
|
destringizing: () => destringizing,
|
|
64
|
+
encryptOdevity: () => encryptOdevity,
|
|
55
65
|
formatPrivKeyForBabyJub: () => formatPrivKeyForBabyJub,
|
|
66
|
+
fromB64: () => fromB64,
|
|
67
|
+
fromBase64: () => fromBase64,
|
|
68
|
+
fromHEX: () => fromHEX,
|
|
69
|
+
fromHex: () => fromHex,
|
|
56
70
|
genAddKeyInput: () => genAddKeyInput,
|
|
57
71
|
genEcdhSharedKey: () => genEcdhSharedKey,
|
|
58
72
|
genKeypair: () => genKeypair,
|
|
@@ -65,6 +79,9 @@ __export(index_exports, {
|
|
|
65
79
|
genRandomKey: () => genRandomKey,
|
|
66
80
|
genRandomSalt: () => genRandomSalt,
|
|
67
81
|
getAMaciRoundCircuitFee: () => getAMaciRoundCircuitFee,
|
|
82
|
+
getCurveFromName: () => getCurveFromName,
|
|
83
|
+
getCurveFromQ: () => getCurveFromQ,
|
|
84
|
+
getCurveFromR: () => getCurveFromR,
|
|
68
85
|
getDefaultParams: () => getDefaultParams,
|
|
69
86
|
hash12: () => hash12,
|
|
70
87
|
hash2: () => hash2,
|
|
@@ -75,6 +92,8 @@ __export(index_exports, {
|
|
|
75
92
|
hashLeftRight: () => hashLeftRight,
|
|
76
93
|
hashN: () => hashN,
|
|
77
94
|
hashOne: () => hashOne,
|
|
95
|
+
hexToBigInt: () => hexToBigInt,
|
|
96
|
+
hexToDecimalString: () => hexToDecimalString,
|
|
78
97
|
isValidAddress: () => isValidAddress,
|
|
79
98
|
packPubKey: () => packPubKey,
|
|
80
99
|
poseidon: () => poseidon,
|
|
@@ -83,9 +102,15 @@ __export(index_exports, {
|
|
|
83
102
|
poseidonT5: () => poseidonT5,
|
|
84
103
|
poseidonT6: () => poseidonT6,
|
|
85
104
|
privateKeyFromTxt: () => privateKeyFromTxt,
|
|
105
|
+
rerandomize: () => rerandomize,
|
|
86
106
|
sha256Hash: () => sha256Hash,
|
|
87
107
|
signMessage: () => signMessage2,
|
|
88
108
|
stringizing: () => stringizing,
|
|
109
|
+
toB64: () => toB64,
|
|
110
|
+
toBase64: () => toBase64,
|
|
111
|
+
toHEX: () => toHEX,
|
|
112
|
+
toHex: () => toHex,
|
|
113
|
+
transformPubkey: () => transformPubkey,
|
|
89
114
|
unpackPubKey: () => unpackPubKey
|
|
90
115
|
});
|
|
91
116
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -427,6 +452,7 @@ function getDefaultParams(network = "mainnet") {
|
|
|
427
452
|
rpcEndpoint: "https://vota-rpc.dorafactory.org",
|
|
428
453
|
restEndpoint: "https://vota-rest.dorafactory.org",
|
|
429
454
|
apiEndpoint: "https://vota-api.dorafactory.org",
|
|
455
|
+
saasApiEndpoint: "https://vota-maci-api.dorafactory.org",
|
|
430
456
|
certificateApiEndpoint: "https://vota-certificate-api.dorafactory.org/api/v1",
|
|
431
457
|
registryAddress: "dora1smg5qp5trjdkcekdjssqpjehdjf6n4cjss0clyvqcud3t3u3948s8rmgg4",
|
|
432
458
|
saasAddress: "dora1ksxvvve2nsw5uyvg7y6lnnxcqxadjepc78z0qa8enm5zhayxaqgqpsewf8",
|
|
@@ -446,6 +472,7 @@ function getDefaultParams(network = "mainnet") {
|
|
|
446
472
|
rpcEndpoint: "https://vota-testnet-rpc.dorafactory.org",
|
|
447
473
|
restEndpoint: "https://vota-testnet-rest.dorafactory.org",
|
|
448
474
|
apiEndpoint: "https://vota-testnet-api.dorafactory.org",
|
|
475
|
+
saasApiEndpoint: "https://vota-testnet-maci-api.dorafactory.org",
|
|
449
476
|
certificateApiEndpoint: "https://vota-testnet-certificate-api.dorafactory.org/api/v1",
|
|
450
477
|
registryAddress: "dora13c8aecstyxrhax9znvvh5zey89edrmd2k5va57pxvpe3fxtfsfeqlhsjnd",
|
|
451
478
|
saasAddress: "dora1dgnszrwnwxgr5djprrr6w4q45z8s3ghsew869g6tlp4ruqah39nqnemjya",
|
|
@@ -536,7 +563,61 @@ var Circuit = class {
|
|
|
536
563
|
}
|
|
537
564
|
};
|
|
538
565
|
|
|
539
|
-
// src/utils/
|
|
566
|
+
// src/utils/base64.ts
|
|
567
|
+
function fromBase64(base64String) {
|
|
568
|
+
return Uint8Array.from(atob(base64String), (char) => char.charCodeAt(0));
|
|
569
|
+
}
|
|
570
|
+
var CHUNK_SIZE = 8192;
|
|
571
|
+
function toBase64(bytes) {
|
|
572
|
+
if (bytes.length < CHUNK_SIZE) {
|
|
573
|
+
return btoa(String.fromCharCode(...bytes));
|
|
574
|
+
}
|
|
575
|
+
let output = "";
|
|
576
|
+
for (var i = 0; i < bytes.length; i += CHUNK_SIZE) {
|
|
577
|
+
const chunk = bytes.slice(i, i + CHUNK_SIZE);
|
|
578
|
+
output += String.fromCharCode(...chunk);
|
|
579
|
+
}
|
|
580
|
+
return btoa(output);
|
|
581
|
+
}
|
|
582
|
+
var toB64 = toBase64;
|
|
583
|
+
var fromB64 = fromBase64;
|
|
584
|
+
|
|
585
|
+
// src/utils/hex.ts
|
|
586
|
+
function fromHex(hexStr) {
|
|
587
|
+
const normalized = hexStr.startsWith("0x") ? hexStr.slice(2) : hexStr;
|
|
588
|
+
const padded = normalized.length % 2 === 0 ? normalized : `0${normalized}}`;
|
|
589
|
+
const intArr = padded.match(/.{2}/g)?.map((byte) => parseInt(byte, 16)) ?? [];
|
|
590
|
+
return Uint8Array.from(intArr);
|
|
591
|
+
}
|
|
592
|
+
function toHex(bytes) {
|
|
593
|
+
return bytes.reduce(
|
|
594
|
+
(str, byte) => str + byte.toString(16).padStart(2, "0"),
|
|
595
|
+
""
|
|
596
|
+
);
|
|
597
|
+
}
|
|
598
|
+
var toHEX = toHex;
|
|
599
|
+
var fromHEX = fromHex;
|
|
600
|
+
|
|
601
|
+
// src/utils/decode-address.ts
|
|
602
|
+
var import_sha256 = require("@noble/hashes/sha256");
|
|
603
|
+
function addressToUint256(address) {
|
|
604
|
+
const addressBytes = new TextEncoder().encode(address);
|
|
605
|
+
const hashResult = (0, import_sha256.sha256)(addressBytes);
|
|
606
|
+
const uint256Bytes = new Uint8Array(32);
|
|
607
|
+
for (let i = 0; i < hashResult.length && i < 32; i++) {
|
|
608
|
+
uint256Bytes[31 - i] = hashResult[i];
|
|
609
|
+
}
|
|
610
|
+
let result = 0n;
|
|
611
|
+
for (let i = 0; i < uint256Bytes.length; i++) {
|
|
612
|
+
result = (result << 8n) + BigInt(uint256Bytes[i]);
|
|
613
|
+
}
|
|
614
|
+
return result;
|
|
615
|
+
}
|
|
616
|
+
function bigintToHex(value) {
|
|
617
|
+
return "0x" + value.toString(16).padStart(64, "0");
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// src/utils/validate-address.ts
|
|
540
621
|
var import_bech32 = require("bech32");
|
|
541
622
|
|
|
542
623
|
// src/libs/crypto/keys.ts
|
|
@@ -610,9 +691,7 @@ var import_assert = __toESM(require("assert"));
|
|
|
610
691
|
var SNARK_FIELD_SIZE = import_baby_jubjub.r;
|
|
611
692
|
var NOTHING_UP_MY_SLEEVE = BigInt((0, import_ethers.keccak256)((0, import_ethers.toUtf8Bytes)("Maci"))) % SNARK_FIELD_SIZE;
|
|
612
693
|
(0, import_assert.default)(
|
|
613
|
-
NOTHING_UP_MY_SLEEVE === BigInt(
|
|
614
|
-
"8370432830353022751713833565135785980866757267633941821328460903436894336785"
|
|
615
|
-
)
|
|
694
|
+
NOTHING_UP_MY_SLEEVE === BigInt("8370432830353022751713833565135785980866757267633941821328460903436894336785")
|
|
616
695
|
);
|
|
617
696
|
var PAD_KEY_HASH = BigInt(
|
|
618
697
|
"1309255631273308531193241901289907343161346846555918942743921933037802809814"
|
|
@@ -830,9 +909,7 @@ var Tree = class _Tree {
|
|
|
830
909
|
while (idx > 0) {
|
|
831
910
|
const parentIdx = Math.floor((idx - 1) / this.DEGREE);
|
|
832
911
|
const childrenIdx0 = parentIdx * this.DEGREE + 1;
|
|
833
|
-
this.nodes[parentIdx] = poseidon(
|
|
834
|
-
this.nodes.slice(childrenIdx0, childrenIdx0 + 5)
|
|
835
|
-
);
|
|
912
|
+
this.nodes[parentIdx] = poseidon(this.nodes.slice(childrenIdx0, childrenIdx0 + 5));
|
|
836
913
|
idx = parentIdx;
|
|
837
914
|
}
|
|
838
915
|
}
|
|
@@ -918,9 +995,7 @@ var genRandomBabyJubValue = () => {
|
|
|
918
995
|
const min = 6350874878119819312338956282401532410528162663560392320966563075034087161851n;
|
|
919
996
|
let rand;
|
|
920
997
|
while (true) {
|
|
921
|
-
rand = BigInt(
|
|
922
|
-
`0x${import_crypto_js.default.lib.WordArray.random(32).toString(import_crypto_js.default.enc.Hex)}`
|
|
923
|
-
);
|
|
998
|
+
rand = BigInt(`0x${import_crypto_js.default.lib.WordArray.random(32).toString(import_crypto_js.default.enc.Hex)}`);
|
|
924
999
|
if (rand >= min) {
|
|
925
1000
|
break;
|
|
926
1001
|
}
|
|
@@ -953,9 +1028,7 @@ var genKeypair = (pkey) => {
|
|
|
953
1028
|
var genEcdhSharedKey = (privKey, pubKey) => (0, import_baby_jubjub2.mulPointEscalar)(pubKey, formatPrivKeyForBabyJub(privKey));
|
|
954
1029
|
var genMessageFactory = (stateIdx, signPriKey, signPubKey, coordPubKey) => (encPriKey, nonce, voIdx, newVotes, isLastCmd, salt) => {
|
|
955
1030
|
if (!salt) {
|
|
956
|
-
salt = BigInt(
|
|
957
|
-
`0x${import_crypto_js2.default.lib.WordArray.random(7).toString(import_crypto_js2.default.enc.Hex)}`
|
|
958
|
-
);
|
|
1031
|
+
salt = BigInt(`0x${import_crypto_js2.default.lib.WordArray.random(7).toString(import_crypto_js2.default.enc.Hex)}`);
|
|
959
1032
|
}
|
|
960
1033
|
const packaged = BigInt(nonce) + (BigInt(stateIdx) << 32n) + (BigInt(voIdx) << 64n) + (BigInt(newVotes) << 96n) + (BigInt(salt) << 192n);
|
|
961
1034
|
let newPubKey = [...signPubKey];
|
|
@@ -965,11 +1038,7 @@ var genMessageFactory = (stateIdx, signPriKey, signPubKey, coordPubKey) => (encP
|
|
|
965
1038
|
const hash = poseidon([packaged, ...newPubKey]);
|
|
966
1039
|
const signature = (0, import_eddsa_poseidon.signMessage)(bigInt2Buffer(signPriKey), hash);
|
|
967
1040
|
const command = [packaged, ...newPubKey, ...signature.R8, signature.S];
|
|
968
|
-
const message = (0, import_poseidon_cipher2.poseidonEncrypt)(
|
|
969
|
-
command,
|
|
970
|
-
genEcdhSharedKey(encPriKey, coordPubKey),
|
|
971
|
-
0n
|
|
972
|
-
);
|
|
1041
|
+
const message = (0, import_poseidon_cipher2.poseidonEncrypt)(command, genEcdhSharedKey(encPriKey, coordPubKey), 0n);
|
|
973
1042
|
return message;
|
|
974
1043
|
};
|
|
975
1044
|
var batchGenMessage = (stateIdx, keypair, coordPubKey, plan) => {
|
|
@@ -983,13 +1052,7 @@ var batchGenMessage = (stateIdx, keypair, coordPubKey, plan) => {
|
|
|
983
1052
|
for (let i = plan.length - 1; i >= 0; i--) {
|
|
984
1053
|
const p = plan[i];
|
|
985
1054
|
const encAccount = genKeypair();
|
|
986
|
-
const msg = genMessage(
|
|
987
|
-
BigInt(encAccount.privKey),
|
|
988
|
-
i + 1,
|
|
989
|
-
p[0],
|
|
990
|
-
p[1],
|
|
991
|
-
i === plan.length - 1
|
|
992
|
-
);
|
|
1055
|
+
const msg = genMessage(BigInt(encAccount.privKey), i + 1, p[0], p[1], i === plan.length - 1);
|
|
993
1056
|
payload.push({
|
|
994
1057
|
msg,
|
|
995
1058
|
encPubkeys: encAccount.pubKey
|
|
@@ -1041,10 +1104,7 @@ var genAddKeyInput = (depth, {
|
|
|
1041
1104
|
const c1 = [deactivateLeaf[0], deactivateLeaf[1]];
|
|
1042
1105
|
const c2 = [deactivateLeaf[2], deactivateLeaf[3]];
|
|
1043
1106
|
const { d1, d2 } = rerandomize(coordPubKey, { c1, c2 }, randomVal);
|
|
1044
|
-
const nullifier = poseidon([
|
|
1045
|
-
BigInt(oldKey.formatedPrivKey),
|
|
1046
|
-
1444992409218394441042n
|
|
1047
|
-
]);
|
|
1107
|
+
const nullifier = poseidon([BigInt(oldKey.formatedPrivKey), 1444992409218394441042n]);
|
|
1048
1108
|
const tree = new Tree(5, depth, 0n);
|
|
1049
1109
|
const leaves = deactivates.map((d) => poseidon(d));
|
|
1050
1110
|
tree.initLeaves(leaves);
|
|
@@ -1091,12 +1151,7 @@ function randomUint256() {
|
|
|
1091
1151
|
return buffer.join("");
|
|
1092
1152
|
}
|
|
1093
1153
|
var genRandomKey = () => {
|
|
1094
|
-
const key = [
|
|
1095
|
-
randomUint256(),
|
|
1096
|
-
randomUint256(),
|
|
1097
|
-
randomUint256(),
|
|
1098
|
-
randomUint256()
|
|
1099
|
-
].join("");
|
|
1154
|
+
const key = [randomUint256(), randomUint256(), randomUint256(), randomUint256()].join("");
|
|
1100
1155
|
return ["-----BEGIN MACI KEY-----", key, "-----END MACI KEY-----"].join("\n");
|
|
1101
1156
|
};
|
|
1102
1157
|
|
|
@@ -1152,19 +1207,127 @@ async function genKeypairFromSign({
|
|
|
1152
1207
|
if (!address) {
|
|
1153
1208
|
[{ address }] = await signer.getAccounts();
|
|
1154
1209
|
}
|
|
1155
|
-
const sig = await signMessage2(
|
|
1156
|
-
signer,
|
|
1157
|
-
address,
|
|
1158
|
-
"Generate_MACI_Private_Key",
|
|
1159
|
-
network
|
|
1160
|
-
);
|
|
1210
|
+
const sig = await signMessage2(signer, address, "Generate_MACI_Private_Key", network);
|
|
1161
1211
|
return genKeypairFromSignature(sig.signature);
|
|
1162
1212
|
}
|
|
1163
1213
|
|
|
1164
|
-
// src/
|
|
1214
|
+
// src/libs/crypto/curve.ts
|
|
1215
|
+
var import_ffjavascript = require("ffjavascript");
|
|
1216
|
+
var bls12381r = import_ffjavascript.Scalar.e("73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001", 16);
|
|
1217
|
+
var bn128r = import_ffjavascript.Scalar.e(
|
|
1218
|
+
"21888242871839275222246405745257275088548364400416034343698204186575808495617"
|
|
1219
|
+
);
|
|
1220
|
+
var bls12381q = import_ffjavascript.Scalar.e(
|
|
1221
|
+
"1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab",
|
|
1222
|
+
16
|
|
1223
|
+
);
|
|
1224
|
+
var bn128q = import_ffjavascript.Scalar.e(
|
|
1225
|
+
"21888242871839275222246405745257275088696311157297823662689037894645226208583"
|
|
1226
|
+
);
|
|
1227
|
+
async function getCurveFromR(r2) {
|
|
1228
|
+
let curve;
|
|
1229
|
+
if (import_ffjavascript.Scalar.eq(r2, bn128r)) {
|
|
1230
|
+
curve = await (0, import_ffjavascript.buildBn128)();
|
|
1231
|
+
} else if (import_ffjavascript.Scalar.eq(r2, bls12381r)) {
|
|
1232
|
+
curve = await (0, import_ffjavascript.buildBls12381)();
|
|
1233
|
+
} else {
|
|
1234
|
+
throw new Error(`Curve not supported: ${import_ffjavascript.Scalar.toString(r2)}`);
|
|
1235
|
+
}
|
|
1236
|
+
return curve;
|
|
1237
|
+
}
|
|
1238
|
+
async function getCurveFromQ(q) {
|
|
1239
|
+
let curve;
|
|
1240
|
+
if (import_ffjavascript.Scalar.eq(q, bn128q)) {
|
|
1241
|
+
curve = await (0, import_ffjavascript.buildBn128)();
|
|
1242
|
+
} else if (import_ffjavascript.Scalar.eq(q, bls12381q)) {
|
|
1243
|
+
curve = await (0, import_ffjavascript.buildBls12381)();
|
|
1244
|
+
} else {
|
|
1245
|
+
throw new Error(`Curve not supported: ${import_ffjavascript.Scalar.toString(q)}`);
|
|
1246
|
+
}
|
|
1247
|
+
return curve;
|
|
1248
|
+
}
|
|
1249
|
+
async function getCurveFromName(name) {
|
|
1250
|
+
let curve;
|
|
1251
|
+
const normName = normalizeName(name);
|
|
1252
|
+
if (["BN128", "BN254", "ALTBN128"].indexOf(normName) >= 0) {
|
|
1253
|
+
curve = await (0, import_ffjavascript.buildBn128)();
|
|
1254
|
+
} else if (["BLS12381"].indexOf(normName) >= 0) {
|
|
1255
|
+
curve = await (0, import_ffjavascript.buildBls12381)();
|
|
1256
|
+
} else {
|
|
1257
|
+
throw new Error(`Curve not supported: ${name}`);
|
|
1258
|
+
}
|
|
1259
|
+
return curve;
|
|
1260
|
+
function normalizeName(n) {
|
|
1261
|
+
return (n.toUpperCase().match(/[A-Za-z0-9]+/g) || []).join("");
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
// src/libs/crypto/adapter.ts
|
|
1266
|
+
var import_ffjavascript2 = require("ffjavascript");
|
|
1267
|
+
var { unstringifyBigInts } = import_ffjavascript2.utils;
|
|
1268
|
+
var Bytes2Str = (arr) => {
|
|
1269
|
+
let str = "";
|
|
1270
|
+
for (let i = 0; i < arr.length; i++) {
|
|
1271
|
+
let tmp = arr[i].toString(16);
|
|
1272
|
+
if (tmp.length == 1) {
|
|
1273
|
+
tmp = "0" + tmp;
|
|
1274
|
+
}
|
|
1275
|
+
str += tmp;
|
|
1276
|
+
}
|
|
1277
|
+
return str;
|
|
1278
|
+
};
|
|
1279
|
+
var BN128Curve = null;
|
|
1280
|
+
var adaptToUncompressed = async (proof) => {
|
|
1281
|
+
const p = unstringifyBigInts(proof);
|
|
1282
|
+
let curve = BN128Curve;
|
|
1283
|
+
if (!curve) {
|
|
1284
|
+
BN128Curve = await getCurveFromName("BN128");
|
|
1285
|
+
curve = BN128Curve;
|
|
1286
|
+
}
|
|
1287
|
+
const pi_a = curve.G1.toUncompressed(curve.G1.fromObject(p.pi_a));
|
|
1288
|
+
const pi_b = curve.G2.toUncompressed(curve.G2.fromObject(p.pi_b));
|
|
1289
|
+
const pi_c = curve.G1.toUncompressed(curve.G1.fromObject(p.pi_c));
|
|
1290
|
+
return {
|
|
1291
|
+
a: Bytes2Str(Array.from(pi_a)),
|
|
1292
|
+
b: Bytes2Str(Array.from(pi_b)),
|
|
1293
|
+
c: Bytes2Str(Array.from(pi_c))
|
|
1294
|
+
};
|
|
1295
|
+
};
|
|
1296
|
+
|
|
1297
|
+
// src/libs/crypto/rerandomize.ts
|
|
1298
|
+
var BabyJub2 = __toESM(require("@zk-kit/baby-jubjub"));
|
|
1299
|
+
var F = BabyJub2.Fr;
|
|
1300
|
+
var encodeToMessage = (original, randomKey = genKeypair()) => {
|
|
1301
|
+
const xIncrement = F.e(F.sub(randomKey.pubKey[0], original));
|
|
1302
|
+
return {
|
|
1303
|
+
point: {
|
|
1304
|
+
x: randomKey.pubKey[0],
|
|
1305
|
+
y: randomKey.pubKey[1]
|
|
1306
|
+
},
|
|
1307
|
+
xIncrement
|
|
1308
|
+
};
|
|
1309
|
+
};
|
|
1310
|
+
var encryptOdevity = (isOdd, pubKey, randomVal = genRandomBabyJubValue()) => {
|
|
1311
|
+
let i = 0n;
|
|
1312
|
+
let message = encodeToMessage(123n, genKeypair(randomVal + i));
|
|
1313
|
+
while (message.point.x % 2n === 1n !== isOdd) {
|
|
1314
|
+
i++;
|
|
1315
|
+
message = encodeToMessage(123n, genKeypair(randomVal + i));
|
|
1316
|
+
}
|
|
1317
|
+
const c1Point = BabyJub2.mulPointEscalar(BabyJub2.Base8, randomVal);
|
|
1318
|
+
const pky = BabyJub2.mulPointEscalar(pubKey, randomVal);
|
|
1319
|
+
const c2Point = BabyJub2.addPoint([message.point.x, message.point.y], pky);
|
|
1320
|
+
return {
|
|
1321
|
+
c1: { x: c1Point[0], y: c1Point[1] },
|
|
1322
|
+
c2: { x: c2Point[0], y: c2Point[1] },
|
|
1323
|
+
xIncrement: message.xIncrement
|
|
1324
|
+
};
|
|
1325
|
+
};
|
|
1326
|
+
|
|
1327
|
+
// src/utils/validate-address.ts
|
|
1165
1328
|
function verifyIsBech32(address) {
|
|
1166
1329
|
try {
|
|
1167
|
-
|
|
1330
|
+
import_bech32.bech32.decode(address);
|
|
1168
1331
|
} catch (error) {
|
|
1169
1332
|
return error instanceof Error ? error : new Error("Unknown error");
|
|
1170
1333
|
}
|
|
@@ -1173,6 +1336,46 @@ function verifyIsBech32(address) {
|
|
|
1173
1336
|
function isValidAddress(address) {
|
|
1174
1337
|
return address.startsWith("dora") && verifyIsBech32(address) === void 0;
|
|
1175
1338
|
}
|
|
1339
|
+
function hexToDecimalString(hexString) {
|
|
1340
|
+
const decimalString = BigInt("0x" + hexString).toString(10);
|
|
1341
|
+
return decimalString;
|
|
1342
|
+
}
|
|
1343
|
+
function hexToBigInt(hexString) {
|
|
1344
|
+
return BigInt("0x" + hexString);
|
|
1345
|
+
}
|
|
1346
|
+
function padWithZerosIfNeeded(inputString) {
|
|
1347
|
+
if (inputString.length === 64) {
|
|
1348
|
+
return inputString;
|
|
1349
|
+
} else if (inputString.length < 64) {
|
|
1350
|
+
const zerosToAdd = 64 - inputString.length;
|
|
1351
|
+
const zeroPadding = "0".repeat(zerosToAdd);
|
|
1352
|
+
return zeroPadding + inputString;
|
|
1353
|
+
}
|
|
1354
|
+
throw new Error("Invalid input string length");
|
|
1355
|
+
}
|
|
1356
|
+
function decompressPublicKey(compressedPubkey) {
|
|
1357
|
+
const x = compressedPubkey.slice(0, 64);
|
|
1358
|
+
const y = compressedPubkey.slice(64);
|
|
1359
|
+
return {
|
|
1360
|
+
x: hexToDecimalString(x),
|
|
1361
|
+
y: hexToDecimalString(y)
|
|
1362
|
+
};
|
|
1363
|
+
}
|
|
1364
|
+
function compressPublicKey(decompressedPubkey) {
|
|
1365
|
+
const x = decompressedPubkey[0];
|
|
1366
|
+
const y = decompressedPubkey[1];
|
|
1367
|
+
const compressedPubkey = padWithZerosIfNeeded(x.toString(16)) + padWithZerosIfNeeded(y.toString(16));
|
|
1368
|
+
return compressedPubkey;
|
|
1369
|
+
}
|
|
1370
|
+
function transformPubkey(oldPubkey) {
|
|
1371
|
+
const x = oldPubkey.slice(0, 64);
|
|
1372
|
+
const y = oldPubkey.slice(64);
|
|
1373
|
+
const pubkey = [hexToBigInt(x), hexToBigInt(y)];
|
|
1374
|
+
console.log(pubkey);
|
|
1375
|
+
console.log([hexToDecimalString(x), hexToDecimalString(y)]);
|
|
1376
|
+
const packedPubkey = packPubKey(pubkey);
|
|
1377
|
+
return packedPubkey;
|
|
1378
|
+
}
|
|
1176
1379
|
|
|
1177
1380
|
// src/libs/query/operator.ts
|
|
1178
1381
|
var Operator = class {
|
|
@@ -8559,6 +8762,257 @@ var MACI = class {
|
|
|
8559
8762
|
}
|
|
8560
8763
|
};
|
|
8561
8764
|
|
|
8765
|
+
// src/libs/api/client.ts
|
|
8766
|
+
var MaciApiClient = class {
|
|
8767
|
+
constructor(config) {
|
|
8768
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
8769
|
+
this.apiKey = config.apiKey;
|
|
8770
|
+
this.customFetch = config.customFetch || fetch;
|
|
8771
|
+
this.timeout = config.timeout || 12e4;
|
|
8772
|
+
this.apiKeyHeader = config.apiKeyHeader || "x-api-key";
|
|
8773
|
+
}
|
|
8774
|
+
/**
|
|
8775
|
+
* Update API key
|
|
8776
|
+
*/
|
|
8777
|
+
setApiKey(apiKey) {
|
|
8778
|
+
this.apiKey = apiKey;
|
|
8779
|
+
}
|
|
8780
|
+
/**
|
|
8781
|
+
* Update base URL
|
|
8782
|
+
*/
|
|
8783
|
+
setBaseUrl(baseUrl) {
|
|
8784
|
+
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
8785
|
+
}
|
|
8786
|
+
/**
|
|
8787
|
+
* Internal fetch method with timeout and error handling
|
|
8788
|
+
*/
|
|
8789
|
+
async fetch(path, options) {
|
|
8790
|
+
const controller = new AbortController();
|
|
8791
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
8792
|
+
try {
|
|
8793
|
+
const headers = {
|
|
8794
|
+
"Content-Type": "application/json"
|
|
8795
|
+
};
|
|
8796
|
+
if (options?.headers) {
|
|
8797
|
+
Object.assign(headers, options.headers);
|
|
8798
|
+
}
|
|
8799
|
+
if (this.apiKey) {
|
|
8800
|
+
if (this.apiKeyHeader === "x-api-key") {
|
|
8801
|
+
headers["x-api-key"] = this.apiKey;
|
|
8802
|
+
} else {
|
|
8803
|
+
headers["Authorization"] = `Bearer ${this.apiKey}`;
|
|
8804
|
+
}
|
|
8805
|
+
}
|
|
8806
|
+
const response = await this.customFetch(`${this.baseUrl}${path}`, {
|
|
8807
|
+
...options,
|
|
8808
|
+
headers,
|
|
8809
|
+
signal: controller.signal
|
|
8810
|
+
});
|
|
8811
|
+
clearTimeout(timeoutId);
|
|
8812
|
+
if (!response.ok) {
|
|
8813
|
+
const errorData = await response.json().catch(() => ({}));
|
|
8814
|
+
throw new HttpError(
|
|
8815
|
+
errorData.error || `HTTP error! status: ${response.status}`,
|
|
8816
|
+
response.status
|
|
8817
|
+
);
|
|
8818
|
+
}
|
|
8819
|
+
if (response.status === 204) {
|
|
8820
|
+
return null;
|
|
8821
|
+
}
|
|
8822
|
+
return await response.json();
|
|
8823
|
+
} catch (error) {
|
|
8824
|
+
clearTimeout(timeoutId);
|
|
8825
|
+
if (error instanceof HttpError) {
|
|
8826
|
+
throw error;
|
|
8827
|
+
}
|
|
8828
|
+
if (error.name === "AbortError") {
|
|
8829
|
+
throw new HttpError("Request timeout", 408);
|
|
8830
|
+
}
|
|
8831
|
+
throw new HttpError(`Failed to fetch: ${error.message}`, 500);
|
|
8832
|
+
}
|
|
8833
|
+
}
|
|
8834
|
+
/**
|
|
8835
|
+
* Health check
|
|
8836
|
+
*/
|
|
8837
|
+
async health() {
|
|
8838
|
+
return this.fetch("/health", { method: "GET" });
|
|
8839
|
+
}
|
|
8840
|
+
// ==================== Admin APIs ====================
|
|
8841
|
+
/**
|
|
8842
|
+
* Create API key (Admin)
|
|
8843
|
+
*/
|
|
8844
|
+
async createApiKey(data) {
|
|
8845
|
+
return this.fetch("/admin/keys", {
|
|
8846
|
+
method: "POST",
|
|
8847
|
+
body: JSON.stringify(data)
|
|
8848
|
+
});
|
|
8849
|
+
}
|
|
8850
|
+
/**
|
|
8851
|
+
* Create tenant (Admin)
|
|
8852
|
+
*/
|
|
8853
|
+
async createTenant(data) {
|
|
8854
|
+
return this.fetch("/admin/tenants", {
|
|
8855
|
+
method: "POST",
|
|
8856
|
+
body: JSON.stringify(data)
|
|
8857
|
+
});
|
|
8858
|
+
}
|
|
8859
|
+
// ==================== Usage API ====================
|
|
8860
|
+
/**
|
|
8861
|
+
* Get usage for current API key
|
|
8862
|
+
*/
|
|
8863
|
+
async getUsage(params) {
|
|
8864
|
+
const queryString = params ? "?" + new URLSearchParams(params).toString() : "";
|
|
8865
|
+
return this.fetch(`/v1/usage${queryString}`, { method: "GET" });
|
|
8866
|
+
}
|
|
8867
|
+
// ==================== Core MACI APIs ====================
|
|
8868
|
+
/**
|
|
8869
|
+
* Signup
|
|
8870
|
+
*/
|
|
8871
|
+
async signup(data) {
|
|
8872
|
+
return this.fetch("/v1/signup", {
|
|
8873
|
+
method: "POST",
|
|
8874
|
+
body: JSON.stringify(data)
|
|
8875
|
+
});
|
|
8876
|
+
}
|
|
8877
|
+
/**
|
|
8878
|
+
* Vote
|
|
8879
|
+
*/
|
|
8880
|
+
async vote(data) {
|
|
8881
|
+
return this.fetch("/v1/vote", {
|
|
8882
|
+
method: "POST",
|
|
8883
|
+
body: JSON.stringify(data)
|
|
8884
|
+
});
|
|
8885
|
+
}
|
|
8886
|
+
/**
|
|
8887
|
+
* Create Round
|
|
8888
|
+
*/
|
|
8889
|
+
async createRound(data) {
|
|
8890
|
+
return this.fetch("/v1/create-round", {
|
|
8891
|
+
method: "POST",
|
|
8892
|
+
body: JSON.stringify(data)
|
|
8893
|
+
});
|
|
8894
|
+
}
|
|
8895
|
+
/**
|
|
8896
|
+
* Create AMaci Round
|
|
8897
|
+
*/
|
|
8898
|
+
async createAmaciRound(data) {
|
|
8899
|
+
return this.fetch("/v1/create-amaci-round", {
|
|
8900
|
+
method: "POST",
|
|
8901
|
+
body: JSON.stringify(data)
|
|
8902
|
+
});
|
|
8903
|
+
}
|
|
8904
|
+
/**
|
|
8905
|
+
* Set Round Info
|
|
8906
|
+
*/
|
|
8907
|
+
async setRoundInfo(data) {
|
|
8908
|
+
return this.fetch("/v1/set-round-info", {
|
|
8909
|
+
method: "POST",
|
|
8910
|
+
body: JSON.stringify(data)
|
|
8911
|
+
});
|
|
8912
|
+
}
|
|
8913
|
+
/**
|
|
8914
|
+
* Set Vote Options
|
|
8915
|
+
*/
|
|
8916
|
+
async setVoteOptions(data) {
|
|
8917
|
+
return this.fetch("/v1/set-vote-options", {
|
|
8918
|
+
method: "POST",
|
|
8919
|
+
body: JSON.stringify(data)
|
|
8920
|
+
});
|
|
8921
|
+
}
|
|
8922
|
+
/**
|
|
8923
|
+
* Deactivate
|
|
8924
|
+
*/
|
|
8925
|
+
async deactivate(data) {
|
|
8926
|
+
return this.fetch("/v1/deactivate", {
|
|
8927
|
+
method: "POST",
|
|
8928
|
+
body: JSON.stringify(data)
|
|
8929
|
+
});
|
|
8930
|
+
}
|
|
8931
|
+
/**
|
|
8932
|
+
* Add New Key
|
|
8933
|
+
*/
|
|
8934
|
+
async addNewKey(data) {
|
|
8935
|
+
return this.fetch("/v1/add-new-key", {
|
|
8936
|
+
method: "POST",
|
|
8937
|
+
body: JSON.stringify(data)
|
|
8938
|
+
});
|
|
8939
|
+
}
|
|
8940
|
+
/**
|
|
8941
|
+
* Pre Add New Key
|
|
8942
|
+
*/
|
|
8943
|
+
async preAddNewKey(data) {
|
|
8944
|
+
return this.fetch("/v1/pre-add-new-key", {
|
|
8945
|
+
method: "POST",
|
|
8946
|
+
body: JSON.stringify(data)
|
|
8947
|
+
});
|
|
8948
|
+
}
|
|
8949
|
+
// ==================== Allowlist APIs ====================
|
|
8950
|
+
/**
|
|
8951
|
+
* Get allowlist list
|
|
8952
|
+
*/
|
|
8953
|
+
async getAllowlists(params) {
|
|
8954
|
+
const queryString = params ? "?" + new URLSearchParams(params).toString() : "";
|
|
8955
|
+
return this.fetch(`/v1/allowlists/${queryString}`, { method: "GET" });
|
|
8956
|
+
}
|
|
8957
|
+
/**
|
|
8958
|
+
* Create allowlist
|
|
8959
|
+
*/
|
|
8960
|
+
async createAllowlist(data) {
|
|
8961
|
+
return this.fetch("/v1/allowlists/", {
|
|
8962
|
+
method: "POST",
|
|
8963
|
+
body: JSON.stringify(data)
|
|
8964
|
+
});
|
|
8965
|
+
}
|
|
8966
|
+
/**
|
|
8967
|
+
* Get allowlist details
|
|
8968
|
+
*/
|
|
8969
|
+
async getAllowlistDetail(params) {
|
|
8970
|
+
return this.fetch(`/v1/allowlists/${params.id}`, { method: "GET" });
|
|
8971
|
+
}
|
|
8972
|
+
/**
|
|
8973
|
+
* Update allowlist
|
|
8974
|
+
*/
|
|
8975
|
+
async updateAllowlist(params, data) {
|
|
8976
|
+
return this.fetch(`/v1/allowlists/${params.id}`, {
|
|
8977
|
+
method: "PUT",
|
|
8978
|
+
body: JSON.stringify(data)
|
|
8979
|
+
});
|
|
8980
|
+
}
|
|
8981
|
+
/**
|
|
8982
|
+
* Delete allowlist
|
|
8983
|
+
*/
|
|
8984
|
+
async deleteAllowlist(params) {
|
|
8985
|
+
return this.fetch(`/v1/allowlists/${params.id}`, { method: "DELETE" });
|
|
8986
|
+
}
|
|
8987
|
+
/**
|
|
8988
|
+
* Get round allowlist snapshot
|
|
8989
|
+
*/
|
|
8990
|
+
async getRoundAllowlistSnapshot(params) {
|
|
8991
|
+
return this.fetch(`/v1/allowlists/snapshots/${params.contractAddress}`, {
|
|
8992
|
+
method: "GET"
|
|
8993
|
+
});
|
|
8994
|
+
}
|
|
8995
|
+
// ==================== Certificate APIs ====================
|
|
8996
|
+
/**
|
|
8997
|
+
* Request certificate
|
|
8998
|
+
*/
|
|
8999
|
+
async requestCertificate(data) {
|
|
9000
|
+
return this.fetch("/v1/certificates/request", {
|
|
9001
|
+
method: "POST",
|
|
9002
|
+
body: JSON.stringify(data)
|
|
9003
|
+
});
|
|
9004
|
+
}
|
|
9005
|
+
// ==================== Pre-deactivate APIs ====================
|
|
9006
|
+
/**
|
|
9007
|
+
* Get pre-deactivate data by contract address
|
|
9008
|
+
*/
|
|
9009
|
+
async getPreDeactivate(params) {
|
|
9010
|
+
return this.fetch(`/v1/pre-deactivate/${params.contractAddress}`, {
|
|
9011
|
+
method: "GET"
|
|
9012
|
+
});
|
|
9013
|
+
}
|
|
9014
|
+
};
|
|
9015
|
+
|
|
8562
9016
|
// src/maci.ts
|
|
8563
9017
|
var MaciClient2 = class {
|
|
8564
9018
|
/**
|
|
@@ -8571,6 +9025,8 @@ var MaciClient2 = class {
|
|
|
8571
9025
|
rpcEndpoint,
|
|
8572
9026
|
restEndpoint,
|
|
8573
9027
|
apiEndpoint,
|
|
9028
|
+
saasApiEndpoint,
|
|
9029
|
+
saasApiKey,
|
|
8574
9030
|
registryAddress,
|
|
8575
9031
|
saasAddress,
|
|
8576
9032
|
apiSaasAddress,
|
|
@@ -8589,6 +9045,7 @@ var MaciClient2 = class {
|
|
|
8589
9045
|
this.rpcEndpoint = rpcEndpoint || defaultParams.rpcEndpoint;
|
|
8590
9046
|
this.restEndpoint = restEndpoint || defaultParams.restEndpoint;
|
|
8591
9047
|
this.apiEndpoint = apiEndpoint || defaultParams.apiEndpoint;
|
|
9048
|
+
this.saasApiEndpoint = saasApiEndpoint;
|
|
8592
9049
|
this.certificateApiEndpoint = certificateApiEndpoint || defaultParams.certificateApiEndpoint;
|
|
8593
9050
|
this.registryAddress = registryAddress || defaultParams.registryAddress;
|
|
8594
9051
|
this.saasAddress = saasAddress || defaultParams.saasAddress;
|
|
@@ -8598,15 +9055,11 @@ var MaciClient2 = class {
|
|
|
8598
9055
|
this.feegrantOperator = feegrantOperator || defaultParams.oracleFeegrantOperator;
|
|
8599
9056
|
this.whitelistBackendPubkey = whitelistBackendPubkey || defaultParams.oracleWhitelistBackendPubkey;
|
|
8600
9057
|
this.maciKeypair = maciKeypair ?? genKeypair();
|
|
8601
|
-
this.http = new Http(
|
|
8602
|
-
this.apiEndpoint,
|
|
8603
|
-
this.restEndpoint,
|
|
8604
|
-
customFetch,
|
|
8605
|
-
defaultOptions
|
|
8606
|
-
);
|
|
9058
|
+
this.http = new Http(this.apiEndpoint, this.restEndpoint, customFetch, defaultOptions);
|
|
8607
9059
|
this.indexer = new Indexer({
|
|
8608
9060
|
restEndpoint: this.restEndpoint,
|
|
8609
9061
|
apiEndpoint: this.apiEndpoint,
|
|
9062
|
+
// Indexer GraphQL API
|
|
8610
9063
|
registryAddress: this.registryAddress,
|
|
8611
9064
|
http: this.http
|
|
8612
9065
|
});
|
|
@@ -8631,6 +9084,13 @@ var MaciClient2 = class {
|
|
|
8631
9084
|
oracleCertificate: this.oracleCertificate,
|
|
8632
9085
|
maciKeypair: this.maciKeypair
|
|
8633
9086
|
});
|
|
9087
|
+
if (this.saasApiEndpoint) {
|
|
9088
|
+
this.saasApiClient = new MaciApiClient({
|
|
9089
|
+
baseUrl: this.saasApiEndpoint,
|
|
9090
|
+
apiKey: saasApiKey,
|
|
9091
|
+
customFetch
|
|
9092
|
+
});
|
|
9093
|
+
}
|
|
8634
9094
|
}
|
|
8635
9095
|
getSigner(signer) {
|
|
8636
9096
|
if (signer) {
|
|
@@ -8641,6 +9101,28 @@ var MaciClient2 = class {
|
|
|
8641
9101
|
}
|
|
8642
9102
|
throw new Error("No signer provided, please provide a signer");
|
|
8643
9103
|
}
|
|
9104
|
+
/**
|
|
9105
|
+
* Set SaaS API key for MaciApiClient
|
|
9106
|
+
*/
|
|
9107
|
+
setSaasApiKey(apiKey) {
|
|
9108
|
+
if (!this.saasApiClient) {
|
|
9109
|
+
throw new Error(
|
|
9110
|
+
"SaaS API client not initialized. Please provide saasApiEndpoint in constructor."
|
|
9111
|
+
);
|
|
9112
|
+
}
|
|
9113
|
+
this.saasApiClient.setApiKey(apiKey);
|
|
9114
|
+
}
|
|
9115
|
+
/**
|
|
9116
|
+
* Get SaaS API client instance
|
|
9117
|
+
*/
|
|
9118
|
+
getSaasApiClient() {
|
|
9119
|
+
if (!this.saasApiClient) {
|
|
9120
|
+
throw new Error(
|
|
9121
|
+
"SaaS API client not initialized. Please provide saasApiEndpoint in constructor."
|
|
9122
|
+
);
|
|
9123
|
+
}
|
|
9124
|
+
return this.saasApiClient;
|
|
9125
|
+
}
|
|
8644
9126
|
getMaciKeypair() {
|
|
8645
9127
|
return this.maciKeypair;
|
|
8646
9128
|
}
|
|
@@ -8843,9 +9325,7 @@ var MaciClient2 = class {
|
|
|
8843
9325
|
async getRounds(after, limit) {
|
|
8844
9326
|
const rounds = await this.indexer.getRounds(after || "", limit || 10);
|
|
8845
9327
|
if (isErrorResponse(rounds)) {
|
|
8846
|
-
throw new Error(
|
|
8847
|
-
`Failed to get rounds: ${rounds.code} ${rounds.error.message}`
|
|
8848
|
-
);
|
|
9328
|
+
throw new Error(`Failed to get rounds: ${rounds.code} ${rounds.error.message}`);
|
|
8849
9329
|
}
|
|
8850
9330
|
return rounds;
|
|
8851
9331
|
}
|
|
@@ -8858,15 +9338,10 @@ var MaciClient2 = class {
|
|
|
8858
9338
|
async queryRoundIsQv({ contractAddress }) {
|
|
8859
9339
|
return await this.maci.queryRoundIsQv({ contractAddress });
|
|
8860
9340
|
}
|
|
8861
|
-
async queryRoundClaimable({
|
|
8862
|
-
contractAddress
|
|
8863
|
-
}) {
|
|
9341
|
+
async queryRoundClaimable({ contractAddress }) {
|
|
8864
9342
|
return await this.maci.queryRoundClaimable({ contractAddress });
|
|
8865
9343
|
}
|
|
8866
|
-
async queryAMaciChargeFee({
|
|
8867
|
-
maxVoter,
|
|
8868
|
-
maxOption
|
|
8869
|
-
}) {
|
|
9344
|
+
async queryAMaciChargeFee({ maxVoter, maxOption }) {
|
|
8870
9345
|
return await this.maci.queryAMaciChargeFee({
|
|
8871
9346
|
maxVoter,
|
|
8872
9347
|
maxOption
|
|
@@ -8876,12 +9351,7 @@ var MaciClient2 = class {
|
|
|
8876
9351
|
return await this.maci.queryRoundGasStation({ contractAddress });
|
|
8877
9352
|
}
|
|
8878
9353
|
parseRoundStatus(votingStart, votingEnd, status, currentTime) {
|
|
8879
|
-
return this.maci.parseRoundStatus(
|
|
8880
|
-
votingStart,
|
|
8881
|
-
votingEnd,
|
|
8882
|
-
status,
|
|
8883
|
-
currentTime
|
|
8884
|
-
);
|
|
9354
|
+
return this.maci.parseRoundStatus(votingStart, votingEnd, status, currentTime);
|
|
8885
9355
|
}
|
|
8886
9356
|
async queryRoundBalance({ contractAddress }) {
|
|
8887
9357
|
return await this.maci.queryRoundBalance({ contractAddress });
|
|
@@ -9141,13 +9611,941 @@ var MaciClient2 = class {
|
|
|
9141
9611
|
fee
|
|
9142
9612
|
});
|
|
9143
9613
|
}
|
|
9614
|
+
// ==================== SaaS API Client Methods ====================
|
|
9615
|
+
/**
|
|
9616
|
+
* Create AMaci round via SaaS API
|
|
9617
|
+
* @param params - Round creation parameters
|
|
9618
|
+
*/
|
|
9619
|
+
async saasCreateAmaciRound(params) {
|
|
9620
|
+
if (!this.saasApiClient) {
|
|
9621
|
+
throw new Error("SaaS API client not initialized");
|
|
9622
|
+
}
|
|
9623
|
+
return await this.saasApiClient.createAmaciRound(params);
|
|
9624
|
+
}
|
|
9625
|
+
/**
|
|
9626
|
+
* Set round info via SaaS API
|
|
9627
|
+
* @param params - Round info parameters
|
|
9628
|
+
*/
|
|
9629
|
+
async saasSetRoundInfo(params) {
|
|
9630
|
+
if (!this.saasApiClient) {
|
|
9631
|
+
throw new Error("SaaS API client not initialized");
|
|
9632
|
+
}
|
|
9633
|
+
return await this.saasApiClient.setRoundInfo(params);
|
|
9634
|
+
}
|
|
9635
|
+
/**
|
|
9636
|
+
* Set vote options via SaaS API
|
|
9637
|
+
* @param params - Vote options parameters
|
|
9638
|
+
*/
|
|
9639
|
+
async saasSetVoteOptions(params) {
|
|
9640
|
+
if (!this.saasApiClient) {
|
|
9641
|
+
throw new Error("SaaS API client not initialized");
|
|
9642
|
+
}
|
|
9643
|
+
return await this.saasApiClient.setVoteOptions(params);
|
|
9644
|
+
}
|
|
9645
|
+
};
|
|
9646
|
+
|
|
9647
|
+
// src/voter.ts
|
|
9648
|
+
var import_crypto_js3 = __toESM(require("crypto-js"));
|
|
9649
|
+
var import_ethers4 = require("ethers");
|
|
9650
|
+
var import_snarkjs = require("snarkjs");
|
|
9651
|
+
|
|
9652
|
+
// src/libs/keypairs/eddsa-poseidon/keypair.ts
|
|
9653
|
+
var import_blake2b = require("@noble/hashes/blake2b");
|
|
9654
|
+
var import_utils9 = require("@noble/hashes/utils");
|
|
9655
|
+
var import_bip32 = require("@scure/bip32");
|
|
9656
|
+
var import_sha2563 = require("@noble/hashes/sha256");
|
|
9657
|
+
var import_eddsa_poseidon4 = require("@zk-kit/eddsa-poseidon");
|
|
9658
|
+
|
|
9659
|
+
// src/libs/cryptography/keypair.ts
|
|
9660
|
+
var Signer = class {
|
|
9661
|
+
/**
|
|
9662
|
+
* Sign messages with a specific payload. By combining the message bytes with the payload before hashing and signing,
|
|
9663
|
+
* it ensures that a signed message is tied to a specific purpose and domain separator is provided
|
|
9664
|
+
*/
|
|
9665
|
+
async signWithPayload(message) {
|
|
9666
|
+
const signature = await this.sign(message);
|
|
9667
|
+
return {
|
|
9668
|
+
message,
|
|
9669
|
+
signature
|
|
9670
|
+
};
|
|
9671
|
+
}
|
|
9672
|
+
};
|
|
9673
|
+
var Keypair3 = class extends Signer {
|
|
9674
|
+
};
|
|
9675
|
+
|
|
9676
|
+
// src/libs/cryptography/mnemonics.ts
|
|
9677
|
+
var import_bip39 = require("@scure/bip39");
|
|
9678
|
+
function isValidBIP32Path(path) {
|
|
9679
|
+
if (!new RegExp("^m\\/(44|54|74)'\\/118'\\/[0-9]+'\\/[0-9]+\\/[0-9]+$").test(path)) {
|
|
9680
|
+
return false;
|
|
9681
|
+
}
|
|
9682
|
+
return true;
|
|
9683
|
+
}
|
|
9684
|
+
function mnemonicToSeed(mnemonics) {
|
|
9685
|
+
return (0, import_bip39.mnemonicToSeedSync)(mnemonics, "");
|
|
9686
|
+
}
|
|
9687
|
+
|
|
9688
|
+
// src/libs/keypairs/eddsa-poseidon/publickey.ts
|
|
9689
|
+
var import_sha2562 = require("@noble/hashes/sha256");
|
|
9690
|
+
|
|
9691
|
+
// src/libs/cryptography/publickey.ts
|
|
9692
|
+
var PublicKey = class {
|
|
9693
|
+
/**
|
|
9694
|
+
* Checks if two public keys are equal
|
|
9695
|
+
*/
|
|
9696
|
+
equals(publicKey) {
|
|
9697
|
+
return this.toPackedData() === publicKey.toPackedData();
|
|
9698
|
+
}
|
|
9699
|
+
};
|
|
9700
|
+
|
|
9701
|
+
// src/libs/keypairs/eddsa-poseidon/publickey.ts
|
|
9702
|
+
var import_eddsa_poseidon3 = require("@zk-kit/eddsa-poseidon");
|
|
9703
|
+
var EdDSAPoseidonPublicKey = class extends PublicKey {
|
|
9704
|
+
/**
|
|
9705
|
+
* Create a new EdDSAPoseidonPublicKey object
|
|
9706
|
+
* @param value public key as packed bigint, Point array, Uint8Array or string
|
|
9707
|
+
*/
|
|
9708
|
+
constructor(value) {
|
|
9709
|
+
super();
|
|
9710
|
+
if (typeof value === "bigint") {
|
|
9711
|
+
this.packedData = value;
|
|
9712
|
+
this.rawPoint = unpackPubKey(value);
|
|
9713
|
+
} else if (Array.isArray(value) && value.length === 2) {
|
|
9714
|
+
this.rawPoint = value;
|
|
9715
|
+
this.packedData = packPubKey(this.rawPoint);
|
|
9716
|
+
} else if (typeof value === "string") {
|
|
9717
|
+
this.packedData = BigInt(value);
|
|
9718
|
+
this.rawPoint = unpackPubKey(this.packedData);
|
|
9719
|
+
} else if (value instanceof Uint8Array) {
|
|
9720
|
+
const hex = Array.from(value).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
9721
|
+
this.packedData = BigInt("0x" + hex);
|
|
9722
|
+
this.rawPoint = unpackPubKey(this.packedData);
|
|
9723
|
+
} else {
|
|
9724
|
+
const bytes = new Uint8Array(value);
|
|
9725
|
+
const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
9726
|
+
this.packedData = BigInt("0x" + hex);
|
|
9727
|
+
this.rawPoint = unpackPubKey(this.packedData);
|
|
9728
|
+
}
|
|
9729
|
+
}
|
|
9730
|
+
/**
|
|
9731
|
+
* Checks if two EdDSAPoseidon public keys are equal
|
|
9732
|
+
*/
|
|
9733
|
+
equals(publicKey) {
|
|
9734
|
+
return super.equals(publicKey);
|
|
9735
|
+
}
|
|
9736
|
+
/**
|
|
9737
|
+
* Return the Point representation of the EdDSAPoseidon public key
|
|
9738
|
+
*/
|
|
9739
|
+
toPoints() {
|
|
9740
|
+
return this.rawPoint;
|
|
9741
|
+
}
|
|
9742
|
+
/**
|
|
9743
|
+
* Return the packed bigint representation of the EdDSAPoseidon public key
|
|
9744
|
+
*/
|
|
9745
|
+
toPackedData() {
|
|
9746
|
+
return this.packedData;
|
|
9747
|
+
}
|
|
9748
|
+
/**
|
|
9749
|
+
* Verifies that the signature is valid for for the provided message
|
|
9750
|
+
*/
|
|
9751
|
+
verify(message, signature) {
|
|
9752
|
+
try {
|
|
9753
|
+
return (0, import_eddsa_poseidon3.verifySignature)(message, signature, this.rawPoint);
|
|
9754
|
+
} catch (error) {
|
|
9755
|
+
return false;
|
|
9756
|
+
}
|
|
9757
|
+
}
|
|
9758
|
+
/**
|
|
9759
|
+
* Verifies that the signature is valid for the provided address and amount
|
|
9760
|
+
*/
|
|
9761
|
+
verifyPayload({
|
|
9762
|
+
amount,
|
|
9763
|
+
contractAddress,
|
|
9764
|
+
signature
|
|
9765
|
+
}) {
|
|
9766
|
+
const payload = {
|
|
9767
|
+
amount,
|
|
9768
|
+
contract_address: addressToUint256(contractAddress).toString(),
|
|
9769
|
+
pubkey_x: this.toPoints()[0].toString(),
|
|
9770
|
+
pubkey_y: this.toPoints()[1].toString()
|
|
9771
|
+
};
|
|
9772
|
+
const signatureBytes = fromBase64(signature);
|
|
9773
|
+
const rawSignature = (0, import_eddsa_poseidon3.unpackSignature)(new Buffer(signatureBytes));
|
|
9774
|
+
const payloadHash = (0, import_sha2562.sha256)(new TextEncoder().encode(JSON.stringify(payload)));
|
|
9775
|
+
return this.verify(payloadHash, rawSignature);
|
|
9776
|
+
}
|
|
9777
|
+
/**
|
|
9778
|
+
* Verifies that the signature is valid for the provided address and amount
|
|
9779
|
+
*/
|
|
9780
|
+
verifyCredential({
|
|
9781
|
+
amount,
|
|
9782
|
+
contractAddress,
|
|
9783
|
+
signature
|
|
9784
|
+
}) {
|
|
9785
|
+
const messageHash = hash5([
|
|
9786
|
+
BigInt(amount),
|
|
9787
|
+
BigInt(addressToUint256(contractAddress)),
|
|
9788
|
+
this.toPoints()[0],
|
|
9789
|
+
this.toPoints()[1],
|
|
9790
|
+
BigInt(0)
|
|
9791
|
+
]);
|
|
9792
|
+
const signatureBytes = fromBase64(signature);
|
|
9793
|
+
const rawSignature = (0, import_eddsa_poseidon3.unpackSignature)(new Buffer(signatureBytes));
|
|
9794
|
+
return this.verify(bigInt2Buffer(messageHash), rawSignature);
|
|
9795
|
+
}
|
|
9796
|
+
};
|
|
9797
|
+
|
|
9798
|
+
// src/libs/keypairs/eddsa-poseidon/keypair.ts
|
|
9799
|
+
var import_baby_jubjub3 = require("@zk-kit/baby-jubjub");
|
|
9800
|
+
var DEFAULT_EDDSA_POSEIDON_DERIVATION_PATH = "m/44'/118'/0'/0/0";
|
|
9801
|
+
var EdDSAPoseidonKeypair = class _EdDSAPoseidonKeypair extends Keypair3 {
|
|
9802
|
+
/**
|
|
9803
|
+
* Create a new EdDSA-Poseidon keypair instance.
|
|
9804
|
+
*
|
|
9805
|
+
* If no keypair data is provided, a new random keypair will be generated
|
|
9806
|
+
* using cryptographically secure random number generation.
|
|
9807
|
+
*
|
|
9808
|
+
* @param keypair Optional existing EdDSA-Poseidon keypair data to initialize with
|
|
9809
|
+
*/
|
|
9810
|
+
constructor(keypair) {
|
|
9811
|
+
super();
|
|
9812
|
+
if (keypair) {
|
|
9813
|
+
this.keypair = keypair;
|
|
9814
|
+
} else {
|
|
9815
|
+
const generatedKeypair = genKeypair();
|
|
9816
|
+
const secretKey = generatedKeypair.privKey;
|
|
9817
|
+
const unPackedPublicKey = generatedKeypair.pubKey;
|
|
9818
|
+
const publicKey = packPubKey(unPackedPublicKey);
|
|
9819
|
+
const formatedPrivKey = formatPrivKeyForBabyJub(secretKey);
|
|
9820
|
+
this.keypair = { publicKey, secretKey, formatedPrivKey };
|
|
9821
|
+
}
|
|
9822
|
+
}
|
|
9823
|
+
/**
|
|
9824
|
+
* Get the signature scheme identifier for this keypair.
|
|
9825
|
+
*
|
|
9826
|
+
* @returns The signature scheme type 'EDDSA_POSEIDON'
|
|
9827
|
+
*/
|
|
9828
|
+
getKeyScheme() {
|
|
9829
|
+
return "EDDSA_POSEIDON";
|
|
9830
|
+
}
|
|
9831
|
+
/**
|
|
9832
|
+
* Generate a new random EdDSA-Poseidon keypair.
|
|
9833
|
+
*
|
|
9834
|
+
* This is a convenience static method that creates a new instance
|
|
9835
|
+
* with randomly generated cryptographic keys.
|
|
9836
|
+
*
|
|
9837
|
+
* @returns A new EdDSAPoseidonKeypair instance with random keys
|
|
9838
|
+
*/
|
|
9839
|
+
static generate() {
|
|
9840
|
+
return new _EdDSAPoseidonKeypair();
|
|
9841
|
+
}
|
|
9842
|
+
/**
|
|
9843
|
+
* Create a keypair from an existing secret key.
|
|
9844
|
+
*
|
|
9845
|
+
* This method reconstructs a keypair from a previously generated secret key.
|
|
9846
|
+
* The secret key can be provided as either a hex string (with or without '0x' prefix)
|
|
9847
|
+
* or as a bigint value. For generating keypairs from mnemonic seeds, use the
|
|
9848
|
+
* {@link EdDSAPoseidonKeypair.deriveKeypair} method instead.
|
|
9849
|
+
*
|
|
9850
|
+
* @param secretKey The secret key as a hex string or bigint
|
|
9851
|
+
* @param options Configuration options for key reconstruction
|
|
9852
|
+
* @param options.skipValidation If true, skips cryptographic validation of the secret key
|
|
9853
|
+
*
|
|
9854
|
+
* @returns A new EdDSAPoseidonKeypair instance created from the secret key
|
|
9855
|
+
* @throws Error if the provided secret key is invalid and validation is not skipped
|
|
9856
|
+
*/
|
|
9857
|
+
static fromSecretKey(secretKey, options) {
|
|
9858
|
+
if (typeof secretKey === "string") {
|
|
9859
|
+
const cleanSecretKey = secretKey.startsWith("0x") ? secretKey.slice(2) : secretKey;
|
|
9860
|
+
const decoded = buffer2Bigint((0, import_utils9.hexToBytes)(cleanSecretKey));
|
|
9861
|
+
return this.fromSecretKey(decoded, options);
|
|
9862
|
+
}
|
|
9863
|
+
const unPackedPublicKey = genPubKey(secretKey);
|
|
9864
|
+
const publicKey = packPubKey(unPackedPublicKey);
|
|
9865
|
+
if (!options || !options.skipValidation) {
|
|
9866
|
+
const encoder = new TextEncoder();
|
|
9867
|
+
const signData = encoder.encode("dora validation");
|
|
9868
|
+
const msgHash = (0, import_utils9.bytesToHex)((0, import_blake2b.blake2b)(signData, { dkLen: 16 }));
|
|
9869
|
+
const signature = (0, import_eddsa_poseidon4.signMessage)(bigInt2Buffer(secretKey), msgHash);
|
|
9870
|
+
if (!(0, import_eddsa_poseidon4.verifySignature)(msgHash, signature, unPackedPublicKey)) {
|
|
9871
|
+
throw new Error("Provided secretKey is invalid");
|
|
9872
|
+
}
|
|
9873
|
+
}
|
|
9874
|
+
const formatedPrivKey = formatPrivKeyForBabyJub(secretKey);
|
|
9875
|
+
return new _EdDSAPoseidonKeypair({
|
|
9876
|
+
publicKey,
|
|
9877
|
+
secretKey,
|
|
9878
|
+
formatedPrivKey
|
|
9879
|
+
});
|
|
9880
|
+
}
|
|
9881
|
+
/**
|
|
9882
|
+
* Get the public key associated with this keypair.
|
|
9883
|
+
*
|
|
9884
|
+
* @returns An EdDSAPoseidonPublicKey instance containing the public key data
|
|
9885
|
+
*/
|
|
9886
|
+
getPublicKey() {
|
|
9887
|
+
return new EdDSAPoseidonPublicKey(this.keypair.publicKey);
|
|
9888
|
+
}
|
|
9889
|
+
/**
|
|
9890
|
+
* Get the secret key as a hexadecimal string.
|
|
9891
|
+
*
|
|
9892
|
+
* Returns the secret key component of this keypair encoded as a hex string.
|
|
9893
|
+
* This can be used to serialize the secret key for storage or transmission.
|
|
9894
|
+
*
|
|
9895
|
+
* @returns The secret key encoded as a hexadecimal string
|
|
9896
|
+
*/
|
|
9897
|
+
getSecretKey() {
|
|
9898
|
+
return (0, import_utils9.bytesToHex)(bigInt2Buffer(this.keypair.secretKey));
|
|
9899
|
+
}
|
|
9900
|
+
getFormatedPrivKey() {
|
|
9901
|
+
return this.keypair.formatedPrivKey;
|
|
9902
|
+
}
|
|
9903
|
+
/**
|
|
9904
|
+
* Sign a message using this keypair's secret key.
|
|
9905
|
+
*
|
|
9906
|
+
* Creates a cryptographic signature for the provided message using the
|
|
9907
|
+
* EdDSA-Poseidon signature algorithm. The signature can later be verified
|
|
9908
|
+
* using the corresponding public key.
|
|
9909
|
+
*
|
|
9910
|
+
* @param message The message to sign (as BigNumberish - can be bigint, string, or number)
|
|
9911
|
+
* @returns The cryptographic signature of the message
|
|
9912
|
+
*/
|
|
9913
|
+
sign(message) {
|
|
9914
|
+
const sig = (0, import_eddsa_poseidon4.signMessage)(bigInt2Buffer(this.keypair.secretKey), message);
|
|
9915
|
+
return sig;
|
|
9916
|
+
}
|
|
9917
|
+
/**
|
|
9918
|
+
* Derive an EdDSA-Poseidon keypair from a mnemonic phrase and derivation path.
|
|
9919
|
+
*
|
|
9920
|
+
* This method implements hierarchical deterministic (HD) key derivation following
|
|
9921
|
+
* the BIP-32 standard. The mnemonic phrase must be normalized and validated against
|
|
9922
|
+
* the English wordlist before use.
|
|
9923
|
+
*
|
|
9924
|
+
* @param mnemonics The mnemonic phrase (12, 15, 18, 21, or 24 words)
|
|
9925
|
+
* @param path Optional BIP-32 derivation path. If not provided, uses the default path.
|
|
9926
|
+
* Must be in the form m/44'/118'/{account_index}'/{change_index}/{address_index}
|
|
9927
|
+
*
|
|
9928
|
+
* @returns A new EdDSAPoseidonKeypair derived from the mnemonic and path
|
|
9929
|
+
* @throws Error if the derivation path is invalid or key derivation fails
|
|
9930
|
+
*/
|
|
9931
|
+
static deriveKeypair(mnemonics, path) {
|
|
9932
|
+
if (path == null) {
|
|
9933
|
+
path = DEFAULT_EDDSA_POSEIDON_DERIVATION_PATH;
|
|
9934
|
+
}
|
|
9935
|
+
if (!isValidBIP32Path(path)) {
|
|
9936
|
+
throw new Error("Invalid derivation path");
|
|
9937
|
+
}
|
|
9938
|
+
const seed = mnemonicToSeed(mnemonics);
|
|
9939
|
+
const hdKey = import_bip32.HDKey.fromMasterSeed(seed);
|
|
9940
|
+
const derivedKey = hdKey.derive(path);
|
|
9941
|
+
if (!derivedKey.privateKey) {
|
|
9942
|
+
throw new Error("Invalid key");
|
|
9943
|
+
}
|
|
9944
|
+
const privateKeyHex = Buffer.from(derivedKey.privateKey).toString(
|
|
9945
|
+
"hex"
|
|
9946
|
+
);
|
|
9947
|
+
const secretKey = BigInt("0x" + privateKeyHex) % SNARK_FIELD_SIZE;
|
|
9948
|
+
const unPackedPubKey = genPubKey(secretKey);
|
|
9949
|
+
const pubKey = packPubKey(unPackedPubKey);
|
|
9950
|
+
return new _EdDSAPoseidonKeypair({
|
|
9951
|
+
publicKey: pubKey,
|
|
9952
|
+
secretKey,
|
|
9953
|
+
formatedPrivKey: formatPrivKeyForBabyJub(secretKey)
|
|
9954
|
+
});
|
|
9955
|
+
}
|
|
9956
|
+
/**
|
|
9957
|
+
* Sign a payload containing contract address and amount information.
|
|
9958
|
+
*
|
|
9959
|
+
* This method creates a structured payload with the contract address, amount,
|
|
9960
|
+
* and public key coordinates, then generates a cryptographic signature over
|
|
9961
|
+
* the JSON-serialized payload using SHA-256 hashing.
|
|
9962
|
+
*
|
|
9963
|
+
* The resulting signature can be used as a certificate or proof of authorization
|
|
9964
|
+
* for the specified contract address and amount.
|
|
9965
|
+
*
|
|
9966
|
+
* @param params The payload parameters
|
|
9967
|
+
* @param params.amount The amount value as a string
|
|
9968
|
+
* @param params.contractAddress The contract address to include in the payload
|
|
9969
|
+
*
|
|
9970
|
+
* @returns Base64-encoded signature of the payload
|
|
9971
|
+
*/
|
|
9972
|
+
signPayload({
|
|
9973
|
+
amount,
|
|
9974
|
+
contractAddress
|
|
9975
|
+
}) {
|
|
9976
|
+
const payload = {
|
|
9977
|
+
amount,
|
|
9978
|
+
contract_address: addressToUint256(contractAddress).toString(),
|
|
9979
|
+
pubkey_x: this.getPublicKey().toPoints()[0].toString(),
|
|
9980
|
+
pubkey_y: this.getPublicKey().toPoints()[1].toString()
|
|
9981
|
+
};
|
|
9982
|
+
const bytes = new TextEncoder().encode(JSON.stringify(payload));
|
|
9983
|
+
const msgHash = (0, import_sha2563.sha256)(bytes);
|
|
9984
|
+
const signature = this.sign(msgHash);
|
|
9985
|
+
return toBase64(new Uint8Array((0, import_eddsa_poseidon4.packSignature)(signature)));
|
|
9986
|
+
}
|
|
9987
|
+
/**
|
|
9988
|
+
* Sign a credential containing contract address and amount using Poseidon hashing.
|
|
9989
|
+
*
|
|
9990
|
+
* This method creates a cryptographic credential by signing a structured message
|
|
9991
|
+
* using the Poseidon hash function (hash5). The message includes the amount,
|
|
9992
|
+
* contract address (converted to uint256), public key coordinates, and a zero nonce.
|
|
9993
|
+
*
|
|
9994
|
+
* This type of credential is optimized for zero-knowledge proof systems where
|
|
9995
|
+
* Poseidon hashing is more efficient than traditional hash functions.
|
|
9996
|
+
*
|
|
9997
|
+
* @param params The credential parameters
|
|
9998
|
+
* @param params.amount The amount value as a string (will be converted to BigInt)
|
|
9999
|
+
* @param params.contractAddress The contract address (will be converted to uint256)
|
|
10000
|
+
*
|
|
10001
|
+
* @returns Base64-encoded signature of the credential
|
|
10002
|
+
*/
|
|
10003
|
+
signCredential({
|
|
10004
|
+
amount,
|
|
10005
|
+
contractAddress
|
|
10006
|
+
}) {
|
|
10007
|
+
const messageHash = hash5([
|
|
10008
|
+
BigInt(amount),
|
|
10009
|
+
BigInt(addressToUint256(contractAddress)),
|
|
10010
|
+
this.getPublicKey().toPoints()[0],
|
|
10011
|
+
this.getPublicKey().toPoints()[1],
|
|
10012
|
+
BigInt(0)
|
|
10013
|
+
// Nonce field (currently set to 0)
|
|
10014
|
+
]);
|
|
10015
|
+
const signature = this.sign(messageHash);
|
|
10016
|
+
return toBase64(new Uint8Array((0, import_eddsa_poseidon4.packSignature)(signature)));
|
|
10017
|
+
}
|
|
10018
|
+
/**
|
|
10019
|
+
* Generates an Elliptic-Curve Diffie–Hellman (ECDH) shared key given a private
|
|
10020
|
+
* key and a public key.
|
|
10021
|
+
* @param pubKey A public key generated using genPubKey()
|
|
10022
|
+
* @returns The ECDH shared key.
|
|
10023
|
+
*/
|
|
10024
|
+
genEcdhSharedKey(pubKey) {
|
|
10025
|
+
return (0, import_baby_jubjub3.mulPointEscalar)(
|
|
10026
|
+
pubKey,
|
|
10027
|
+
this.keypair.formatedPrivKey
|
|
10028
|
+
);
|
|
10029
|
+
}
|
|
10030
|
+
genDeactivateRoot(accounts, stateTreeDepth) {
|
|
10031
|
+
const unpackedAccounts = accounts.length > 0 && typeof accounts[0] === "bigint" ? accounts.map((account) => unpackPubKey(account)) : accounts;
|
|
10032
|
+
const deactivates = unpackedAccounts.map((account) => {
|
|
10033
|
+
const sharedKey = this.genEcdhSharedKey(account);
|
|
10034
|
+
const deactivate = encryptOdevity(
|
|
10035
|
+
false,
|
|
10036
|
+
// isOdd: According to circuit rules, odd values indicate active accounts and even values indicate inactive accounts. Set to false here to ensure valid signup
|
|
10037
|
+
this.getPublicKey().toPoints(),
|
|
10038
|
+
genRandomBabyJubValue()
|
|
10039
|
+
);
|
|
10040
|
+
return [
|
|
10041
|
+
deactivate.c1.x,
|
|
10042
|
+
deactivate.c1.y,
|
|
10043
|
+
deactivate.c2.x,
|
|
10044
|
+
deactivate.c2.y,
|
|
10045
|
+
poseidon(sharedKey)
|
|
10046
|
+
];
|
|
10047
|
+
});
|
|
10048
|
+
const degree = 5;
|
|
10049
|
+
const depth = stateTreeDepth + 2;
|
|
10050
|
+
const zero = 0n;
|
|
10051
|
+
const tree = new Tree(degree, depth, zero);
|
|
10052
|
+
const leaves = deactivates.map((deactivate) => poseidon(deactivate));
|
|
10053
|
+
tree.initLeaves(leaves);
|
|
10054
|
+
return {
|
|
10055
|
+
deactivates,
|
|
10056
|
+
root: tree.root,
|
|
10057
|
+
leaves,
|
|
10058
|
+
tree
|
|
10059
|
+
// Return tree instance for later retrieval of path elements
|
|
10060
|
+
};
|
|
10061
|
+
}
|
|
10062
|
+
};
|
|
10063
|
+
|
|
10064
|
+
// src/libs/account/keypair.ts
|
|
10065
|
+
var getDerivePathForMACI = (derivePathParams = {}) => {
|
|
10066
|
+
const { accountIndex = 0, isExternal = false, addressIndex = 0 } = derivePathParams;
|
|
10067
|
+
return `m/44'/118'/${accountIndex}'/${isExternal ? 1 : 0}/${addressIndex}`;
|
|
10068
|
+
};
|
|
10069
|
+
var getKeyPair = (mnemonics, derivePathParams = {}) => {
|
|
10070
|
+
const derivePath = getDerivePathForMACI(derivePathParams);
|
|
10071
|
+
return EdDSAPoseidonKeypair.deriveKeypair(mnemonics, derivePath);
|
|
10072
|
+
};
|
|
10073
|
+
|
|
10074
|
+
// src/libs/account/crypto.ts
|
|
10075
|
+
var import_bip392 = require("@scure/bip39");
|
|
10076
|
+
var import_english = require("@scure/bip39/wordlists/english");
|
|
10077
|
+
var generateMnemonic = (numberOfWords = 24) => {
|
|
10078
|
+
const strength = numberOfWords === 12 ? 128 : 256;
|
|
10079
|
+
return (0, import_bip392.generateMnemonic)(import_english.wordlist, strength);
|
|
10080
|
+
};
|
|
10081
|
+
|
|
10082
|
+
// src/libs/account/index.ts
|
|
10083
|
+
var MaciAccount = class {
|
|
10084
|
+
/**
|
|
10085
|
+
* Support the following ways to init the SuiToolkit:
|
|
10086
|
+
* 1. mnemonics
|
|
10087
|
+
* 2. secretKey (base64 or hex)
|
|
10088
|
+
* If none of them is provided, will generate a random mnemonics with 24 words.
|
|
10089
|
+
*
|
|
10090
|
+
* @param mnemonics, 12 or 24 mnemonics words, separated by space
|
|
10091
|
+
* @param secretKey, base64 or hex string or Bech32 string, when mnemonics is provided, secretKey will be ignored
|
|
10092
|
+
*/
|
|
10093
|
+
constructor({ mnemonic, secretKey } = {}) {
|
|
10094
|
+
this.mnemonic = mnemonic || "";
|
|
10095
|
+
this.secretKey = secretKey || "";
|
|
10096
|
+
if (!this.mnemonic && !this.secretKey) {
|
|
10097
|
+
this.mnemonic = generateMnemonic(24);
|
|
10098
|
+
}
|
|
10099
|
+
this.currentKeypair = this.secretKey ? this.parseSecretKey(this.secretKey) : getKeyPair(this.mnemonic);
|
|
10100
|
+
this.currentPubkey = this.currentKeypair.getPublicKey();
|
|
10101
|
+
}
|
|
10102
|
+
/**
|
|
10103
|
+
* Check if the secretKey starts with bench32 format
|
|
10104
|
+
*/
|
|
10105
|
+
parseSecretKey(secretKey) {
|
|
10106
|
+
return EdDSAPoseidonKeypair.fromSecretKey(secretKey);
|
|
10107
|
+
}
|
|
10108
|
+
/**
|
|
10109
|
+
* if derivePathParams is not provided or mnemonics is empty, it will return the currentKeyPair.
|
|
10110
|
+
* else:
|
|
10111
|
+
* it will generate keyPair from the mnemonic with the given derivePathParams.
|
|
10112
|
+
*/
|
|
10113
|
+
getKeyPair(derivePathParams) {
|
|
10114
|
+
if (!derivePathParams || !this.mnemonic) return this.currentKeypair;
|
|
10115
|
+
return getKeyPair(this.mnemonic, derivePathParams);
|
|
10116
|
+
}
|
|
10117
|
+
/**
|
|
10118
|
+
* Switch the current account with the given derivePathParams.
|
|
10119
|
+
* This is only useful when the mnemonic is provided. For secretKey mode, it will always use the same account.
|
|
10120
|
+
*/
|
|
10121
|
+
switchAccount(derivePathParams) {
|
|
10122
|
+
if (this.mnemonic) {
|
|
10123
|
+
this.currentKeypair = getKeyPair(this.mnemonic, derivePathParams);
|
|
10124
|
+
this.currentPubkey = this.currentKeypair.getPublicKey();
|
|
10125
|
+
}
|
|
10126
|
+
}
|
|
10127
|
+
};
|
|
10128
|
+
|
|
10129
|
+
// src/voter.ts
|
|
10130
|
+
var import_poseidon_cipher3 = require("@zk-kit/poseidon-cipher");
|
|
10131
|
+
var VoterClient = class _VoterClient {
|
|
10132
|
+
/**
|
|
10133
|
+
* @constructor
|
|
10134
|
+
* @param {VoterClientParams} params - The parameters for the Maci Voter Client instance.
|
|
10135
|
+
*/
|
|
10136
|
+
constructor({
|
|
10137
|
+
network,
|
|
10138
|
+
mnemonic,
|
|
10139
|
+
secretKey,
|
|
10140
|
+
apiEndpoint,
|
|
10141
|
+
restEndpoint,
|
|
10142
|
+
saasApiEndpoint,
|
|
10143
|
+
saasApiKey,
|
|
10144
|
+
registryAddress,
|
|
10145
|
+
customFetch,
|
|
10146
|
+
defaultOptions
|
|
10147
|
+
}) {
|
|
10148
|
+
this.network = network;
|
|
10149
|
+
this.accountManager = new MaciAccount({ mnemonic, secretKey });
|
|
10150
|
+
const defaultParams = getDefaultParams(network);
|
|
10151
|
+
this.restEndpoint = restEndpoint || defaultParams.restEndpoint;
|
|
10152
|
+
this.apiEndpoint = apiEndpoint || defaultParams.apiEndpoint;
|
|
10153
|
+
this.saasApiEndpoint = saasApiEndpoint || defaultParams.saasApiEndpoint;
|
|
10154
|
+
this.registryAddress = registryAddress || defaultParams.registryAddress;
|
|
10155
|
+
this.http = new Http(this.apiEndpoint, this.restEndpoint, customFetch, defaultOptions);
|
|
10156
|
+
this.indexer = new Indexer({
|
|
10157
|
+
restEndpoint: this.restEndpoint,
|
|
10158
|
+
apiEndpoint: this.apiEndpoint,
|
|
10159
|
+
// Indexer GraphQL API
|
|
10160
|
+
registryAddress: this.registryAddress,
|
|
10161
|
+
http: this.http
|
|
10162
|
+
});
|
|
10163
|
+
this.saasApiClient = new MaciApiClient({
|
|
10164
|
+
baseUrl: this.saasApiEndpoint,
|
|
10165
|
+
apiKey: saasApiKey,
|
|
10166
|
+
customFetch
|
|
10167
|
+
});
|
|
10168
|
+
}
|
|
10169
|
+
/**
|
|
10170
|
+
* Set SaaS API key for MaciApiClient
|
|
10171
|
+
*/
|
|
10172
|
+
setSaasApiKey(apiKey) {
|
|
10173
|
+
if (!this.saasApiClient) {
|
|
10174
|
+
throw new Error(
|
|
10175
|
+
"SaaS API client not initialized. Please provide saasApiEndpoint in constructor."
|
|
10176
|
+
);
|
|
10177
|
+
}
|
|
10178
|
+
this.saasApiClient.setApiKey(apiKey);
|
|
10179
|
+
}
|
|
10180
|
+
/**
|
|
10181
|
+
* Get SaaS API client instance
|
|
10182
|
+
*/
|
|
10183
|
+
getSaasApiClient() {
|
|
10184
|
+
if (!this.saasApiClient) {
|
|
10185
|
+
throw new Error(
|
|
10186
|
+
"SaaS API client not initialized. Please provide saasApiEndpoint in constructor."
|
|
10187
|
+
);
|
|
10188
|
+
}
|
|
10189
|
+
return this.saasApiClient;
|
|
10190
|
+
}
|
|
10191
|
+
/**
|
|
10192
|
+
* else:
|
|
10193
|
+
* it will generate signer from the mnemonic with the given derivePathParams.
|
|
10194
|
+
* @param derivePathParams, such as { accountIndex: 2, isExternal: false, addressIndex: 10 }, comply with the BIP44 standard
|
|
10195
|
+
*/
|
|
10196
|
+
getSigner(derivePathParams) {
|
|
10197
|
+
return this.accountManager.getKeyPair(derivePathParams);
|
|
10198
|
+
}
|
|
10199
|
+
packMaciPubkey(pubkey) {
|
|
10200
|
+
return packPubKey(pubkey || this.accountManager.currentPubkey.toPoints());
|
|
10201
|
+
}
|
|
10202
|
+
unpackMaciPubkey(pubkey) {
|
|
10203
|
+
return unpackPubKey(BigInt(pubkey));
|
|
10204
|
+
}
|
|
10205
|
+
getPubkey(derivePathParams) {
|
|
10206
|
+
return this.accountManager.getKeyPair(derivePathParams).getPublicKey();
|
|
10207
|
+
}
|
|
10208
|
+
buildVotePayload({
|
|
10209
|
+
stateIdx,
|
|
10210
|
+
operatorPubkey,
|
|
10211
|
+
selectedOptions,
|
|
10212
|
+
derivePathParams
|
|
10213
|
+
}) {
|
|
10214
|
+
const idxSet = /* @__PURE__ */ new Set();
|
|
10215
|
+
for (const option of selectedOptions) {
|
|
10216
|
+
if (idxSet.has(option.idx)) {
|
|
10217
|
+
throw new Error(`Duplicate option index (${option.idx}) is not allowed`);
|
|
10218
|
+
}
|
|
10219
|
+
idxSet.add(option.idx);
|
|
10220
|
+
}
|
|
10221
|
+
const options = selectedOptions.filter((o) => !!o.vc).sort((a, b) => a.idx - b.idx);
|
|
10222
|
+
const plan = options.map((o) => {
|
|
10223
|
+
return [o.idx, o.vc];
|
|
10224
|
+
});
|
|
10225
|
+
const payload = this.batchGenMessage(stateIdx, operatorPubkey, plan, derivePathParams);
|
|
10226
|
+
return stringizing(payload);
|
|
10227
|
+
}
|
|
10228
|
+
batchGenMessage(stateIdx, operatorPubkey, plan, derivePathParams) {
|
|
10229
|
+
const genMessage = this.genMessageFactory(stateIdx, operatorPubkey, derivePathParams);
|
|
10230
|
+
const payload = [];
|
|
10231
|
+
for (let i = plan.length - 1; i >= 0; i--) {
|
|
10232
|
+
const p = plan[i];
|
|
10233
|
+
const encAccount = genKeypair();
|
|
10234
|
+
const msg = genMessage(BigInt(encAccount.privKey), i + 1, p[0], p[1], i === plan.length - 1);
|
|
10235
|
+
payload.push({
|
|
10236
|
+
msg,
|
|
10237
|
+
encPubkeys: encAccount.pubKey
|
|
10238
|
+
});
|
|
10239
|
+
}
|
|
10240
|
+
return payload;
|
|
10241
|
+
}
|
|
10242
|
+
genMessageFactory(stateIdx, operatorPubkey, derivePathParams) {
|
|
10243
|
+
return (encPriKey, nonce, voIdx, newVotes, isLastCmd, salt) => {
|
|
10244
|
+
if (!salt) {
|
|
10245
|
+
salt = BigInt(`0x${import_crypto_js3.default.lib.WordArray.random(7).toString(import_crypto_js3.default.enc.Hex)}`);
|
|
10246
|
+
}
|
|
10247
|
+
const packaged = BigInt(nonce) + (BigInt(stateIdx) << 32n) + (BigInt(voIdx) << 64n) + (BigInt(newVotes) << 96n) + (BigInt(salt) << 192n);
|
|
10248
|
+
const signer = this.getSigner(derivePathParams);
|
|
10249
|
+
let newPubKey = [...signer.getPublicKey().toPoints()];
|
|
10250
|
+
if (isLastCmd) {
|
|
10251
|
+
newPubKey = [0n, 0n];
|
|
10252
|
+
}
|
|
10253
|
+
const hash = poseidon([packaged, ...newPubKey]);
|
|
10254
|
+
const signature = signer.sign(hash);
|
|
10255
|
+
const command = [packaged, ...newPubKey, ...signature.R8, signature.S];
|
|
10256
|
+
const coordPubkey = this.unpackMaciPubkey(operatorPubkey);
|
|
10257
|
+
const message = (0, import_poseidon_cipher3.poseidonEncrypt)(command, genEcdhSharedKey(encPriKey, coordPubkey), 0n);
|
|
10258
|
+
return message;
|
|
10259
|
+
};
|
|
10260
|
+
}
|
|
10261
|
+
async getStateIdxByPubKey({
|
|
10262
|
+
contractAddress,
|
|
10263
|
+
pubKey
|
|
10264
|
+
}) {
|
|
10265
|
+
const response = await this.indexer.getSignUpEventByPubKey(contractAddress, pubKey);
|
|
10266
|
+
if (isErrorResponse(response)) {
|
|
10267
|
+
return -1;
|
|
10268
|
+
}
|
|
10269
|
+
return response.data.signUpEvents[0].stateIdx;
|
|
10270
|
+
}
|
|
10271
|
+
async buildAddNewKeyPayload({
|
|
10272
|
+
stateTreeDepth,
|
|
10273
|
+
operatorPubkey,
|
|
10274
|
+
deactivates,
|
|
10275
|
+
wasmFile,
|
|
10276
|
+
zkeyFile,
|
|
10277
|
+
derivePathParams
|
|
10278
|
+
}) {
|
|
10279
|
+
const [coordPubkeyX, coordPubkeyY] = this.unpackMaciPubkey(operatorPubkey);
|
|
10280
|
+
const addKeyInput = await this.genAddKeyInput(stateTreeDepth + 2, {
|
|
10281
|
+
coordPubKey: [coordPubkeyX, coordPubkeyY],
|
|
10282
|
+
deactivates: deactivates.map((d) => d.map(BigInt)),
|
|
10283
|
+
derivePathParams
|
|
10284
|
+
});
|
|
10285
|
+
if (addKeyInput === null) {
|
|
10286
|
+
throw Error("genAddKeyInput failed");
|
|
10287
|
+
}
|
|
10288
|
+
const { proof } = await import_snarkjs.groth16.fullProve(addKeyInput, wasmFile, zkeyFile);
|
|
10289
|
+
const proofHex = await adaptToUncompressed(proof);
|
|
10290
|
+
return {
|
|
10291
|
+
proof: proofHex,
|
|
10292
|
+
d: [
|
|
10293
|
+
addKeyInput.d1[0].toString(),
|
|
10294
|
+
addKeyInput.d1[1].toString(),
|
|
10295
|
+
addKeyInput.d2[0].toString(),
|
|
10296
|
+
addKeyInput.d2[1].toString()
|
|
10297
|
+
],
|
|
10298
|
+
nullifier: addKeyInput.nullifier.toString()
|
|
10299
|
+
};
|
|
10300
|
+
}
|
|
10301
|
+
async buildPreAddNewKeyPayload({
|
|
10302
|
+
stateTreeDepth,
|
|
10303
|
+
coordinatorPubkey,
|
|
10304
|
+
deactivates,
|
|
10305
|
+
wasmFile,
|
|
10306
|
+
zkeyFile,
|
|
10307
|
+
derivePathParams
|
|
10308
|
+
}) {
|
|
10309
|
+
const [coordPubkeyX, coordPubkeyY] = this.unpackMaciPubkey(coordinatorPubkey);
|
|
10310
|
+
const addKeyInput = await this.genPreAddKeyInput(stateTreeDepth + 2, {
|
|
10311
|
+
coordPubKey: [coordPubkeyX, coordPubkeyY],
|
|
10312
|
+
deactivates: deactivates.map((d) => d.map(BigInt)),
|
|
10313
|
+
derivePathParams
|
|
10314
|
+
});
|
|
10315
|
+
if (addKeyInput === null) {
|
|
10316
|
+
throw Error("genPreAddKeyInput failed, cannot find deactivate idx");
|
|
10317
|
+
}
|
|
10318
|
+
const { proof } = await import_snarkjs.groth16.fullProve(addKeyInput, wasmFile, zkeyFile);
|
|
10319
|
+
const proofHex = await adaptToUncompressed(proof);
|
|
10320
|
+
return {
|
|
10321
|
+
proof: proofHex,
|
|
10322
|
+
d: [
|
|
10323
|
+
addKeyInput.d1[0].toString(),
|
|
10324
|
+
addKeyInput.d1[1].toString(),
|
|
10325
|
+
addKeyInput.d2[0].toString(),
|
|
10326
|
+
addKeyInput.d2[1].toString()
|
|
10327
|
+
],
|
|
10328
|
+
nullifier: addKeyInput.nullifier.toString()
|
|
10329
|
+
};
|
|
10330
|
+
}
|
|
10331
|
+
async genAddKeyInput(depth, {
|
|
10332
|
+
coordPubKey,
|
|
10333
|
+
deactivates,
|
|
10334
|
+
derivePathParams
|
|
10335
|
+
}) {
|
|
10336
|
+
const signer = this.getSigner(derivePathParams);
|
|
10337
|
+
const sharedKeyHash = poseidon(signer.genEcdhSharedKey(coordPubKey));
|
|
10338
|
+
const randomVal = genRandomSalt();
|
|
10339
|
+
const deactivateIdx = deactivates.findIndex((d) => d[4] === sharedKeyHash);
|
|
10340
|
+
if (deactivateIdx < 0) {
|
|
10341
|
+
return null;
|
|
10342
|
+
}
|
|
10343
|
+
const deactivateLeaf = deactivates[deactivateIdx];
|
|
10344
|
+
const c1 = [deactivateLeaf[0], deactivateLeaf[1]];
|
|
10345
|
+
const c2 = [deactivateLeaf[2], deactivateLeaf[3]];
|
|
10346
|
+
const { d1, d2 } = rerandomize(coordPubKey, { c1, c2 }, randomVal);
|
|
10347
|
+
const nullifier = poseidon([signer.getFormatedPrivKey(), 1444992409218394441042n]);
|
|
10348
|
+
const tree = new Tree(5, depth, 0n);
|
|
10349
|
+
const leaves = deactivates.map((d) => poseidon(d));
|
|
10350
|
+
tree.initLeaves(leaves);
|
|
10351
|
+
const deactivateRoot = tree.root;
|
|
10352
|
+
const deactivateLeafPathElements = tree.pathElementOf(deactivateIdx);
|
|
10353
|
+
const inputHash = BigInt(
|
|
10354
|
+
(0, import_ethers4.solidityPackedSha256)(
|
|
10355
|
+
new Array(7).fill("uint256"),
|
|
10356
|
+
stringizing([
|
|
10357
|
+
deactivateRoot,
|
|
10358
|
+
poseidon(coordPubKey),
|
|
10359
|
+
nullifier,
|
|
10360
|
+
d1[0],
|
|
10361
|
+
d1[1],
|
|
10362
|
+
d2[0],
|
|
10363
|
+
d2[1]
|
|
10364
|
+
])
|
|
10365
|
+
)
|
|
10366
|
+
) % SNARK_FIELD_SIZE;
|
|
10367
|
+
const input = {
|
|
10368
|
+
inputHash,
|
|
10369
|
+
coordPubKey,
|
|
10370
|
+
deactivateRoot,
|
|
10371
|
+
deactivateIndex: deactivateIdx,
|
|
10372
|
+
deactivateLeaf: poseidon(deactivateLeaf),
|
|
10373
|
+
c1,
|
|
10374
|
+
c2,
|
|
10375
|
+
randomVal,
|
|
10376
|
+
d1,
|
|
10377
|
+
d2,
|
|
10378
|
+
deactivateLeafPathElements,
|
|
10379
|
+
nullifier,
|
|
10380
|
+
oldPrivateKey: signer.getFormatedPrivKey()
|
|
10381
|
+
};
|
|
10382
|
+
return input;
|
|
10383
|
+
}
|
|
10384
|
+
async genPreAddKeyInput(depth, {
|
|
10385
|
+
coordPubKey,
|
|
10386
|
+
deactivates,
|
|
10387
|
+
derivePathParams
|
|
10388
|
+
}) {
|
|
10389
|
+
const signer = this.getSigner(derivePathParams);
|
|
10390
|
+
const sharedKeyHash = poseidon(signer.genEcdhSharedKey(coordPubKey));
|
|
10391
|
+
const randomVal = genRandomSalt();
|
|
10392
|
+
const deactivateIdx = deactivates.findIndex((d) => d[4] === sharedKeyHash);
|
|
10393
|
+
if (deactivateIdx < 0) {
|
|
10394
|
+
return null;
|
|
10395
|
+
}
|
|
10396
|
+
const deactivateLeaf = deactivates[deactivateIdx];
|
|
10397
|
+
const c1 = [deactivateLeaf[0], deactivateLeaf[1]];
|
|
10398
|
+
const c2 = [deactivateLeaf[2], deactivateLeaf[3]];
|
|
10399
|
+
const { d1, d2 } = rerandomize(coordPubKey, { c1, c2 }, randomVal);
|
|
10400
|
+
const nullifier = poseidon([signer.getFormatedPrivKey(), 1444992409218394441042n]);
|
|
10401
|
+
const tree = new Tree(5, depth, 0n);
|
|
10402
|
+
const leaves = deactivates.map((d) => poseidon(d));
|
|
10403
|
+
tree.initLeaves(leaves);
|
|
10404
|
+
const deactivateRoot = tree.root;
|
|
10405
|
+
const deactivateLeafPathElements = tree.pathElementOf(deactivateIdx);
|
|
10406
|
+
const inputHash = BigInt(
|
|
10407
|
+
(0, import_ethers4.solidityPackedSha256)(
|
|
10408
|
+
new Array(7).fill("uint256"),
|
|
10409
|
+
stringizing([
|
|
10410
|
+
deactivateRoot,
|
|
10411
|
+
poseidon(coordPubKey),
|
|
10412
|
+
nullifier,
|
|
10413
|
+
d1[0],
|
|
10414
|
+
d1[1],
|
|
10415
|
+
d2[0],
|
|
10416
|
+
d2[1]
|
|
10417
|
+
])
|
|
10418
|
+
)
|
|
10419
|
+
) % SNARK_FIELD_SIZE;
|
|
10420
|
+
const input = {
|
|
10421
|
+
inputHash,
|
|
10422
|
+
coordPubKey,
|
|
10423
|
+
deactivateRoot,
|
|
10424
|
+
deactivateIndex: deactivateIdx,
|
|
10425
|
+
deactivateLeaf: poseidon(deactivateLeaf),
|
|
10426
|
+
c1,
|
|
10427
|
+
c2,
|
|
10428
|
+
randomVal,
|
|
10429
|
+
d1,
|
|
10430
|
+
d2,
|
|
10431
|
+
deactivateLeafPathElements,
|
|
10432
|
+
nullifier,
|
|
10433
|
+
oldPrivateKey: signer.getFormatedPrivKey()
|
|
10434
|
+
};
|
|
10435
|
+
return input;
|
|
10436
|
+
}
|
|
10437
|
+
async buildDeactivatePayload({
|
|
10438
|
+
stateIdx,
|
|
10439
|
+
operatorPubkey,
|
|
10440
|
+
derivePathParams
|
|
10441
|
+
}) {
|
|
10442
|
+
const payload = this.batchGenMessage(stateIdx, operatorPubkey, [[0, 0]], derivePathParams);
|
|
10443
|
+
return stringizing(payload[0]);
|
|
10444
|
+
}
|
|
10445
|
+
// ==================== SaaS API Client Methods ====================
|
|
10446
|
+
/**
|
|
10447
|
+
* Get pre-deactivate data via SaaS API
|
|
10448
|
+
* @param contractAddress - Contract address
|
|
10449
|
+
*/
|
|
10450
|
+
async saasGetPreDeactivate(contractAddress) {
|
|
10451
|
+
if (!this.saasApiClient) {
|
|
10452
|
+
throw new Error("SaaS API client not initialized");
|
|
10453
|
+
}
|
|
10454
|
+
return await this.saasApiClient.getPreDeactivate({ contractAddress });
|
|
10455
|
+
}
|
|
10456
|
+
/**
|
|
10457
|
+
* Pre add new key via SaaS API
|
|
10458
|
+
* @param params - Pre add new key parameters
|
|
10459
|
+
*/
|
|
10460
|
+
async saasSubmitPreAddNewKey(params) {
|
|
10461
|
+
if (!this.saasApiClient) {
|
|
10462
|
+
throw new Error("SaaS API client not initialized");
|
|
10463
|
+
}
|
|
10464
|
+
return await this.saasApiClient.preAddNewKey(params);
|
|
10465
|
+
}
|
|
10466
|
+
/**
|
|
10467
|
+
* Vote via SaaS API
|
|
10468
|
+
* @param params - Vote parameters
|
|
10469
|
+
*/
|
|
10470
|
+
async saasSubmitVote(params) {
|
|
10471
|
+
if (!this.saasApiClient) {
|
|
10472
|
+
throw new Error("SaaS API client not initialized");
|
|
10473
|
+
}
|
|
10474
|
+
return await this.saasApiClient.vote(params);
|
|
10475
|
+
}
|
|
10476
|
+
// ==================== Maci Voter Methods ====================
|
|
10477
|
+
async saasPreCreateNewAccount({
|
|
10478
|
+
contractAddress,
|
|
10479
|
+
stateTreeDepth,
|
|
10480
|
+
coordinatorPubkey,
|
|
10481
|
+
deactivates,
|
|
10482
|
+
wasmFile,
|
|
10483
|
+
zkeyFile,
|
|
10484
|
+
derivePathParams
|
|
10485
|
+
}) {
|
|
10486
|
+
const addNewKeyPayload = await this.buildPreAddNewKeyPayload({
|
|
10487
|
+
stateTreeDepth,
|
|
10488
|
+
coordinatorPubkey,
|
|
10489
|
+
deactivates,
|
|
10490
|
+
wasmFile,
|
|
10491
|
+
zkeyFile,
|
|
10492
|
+
derivePathParams
|
|
10493
|
+
});
|
|
10494
|
+
const newVoterClient = new _VoterClient({
|
|
10495
|
+
network: this.network,
|
|
10496
|
+
restEndpoint: this.restEndpoint,
|
|
10497
|
+
apiEndpoint: this.apiEndpoint,
|
|
10498
|
+
saasApiEndpoint: this.saasApiEndpoint,
|
|
10499
|
+
registryAddress: this.registryAddress
|
|
10500
|
+
});
|
|
10501
|
+
const addNewKeyResult = await newVoterClient.saasSubmitPreAddNewKey({
|
|
10502
|
+
contractAddress,
|
|
10503
|
+
proof: addNewKeyPayload.proof,
|
|
10504
|
+
d: addNewKeyPayload.d,
|
|
10505
|
+
nullifier: addNewKeyPayload.nullifier,
|
|
10506
|
+
newPubkey: newVoterClient.getPubkey().toPoints().map((p) => p.toString())
|
|
10507
|
+
});
|
|
10508
|
+
return {
|
|
10509
|
+
result: addNewKeyResult,
|
|
10510
|
+
account: newVoterClient
|
|
10511
|
+
};
|
|
10512
|
+
}
|
|
10513
|
+
async saasVote({
|
|
10514
|
+
contractAddress,
|
|
10515
|
+
// stateIdx,
|
|
10516
|
+
operatorPubkey,
|
|
10517
|
+
selectedOptions,
|
|
10518
|
+
derivePathParams
|
|
10519
|
+
}) {
|
|
10520
|
+
const stateIdx = await this.getStateIdxByPubKey({
|
|
10521
|
+
contractAddress,
|
|
10522
|
+
pubKey: this.getPubkey(derivePathParams).toPoints()
|
|
10523
|
+
});
|
|
10524
|
+
if (stateIdx === -1) {
|
|
10525
|
+
throw new Error("State index is not set, Please signup or addNewKey first");
|
|
10526
|
+
}
|
|
10527
|
+
const payload = this.buildVotePayload({
|
|
10528
|
+
stateIdx,
|
|
10529
|
+
operatorPubkey,
|
|
10530
|
+
selectedOptions,
|
|
10531
|
+
derivePathParams
|
|
10532
|
+
});
|
|
10533
|
+
const voteResult = await this.saasSubmitVote({
|
|
10534
|
+
contractAddress,
|
|
10535
|
+
payload
|
|
10536
|
+
});
|
|
10537
|
+
return voteResult;
|
|
10538
|
+
}
|
|
9144
10539
|
};
|
|
9145
10540
|
// Annotate the CommonJS export names for ESM import in node:
|
|
9146
10541
|
0 && (module.exports = {
|
|
9147
10542
|
Circuit,
|
|
10543
|
+
EdDSAPoseidonKeypair,
|
|
10544
|
+
EdDSAPoseidonPublicKey,
|
|
9148
10545
|
G1Point,
|
|
9149
10546
|
G2Point,
|
|
9150
10547
|
Http,
|
|
10548
|
+
MaciApiClient,
|
|
9151
10549
|
MaciCertSystemType,
|
|
9152
10550
|
MaciCircuitType,
|
|
9153
10551
|
MaciClient,
|
|
@@ -9161,12 +10559,23 @@ var MaciClient2 = class {
|
|
|
9161
10559
|
Transaction,
|
|
9162
10560
|
Tree,
|
|
9163
10561
|
UserAccount,
|
|
10562
|
+
VoterClient,
|
|
10563
|
+
adaptToUncompressed,
|
|
10564
|
+
addressToUint256,
|
|
9164
10565
|
batchGenMessage,
|
|
9165
10566
|
bigInt2Buffer,
|
|
10567
|
+
bigintToHex,
|
|
9166
10568
|
buffer2Bigint,
|
|
9167
10569
|
circuits,
|
|
10570
|
+
compressPublicKey,
|
|
10571
|
+
decompressPublicKey,
|
|
9168
10572
|
destringizing,
|
|
10573
|
+
encryptOdevity,
|
|
9169
10574
|
formatPrivKeyForBabyJub,
|
|
10575
|
+
fromB64,
|
|
10576
|
+
fromBase64,
|
|
10577
|
+
fromHEX,
|
|
10578
|
+
fromHex,
|
|
9170
10579
|
genAddKeyInput,
|
|
9171
10580
|
genEcdhSharedKey,
|
|
9172
10581
|
genKeypair,
|
|
@@ -9179,6 +10588,9 @@ var MaciClient2 = class {
|
|
|
9179
10588
|
genRandomKey,
|
|
9180
10589
|
genRandomSalt,
|
|
9181
10590
|
getAMaciRoundCircuitFee,
|
|
10591
|
+
getCurveFromName,
|
|
10592
|
+
getCurveFromQ,
|
|
10593
|
+
getCurveFromR,
|
|
9182
10594
|
getDefaultParams,
|
|
9183
10595
|
hash12,
|
|
9184
10596
|
hash2,
|
|
@@ -9189,6 +10601,8 @@ var MaciClient2 = class {
|
|
|
9189
10601
|
hashLeftRight,
|
|
9190
10602
|
hashN,
|
|
9191
10603
|
hashOne,
|
|
10604
|
+
hexToBigInt,
|
|
10605
|
+
hexToDecimalString,
|
|
9192
10606
|
isValidAddress,
|
|
9193
10607
|
packPubKey,
|
|
9194
10608
|
poseidon,
|
|
@@ -9197,9 +10611,15 @@ var MaciClient2 = class {
|
|
|
9197
10611
|
poseidonT5,
|
|
9198
10612
|
poseidonT6,
|
|
9199
10613
|
privateKeyFromTxt,
|
|
10614
|
+
rerandomize,
|
|
9200
10615
|
sha256Hash,
|
|
9201
10616
|
signMessage,
|
|
9202
10617
|
stringizing,
|
|
10618
|
+
toB64,
|
|
10619
|
+
toBase64,
|
|
10620
|
+
toHEX,
|
|
10621
|
+
toHex,
|
|
10622
|
+
transformPubkey,
|
|
9203
10623
|
unpackPubKey
|
|
9204
10624
|
});
|
|
9205
10625
|
//# sourceMappingURL=index.js.map
|