@dorafactory/maci-sdk 0.0.6 → 0.0.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.mjs CHANGED
@@ -232,7 +232,7 @@ var ERROR = {
232
232
  };
233
233
 
234
234
  // src/libs/query/account.ts
235
- var Account = class {
235
+ var UserAccount = class {
236
236
  constructor(http) {
237
237
  this.http = http;
238
238
  }
@@ -1438,7 +1438,7 @@ var Indexer = class {
1438
1438
  this.apiEndpoint = apiEndpoint;
1439
1439
  this.registryAddress = registryAddress;
1440
1440
  this.round = new Round(this.http);
1441
- this.account = new Account(this.http);
1441
+ this.account = new UserAccount(this.http);
1442
1442
  this.circuit = new Circuit(this.http);
1443
1443
  this.operator = new Operator(this.http, this.registryAddress);
1444
1444
  this.proof = new Proof(this.http);
@@ -3671,10 +3671,17 @@ function getContractParams(type, circuitType, proofSystem, maxVoter, maxOption)
3671
3671
  // plonkTallyVkey,
3672
3672
  };
3673
3673
  case "2" /* ORACLE_MACI */:
3674
+ if (circuitType === "0" /* IP1V */) {
3675
+ groth16ProcessVkey = CIRCUIT_INFO["9-4-3-625"]["groth16"].process_1p1v_vkey;
3676
+ groth16TallyVkey = CIRCUIT_INFO["9-4-3-625"]["groth16"].tally_1p1v_vkey;
3677
+ } else if (circuitType === "1" /* QV */) {
3678
+ groth16ProcessVkey = CIRCUIT_INFO["9-4-3-625"]["groth16"].process_qv_vkey;
3679
+ groth16TallyVkey = CIRCUIT_INFO["9-4-3-625"]["groth16"].tally_qv_vkey;
3680
+ }
3674
3681
  return {
3675
3682
  parameters: CIRCUIT_INFO["9-4-3-625"].parameter,
3676
- groth16ProcessVkey: CIRCUIT_INFO["9-4-3-625"]["groth16"].process_vkey,
3677
- groth16TallyVkey: CIRCUIT_INFO["9-4-3-625"]["groth16"].tally_vkey,
3683
+ groth16ProcessVkey,
3684
+ groth16TallyVkey,
3678
3685
  plonkProcessVkey: null,
3679
3686
  plonkTallyVkey: null,
3680
3687
  maciVoteType,
@@ -3940,6 +3947,272 @@ var Contract = class {
3940
3947
  contractAddress
3941
3948
  });
3942
3949
  }
3950
+ async contractClient({ signer }) {
3951
+ return createContractClientByWallet(this.rpcEndpoint, signer);
3952
+ }
3953
+ };
3954
+
3955
+ // src/libs/circom/index.ts
3956
+ import {
3957
+ isOfflineDirectSigner
3958
+ } from "@cosmjs/proto-signing";
3959
+
3960
+ // src/libs/circom/circomlib.ts
3961
+ import { randomBytes } from "crypto";
3962
+ import {
3963
+ babyJub,
3964
+ eddsa,
3965
+ poseidon,
3966
+ poseidonEncrypt,
3967
+ Tree
3968
+ } from "@dorafactory/circomlib";
3969
+ import { Scalar, utils } from "ffjavascript";
3970
+ import createBlakeHash from "blake-hash";
3971
+ import { solidityPackedSha256 } from "ethers";
3972
+ var SNARK_FIELD_SIZE = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
3973
+ var bigInt2Buffer = (i) => {
3974
+ let hex = i.toString(16);
3975
+ if (hex.length % 2 === 1) {
3976
+ hex = "0" + hex;
3977
+ }
3978
+ return Buffer.from(hex, "hex");
3979
+ };
3980
+ var genRandomKey = () => {
3981
+ const min = 6350874878119819312338956282401532410528162663560392320966563075034087161851n;
3982
+ let rand;
3983
+ while (true) {
3984
+ rand = BigInt("0x" + randomBytes(32).toString("hex"));
3985
+ if (rand >= min) {
3986
+ break;
3987
+ }
3988
+ }
3989
+ const privKey = rand % SNARK_FIELD_SIZE;
3990
+ return privKey;
3991
+ };
3992
+ var genPubKey = (privKey) => {
3993
+ return eddsa.prv2pub(bigInt2Buffer(privKey));
3994
+ };
3995
+ var stringizing = (o, path = []) => {
3996
+ if (path.includes(o)) {
3997
+ throw new Error("loop nesting!");
3998
+ }
3999
+ const newPath = [...path, o];
4000
+ if (Array.isArray(o)) {
4001
+ return o.map((item) => stringizing(item, newPath));
4002
+ } else if (typeof o === "object") {
4003
+ const output = {};
4004
+ for (const key in o) {
4005
+ output[key] = stringizing(o[key], newPath);
4006
+ }
4007
+ return output;
4008
+ } else {
4009
+ return o.toString();
4010
+ }
4011
+ };
4012
+ var genKeypair = (pkey) => {
4013
+ const privKey = pkey ? pkey % SNARK_FIELD_SIZE : genRandomKey();
4014
+ const pubKey = genPubKey(privKey);
4015
+ const formatedPrivKey = formatPrivKeyForBabyJub(privKey);
4016
+ return { privKey, pubKey, formatedPrivKey };
4017
+ };
4018
+ var formatPrivKeyForBabyJub = (privKey) => {
4019
+ const sBuff = eddsa.pruneBuffer(
4020
+ createBlakeHash("blake512").update(bigInt2Buffer(privKey)).digest().slice(0, 32)
4021
+ );
4022
+ const s = utils.leBuff2int(sBuff);
4023
+ return Scalar.shr(s, 3);
4024
+ };
4025
+ var genEcdhSharedKey = (privKey, pubKey) => {
4026
+ const sharedKey = babyJub.mulPointEscalar(
4027
+ pubKey,
4028
+ formatPrivKeyForBabyJub(privKey)
4029
+ );
4030
+ if (sharedKey[0] === 0n) {
4031
+ return [0n, 1n];
4032
+ } else {
4033
+ return sharedKey;
4034
+ }
4035
+ };
4036
+ var genMessageFactory = (stateIdx, signPriKey, signPubKey, coordPubKey) => (encPriKey, nonce, voIdx, newVotes, isLastCmd, salt) => {
4037
+ if (!salt) {
4038
+ salt = BigInt("0x" + randomBytes(7).toString("hex"));
4039
+ }
4040
+ const packaged = BigInt(nonce) + (BigInt(stateIdx) << 32n) + (BigInt(voIdx) << 64n) + (BigInt(newVotes) << 96n) + (BigInt(salt) << 192n);
4041
+ let newPubKey = [...signPubKey];
4042
+ if (isLastCmd) {
4043
+ newPubKey = [0n, 0n];
4044
+ }
4045
+ const hash = poseidon([packaged, ...newPubKey]);
4046
+ const signature = eddsa.signPoseidon(bigInt2Buffer(signPriKey), hash);
4047
+ const command = [packaged, ...newPubKey, ...signature.R8, signature.S];
4048
+ const message = poseidonEncrypt(
4049
+ command,
4050
+ genEcdhSharedKey(encPriKey, coordPubKey),
4051
+ 0n
4052
+ );
4053
+ return message;
4054
+ };
4055
+ var batchGenMessage = (stateIdx, account, coordPubKey, plan) => {
4056
+ const genMessage = genMessageFactory(
4057
+ stateIdx,
4058
+ account.privKey,
4059
+ account.pubKey,
4060
+ coordPubKey
4061
+ );
4062
+ const payload = [];
4063
+ for (let i = plan.length - 1; i >= 0; i--) {
4064
+ const p = plan[i];
4065
+ const encAccount = genKeypair();
4066
+ const msg = genMessage(
4067
+ encAccount.privKey,
4068
+ i + 1,
4069
+ p[0],
4070
+ p[1],
4071
+ i === plan.length - 1
4072
+ );
4073
+ payload.push({
4074
+ msg,
4075
+ encPubkeys: encAccount.pubKey
4076
+ });
4077
+ }
4078
+ return payload;
4079
+ };
4080
+ var privateKeyFromTxt = (txt) => {
4081
+ if (typeof txt !== "string") {
4082
+ return;
4083
+ }
4084
+ const key = txt.split("\n")[1] || "";
4085
+ if (key.length !== 512) {
4086
+ return;
4087
+ }
4088
+ const keys = key.match(/[0-9a-f]{128}/g);
4089
+ if (!keys || keys.length !== 4) {
4090
+ return;
4091
+ }
4092
+ const priKey = poseidon(keys.map((k) => BigInt("0x" + k)));
4093
+ return genKeypair(priKey % SNARK_FIELD_SIZE);
4094
+ };
4095
+ var rerandomize = (pubKey, ciphertext, randomVal = genRandomKey()) => {
4096
+ const d1 = babyJub.addPoint(
4097
+ babyJub.mulPointEscalar(babyJub.Base8, randomVal),
4098
+ ciphertext.c1
4099
+ );
4100
+ const d2 = babyJub.addPoint(
4101
+ babyJub.mulPointEscalar(pubKey, randomVal),
4102
+ ciphertext.c2
4103
+ );
4104
+ return {
4105
+ d1,
4106
+ d2
4107
+ };
4108
+ };
4109
+ var genAddKeyProof = async (depth, {
4110
+ coordPubKey,
4111
+ oldKey,
4112
+ deactivates
4113
+ }) => {
4114
+ const sharedKeyHash = poseidon(genEcdhSharedKey(oldKey.privKey, coordPubKey));
4115
+ const randomVal = genRandomKey();
4116
+ const deactivateIdx = deactivates.findIndex((d) => d[4] === sharedKeyHash);
4117
+ if (deactivateIdx < 0) {
4118
+ return null;
4119
+ }
4120
+ const deactivateLeaf = deactivates[deactivateIdx];
4121
+ const c1 = [deactivateLeaf[0], deactivateLeaf[1]];
4122
+ const c2 = [deactivateLeaf[2], deactivateLeaf[3]];
4123
+ const { d1, d2 } = rerandomize(coordPubKey, { c1, c2 }, randomVal);
4124
+ const nullifier = poseidon([oldKey.formatedPrivKey, 1444992409218394441042n]);
4125
+ const tree = new Tree(5, depth, 0n);
4126
+ const leaves = deactivates.map((d) => poseidon(d));
4127
+ tree.initLeaves(leaves);
4128
+ const deactivateRoot = tree.root;
4129
+ const deactivateLeafPathElements = tree.pathElementOf(deactivateIdx);
4130
+ const inputHash = BigInt(
4131
+ solidityPackedSha256(
4132
+ new Array(7).fill("uint256"),
4133
+ stringizing([
4134
+ deactivateRoot,
4135
+ poseidon(coordPubKey),
4136
+ nullifier,
4137
+ d1[0],
4138
+ d1[1],
4139
+ d2[0],
4140
+ d2[1]
4141
+ ])
4142
+ )
4143
+ ) % SNARK_FIELD_SIZE;
4144
+ const input = {
4145
+ inputHash,
4146
+ coordPubKey,
4147
+ deactivateRoot,
4148
+ deactivateIndex: deactivateIdx,
4149
+ deactivateLeaf: poseidon(deactivateLeaf),
4150
+ c1,
4151
+ c2,
4152
+ randomVal,
4153
+ d1,
4154
+ d2,
4155
+ deactivateLeafPathElements,
4156
+ nullifier,
4157
+ oldPrivateKey: oldKey.formatedPrivKey
4158
+ };
4159
+ return input;
4160
+ };
4161
+
4162
+ // src/libs/circom/index.ts
4163
+ var Circom = class {
4164
+ constructor({ network }) {
4165
+ this.network = network;
4166
+ this.chainId = getDefaultParams(network).chainId;
4167
+ }
4168
+ async signMessage(signer, address, message) {
4169
+ const accounts = await signer.getAccounts();
4170
+ const account = accounts.find((acc) => acc.address === address);
4171
+ if (!account) {
4172
+ throw new Error(`Address ${address} not found in wallet`);
4173
+ }
4174
+ if (isOfflineDirectSigner(signer)) {
4175
+ const signDoc = {
4176
+ bodyBytes: new TextEncoder().encode(message),
4177
+ authInfoBytes: new Uint8Array(),
4178
+ chainId: this.chainId,
4179
+ accountNumber: BigInt(0)
4180
+ };
4181
+ const { signature } = await signer.signDirect(address, signDoc);
4182
+ return {
4183
+ signature: signature.signature,
4184
+ pubkey: account.pubkey
4185
+ };
4186
+ } else {
4187
+ const signDoc = {
4188
+ chain_id: this.chainId,
4189
+ account_number: "0",
4190
+ sequence: "0",
4191
+ fee: {
4192
+ gas: "0",
4193
+ amount: []
4194
+ },
4195
+ msgs: [],
4196
+ memo: message
4197
+ };
4198
+ const { signature } = await signer.signAmino(address, signDoc);
4199
+ return {
4200
+ signature: signature.signature,
4201
+ pubkey: account.pubkey
4202
+ };
4203
+ }
4204
+ }
4205
+ async genKeypairFromSign(signer, address) {
4206
+ const sig = await this.signMessage(
4207
+ signer,
4208
+ address,
4209
+ "Generate_MACI_Private_Key"
4210
+ );
4211
+ const sign = BigInt(
4212
+ "0x" + Buffer.from(sig.signature, "base64").toString("hex")
4213
+ );
4214
+ return genKeypair(sign);
4215
+ }
3943
4216
  };
3944
4217
 
3945
4218
  // src/maci.ts
@@ -3990,6 +4263,7 @@ var MaciClient2 = class {
3990
4263
  feegrantOperator: this.feegrantOperator,
3991
4264
  whitelistBackendPubkey: this.whitelistBackendPubkey
3992
4265
  });
4266
+ this.circom = new Circom({ network });
3993
4267
  }
3994
4268
  async oracleMaciClient({
3995
4269
  signer,
@@ -4168,8 +4442,12 @@ var MaciClient2 = class {
4168
4442
  return await this.indexer.proof.getProofByContractAddress(address);
4169
4443
  }
4170
4444
  };
4445
+
4446
+ // src/index.ts
4447
+ import { Scalar as Scalar2, utils as utils2 } from "ffjavascript";
4448
+ import { default as default2 } from "blake-hash";
4171
4449
  export {
4172
- Account,
4450
+ Circom,
4173
4451
  Circuit,
4174
4452
  Contract,
4175
4453
  Http,
@@ -4181,13 +4459,24 @@ export {
4181
4459
  Operator,
4182
4460
  Proof,
4183
4461
  Round,
4462
+ Scalar2 as Scalar,
4184
4463
  Transaction,
4464
+ UserAccount,
4465
+ batchGenMessage,
4185
4466
  circuits,
4186
4467
  compressPublicKey,
4468
+ default2 as createBlakeHash,
4187
4469
  decompressPublicKey,
4470
+ genAddKeyProof,
4471
+ genEcdhSharedKey,
4472
+ genKeypair,
4473
+ genMessageFactory,
4188
4474
  getDefaultParams,
4189
4475
  hexToDecimalString,
4190
4476
  isValidAddress,
4477
+ privateKeyFromTxt,
4478
+ stringizing,
4479
+ utils2 as utils,
4191
4480
  validator_operator_set
4192
4481
  };
4193
4482
  //# sourceMappingURL=index.mjs.map