@dorafactory/maci-sdk 0.0.20 → 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
@@ -25989,6 +25989,8 @@ var ERROR = {
25989
25989
  ERROR_CIRCUIT_NOT_FOUND: "ERROR_CIRCUIT_NOT_FOUND",
25990
25990
  ERROR_OPERATOR_INVALID_ADDRESS: "ERROR_OPERATOR_INVALID_ADDRESS",
25991
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",
25992
25994
  ERROR_OPERATORS_NOT_FOUND: "ERROR_OPERATORS_NOT_FOUND",
25993
25995
  ERROR_PROOF_NOT_FOUND: "ERROR_PROOF_NOT_FOUND",
25994
25996
  ERROR_ROUND_INVALID_ADDRESS: "ERROR_ROUND_INVALID_ADDRESS",
@@ -26423,6 +26425,64 @@ var Operator = class {
26423
26425
  return handleError(error);
26424
26426
  }
26425
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
+ }
26426
26486
  async getOperators(after, limit) {
26427
26487
  try {
26428
26488
  const OPERATORS_QUERY = `query ($limit: Int, $after: Cursor) {
@@ -26526,6 +26586,228 @@ var Operator = class {
26526
26586
  return handleError(error);
26527
26587
  }
26528
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
+ }
26529
26811
  };
26530
26812
 
26531
26813
  // src/libs/query/round.ts
@@ -27361,6 +27643,16 @@ var Indexer = class {
27361
27643
  async getOperatorByAddress(address) {
27362
27644
  return await this.operator.getOperatorByAddress(address);
27363
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
+ }
27364
27656
  /**
27365
27657
  * @method getOperators
27366
27658
  * @description Get multiple operators.
@@ -29518,7 +29810,7 @@ function getContractParams(type, circuitType, proofSystem, maxVoter, maxOption)
29518
29810
  `Invalid proof system ${proofSystem}, only support GROTH16 and PLONK`
29519
29811
  );
29520
29812
  }
29521
- if (Number(maxVoter) <= 25 && Number(maxOption) <= 5) {
29813
+ if (maxVoter <= 25 && maxOption <= 5) {
29522
29814
  parameters = CIRCUIT_INFO["2-1-1-5"].parameter;
29523
29815
  if (proofSystem === "groth16" /* GROTH16 */) {
29524
29816
  groth16ProcessVkey = CIRCUIT_INFO["2-1-1-5"]["groth16"].process_vkey;
@@ -29527,7 +29819,7 @@ function getContractParams(type, circuitType, proofSystem, maxVoter, maxOption)
29527
29819
  plonkProcessVkey = CIRCUIT_INFO["2-1-1-5"]["plonk"]?.process_vkey;
29528
29820
  plonkTallyVkey = CIRCUIT_INFO["2-1-1-5"]["plonk"]?.tally_vkey;
29529
29821
  }
29530
- } else if (Number(maxVoter) <= 625 && Number(maxOption) <= 25) {
29822
+ } else if (maxVoter <= 625 && maxOption <= 25) {
29531
29823
  parameters = CIRCUIT_INFO["4-2-2-25"].parameter;
29532
29824
  if (proofSystem === "groth16" /* GROTH16 */) {
29533
29825
  groth16ProcessVkey = CIRCUIT_INFO["4-2-2-25"]["groth16"].process_vkey;
@@ -29536,7 +29828,7 @@ function getContractParams(type, circuitType, proofSystem, maxVoter, maxOption)
29536
29828
  plonkProcessVkey = CIRCUIT_INFO["4-2-2-25"]["plonk"]?.process_vkey;
29537
29829
  plonkTallyVkey = CIRCUIT_INFO["4-2-2-25"]["plonk"]?.tally_vkey;
29538
29830
  }
29539
- } else if (Number(maxVoter) <= 15625 && Number(maxOption) <= 125) {
29831
+ } else if (maxVoter <= 15625 && maxOption <= 125) {
29540
29832
  parameters = CIRCUIT_INFO["6-3-3-125"].parameter;
29541
29833
  if (proofSystem === "groth16" /* GROTH16 */) {
29542
29834
  groth16ProcessVkey = CIRCUIT_INFO["6-3-3-125"]["groth16"].process_vkey;
@@ -29545,7 +29837,7 @@ function getContractParams(type, circuitType, proofSystem, maxVoter, maxOption)
29545
29837
  plonkProcessVkey = CIRCUIT_INFO["6-3-3-125"]["plonk"]?.process_vkey;
29546
29838
  plonkTallyVkey = CIRCUIT_INFO["6-3-3-125"]["plonk"]?.tally_vkey;
29547
29839
  }
29548
- } else if (Number(maxVoter) <= 1953125 && Number(maxOption) <= 125) {
29840
+ } else if (maxVoter <= 1953125 && maxOption <= 125) {
29549
29841
  parameters = CIRCUIT_INFO["9-4-3-625"].parameter;
29550
29842
  if (proofSystem === "groth16" /* GROTH16 */) {
29551
29843
  if (circuitType === "0" /* IP1V */) {
@@ -29599,6 +29891,20 @@ function getContractParams(type, circuitType, proofSystem, maxVoter, maxOption)
29599
29891
  };
29600
29892
  }
29601
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
+ }
29602
29908
 
29603
29909
  // src/libs/contract/contract.ts
29604
29910
  var Contract = class {
@@ -29639,26 +29945,32 @@ var Contract = class {
29639
29945
  wallet: signer,
29640
29946
  contractAddress: this.registryAddress
29641
29947
  });
29948
+ const requiredFee = getAMaciRoundCircuitFee(maxVoter, maxOption);
29642
29949
  preDeactivateRoot = preDeactivateRoot || "0";
29643
- const res = await client.createRound({
29644
- operator,
29645
- preDeactivateRoot,
29646
- voiceCreditAmount,
29647
- whitelist,
29648
- roundInfo: {
29649
- title,
29650
- description: description || "",
29651
- link: link || ""
29652
- },
29653
- votingTime: {
29654
- start_time,
29655
- 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
29656
29969
  },
29657
- maxVoter,
29658
- maxOption,
29659
- certificationSystem: "0",
29660
- circuitType
29661
- });
29970
+ "auto",
29971
+ void 0,
29972
+ [requiredFee]
29973
+ );
29662
29974
  let contractAddress = "";
29663
29975
  res.events.map((event) => {
29664
29976
  if (event.type === "wasm") {
@@ -29758,8 +30070,8 @@ var Contract = class {
29758
30070
  "2" /* ORACLE_MACI */,
29759
30071
  circuitType,
29760
30072
  "groth16" /* GROTH16 */,
29761
- "0",
29762
- "0"
30073
+ 0,
30074
+ 0
29763
30075
  );
29764
30076
  const instantiateResponse = await client.instantiate(
29765
30077
  address,
@@ -30332,6 +30644,50 @@ var MACI = class {
30332
30644
  const circuitType = await this.getRoundCircuitType({ contractAddress });
30333
30645
  return circuitType === "1";
30334
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
+ }
30335
30691
  async queryRoundGasStation({ contractAddress }) {
30336
30692
  const roundInfo = await this.getRoundInfo({ contractAddress });
30337
30693
  return roundInfo.gasStationEnable;