@dorafactory/maci-sdk 0.0.19 → 0.0.21

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/browser.mjs CHANGED
@@ -25946,11 +25946,12 @@ var Http = class {
25946
25946
  );
25947
25947
  }
25948
25948
  }
25949
- async fetchRest(path) {
25949
+ async fetchRest(path, options) {
25950
25950
  try {
25951
25951
  const fetchFn = this.getFetch();
25952
25952
  const response = await fetchFn(`${this.restEndpoint}${path}`, {
25953
- ...this.defaultOptions
25953
+ ...this.defaultOptions,
25954
+ ...options
25954
25955
  });
25955
25956
  if (!response.ok) {
25956
25957
  throw new HttpError(
@@ -25988,6 +25989,8 @@ var ERROR = {
25988
25989
  ERROR_CIRCUIT_NOT_FOUND: "ERROR_CIRCUIT_NOT_FOUND",
25989
25990
  ERROR_OPERATOR_INVALID_ADDRESS: "ERROR_OPERATOR_INVALID_ADDRESS",
25990
25991
  ERROR_OPERATOR_NOT_FOUND: "ERROR_OPERATOR_NOT_FOUND",
25992
+ ERROR_OPERATOR_DELAY_HISTORY_NOT_FOUND: "ERROR_OPERATOR_DELAY_HISTORY_NOT_FOUND",
25993
+ ERROR_QUERY_MISS_RATE_FAILED: "ERROR_QUERY_MISS_RATE_FAILED",
25991
25994
  ERROR_OPERATORS_NOT_FOUND: "ERROR_OPERATORS_NOT_FOUND",
25992
25995
  ERROR_PROOF_NOT_FOUND: "ERROR_PROOF_NOT_FOUND",
25993
25996
  ERROR_ROUND_INVALID_ADDRESS: "ERROR_ROUND_INVALID_ADDRESS",
@@ -26422,6 +26425,64 @@ var Operator = class {
26422
26425
  return handleError(error);
26423
26426
  }
26424
26427
  }
26428
+ async getOperatorDelayOperationsByAddress(address, after, limit) {
26429
+ try {
26430
+ if (!isValidAddress(address)) {
26431
+ return {
26432
+ code: 400,
26433
+ error: {
26434
+ message: "Invalid operator address format",
26435
+ type: ERROR.ERROR_OPERATOR_INVALID_ADDRESS
26436
+ }
26437
+ };
26438
+ }
26439
+ const OPERATORS_QUERY = `query ($limit: Int, $after: Cursor) {
26440
+ operatorDelayOperations(first: $limit, after: $after, filter: {operatorAddress: {equalTo: "${address}"}}, orderBy: [TIMESTAMP_DESC]) {
26441
+ pageInfo {
26442
+ endCursor
26443
+ hasNextPage
26444
+ }
26445
+ totalCount
26446
+ edges {
26447
+ cursor
26448
+ node {
26449
+ blockHeight
26450
+ delayProcessDmsgCount
26451
+ delayDuration
26452
+ delayReason
26453
+ delayType
26454
+ id
26455
+ nodeId
26456
+ operatorAddress
26457
+ timestamp
26458
+ roundAddress
26459
+ }
26460
+ }
26461
+ }
26462
+ }`;
26463
+ const response = await this.http.fetchGraphql(
26464
+ OPERATORS_QUERY,
26465
+ after,
26466
+ limit
26467
+ );
26468
+ if (!response || !response.data || !response.data.operatorDelayOperations || !response.data.operatorDelayOperations.edges || response.data.operatorDelayOperations.edges.length === 0) {
26469
+ return {
26470
+ code: 404,
26471
+ error: {
26472
+ message: `No operatorDelayOperations found for address ${address}`,
26473
+ type: ERROR.ERROR_OPERATOR_DELAY_HISTORY_NOT_FOUND
26474
+ }
26475
+ };
26476
+ }
26477
+ const operator = {
26478
+ code: 200,
26479
+ data: response.data
26480
+ };
26481
+ return operator;
26482
+ } catch (error) {
26483
+ return handleError(error);
26484
+ }
26485
+ }
26425
26486
  async getOperators(after, limit) {
26426
26487
  try {
26427
26488
  const OPERATORS_QUERY = `query ($limit: Int, $after: Cursor) {
@@ -26525,6 +26586,228 @@ var Operator = class {
26525
26586
  return handleError(error);
26526
26587
  }
26527
26588
  }
26589
+ async queryMissRate(address, durationDay) {
26590
+ try {
26591
+ const now = /* @__PURE__ */ new Date();
26592
+ const startTime = new Date(
26593
+ now.getTime() - durationDay * 24 * 60 * 60 * 1e3
26594
+ );
26595
+ const startTimestamp = Math.floor(startTime.getTime() / 1e3);
26596
+ const endNanosTimestamp = Math.floor(startTime.getTime() * 1e6);
26597
+ const txTimestamp = Math.floor(startTime.getTime());
26598
+ const QUERY = `query ($limit: Int, $after: Cursor) {
26599
+ operatorDelayOperations(
26600
+ first: $limit,
26601
+ after: $after,
26602
+ filter: {
26603
+ operatorAddress: {equalTo: "${address}"},
26604
+ timestamp: { greaterThanOrEqualTo: "${startTimestamp}" }
26605
+ },
26606
+ orderBy: [TIMESTAMP_DESC]
26607
+ ) {
26608
+ edges {
26609
+ node {
26610
+ blockHeight
26611
+ delayProcessDmsgCount
26612
+ delayDuration
26613
+ delayReason
26614
+ delayType
26615
+ id
26616
+ nodeId
26617
+ operatorAddress
26618
+ timestamp
26619
+ roundAddress
26620
+ }
26621
+ }
26622
+ }
26623
+ }`;
26624
+ const ROUNDS_QUERY = `query ($limit: Int, $after: Cursor) {
26625
+ rounds(first: $limit, after: $after,
26626
+ filter: {
26627
+ operator: {equalTo: "${address}"},
26628
+ votingEnd: { greaterThanOrEqualTo: "${endNanosTimestamp}" }
26629
+ },
26630
+ orderBy: [TIMESTAMP_DESC]
26631
+ ){
26632
+ pageInfo {
26633
+ endCursor
26634
+ hasNextPage
26635
+ }
26636
+ totalCount
26637
+ edges {
26638
+ node {
26639
+ id
26640
+ blockHeight
26641
+ txHash
26642
+ caller
26643
+ admin
26644
+ operator
26645
+ contractAddress
26646
+ circuitName
26647
+ timestamp
26648
+ votingStart
26649
+ votingEnd
26650
+ status
26651
+ period
26652
+ actionType
26653
+ roundTitle
26654
+ roundDescription
26655
+ roundLink
26656
+ coordinatorPubkeyX
26657
+ coordinatorPubkeyY
26658
+ voteOptionMap
26659
+ results
26660
+ allResult
26661
+ gasStationEnable
26662
+ totalGrant
26663
+ baseGrant
26664
+ totalBond
26665
+ circuitType
26666
+ circuitPower
26667
+ certificationSystem
26668
+ codeId
26669
+ maciType
26670
+ voiceCreditAmount
26671
+ preDeactivateRoot
26672
+ }
26673
+ cursor
26674
+ }
26675
+ }
26676
+ }
26677
+ `;
26678
+ const roundsResponse = await this.http.fetchGraphql(
26679
+ ROUNDS_QUERY,
26680
+ "",
26681
+ 9999
26682
+ );
26683
+ const roundContractAddresses = roundsResponse?.data?.rounds?.edges?.map(
26684
+ (edge) => edge.node.contractAddress
26685
+ ) || [];
26686
+ const TRANSACTIONS_QUERY = `query transactions($limit: Int, $after: Cursor) {
26687
+ transactions(first: $limit, after: $after,
26688
+ filter: {
26689
+ timestamp: { greaterThanOrEqualTo: "${txTimestamp}" },
26690
+ type: { equalTo: "op:procDeactivate" },
26691
+ contractAddress: { in: ${JSON.stringify(roundContractAddresses)} }
26692
+ },
26693
+ orderBy: [TIMESTAMP_DESC]
26694
+ ){
26695
+ pageInfo {
26696
+ endCursor
26697
+ hasNextPage
26698
+ }
26699
+ totalCount
26700
+ edges {
26701
+ cursor
26702
+ node {
26703
+ id
26704
+ blockHeight
26705
+ txHash
26706
+ timestamp
26707
+ type
26708
+ status
26709
+ circuitName
26710
+ fee
26711
+ gasUsed
26712
+ gasWanted
26713
+ caller
26714
+ contractAddress
26715
+ }
26716
+ }
26717
+ }
26718
+ }`;
26719
+ const [delayResponse, transactionsResponse] = await Promise.all([
26720
+ this.http.fetchGraphql(
26721
+ QUERY,
26722
+ "",
26723
+ 9999
26724
+ ),
26725
+ this.http.fetchGraphql(
26726
+ TRANSACTIONS_QUERY,
26727
+ "",
26728
+ 9999
26729
+ )
26730
+ ]);
26731
+ const dailyStats = /* @__PURE__ */ new Map();
26732
+ const endDate = /* @__PURE__ */ new Date();
26733
+ for (let i = 0; i < durationDay; i++) {
26734
+ const date = new Date(endDate.getTime() - i * 24 * 60 * 60 * 1e3).toISOString().split("T")[0];
26735
+ dailyStats.set(date, {
26736
+ delayCount: 0,
26737
+ deactivateDelay: {
26738
+ count: 0,
26739
+ dmsgCount: 0
26740
+ },
26741
+ tallyDelay: {
26742
+ count: 0
26743
+ },
26744
+ totalDelayDuration: 0,
26745
+ avgDelayDuration: 0,
26746
+ tallyCount: 0,
26747
+ deactivateCount: 0,
26748
+ missRate: 0
26749
+ });
26750
+ }
26751
+ delayResponse.data.operatorDelayOperations.edges.forEach(({ node }) => {
26752
+ const date = new Date(parseInt(node.timestamp) * 1e3).toISOString().split("T")[0];
26753
+ if (dailyStats.has(date)) {
26754
+ const stats = dailyStats.get(date);
26755
+ stats.delayCount++;
26756
+ stats.totalDelayDuration += parseInt(node.delayDuration);
26757
+ if (node.delayType === "deactivate_delay") {
26758
+ stats.deactivateDelay.count++;
26759
+ stats.deactivateDelay.dmsgCount += node.delayProcessDmsgCount;
26760
+ } else if (node.delayType === "tally_delay") {
26761
+ stats.tallyDelay.count++;
26762
+ }
26763
+ }
26764
+ });
26765
+ if (roundsResponse?.data?.rounds?.edges) {
26766
+ roundsResponse.data.rounds.edges.forEach(({ node }) => {
26767
+ const date = new Date(parseInt(node.votingEnd) / 1e6).toISOString().split("T")[0];
26768
+ if (dailyStats.has(date)) {
26769
+ const stats = dailyStats.get(date);
26770
+ stats.tallyCount++;
26771
+ }
26772
+ });
26773
+ }
26774
+ if (transactionsResponse?.data?.transactions?.edges) {
26775
+ transactionsResponse.data.transactions.edges.forEach(({ node }) => {
26776
+ const date = new Date(parseInt(node.timestamp)).toISOString().split("T")[0];
26777
+ if (dailyStats.has(date)) {
26778
+ const stats = dailyStats.get(date);
26779
+ stats.deactivateCount++;
26780
+ }
26781
+ });
26782
+ }
26783
+ return {
26784
+ code: 200,
26785
+ data: {
26786
+ missRate: Array.from(dailyStats.entries()).map(([date, stats]) => ({
26787
+ date,
26788
+ delayCount: stats.delayCount,
26789
+ deactivateDelay: stats.deactivateDelay,
26790
+ tallyDelay: stats.tallyDelay,
26791
+ totalDelayDuration: stats.totalDelayDuration,
26792
+ avgDelayDuration: stats.delayCount > 0 ? stats.totalDelayDuration / stats.delayCount : 0,
26793
+ tallyCount: stats.tallyCount,
26794
+ deactivateCount: stats.deactivateCount,
26795
+ missRate: stats.deactivateCount + stats.tallyCount > 0 ? parseFloat(
26796
+ ((stats.deactivateDelay.count + stats.tallyDelay.count) / (stats.deactivateCount + stats.tallyCount)).toFixed(2)
26797
+ ) : 0
26798
+ })).sort((a, b) => b.date.localeCompare(a.date))
26799
+ }
26800
+ };
26801
+ } catch (error) {
26802
+ return {
26803
+ code: 404,
26804
+ error: {
26805
+ message: "Query miss rate failed",
26806
+ type: ERROR.ERROR_QUERY_MISS_RATE_FAILED
26807
+ }
26808
+ };
26809
+ }
26810
+ }
26528
26811
  };
26529
26812
 
26530
26813
  // src/libs/query/round.ts
@@ -27360,6 +27643,16 @@ var Indexer = class {
27360
27643
  async getOperatorByAddress(address) {
27361
27644
  return await this.operator.getOperatorByAddress(address);
27362
27645
  }
27646
+ async getOperatorDelayOperationsByAddress(address, after, limit) {
27647
+ return await this.operator.getOperatorDelayOperationsByAddress(
27648
+ address,
27649
+ after,
27650
+ limit
27651
+ );
27652
+ }
27653
+ async queryMissRate(address, durationDay) {
27654
+ return await this.operator.queryMissRate(address, durationDay);
27655
+ }
27363
27656
  /**
27364
27657
  * @method getOperators
27365
27658
  * @description Get multiple operators.
@@ -29517,7 +29810,7 @@ function getContractParams(type, circuitType, proofSystem, maxVoter, maxOption)
29517
29810
  `Invalid proof system ${proofSystem}, only support GROTH16 and PLONK`
29518
29811
  );
29519
29812
  }
29520
- if (Number(maxVoter) <= 25 && Number(maxOption) <= 5) {
29813
+ if (maxVoter <= 25 && maxOption <= 5) {
29521
29814
  parameters = CIRCUIT_INFO["2-1-1-5"].parameter;
29522
29815
  if (proofSystem === "groth16" /* GROTH16 */) {
29523
29816
  groth16ProcessVkey = CIRCUIT_INFO["2-1-1-5"]["groth16"].process_vkey;
@@ -29526,7 +29819,7 @@ function getContractParams(type, circuitType, proofSystem, maxVoter, maxOption)
29526
29819
  plonkProcessVkey = CIRCUIT_INFO["2-1-1-5"]["plonk"]?.process_vkey;
29527
29820
  plonkTallyVkey = CIRCUIT_INFO["2-1-1-5"]["plonk"]?.tally_vkey;
29528
29821
  }
29529
- } else if (Number(maxVoter) <= 625 && Number(maxOption) <= 25) {
29822
+ } else if (maxVoter <= 625 && maxOption <= 25) {
29530
29823
  parameters = CIRCUIT_INFO["4-2-2-25"].parameter;
29531
29824
  if (proofSystem === "groth16" /* GROTH16 */) {
29532
29825
  groth16ProcessVkey = CIRCUIT_INFO["4-2-2-25"]["groth16"].process_vkey;
@@ -29535,7 +29828,7 @@ function getContractParams(type, circuitType, proofSystem, maxVoter, maxOption)
29535
29828
  plonkProcessVkey = CIRCUIT_INFO["4-2-2-25"]["plonk"]?.process_vkey;
29536
29829
  plonkTallyVkey = CIRCUIT_INFO["4-2-2-25"]["plonk"]?.tally_vkey;
29537
29830
  }
29538
- } else if (Number(maxVoter) <= 15625 && Number(maxOption) <= 125) {
29831
+ } else if (maxVoter <= 15625 && maxOption <= 125) {
29539
29832
  parameters = CIRCUIT_INFO["6-3-3-125"].parameter;
29540
29833
  if (proofSystem === "groth16" /* GROTH16 */) {
29541
29834
  groth16ProcessVkey = CIRCUIT_INFO["6-3-3-125"]["groth16"].process_vkey;
@@ -29544,7 +29837,7 @@ function getContractParams(type, circuitType, proofSystem, maxVoter, maxOption)
29544
29837
  plonkProcessVkey = CIRCUIT_INFO["6-3-3-125"]["plonk"]?.process_vkey;
29545
29838
  plonkTallyVkey = CIRCUIT_INFO["6-3-3-125"]["plonk"]?.tally_vkey;
29546
29839
  }
29547
- } else if (Number(maxVoter) <= 1953125 && Number(maxOption) <= 125) {
29840
+ } else if (maxVoter <= 1953125 && maxOption <= 125) {
29548
29841
  parameters = CIRCUIT_INFO["9-4-3-625"].parameter;
29549
29842
  if (proofSystem === "groth16" /* GROTH16 */) {
29550
29843
  if (circuitType === "0" /* IP1V */) {
@@ -29598,6 +29891,20 @@ function getContractParams(type, circuitType, proofSystem, maxVoter, maxOption)
29598
29891
  };
29599
29892
  }
29600
29893
  }
29894
+ function getAMaciRoundCircuitFee(maxVoter, maxOption) {
29895
+ let requiredFee = {
29896
+ denom: "peaka",
29897
+ amount: "0"
29898
+ };
29899
+ if (maxVoter <= 25 && maxOption <= 5) {
29900
+ requiredFee.amount = "50000000000000000000";
29901
+ } else if (maxVoter <= 625 && maxOption <= 25) {
29902
+ requiredFee.amount = "100000000000000000000";
29903
+ } else {
29904
+ throw new Error("Number of voters or options is too large.");
29905
+ }
29906
+ return requiredFee;
29907
+ }
29601
29908
 
29602
29909
  // src/libs/contract/contract.ts
29603
29910
  var Contract = class {
@@ -29638,26 +29945,32 @@ var Contract = class {
29638
29945
  wallet: signer,
29639
29946
  contractAddress: this.registryAddress
29640
29947
  });
29948
+ const requiredFee = getAMaciRoundCircuitFee(maxVoter, maxOption);
29641
29949
  preDeactivateRoot = preDeactivateRoot || "0";
29642
- const res = await client.createRound({
29643
- operator,
29644
- preDeactivateRoot,
29645
- voiceCreditAmount,
29646
- whitelist,
29647
- roundInfo: {
29648
- title,
29649
- description: description || "",
29650
- link: link || ""
29651
- },
29652
- votingTime: {
29653
- start_time,
29654
- end_time
29950
+ const res = await client.createRound(
29951
+ {
29952
+ operator,
29953
+ preDeactivateRoot,
29954
+ voiceCreditAmount,
29955
+ whitelist,
29956
+ roundInfo: {
29957
+ title,
29958
+ description: description || "",
29959
+ link: link || ""
29960
+ },
29961
+ votingTime: {
29962
+ start_time,
29963
+ end_time
29964
+ },
29965
+ maxVoter: maxVoter.toString(),
29966
+ maxOption: maxOption.toString(),
29967
+ certificationSystem: "0",
29968
+ circuitType
29655
29969
  },
29656
- maxVoter,
29657
- maxOption,
29658
- certificationSystem: "0",
29659
- circuitType
29660
- });
29970
+ "auto",
29971
+ void 0,
29972
+ [requiredFee]
29973
+ );
29661
29974
  let contractAddress = "";
29662
29975
  res.events.map((event) => {
29663
29976
  if (event.type === "wasm") {
@@ -29757,8 +30070,8 @@ var Contract = class {
29757
30070
  "2" /* ORACLE_MACI */,
29758
30071
  circuitType,
29759
30072
  "groth16" /* GROTH16 */,
29760
- "0",
29761
- "0"
30073
+ 0,
30074
+ 0
29762
30075
  );
29763
30076
  const instantiateResponse = await client.instantiate(
29764
30077
  address,
@@ -29873,6 +30186,16 @@ var OracleCertificate = class {
29873
30186
  const signatureData = await response.json();
29874
30187
  return signatureData;
29875
30188
  }
30189
+ async feegrantAllowance(granter, grantee) {
30190
+ const response = await this.http.fetchRest(
30191
+ `/cosmos/feegrant/v1beta1/allowance/${granter}/${grantee}`
30192
+ );
30193
+ return {
30194
+ granter,
30195
+ grantee,
30196
+ spend_limit: response.allowance.allowance.allowance.spend_limit
30197
+ };
30198
+ }
29876
30199
  };
29877
30200
 
29878
30201
  // src/libs/circom/index.ts
@@ -30212,6 +30535,24 @@ var MACI = class {
30212
30535
  }
30213
30536
  return response.data.signUpEvents[0].stateIdx;
30214
30537
  }
30538
+ async feegrantAllowance({
30539
+ address,
30540
+ contractAddress
30541
+ }) {
30542
+ try {
30543
+ const response = await this.oracleCertificate.feegrantAllowance(
30544
+ contractAddress,
30545
+ address
30546
+ );
30547
+ return response;
30548
+ } catch (error) {
30549
+ return {
30550
+ granter: contractAddress,
30551
+ grantee: address,
30552
+ spend_limit: []
30553
+ };
30554
+ }
30555
+ }
30215
30556
  // only for maci and oracle maci, amaci will set the voice credit when deploy the contract
30216
30557
  async queryWhitelistBalanceOf({
30217
30558
  signer,
@@ -30303,6 +30644,50 @@ var MACI = class {
30303
30644
  const circuitType = await this.getRoundCircuitType({ contractAddress });
30304
30645
  return circuitType === "1";
30305
30646
  }
30647
+ async queryRoundClaimable({
30648
+ contractAddress
30649
+ }) {
30650
+ try {
30651
+ const roundInfo = await this.getRoundInfo({ contractAddress });
30652
+ if (roundInfo.maciType !== "aMACI") {
30653
+ return {
30654
+ claimable: null,
30655
+ balance: null
30656
+ };
30657
+ }
30658
+ const votingEndTime = new Date(Number(roundInfo.votingEnd) / 10 ** 6);
30659
+ const currentTime = /* @__PURE__ */ new Date();
30660
+ const threeDaysInMs = 3 * 24 * 60 * 60 * 1e3;
30661
+ if (currentTime.getTime() - votingEndTime.getTime() <= threeDaysInMs) {
30662
+ return {
30663
+ claimable: null,
30664
+ balance: null
30665
+ };
30666
+ }
30667
+ const roundBalance = await this.indexer.balanceOf(contractAddress);
30668
+ if (isErrorResponse(roundBalance)) {
30669
+ throw new Error(
30670
+ `Failed to query round balance: ${roundBalance.error.type} ${roundBalance.error.message}`
30671
+ );
30672
+ }
30673
+ if (roundBalance.data.balance && roundBalance.data.balance !== "0" && roundBalance.data.balance !== "") {
30674
+ return {
30675
+ claimable: true,
30676
+ balance: roundBalance.data.balance
30677
+ };
30678
+ }
30679
+ return {
30680
+ claimable: false,
30681
+ balance: roundBalance.data.balance
30682
+ };
30683
+ } catch (error) {
30684
+ console.error("Error in queryRoundClaimable:", error);
30685
+ return {
30686
+ claimable: null,
30687
+ balance: null
30688
+ };
30689
+ }
30690
+ }
30306
30691
  async queryRoundGasStation({ contractAddress }) {
30307
30692
  const roundInfo = await this.getRoundInfo({ contractAddress });
30308
30693
  return roundInfo.gasStationEnable;