From 5815208158143b42ba2083786cfdad5502cd80b2 Mon Sep 17 00:00:00 2001 From: Sam Richards Date: Thu, 21 Dec 2023 00:52:22 -0500 Subject: [PATCH 01/37] chore: cut down /roadmap length --- website/src/pages/roadmap.md | 120 +++++++++++------------------------ 1 file changed, 37 insertions(+), 83 deletions(-) diff --git a/website/src/pages/roadmap.md b/website/src/pages/roadmap.md index 089f8bfc2b..13527970e3 100644 --- a/website/src/pages/roadmap.md +++ b/website/src/pages/roadmap.md @@ -1,68 +1,46 @@ --- -title: 2024 MACI Product Roadmap +title: MACI Product Roadmap description: An outline of the 2024 MACI team & product roadmap --- -# 2024 MACI Product Roadmap +# MACI Product Roadmap This document aims to outline the 2024 MACI team & product roadmap. -_As part of our core team's efforts to make our work more accessible and to foster more collaboration from our open source community, we're publicly publishing our roadmap. We plan to re-assess & iterate on our roadmap over time, and will update this document when we do._ +_This public roadmap is part of our core team's efforts to make our work more accessible and to foster more collaboration from our open source community. We plan to re-assess & iterate on our roadmap over time, and will update this document when we do._ :::info -Note: this roadmap is still under active discussion - please join the conversation in our [GitHub roadmap discussion](https://github.com/privacy-scaling-explorations/maci/discussions/859) if you have feedback! +Our roadmap is still under active discussion - please join the conversation in our [GitHub discussion](https://github.com/privacy-scaling-explorations/maci/discussions/859) if you have feedback! ::: ## Team description -The MACI core team is a small collaborative team building various projects within [Privacy & Scaling Explorations (PSE)](https://pse.dev/). Our sustained focus is on MACI: a protocol that allows users to have an on-chain voting process with greatly increased collusion resistance & privacy. Additionally, we allocate a significant portion of our time to support the practical adoption of this technology by grassroots community leaders around the world using it to secure Quadratic Voting (QV) & Quadratic Funding (QF) events. +The MACI core team is a small collaborative engineering team building various projects within [Privacy & Scaling Explorations (PSE)](https://pse.dev/). Our sustained focus is on MACI: an on-chain voting protocol that provides greatly increased collusion resistance & privacy. We also allocate a significant portion of our time to support the practical adoption of this technology by supporting community leaders to run democratic governance and public funding initiatives, like Quadratic Voting (QV) & Quadratic Funding (QF) grant rounds. ## MACI mission & vision -MACI (Minimal Anti-Collusion Infrastructure) is a public good & a potential core piece of infrastructure for many Ethereum-based applications to support privacy-protecting on-chain governance. Using MACI, no voter can reveal how they voted yet voting results are published publicly and verified with cryptographic proofs to prevent censorship, bribery, collusion, and other nefarious acts common in public polling processes. With MACI, you get the transparency you want as well as the privacy you need. +MACI (Minimal Anti-Collusion Infrastructure) is a public good & a potential core piece of infrastructure for many Ethereum-based applications to support privacy-protecting on-chain governance. Using MACI, individual votes are private but final results are public, so no voter can reveal how they voted yet voting results are verifiable with cryptographic proofs to prevent censorship, bribery, collusion, and other forms of manipulation common in public polling processes. **Long term, the MACI team’s vision is to build the most secure e-voting solution in the world.** -Short term, our vision is to empower developers to build on MACI to create privacy-protecting voting applications, including quadratic funding platforms & DAO governance tools. Our goal is to provide an out-of-the-box solution for developers to quickly deploy & plug their applications into. MACI enables you to focus less time worrying about voting infrastructure & more time building the logic specific to your application. +Short term, our vision is to empower developers to build with MACI to create collusion resistant & privacy-protecting voting applications, like quadratic funding platforms & DAO governance tools. Our goal is to provide an out-of-the-box solution for developers to quickly integrate into their applications & deploy. MACI aims to handle the voting infrastructure so you can focus on building the logic specific to your application. ### High-level MACI ecosystem goals -1. ~~2023: MACI integrated by 1 PSE project~~ (✅, [QFI](https://github.com/privacy-scaling-explorations/qf)) -2. 2024: MACI integrated by 1 external project -3. 2025: MACI used by several DAOs for governance & multiple QF integrations -4. 2028: MACI used in smaller municipal elections (counties, provinces, etc) -5. 2030: MACI used in national elections +1. ~~2021: MACI integrated by an ecosystem project~~ (✅, [clr.fund](https://github.com/clrfund/monorepo/)) +2. ~~2023: MACI integrated by a PSE project~~ (✅, [QFI](https://github.com/privacy-scaling-explorations/qf)) +3. 2024: MACI integrated by an additional external project +4. 2025: MACI used by multiple DAOs for governance applications & QF integrations +5. 2028: MACI used in smaller municipal elections (counties, provinces, etc) +6. 2030: MACI used in national elections ### High-level MACI development goals -1. ~~2023: build technical feasibility for 10K concurrent voters on the platform.~~ (✅) -2. 2024 Q1: release MACI v1.2, with revamped documentation & educational resources -3. 2026: build technical feasibility for 100K concurrent voters on the platform. -4. 2028: build technical feasibility for 1M concurrent voters on the platform. - -## QF mission & vision - -We’re building technical infrastructure, operational expertise & a network of communities to create a scalable way to enable community organizers to run QF rounds. The mission of our QF project has been to serve as a reference implementation on how to integrate MACI as well as support the practical adoption of this community-funding technology. - -**Long term, our vision is to build the most widely adopted QF solution in the world, powered by MACI.** - -Our vision to eventually enable QF rounds, running e.g. every quarter, at the local, municipal, national and global scale. We want QF rounds to become the “default” place where projects are contributing funds to public goods. - -[Learn more about our QF initiatives here](https://qf.pse.dev/about). - -### High-level QF ecosystem goals - -1. ~~2023: facilitate 15 QF/QV rounds~~ (❌, 6 rounds) -2. 2024: facilitate 12 QF/QV rounds -3. 2025 & beyond: TBD - -### High-level QF development goals - -1. ~~2023: build QFI as a QV reference implementation for MACI v1.x~~ (✅❓) -2. 2024: build out reference implementation with complete QF functionality (vs. only QV) -3. 2024/5: implement additional functionality (key-switching, gas-less voting) -4. 2025: support additional QF mechanisms -5. 2025 & beyond: TBD +1. ~~2021: release MACI v1.0~~ (✅) +2. ~~2023: build technical feasibility for 10K concurrent voters on the platform~~ (✅) +3. 2024 Q1: release MACI v1.2, with revamped documentation & educational resource +4. 2026: build technical feasibility for 100K concurrent voters on the platform +5. 2028: build technical feasibility for 1M concurrent voters on the platform # 2024 workstreams @@ -74,7 +52,7 @@ _To achieve our mission, we’re focused on 4 major workstreams that comprise ou We believe that MACI is only useful to the extent that people use MACI & build on MACI. -As mentioned above in “challenges”, not a single project has yet integrated MACI v1.x in a production environment We view this as a failure, and we want to fix this. **The goal of this workstream is to make MACI as easy to understand and easy to integrate as possible.** +Despite the power of MACI, not a single project has yet integrated MACI v1.x in a production environment. We view this as a failure, and we want to fix this. **The goal of this workstream is to make MACI as easy to understand and easy to integrate as possible.** ### Initiatives within this workstream: @@ -97,11 +75,11 @@ As mentioned above in “challenges”, not a single project has yet integrated _~15% of team’s total bandwidth_ -Along with poor DX, we believe one of the core reasons there hasn’t been ecosystem adoption of MACI is the lack of community engagement (which we touched on in “challenges”). **We’ll create an open source community where integrations & contributions are actively encouraged!** +We want to proactively support adoption of MACI. **We’ll create an open source community where integrations & contributions are actively encouraged!** This workstream relates closely to improving DX but focuses on areas that will require active maintenance, support & engagement from our team vs. improving code, documentation & educational resources that will be available online 24/7/365. -The hope here is that close interactions with integration developers & Ethereum community members will help us gather insightful user feedback that will help us iterate faster to improve MACI as a product. We’ll be rolling out an agile scrum development workflow that should allow us to rapidly respond to input from the community to guide our roadmap & product direction. +The hope here is that close interactions with integration developers & Ethereum community members will help us gather insightful user feedback so that we iterate faster to improve MACI as a product. We’ll be rolling out an agile scrum development workflow that should allow us to rapidly respond to input from the community to guide our roadmap & product direction. ### Initiatives within this workstream: @@ -109,19 +87,16 @@ The hope here is that close interactions with integration developers & Ethereum - Support MACI integrations (starting with [clr.fund](http://clr.fund/) v1.x integration) - Revamp GitHub repo maintenance ([MACI GH processes](https://github.com/privacy-scaling-explorations/maci/issues/757)) - Establish & respond to public channels ([Discord](https://discord.com/invite/sF5CT5rzrR), [Twitter](https://twitter.com/zkMACI)) -- Proactively generate engagement - - Publish public roadmaps, release blog posts, Twitter updates - - Conference talks/presentations - - Hackathon bounties & support - - Actively identify collaboration opportunities with projects in the space +- Proactively engage with the ecosystem to identify collaboration opportunities (conference talks, hackathon bounties, social media) - Update our development processes to quickly react to user needs & input - - Adopt agile/scrum methodologies ## 3) Quadratic Funding Experiments _~30% of team’s total bandwidth_ -[Read context on on our QF initiative here](https://qf.pse.dev/about). +We’re building technical infrastructure, operational expertise & a network of communities to create a scalable way to enable community organizers to run QF rounds. The mission of our QF project has been to serve as a reference implementation on how to integrate MACI as well as support the practical adoption of this community-funding technology. + +[Read more about our QF initiatives here](https://qf.pse.dev/about). ### 2024 goal @@ -140,56 +115,35 @@ _~30% of team’s total bandwidth_ - [GitHub](https://github.com/privacy-scaling-explorations/qf) - [Website](https://qf.pse.dev/) -## 4) P0tion support & handoff - -_~5% of team’s total bandwidth_ - -A big team accomplishment in 2023 was building & launching p0tion. We’ve seen exciting early traction, with multiple development teams requesting ceremonies using our infrastructure. - -For the rest of this year & early into 2024, we plan to hand off this project to the Trusted Setup team for them to maintain. Our developers will continue to support the codebase & ceremonies as we train up that team on this project. For the foreseeable future, we expect to collaborate with that team to align on the vision of the project & direct a product roadmap. - -**References** - -- [Github](https://github.com/privacy-scaling-explorations/p0tion) -- [Website](https://ceremony.pse.dev/) -- [Wiki](https://p0tion.super.site/) - -# Future areas of research & development +## Future R&D While not prioritized as an upcoming workstream, we think it’s worth calling out important areas of research & development that we’re excited to work on in the future: -### [MACI Coordinator Service](https://github.com/privacy-scaling-explorations/maci-coordinator) +### MACI Coordinator Service - The primary responsibility of the Coordinator Service will be to: - offload and automate the tasks performed by the human coordinator - minimize proving time by parallelizing SNARK proof generation and making MACI and QFI easier to adopt +- [GitHub repo](https://github.com/privacy-scaling-explorations/maci-coordinator) -### [QF stack](https://github.com/privacy-scaling-explorations/qf) +### QF stack - To serve as a reference implementation on how to integrate MACI as well as support the practical adoption of this community-funding technology. - Improvements - Support QF (as of now only supports QV functionality) - Make it easier for operators to run rounds - Make it easier for end users to use +- [GitHub repo](https://github.com/privacy-scaling-explorations/qf) ### MACI improvements -- Unconditional Voter Privacy ([#796](https://github.com/privacy-scaling-explorations/maci/issues/796)) -- Gas-less MACI - - Explore ways to support cost-free voting for users - - e.g. via a message aggregation service? - - Instead of users submitting vote transactions on-chain, they could sign their vote messages using their MACI key, then post messages to an aggregator server. Later on, the operator can batch votes into a single Ethereum transaction, and periodically insert them a subtree at a time into the MACI message tree. -- Improving gas efficiency - - Explore SNARK Proof Aggregation: - - The only major way to reduce gas costs is to decrease call data size, we can do this via proof aggregation. - - POC with Maze and other solutions to benchmark on MACI V1 circuits - - aggregate many proofs together and make a solidity verifier for the aggregation circuit, this could offset the need for direct circom optimization -- Different matching mechanisms - - e.g. [Group Wise Matching in Quadratic Funding](https://github.com/privacy-scaling-explorations/maci/issues/905) -- Scaling explorations - - e.g SNARK Folding Schemes ([Nova integration](https://github.com/privacy-scaling-explorations/maci/issues/904)) - -# Feedback +- Unconditional Voter Privacy (e.g. [ElGamal Key Change Mechanism](https://github.com/privacy-scaling-explorations/maci/issues/796)) +- Scaling explorations, like SNARK Folding Schemes (e.g. [Nova integration](https://github.com/privacy-scaling-explorations/maci/issues/904)) +- Different matching mechanisms (e.g. [Group Wise Matching in Quadratic Funding](https://github.com/privacy-scaling-explorations/maci/issues/905)) +- Gas-less MACI for voters +- Gas efficiency + +## Feedback Questions? Concerns? Ideas? We’d love to hear from you! From db1d931062bd1ce5305eeb850608533565bcad7c Mon Sep 17 00:00:00 2001 From: Sam Richards Date: Wed, 27 Dec 2023 14:02:14 -0500 Subject: [PATCH 02/37] chore: remove QFI --- website/src/pages/roadmap.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/src/pages/roadmap.md b/website/src/pages/roadmap.md index 13527970e3..ca3c08dafa 100644 --- a/website/src/pages/roadmap.md +++ b/website/src/pages/roadmap.md @@ -28,7 +28,7 @@ Short term, our vision is to empower developers to build with MACI to create col ### High-level MACI ecosystem goals 1. ~~2021: MACI integrated by an ecosystem project~~ (✅, [clr.fund](https://github.com/clrfund/monorepo/)) -2. ~~2023: MACI integrated by a PSE project~~ (✅, [QFI](https://github.com/privacy-scaling-explorations/qf)) +2. ~~2023: MACI integrated by a PSE project~~ (✅, [QF](https://github.com/privacy-scaling-explorations/qf)) 3. 2024: MACI integrated by an additional external project 4. 2025: MACI used by multiple DAOs for governance applications & QF integrations 5. 2028: MACI used in smaller municipal elections (counties, provinces, etc) @@ -123,7 +123,7 @@ While not prioritized as an upcoming workstream, we think it’s worth calling o - The primary responsibility of the Coordinator Service will be to: - offload and automate the tasks performed by the human coordinator - - minimize proving time by parallelizing SNARK proof generation and making MACI and QFI easier to adopt + - minimize proving time by parallelizing SNARK proof generation and making MACI easier to adopt - [GitHub repo](https://github.com/privacy-scaling-explorations/maci-coordinator) ### QF stack From 823cacd8659281b8390b74c8d765b23ee7a83a80 Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Wed, 13 Dec 2023 17:04:18 +0000 Subject: [PATCH 03/37] refactor(core): refactor the process message functions and general cleanup Remove unnecessary code, fix types, remove unused variables or duplicate ones, refactor the process messages functions to ensure they can be tested individually, add custom error messages for message processing debugging, ensure code is well commented and explained --- circuits/ts/__tests__/ProcessMessages.test.ts | 12 +- circuits/ts/__tests__/TallyVotes.test.ts | 2 - circuits/ts/types/snarkjs.d.ts | 2 +- contracts/tests/MACI.test.ts | 1 - contracts/tests/MessageProcessor.test.ts | 9 +- contracts/tests/Poll.test.ts | 9 +- contracts/tests/Tally.test.ts | 9 +- contracts/ts/genMaciState.ts | 4 +- core/ts/MaciState.ts | 14 +- core/ts/Poll.ts | 498 ++++++++++-------- core/ts/__tests__/MaciState.test.ts | 11 - core/ts/__tests__/constants.ts | 18 + core/ts/__tests__/utils.ts | 6 + core/ts/utils/errors.ts | 29 + core/ts/utils/types.ts | 8 +- .../ts/__tests__/integration.test.ts | 1 - 16 files changed, 348 insertions(+), 285 deletions(-) create mode 100644 core/ts/__tests__/constants.ts create mode 100644 core/ts/__tests__/utils.ts create mode 100644 core/ts/utils/errors.ts diff --git a/circuits/ts/__tests__/ProcessMessages.test.ts b/circuits/ts/__tests__/ProcessMessages.test.ts index 2196ea2cce..0f04b32ef7 100644 --- a/circuits/ts/__tests__/ProcessMessages.test.ts +++ b/circuits/ts/__tests__/ProcessMessages.test.ts @@ -61,8 +61,6 @@ describe("ProcessMessage circuit", function () { ); pollId = maciState.deployPoll( - duration, - // BigInt(2 + duration), BigInt(Math.floor(Date.now() / 1000) + duration), maxValues, treeDepths, @@ -153,7 +151,12 @@ describe("ProcessMessage circuit", function () { expect(newStateRoot.toString()).not.to.be.eq(currentStateRoot.toString()); expect(newBallotRoot.toString()).not.to.be.eq(currentBallotRoot.toString()); - const packedVals = packProcessMessageSmallVals(BigInt(maxValues.maxVoteOptions), BigInt(poll.numSignUps), 0, 2); + const packedVals = packProcessMessageSmallVals( + BigInt(maxValues.maxVoteOptions), + BigInt(poll.maciStateRef.numSignUps), + 0, + 2, + ); // Test the ProcessMessagesInputHasher circuit const hasherCircuitInputs = stringifyBigInts({ @@ -196,7 +199,6 @@ describe("ProcessMessage circuit", function () { ); pollId = maciState.deployPoll( - duration, BigInt(2 + duration), //BigInt(Math.floor(Date.now() / 1000) + duration), maxValues, treeDepths, @@ -291,7 +293,6 @@ describe("ProcessMessage circuit", function () { ); pollId = maciState.deployPoll( - duration, BigInt(2 + duration), //BigInt(Math.floor(Date.now() / 1000) + duration), maxValues, treeDepths, @@ -387,7 +388,6 @@ describe("ProcessMessage circuit", function () { // Sign up and publish const pollId = maciState.deployPoll( - duration, BigInt(Math.floor(Date.now() / 1000) + duration), maxValues, treeDepths, diff --git a/circuits/ts/__tests__/TallyVotes.test.ts b/circuits/ts/__tests__/TallyVotes.test.ts index b4b83d3716..0e665147e9 100644 --- a/circuits/ts/__tests__/TallyVotes.test.ts +++ b/circuits/ts/__tests__/TallyVotes.test.ts @@ -56,7 +56,6 @@ describe("TallyVotes circuit", function () { ); pollId = maciState.deployPoll( - duration, BigInt(Math.floor(Date.now() / 1000) + duration), maxValues, treeDepths, @@ -137,7 +136,6 @@ describe("TallyVotes circuit", function () { } const pollId = maciState.deployPoll( - duration, BigInt(Math.floor(Date.now() / 1000) + duration), maxValues, treeDepths, diff --git a/circuits/ts/types/snarkjs.d.ts b/circuits/ts/types/snarkjs.d.ts index 2ca70734ab..6783c946c3 100644 --- a/circuits/ts/types/snarkjs.d.ts +++ b/circuits/ts/types/snarkjs.d.ts @@ -1,6 +1,6 @@ declare module "snarkjs" { export type NumericString = `${number}` | string; - export type PublicSignals = Record; + export type PublicSignals = Record; export type BigNumberish = number | string | bigint; export interface ISnarkJSVerificationKey { diff --git a/contracts/tests/MACI.test.ts b/contracts/tests/MACI.test.ts index 0f30f4a28f..96fbc50b7e 100644 --- a/contracts/tests/MACI.test.ts +++ b/contracts/tests/MACI.test.ts @@ -217,7 +217,6 @@ describe("MACI", () => { pollId = event.args._pollId; const p = maciState.deployPoll( - duration, BigInt(deployTime + duration), maxValues, treeDepths, diff --git a/contracts/tests/MessageProcessor.test.ts b/contracts/tests/MessageProcessor.test.ts index 0b248bc4b0..efe9be6ccc 100644 --- a/contracts/tests/MessageProcessor.test.ts +++ b/contracts/tests/MessageProcessor.test.ts @@ -71,14 +71,7 @@ describe("MessageProcessor", () => { const deployTime = block!.timestamp; // deploy local poll - const p = maciState.deployPoll( - duration, - BigInt(deployTime + duration), - maxValues, - treeDepths, - messageBatchSize, - coordinator, - ); + const p = maciState.deployPoll(BigInt(deployTime + duration), maxValues, treeDepths, messageBatchSize, coordinator); expect(p.toString()).to.eq(pollId.toString()); // publish the NOTHING_UP_MY_SLEEVE message diff --git a/contracts/tests/Poll.test.ts b/contracts/tests/Poll.test.ts index 18530097f9..e25970287a 100644 --- a/contracts/tests/Poll.test.ts +++ b/contracts/tests/Poll.test.ts @@ -59,14 +59,7 @@ describe("Poll", () => { pollContract = new BaseContract(pollContractAddress, pollAbi, signer) as PollContract; // deploy local poll - const p = maciState.deployPoll( - duration, - BigInt(deployTime + duration), - maxValues, - treeDepths, - messageBatchSize, - coordinator, - ); + const p = maciState.deployPoll(BigInt(deployTime + duration), maxValues, treeDepths, messageBatchSize, coordinator); expect(p.toString()).to.eq(pollId.toString()); // publish the NOTHING_UP_MY_SLEEVE message const messageData = [NOTHING_UP_MY_SLEEVE, BigInt(0)]; diff --git a/contracts/tests/Tally.test.ts b/contracts/tests/Tally.test.ts index 3b65ed9110..20e21c5170 100644 --- a/contracts/tests/Tally.test.ts +++ b/contracts/tests/Tally.test.ts @@ -71,14 +71,7 @@ describe("TallyVotes", () => { pollContract = new BaseContract(pollContractAddress, pollAbi, signer) as PollContract; // deploy local poll - const p = maciState.deployPoll( - duration, - BigInt(deployTime + duration), - maxValues, - treeDepths, - messageBatchSize, - coordinator, - ); + const p = maciState.deployPoll(BigInt(deployTime + duration), maxValues, treeDepths, messageBatchSize, coordinator); expect(p.toString()).to.eq(pollId.toString()); // publish the NOTHING_UP_MY_SLEEVE message const messageData = [NOTHING_UP_MY_SLEEVE, BigInt(0)]; diff --git a/contracts/ts/genMaciState.ts b/contracts/ts/genMaciState.ts index 8610145707..0931772c27 100644 --- a/contracts/ts/genMaciState.ts +++ b/contracts/ts/genMaciState.ts @@ -295,7 +295,6 @@ export const genMaciStateFromContract = async ( case action.type === "DeployPoll" && action.data.pollId?.toString() === pollId.toString(): { maciState.deployPoll( - duration, BigInt(deployTime + duration), maxValues, treeDepths, @@ -338,8 +337,7 @@ export const genMaciStateFromContract = async ( const poll = maciState.polls[pollId]; assert(Number(numSignUpsAndMessages[1]) === poll.messages.length); - - poll.numSignUps = Number(numSignUpsAndMessages[0]); + assert(Number(numSignUpsAndMessages[0]) === maciState.numSignUps); // we need to ensure that the stateRoot is correct assert(maciState.stateTree.root.toString() === (await maciContract.getStateAqRoot()).toString()); diff --git a/core/ts/MaciState.ts b/core/ts/MaciState.ts index cab74732f0..53ffedf8a3 100644 --- a/core/ts/MaciState.ts +++ b/core/ts/MaciState.ts @@ -9,15 +9,19 @@ import { IJsonMaciState, IJsonPoll, IMaciState, MaxValues, TreeDepths } from "./ * A representation of the MACI contract. */ export class MaciState implements IMaciState { + // a MaciState can hold multiple polls public polls: Poll[] = []; + // in this quinary tree we hold all signups (hash of a state leaf) public stateTree: IncrementalQuinTree; + // the leaves of the state tree public stateLeaves: StateLeaf[] = []; + // how deep the state tree is + public stateTreeDepth: number; public numSignUps = 0; - public stateTreeDepth: number; - + // to keep track if a poll is currently being processed public pollBeingProcessed: boolean; public currentPollBeingProcessed: number; @@ -29,6 +33,7 @@ export class MaciState implements IMaciState { this.stateTreeDepth = stateTreeDepth; this.stateTree = new IncrementalQuinTree(this.stateTreeDepth, blankStateLeafHash, STATE_TREE_ARITY, hash5); + // we put a blank state leaf to prevent a DoS attack this.stateLeaves.push(blankStateLeaf); this.stateTree.insert(blankStateLeafHash); } @@ -51,7 +56,6 @@ export class MaciState implements IMaciState { /** * Deploy a new poll with the given parameters. - * @param duration - The duration of the poll in seconds. * @param pollEndTimestamp - The Unix timestamp at which the poll ends. * @param maxValues - The maximum number of values for each vote option. * @param treeDepths - The depths of the tree. @@ -60,16 +64,13 @@ export class MaciState implements IMaciState { * @returns The index of the newly deployed poll. */ public deployPoll( - duration: number, pollEndTimestamp: bigint, maxValues: MaxValues, treeDepths: TreeDepths, messageBatchSize: number, coordinatorKeypair: Keypair, ): number { - // TODO: fix the order of the arguments const poll: Poll = new Poll( - duration, pollEndTimestamp, coordinatorKeypair, treeDepths, @@ -80,7 +81,6 @@ export class MaciState implements IMaciState { }, maxValues, this, - this.stateTreeDepth, ); this.polls.push(poll); diff --git a/core/ts/Poll.ts b/core/ts/Poll.ts index 37cf62ce8c..0b46aa1ed2 100644 --- a/core/ts/Poll.ts +++ b/core/ts/Poll.ts @@ -22,7 +22,6 @@ import { Ballot, PrivKey, blankStateLeaf, - blankStateLeafHash, IMessageContractParams, IJsonCommand, IJsonPCommand, @@ -40,13 +39,14 @@ import { IJsonPoll, IProcessMessagesOutput, } from "./utils/types"; +import { ProcessMessageErrors, ProcessMessageError } from "./utils/errors"; import { STATE_TREE_ARITY, MESSAGE_TREE_ARITY, VOTE_OPTION_TREE_ARITY } from "./utils/constants"; +import { PathElements } from "optimisedmt"; /** * A representation of the Poll contract. */ export class Poll implements IPoll { - public duration: number; // Note that we only store the PubKey on-chain while this class stores the // Keypair for the sake of convenience public coordinatorKeypair: Keypair; @@ -57,8 +57,6 @@ export class Poll implements IPoll { // the depth of the state tree public stateTreeDepth: number; - public numSignUps: number; - public pollEndTimestamp: bigint; public ballots: Ballot[] = []; @@ -100,28 +98,28 @@ export class Poll implements IPoll { public MM = 50; // adjustable parameter public WW = 4; // number of digits for float representation + // an empty ballot and its hash to be used as zero value in the + // ballot tree + public emptyBallot: Ballot; + public emptyBallotHash: bigint; + /** * Constructs a new Poll object. - * @param duration - The duration of the poll in seconds. * @param pollEndTimestamp - The Unix timestamp at which the poll ends. * @param coordinatorKeypair - The keypair of the coordinator. * @param treeDepths - The depths of the trees used in the poll. * @param batchSizes - The sizes of the batches used in the poll. * @param maxValues - The maximum values the MACI circuits can accept. * @param maciStateRef - The reference to the MACI state. - * @param stateTreeDepth - The depth of the state tree. */ constructor( - duration: number, pollEndTimestamp: bigint, coordinatorKeypair: Keypair, treeDepths: TreeDepths, batchSizes: BatchSizes, maxValues: MaxValues, maciStateRef: MaciState, - stateTreeDepth: number, ) { - this.duration = duration; this.pollEndTimestamp = pollEndTimestamp; this.coordinatorKeypair = coordinatorKeypair; this.treeDepths = treeDepths; @@ -129,10 +127,8 @@ export class Poll implements IPoll { this.maxValues = maxValues; this.maciStateRef = maciStateRef; this.pollId = maciStateRef.polls.length; - this.numSignUps = Number(maciStateRef.numSignUps.toString()); - this.stateTreeDepth = stateTreeDepth; + this.stateTreeDepth = maciStateRef.stateTreeDepth; - this.stateTree = new IncrementalQuinTree(this.stateTreeDepth, blankStateLeafHash, STATE_TREE_ARITY, hash5); this.messageTree = new IncrementalQuinTree( this.treeDepths.messageTreeDepth, NOTHING_UP_MY_SLEEVE, @@ -140,14 +136,13 @@ export class Poll implements IPoll { hash5, ); - for (let i = 0; i < this.maxValues.maxVoteOptions; i++) { - this.tallyResult.push(BigInt(0)); - this.perVOSpentVoiceCredits.push(BigInt(0)); - this.subsidy.push(BigInt(0)); - } + this.tallyResult = new Array(this.maxValues.maxVoteOptions).fill(BigInt(0)); + this.perVOSpentVoiceCredits = new Array(this.maxValues.maxVoteOptions).fill(BigInt(0)); + this.subsidy = new Array(this.maxValues.maxVoteOptions).fill(BigInt(0)); - const blankBallot = Ballot.genBlankBallot(this.maxValues.maxVoteOptions, treeDepths.voteOptionTreeDepth); - this.ballots.push(blankBallot); + // we put a blank state leaf to prevent a DoS attack + this.emptyBallot = Ballot.genBlankBallot(this.maxValues.maxVoteOptions, treeDepths.voteOptionTreeDepth); + this.ballots.push(this.emptyBallot); } /** @@ -161,53 +156,41 @@ export class Poll implements IPoll { this.stateTree = this.maciStateRef.stateTree.copy(); // Create as many ballots as state leaves - const emptyBallot = new Ballot(this.maxValues.maxVoteOptions, this.treeDepths.voteOptionTreeDepth); - const emptyBallotHash = emptyBallot.hash(); - this.ballotTree = new IncrementalQuinTree(this.stateTreeDepth, emptyBallot.hash(), STATE_TREE_ARITY, hash5); - this.ballotTree.insert(emptyBallotHash); + this.emptyBallotHash = this.emptyBallot.hash(); + this.ballotTree = new IncrementalQuinTree(this.stateTreeDepth, this.emptyBallotHash, STATE_TREE_ARITY, hash5); + this.ballotTree.insert(this.emptyBallot.hash()); + // we fill the ballotTree with empty ballots hashes to match the number of signups in the tree while (this.ballots.length < this.stateLeaves.length) { - this.ballotTree.insert(emptyBallotHash); - this.ballots.push(emptyBallot); + this.ballotTree.insert(this.emptyBallotHash); + this.ballots.push(this.emptyBallot); } - this.numSignUps = Number(this.maciStateRef.numSignUps.toString()); - this.stateCopied = true; }; /** - * Process one message at index `index`. - * @param index - The index of the message to process. + * Process one message. + * @param message - The message to process. + * @param encPubKey - The public key associated with the encryption private key. * @returns A number of variables which will be used in the zk-SNARK circuit. */ - private processMessage = (index: number): IProcessMessagesOutput => { - //TODO: throw custom errors for no-ops - + public processMessage = (message: Message, encPubKey: PubKey): IProcessMessagesOutput => { try { - // Ensure that the index is valid - assert(index >= 0); - assert(this.messages.length > index); - - // Ensure that there is the correct number of ECDH shared keys - assert(this.encPubKeys.length === this.messages.length); - - const message = this.messages[index]; - const encPubKey = this.encPubKeys[index]; - // Decrypt the message const sharedKey = Keypair.genEcdhSharedKey(this.coordinatorKeypair.privKey, encPubKey); + const { command, signature } = PCommand.decrypt(message, sharedKey); const stateLeafIndex = BigInt(`${command.stateIndex}`); // If the state tree index in the command is invalid, do nothing - if (stateLeafIndex >= BigInt(this.ballots.length) || stateLeafIndex < BigInt(1)) { - throw Error("no-op"); - } - - if (stateLeafIndex >= BigInt(this.stateTree.nextIndex)) { - return {}; + if ( + stateLeafIndex >= BigInt(this.ballots.length) || + stateLeafIndex < BigInt(1) || + stateLeafIndex >= BigInt(this.stateTree.nextIndex) + ) { + throw new ProcessMessageError(ProcessMessageErrors.InvalidStateLeafIndex); } // The user to update (or not) @@ -218,74 +201,86 @@ export class Poll implements IPoll { // If the signature is invalid, do nothing if (!command.verifySignature(signature, stateLeaf.pubKey)) { - throw Error("no-op"); + throw new ProcessMessageError(ProcessMessageErrors.InvalidSignature); } // If the nonce is invalid, do nothing if (command.nonce !== BigInt(`${ballot.nonce}`) + BigInt(1)) { - throw Error("no-op"); + throw new ProcessMessageError(ProcessMessageErrors.InvalidNonce); } - const prevSpentCred = ballot.votes[Number(command.voteOptionIndex)]; + // If the vote option index is invalid, do nothing + if (command.voteOptionIndex < BigInt(0) || command.voteOptionIndex >= BigInt(this.maxValues.maxVoteOptions)) { + throw new ProcessMessageError(ProcessMessageErrors.InvalidVoteOptionIndex); + } + const voteOptionIndex = Number(command.voteOptionIndex); + const originalVoteWeight = ballot.votes[voteOptionIndex]; + + // the voice credits left are: + // voiceCreditsBalance (how many the user has) + + // voiceCreditsPreviouslySpent (the original vote weight for this option) ** 2 - + // command.newVoteWeight ** 2 (the new vote weight squared) + // basically we are replacing the previous vote weight for this + // particular vote option with the new one + // but we need to ensure that we are not going >= balance const voiceCreditsLeft = BigInt(`${stateLeaf.voiceCreditBalance}`) + - BigInt(`${prevSpentCred}`) * BigInt(`${prevSpentCred}`) - + BigInt(`${originalVoteWeight}`) * BigInt(`${originalVoteWeight}`) - BigInt(`${command.newVoteWeight}`) * BigInt(`${command.newVoteWeight}`); // If the remaining voice credits is insufficient, do nothing if (voiceCreditsLeft < BigInt(0)) { - throw Error("no-op"); - } - - // If the vote option index is invalid, do nothing - if (command.voteOptionIndex < BigInt(0) || command.voteOptionIndex >= BigInt(this.maxValues.maxVoteOptions)) { - throw Error("no-op"); + throw new ProcessMessageError(ProcessMessageErrors.InsufficientVoiceCredits); } // Deep-copy the state leaf and update its attributes const newStateLeaf = stateLeaf.copy(); newStateLeaf.voiceCreditBalance = voiceCreditsLeft; + // if the key changes, this is effectively a key-change message too newStateLeaf.pubKey = command.newPubKey.copy(); // Deep-copy the ballot and update its attributes const newBallot = ballot.copy(); + // increase the nonce newBallot.nonce = BigInt(`${newBallot.nonce}`) + BigInt(1); - newBallot.votes[Number(command.voteOptionIndex)] = command.newVoteWeight; + // we change the vote for this exact vote option + newBallot.votes[voteOptionIndex] = command.newVoteWeight; + // calculate the path elements for the state tree given the original state tree (before any changes) + // changes could effectively be made by this new vote - either a key change or vote change + // would result in a different state leaf const originalStateLeafPathElements = this.stateTree.genMerklePath(Number(stateLeafIndex)).pathElements; - + // calculate the path elements for the ballot tree given the original ballot tree (before any changes) + // changes could effectively be made by this new ballot const originalBallotPathElements = this.ballotTree.genMerklePath(Number(stateLeafIndex)).pathElements; - const voteOptionIndex = Number(command.voteOptionIndex); - - const originalVoteWeight = ballot.votes[voteOptionIndex]; - const vt = new IncrementalQuinTree(this.treeDepths.voteOptionTreeDepth, BigInt(0), 5, hash5); + // create a new quinary tree where we insert the votes of the origin (up until this message is processed) ballot + const vt = new IncrementalQuinTree(this.treeDepths.voteOptionTreeDepth, BigInt(0), STATE_TREE_ARITY, hash5); for (let i = 0; i < this.ballots[0].votes.length; i++) { vt.insert(ballot.votes[i]); } - + // calculate the path elements for the vote option tree given the original vote option tree (before any changes) const originalVoteWeightsPathElements = vt.genMerklePath(voteOptionIndex).pathElements; - + // we return the data which is then to be used in the processMessage circuit + // to generate a proof of processing return { stateLeafIndex: Number(stateLeafIndex), - newStateLeaf, originalStateLeaf: stateLeaf.copy(), originalStateLeafPathElements, originalVoteWeight, originalVoteWeightsPathElements, - newBallot, originalBallot: ballot.copy(), originalBallotPathElements, command, }; } catch (e) { - //TODO: throw custom errors for no-ops - switch (e.message) { - default: - throw Error("no-op"); + if (e instanceof ProcessMessageError) { + throw e; + } else { + throw new ProcessMessageError(ProcessMessageErrors.FailedDecryption); } } }; @@ -295,20 +290,24 @@ export class Poll implements IPoll { * @param message - The message to top up the voice credit balance */ public topupMessage = (message: Message): void => { - assert(message.msgType == BigInt(2)); + assert(message.msgType == BigInt(2), "A Topup message must have msgType 2"); + for (const d of message.data) { - assert((d as bigint) < SNARK_FIELD_SIZE); + assert(d < SNARK_FIELD_SIZE, "The message data is not in the correct range"); } - this.messages.push(message); const padKey = new PubKey([ BigInt("10457101036533406547632367118273992217979173478358440826365724437999023779287"), BigInt("19824078218392094440610104313265183977899662750282163392862422243483260492317"), ]); + // save the message + this.messages.push(message); + // save the pad key this.encPubKeys.push(padKey); - const messageLeaf = message.hash(padKey); - this.messageTree.insert(messageLeaf); + // insert the message into the message tree + this.messageTree.insert(message.hash(padKey)); + // we create a topup command and save it const command = new TCommand(message.data[0], message.data[1], BigInt(this.pollId)); this.commands.push(command as ICommand); }; @@ -320,27 +319,32 @@ export class Poll implements IPoll { * @param encPubKey - The public key used to encrypt the message */ public publishMessage = (message: Message, encPubKey: PubKey): void => { - assert(message.msgType == BigInt(1)); + assert(message.msgType == BigInt(1), "A vote or key change message must have msgType 1"); assert( - (encPubKey.rawPubKey[0] as bigint) < SNARK_FIELD_SIZE && (encPubKey.rawPubKey[1] as bigint) < SNARK_FIELD_SIZE, + encPubKey.rawPubKey[0] < SNARK_FIELD_SIZE && encPubKey.rawPubKey[1] < SNARK_FIELD_SIZE, + "The public key is not in the correct range", ); for (const d of message.data) { - assert((d as bigint) < SNARK_FIELD_SIZE); + assert(d < SNARK_FIELD_SIZE, "The message data is not in the correct range"); } + // store the encryption pub key this.encPubKeys.push(encPubKey); + // store the message locally this.messages.push(message); - - const messageLeaf = message.hash(encPubKey); - this.messageTree.insert(messageLeaf); + // add the message hash to the message tree + this.messageTree.insert(message.hash(encPubKey)); // Decrypt the message and store the Command + // step 1. we generate the shared key const sharedKey = Keypair.genEcdhSharedKey(this.coordinatorKeypair.privKey, encPubKey); try { + // step 2. we decrypt it const { command } = PCommand.decrypt(message, sharedKey); + // step 3. we store it in the commands array this.commands.push(command as ICommand); } catch (e) { - //console.log(`error cannot decrypt: ${e.message}`) + // if there is an error we store an empty command const keyPair = new Keypair(); const command = new PCommand(BigInt(0), keyPair.pubKey, BigInt(0), BigInt(0), BigInt(0), BigInt(0), BigInt(0)); this.commands.push(command as ICommand); @@ -387,10 +391,10 @@ export class Poll implements IPoll { // Note that we process messages in reverse order. // e.g if there are 8 messages and the batch size is 5, then // the starting index should be 5. - assert(this.currentMessageBatchIndex == undefined); - } - - if (this.numBatchesProcessed === 0) { + assert( + this.currentMessageBatchIndex == undefined, + "The current message batch index should not be defined if this is the first batch", + ); // Prevent other polls from being processed until this poll has // been fully processed this.maciStateRef.pollBeingProcessed = true; @@ -399,18 +403,15 @@ export class Poll implements IPoll { // Only allow one poll to be processed at a time if (this.maciStateRef.pollBeingProcessed) { - assert(this.maciStateRef.currentPollBeingProcessed === pollId); + assert(this.maciStateRef.currentPollBeingProcessed === pollId, "Another poll is currently being processed"); } if (this.numBatchesProcessed === 0) { const r = this.messages.length % batchSize; - if (r === 0) { - this.currentMessageBatchIndex = Math.floor(this.messages.length / batchSize) * batchSize; - } else { - this.currentMessageBatchIndex = this.messages.length; - } + this.currentMessageBatchIndex = this.messages.length; + // if there are messages if (this.currentMessageBatchIndex > 0) { if (r === 0) { this.currentMessageBatchIndex -= batchSize; @@ -423,9 +424,11 @@ export class Poll implements IPoll { } // The starting index must be valid - assert(this.currentMessageBatchIndex >= 0); - assert(this.currentMessageBatchIndex % batchSize === 0); + assert(this.currentMessageBatchIndex >= 0, "The starting index must be >= 0"); + assert(this.currentMessageBatchIndex % batchSize === 0, "The starting index must be a multiple of the batch size"); + // ensure we copy the state from MACI when we start processing the + // first batch if (!this.stateCopied) { this.copyStateFromMaci(); } @@ -433,126 +436,155 @@ export class Poll implements IPoll { // Generate circuit inputs const circuitInputs = stringifyBigInts( this.genProcessMessagesCircuitInputsPartial(this.currentMessageBatchIndex), - ) as Record; + ) as CircuitInputs; + // we want to store the state leaves at this point in time + // and the path elements of the state tree const currentStateLeaves: StateLeaf[] = []; - const currentStateLeavesPathElements: any[] = []; + const currentStateLeavesPathElements: PathElements[] = []; + // we want to store the ballots at this point in time + // and the path elements of the ballot tree const currentBallots: Ballot[] = []; - const currentBallotsPathElements: any[] = []; + const currentBallotsPathElements: PathElements[] = []; + // we want to store the vote weights at this point in time + // and the path elements of the vote weight tree const currentVoteWeights: bigint[] = []; - const currentVoteWeightsPathElements: any[] = []; + const currentVoteWeightsPathElements: PathElements[] = []; + // loop through the batch of messages for (let i = 0; i < batchSize; i++) { + // we process the messages in reverse order const idx = this.currentMessageBatchIndex + batchSize - i - 1; - assert(idx >= 0); + assert(idx >= 0, "The message index must be >= 0"); let message: Message; - if (idx >= this.messages.length) { - message = new Message(BigInt(1), Array(10).fill(BigInt(0))); // when idx large than actual size, just use something to pass to switch - } else { + let encPubKey: PubKey; + if (idx < this.messages.length) { message = this.messages[idx]; - } - switch (message.msgType) { - case BigInt(1): - try { - // If the command is valid - const r = this.processMessage(idx); - // console.log(messageIndex, r ? 'valid' : 'invalid') - // console.log("r:"+r.newStateLeaf ) - // DONE: replace with try/catch after implementing error - // handling - const index = r.stateLeafIndex; - - currentStateLeaves.unshift(r.originalStateLeaf); - currentBallots.unshift(r.originalBallot); - currentVoteWeights.unshift(r.originalVoteWeight); - currentVoteWeightsPathElements.unshift(r.originalVoteWeightsPathElements); - - currentStateLeavesPathElements.unshift(r.originalStateLeafPathElements); - currentBallotsPathElements.unshift(r.originalBallotPathElements); - - this.stateLeaves[index] = r.newStateLeaf.copy(); - this.stateTree.update(index, r.newStateLeaf.hash()); - - this.ballots[index] = r.newBallot; - this.ballotTree.update(index, r.newBallot.hash()); - } catch (e) { - if (e.message === "no-op") { - // Since the command is invalid, use a blank state leaf - currentStateLeaves.unshift(this.stateLeaves[0].copy()); - currentStateLeavesPathElements.unshift(this.stateTree.genMerklePath(0).pathElements); - - currentBallots.unshift(this.ballots[0].copy()); - currentBallotsPathElements.unshift(this.ballotTree.genMerklePath(0).pathElements); - - // Since the command is invalid, use vote option index 0 - currentVoteWeights.unshift(this.ballots[0].votes[0]); - - // No need to iterate through the entire votes array if the - // remaining elements are 0 - let lastIndexToInsert = this.ballots[0].votes.length - 1; - while (lastIndexToInsert > 0) { - if (this.ballots[0].votes[lastIndexToInsert] === BigInt(0)) { - lastIndexToInsert--; - } else { - break; - } + encPubKey = this.encPubKeys[idx]; + + // based on the message type we have to process it differently + switch (message.msgType) { + case BigInt(1): + try { + // check if the command is valid + const r = this.processMessage(message, encPubKey); + const index = r.stateLeafIndex; + + // we add at position 0 the original data + currentStateLeaves.unshift(r.originalStateLeaf); + currentBallots.unshift(r.originalBallot); + currentVoteWeights.unshift(r.originalVoteWeight); + currentVoteWeightsPathElements.unshift(r.originalVoteWeightsPathElements); + currentStateLeavesPathElements.unshift(r.originalStateLeafPathElements); + currentBallotsPathElements.unshift(r.originalBallotPathElements); + + // update the state leaves with the new state leaf (result of processing the message) + this.stateLeaves[index] = r.newStateLeaf.copy(); + // we also update the state tree with the hash of the new state leaf + this.stateTree.update(index, r.newStateLeaf.hash()); + // store the new ballot + this.ballots[index] = r.newBallot; + // update the ballot tree + this.ballotTree.update(index, r.newBallot.hash()); + } catch (e) { + // if the error is not a ProcessMessageError we throw it and exit here + // otherwise we continue processing but add the default blank data instead of + // this invalid message + if (e instanceof ProcessMessageError) { + // Since the command is invalid, use a blank state leaf + currentStateLeaves.unshift(this.stateLeaves[0].copy()); + currentStateLeavesPathElements.unshift(this.stateTree.genMerklePath(0).pathElements); + // since the command is invliad we use the blank ballot + currentBallots.unshift(this.ballots[0].copy()); + currentBallotsPathElements.unshift(this.ballotTree.genMerklePath(0).pathElements); + + // Since the command is invalid, we use a zero vote weight + currentVoteWeights.unshift(this.ballots[0].votes[0]); + + // create a new quinary tree and add an empty vote + const vt = new IncrementalQuinTree( + this.treeDepths.voteOptionTreeDepth, + BigInt(0), + STATE_TREE_ARITY, + hash5, + ); + vt.insert(this.ballots[0].votes[0]); + // get the path elements for this empty vote weight leaf + currentVoteWeightsPathElements.unshift(vt.genMerklePath(0).pathElements); + } else { + throw e; } - - const vt = new IncrementalQuinTree(this.treeDepths.voteOptionTreeDepth, BigInt(0), 5, hash5); - for (let i = 0; i <= lastIndexToInsert; i++) { - vt.insert(this.ballots[0].votes[i]); + } + break; + case BigInt(2): + try { + // -------------------------------------- + // generate topup circuit inputs + const stateIndex = Number(message.data[0] >= BigInt(this.ballots.length) ? BigInt(0) : message.data[0]); + const amount = message.data[0] >= BigInt(this.ballots.length) ? BigInt(0) : message.data[1]; + + currentStateLeaves.unshift(this.stateLeaves[stateIndex].copy()); + currentStateLeavesPathElements.unshift(this.stateTree.genMerklePath(stateIndex).pathElements); + + // create a copy of the state leaf + const newStateLeaf = this.stateLeaves[stateIndex].copy(); + // update the voice credit balance + newStateLeaf.voiceCreditBalance = newStateLeaf.voiceCreditBalance + amount; + // save it + this.stateLeaves[stateIndex] = newStateLeaf; + // update the state tree + this.stateTree.update(stateIndex, newStateLeaf.hash()); + + // we still need them as placeholder for vote command + const currentBallot = this.ballots[stateIndex].copy(); + currentBallots.unshift(currentBallot); + currentBallotsPathElements.unshift(this.ballotTree.genMerklePath(Number(stateIndex)).pathElements); + currentVoteWeights.unshift(currentBallot.votes[0]); + + // create a quinary tree to fill with the votes of the current ballot + const vt = new IncrementalQuinTree( + this.treeDepths.voteOptionTreeDepth, + BigInt(0), + STATE_TREE_ARITY, + hash5, + ); + for (let i = 0; i < this.ballots[0].votes.length; i++) { + vt.insert(currentBallot.votes[i]); } + + // add to the first position the path elements of the vote weight tree currentVoteWeightsPathElements.unshift(vt.genMerklePath(0).pathElements); - } else { + } catch (e) { + console.log("Error processing topup message: ", e.message); throw e; } - } - break; - case BigInt(2): - try { - // -------------------------------------- - // generate topup circuit inputs - let stateIndex = BigInt(message.data[0]); - let amount = BigInt(message.data[1]); - - if (stateIndex >= BigInt(this.ballots.length)) { - stateIndex = BigInt(0); - amount = BigInt(0); - } - - currentStateLeaves.unshift(this.stateLeaves[Number(stateIndex)].copy()); - currentStateLeavesPathElements.unshift(this.stateTree.genMerklePath(Number(stateIndex)).pathElements); - - const newStateLeaf = this.stateLeaves[Number(stateIndex)].copy(); - newStateLeaf.voiceCreditBalance = BigInt(newStateLeaf.voiceCreditBalance.valueOf()) + BigInt(amount); - this.stateLeaves[Number(stateIndex)] = newStateLeaf; - this.stateTree.update(Number(stateIndex), newStateLeaf.hash()); - - // we still need them as placeholder for vote command - const currentBallot = this.ballots[Number(stateIndex)].copy(); - currentBallots.unshift(currentBallot); - currentBallotsPathElements.unshift(this.ballotTree.genMerklePath(Number(stateIndex)).pathElements); - currentVoteWeights.unshift(currentBallot.votes[0]); - - const vt = new IncrementalQuinTree(this.treeDepths.voteOptionTreeDepth, BigInt(0), 5, hash5); - for (let i = 0; i < this.ballots[0].votes.length; i++) { - vt.insert(currentBallot.votes[i]); - } - - currentVoteWeightsPathElements.unshift(vt.genMerklePath(0).pathElements); - } catch (e) { - console.error("An error occurred: ", e.message); - throw e; - } - break; - default: - break; - } // end msgType switch + break; + default: + break; + } + } else { + // Since we don't have a command at that position, use a blank state leaf + currentStateLeaves.unshift(this.stateLeaves[0].copy()); + currentStateLeavesPathElements.unshift(this.stateTree.genMerklePath(0).pathElements); + // since the command is invliad we use the blank ballot + currentBallots.unshift(this.ballots[0].copy()); + currentBallotsPathElements.unshift(this.ballotTree.genMerklePath(0).pathElements); + + // Since the command is invalid, we use a zero vote weight + currentVoteWeights.unshift(this.ballots[0].votes[0]); + + // create a new quinary tree and add an empty vote + const vt = new IncrementalQuinTree(this.treeDepths.voteOptionTreeDepth, BigInt(0), STATE_TREE_ARITY, hash5); + vt.insert(this.ballots[0].votes[0]); + + // get the path elements for this empty vote weight leaf + currentVoteWeightsPathElements.unshift(vt.genMerklePath(0).pathElements); + } } - // loop for batch + // store the data in the circuit inputs object circuitInputs.currentStateLeaves = currentStateLeaves.map((x) => x.asCircuitInputs()); circuitInputs.currentStateLeavesPathElements = currentStateLeavesPathElements; circuitInputs.currentBallots = currentBallots.map((x) => x.asCircuitInputs()); @@ -560,22 +592,33 @@ export class Poll implements IPoll { circuitInputs.currentVoteWeights = currentVoteWeights; circuitInputs.currentVoteWeightsPathElements = currentVoteWeightsPathElements; + // record that we processed one batch this.numBatchesProcessed++; if (this.currentMessageBatchIndex > 0) { this.currentMessageBatchIndex -= batchSize; } - // TODO: ensure newSbSalt differs from currentSbSalt - const newSbSalt = genRandomSalt(); + // ensure newSbSalt differs from currentSbSalt + let newSbSalt = genRandomSalt(); + while (this.sbSalts[this.currentMessageBatchIndex] === newSbSalt) { + newSbSalt = genRandomSalt(); + } this.sbSalts[this.currentMessageBatchIndex] = newSbSalt; + // store the salt in the circuit inputs circuitInputs.newSbSalt = newSbSalt; const newStateRoot = this.stateTree.root; const newBallotRoot = this.ballotTree.root; + // create a commitment to the state and ballot tree roots + // this will be the hash of the roots with a salt circuitInputs.newSbCommitment = hash3([newStateRoot, newBallotRoot, newSbSalt]); + // here is important that a user validates it matches the one in the + // smart contract const coordPubKeyHash = this.coordinatorKeypair.pubKey.hash(); + // create the input hash which is the only public input to the + // process messages circuit circuitInputs.inputHash = sha256Hash([ circuitInputs.packedVals as bigint, coordPubKeyHash, @@ -600,44 +643,59 @@ export class Poll implements IPoll { private genProcessMessagesCircuitInputsPartial = (index: number): CircuitInputs => { const messageBatchSize = this.batchSizes.messageBatchSize; - assert(index <= this.messages.length); - assert(index % messageBatchSize === 0); + assert(index <= this.messages.length, "The index must be <= the number of messages"); + assert(index % messageBatchSize === 0, "The index must be a multiple of the message batch size"); + // fill the msgs array with a copy of the messages we have + // plus empty messages to fill the batch let msgs = this.messages.map((x) => x.asCircuitInputs()); while (msgs.length % messageBatchSize > 0) { msgs.push(msgs[msgs.length - 1]); } - + // we only take the messages we need for this batch msgs = msgs.slice(index, index + messageBatchSize); + // fill the commands array with a copy of the commands we have let commands = this.commands.map((x) => x.copy()); while (commands.length % messageBatchSize > 0) { commands.push(commands[commands.length - 1]); } + // we only take the commands we need for this batch commands = commands.slice(index, index + messageBatchSize); while (this.messageTree.nextIndex < index + messageBatchSize) { this.messageTree.insert(this.messageTree.zeroValue); } + // generate the path to the subroot of the message tree for this batch const messageSubrootPath = this.messageTree.genMerkleSubrootPath(index, index + messageBatchSize); - assert(IncrementalQuinTree.verifyMerklePath(messageSubrootPath, this.messageTree.hashFunc) === true); + assert( + IncrementalQuinTree.verifyMerklePath(messageSubrootPath, this.messageTree.hashFunc) === true, + "The message subroot path is invalid", + ); + // validate that the batch index is correct, if not fix it + // this means that the end will be the last message let batchEndIndex = index + messageBatchSize; if (batchEndIndex > this.messages.length) { batchEndIndex = this.messages.length; } + // copy the public keys, pad the array with the last keys if needed let encPubKeys = this.encPubKeys.map((x) => x.copy()); while (encPubKeys.length % messageBatchSize > 0) { encPubKeys.push(encPubKeys[encPubKeys.length - 1]); } + // then take the ones part of this batch encPubKeys = encPubKeys.slice(index, index + messageBatchSize); const msgRoot = this.messageTree.root; const currentStateRoot = this.stateTree.root; const currentBallotRoot = this.ballotTree.root; + // calculate the current state and ballot root + // commitment which is the hash of the state tree + // root, the ballot tree root and a salt const currentSbCommitment = hash3([ currentStateRoot, currentBallotRoot, @@ -647,12 +705,10 @@ export class Poll implements IPoll { // Generate a SHA256 hash of inputs which the contract provides const packedVals = BigInt(this.maxValues.maxVoteOptions) + - (BigInt(this.numSignUps) << BigInt(50)) + + (BigInt(this.maciStateRef.numSignUps) << BigInt(50)) + (BigInt(index) << BigInt(100)) + (BigInt(batchEndIndex) << BigInt(150)); - const coordPubKey = this.coordinatorKeypair.pubKey; - return stringifyBigInts({ pollEndTimestamp: this.pollEndTimestamp, packedVals, @@ -660,7 +716,7 @@ export class Poll implements IPoll { msgs, msgSubrootPathElements: messageSubrootPath.pathElements, coordPrivKey: this.coordinatorKeypair.privKey.asCircuitInputs(), - coordPubKey: coordPubKey.asCircuitInputs(), + coordPubKey: this.coordinatorKeypair.pubKey.asCircuitInputs(), encPubKeys: encPubKeys.map((x) => x.asCircuitInputs()), currentStateRoot, currentBallotRoot, @@ -676,11 +732,10 @@ export class Poll implements IPoll { * @returns The state leaves and ballots of the poll */ public processAllMessages = (): { stateLeaves: StateLeaf[]; ballots: Ballot[] } => { - if (!this.stateCopied) { - this.copyStateFromMaci(); - } const stateLeaves = this.stateLeaves.map((x) => x.copy()); const ballots = this.ballots.map((x) => x.copy()); + + // process all messages in one go (batch by batch but without manual intervention) while (this.hasUnprocessedMessages()) { this.processMessages(this.pollId); } @@ -747,7 +802,7 @@ export class Poll implements IPoll { this.subsidySalts[saltIndex] = newSubsidySalt; const newSubsidyCommitment = genTreeCommitment(this.subsidy, newSubsidySalt, this.treeDepths.voteOptionTreeDepth); - const packedVals = packSubsidySmallVals(this.rbi, this.cbi, this.numSignUps); + const packedVals = packSubsidySmallVals(this.rbi, this.cbi, this.maciStateRef.numSignUps); const inputHash = sha256Hash([packedVals, sbCommitment, currentSubsidyCommitment, newSubsidyCommitment]); @@ -803,16 +858,18 @@ export class Poll implements IPoll { const numBatches = Math.ceil(this.ballots.length / batchSize); let cbi = this.cbi; let rbi = this.rbi; + if (this.cbi === 0 && this.rbi === 0) { return "0-0"; } + if (this.cbi > this.rbi) { cbi--; } else { rbi--; cbi = numBatches - 1; } - return rbi.toString() + "-" + cbi.toString(); + return `${rbi.toString()}-${cbi.toString()}`; }; /** @@ -842,6 +899,7 @@ export class Poll implements IPoll { const ballots1: Ballot[] = []; const ballots2: Ballot[] = []; const emptyBallot = new Ballot(this.maxValues.maxVoteOptions, this.treeDepths.voteOptionTreeDepth); + for (let i = 0; i < batchSize; i++) { const row = rowStartIndex + i; const col = colStartIndex + i; @@ -967,14 +1025,12 @@ export class Poll implements IPoll { newPerVOSpentVoiceCreditsCommitment, ]); - //debugger - - const stateRoot = this.stateTree.root as bigint; - const ballotRoot = this.ballotTree.root as bigint; + const stateRoot = this.stateTree.root; + const ballotRoot = this.ballotTree.root; const sbSalt = this.sbSalts[this.currentMessageBatchIndex]; const sbCommitment = hash3([stateRoot, ballotRoot, sbSalt]); - const packedVals = packTallyVotesSmallVals(batchStartIndex, batchSize, this.numSignUps); + const packedVals = packTallyVotesSmallVals(batchStartIndex, batchSize, this.maciStateRef.numSignUps); const inputHash = sha256Hash([packedVals, sbCommitment, currentTallyCommitment, newTallyCommitment]); const ballotSubrootProof = this.ballotTree.genMerkleSubrootPath(batchStartIndex, batchStartIndex + batchSize); @@ -1105,7 +1161,6 @@ export class Poll implements IPoll { */ public copy = (): Poll => { const copied = new Poll( - Number(this.duration.toString()), BigInt(this.pollEndTimestamp.toString()), this.coordinatorKeypair.copy(), { @@ -1124,7 +1179,6 @@ export class Poll implements IPoll { maxVoteOptions: Number(this.maxValues.maxVoteOptions.toString()), }, this.maciStateRef, - this.stateTreeDepth, ); copied.stateLeaves = this.stateLeaves.map((x) => x.copy()); @@ -1185,7 +1239,6 @@ export class Poll implements IPoll { */ public equals = (p: Poll): boolean => { const result = - this.duration === p.duration && this.coordinatorKeypair.equals(p.coordinatorKeypair) && this.treeDepths.intStateTreeDepth === p.treeDepths.intStateTreeDepth && this.treeDepths.messageTreeDepth === p.treeDepths.messageTreeDepth && @@ -1219,7 +1272,6 @@ export class Poll implements IPoll { */ toJSON(): IJsonPoll { return { - duration: this.duration, pollEndTimestamp: this.pollEndTimestamp.toString(), treeDepths: this.treeDepths, batchSizes: this.batchSizes, @@ -1243,14 +1295,12 @@ export class Poll implements IPoll { */ static fromJSON(json: IJsonPoll, maciState: MaciState): Poll { const poll = new Poll( - json.duration, BigInt(json.pollEndTimestamp), new Keypair(), json.treeDepths, json.batchSizes, json.maxValues, maciState, - maciState.stateTreeDepth, ); // set all properties diff --git a/core/ts/__tests__/MaciState.test.ts b/core/ts/__tests__/MaciState.test.ts index b4d62b6bf7..595f25faad 100644 --- a/core/ts/__tests__/MaciState.test.ts +++ b/core/ts/__tests__/MaciState.test.ts @@ -74,7 +74,6 @@ describe("MaciState", function () { it("the message root should be correct", () => { pollId = maciState.deployPoll( - duration, BigInt(Math.floor(Date.now() / 1000) + duration), maxValues, treeDepths, @@ -172,7 +171,6 @@ describe("MaciState", function () { } pollId = maciState.deployPoll( - duration, BigInt(Math.floor(Date.now() / 1000) + duration), maxValues, treeDepths, @@ -306,7 +304,6 @@ describe("MaciState", function () { m1 = new MaciState(STATE_TREE_DEPTH); m1.signUp(userKeypair.pubKey, voiceCreditBalance, BigInt(Math.floor(Date.now() / 1000))); pollId = m1.deployPoll( - duration, BigInt(Math.floor(Date.now() / 1000) + duration), maxValues, treeDepths, @@ -348,11 +345,6 @@ describe("MaciState", function () { m4.stateLeaves[0].voiceCreditBalance = BigInt(m4.stateLeaves[0].voiceCreditBalance) + BigInt(1); expect(m1.equals(m4)).not.to.be.true; - // modify poll.duration - const m5 = m1.copy(); - m5.polls[pollId].duration = m5.polls[pollId].duration + 1; - expect(m1.equals(m5)).not.to.be.true; - // modify poll.coordinatorKeypair const m6 = m1.copy(); m6.polls[pollId].coordinatorKeypair = new Keypair(); @@ -455,7 +447,6 @@ describe("MaciState", function () { // deploy a poll pollId = maciState.deployPoll( - duration, BigInt(Math.floor(Date.now() / 1000) + duration), maxValues, treeDepths, @@ -555,7 +546,6 @@ describe("MaciState", function () { // deploy a poll pollId = maciState.deployPoll( - duration, BigInt(Math.floor(Date.now() / 1000) + duration), maxValues, treeDepths, @@ -670,7 +660,6 @@ describe("MaciState", function () { // deploy a poll pollId = maciState.deployPoll( - duration, BigInt(Math.floor(Date.now() / 1000) + duration), maxValues, treeDepths, diff --git a/core/ts/__tests__/constants.ts b/core/ts/__tests__/constants.ts new file mode 100644 index 0000000000..ce60e9d392 --- /dev/null +++ b/core/ts/__tests__/constants.ts @@ -0,0 +1,18 @@ +import { Keypair } from "maci-domainobjs"; + +export const voiceCreditBalance = BigInt(100); +export const duration = 30; +export const messageBatchSize = 25; +export const coordinatorKeypair = new Keypair(); +export const maxValues = { + maxUsers: 25, + maxMessages: 25, + maxVoteOptions: 25, +}; + +export const treeDepths = { + intStateTreeDepth: 2, + messageTreeDepth: 3, + messageTreeSubDepth: 2, + voteOptionTreeDepth: 4, +}; diff --git a/core/ts/__tests__/utils.ts b/core/ts/__tests__/utils.ts new file mode 100644 index 0000000000..fa5b637345 --- /dev/null +++ b/core/ts/__tests__/utils.ts @@ -0,0 +1,6 @@ +/** + * Calculates the total of a tally result + * @param tallyResult - the tally result + * @returns the total of the tally result + */ +export const calculateTotal = (tallyResult: bigint[]): bigint => tallyResult.reduce((acc, v) => acc + v, BigInt(0)); diff --git a/core/ts/utils/errors.ts b/core/ts/utils/errors.ts new file mode 100644 index 0000000000..3eb7e3fa12 --- /dev/null +++ b/core/ts/utils/errors.ts @@ -0,0 +1,29 @@ +/** + * An enum describing the possible errors that can occur + * in Poll.processMessage() + */ +export enum ProcessMessageErrors { + InvalidCommand = "invalid command", + InvalidStateLeafIndex = "invalid state leaf index", + InvalidSignature = "invalid signature", + InvalidNonce = "invalid nonce", + InsufficientVoiceCredits = "insufficient voice credits", + InvalidVoteOptionIndex = "invalid vote option index", + FailedDecryption = "failed decryption due to either wrong encryption public key or corrupted ciphertext", +} + +/** + * A class which extends the Error class + * which is to be used when an error occurs + * in Poll.processMessage() + */ +export class ProcessMessageError extends Error { + /** + * Generate a new instance of the ProcessMessageError class + * @param code - the error code + */ + constructor(public code: ProcessMessageErrors) { + super(code); + this.name = this.constructor.name; + } +} diff --git a/core/ts/utils/types.ts b/core/ts/utils/types.ts index 1739a4a213..2e8ac887a9 100644 --- a/core/ts/utils/types.ts +++ b/core/ts/utils/types.ts @@ -19,7 +19,7 @@ import { PathElements } from "optimisedmt"; /** * A circuit inputs for the circom circuit */ -export type CircuitInputs = Record; +export type CircuitInputs = Record; /** * This interface defines the tree depths. @@ -65,7 +65,6 @@ export interface IMaciState { signUp(pubKey: PubKey, initialVoiceCreditBalance: bigint, timestamp: bigint): number; // This method is used for deploying poll. deployPoll( - duration: number, pollEndTimestamp: bigint, maxValues: MaxValues, treeDepths: TreeDepths, @@ -76,7 +75,7 @@ export interface IMaciState { deployNullPoll(): void; copy(): MaciState; equals(m: MaciState): boolean; - toJSON(): any; + toJSON(): IJsonMaciState; } /** @@ -97,7 +96,7 @@ export interface IPoll { subsidyPerBatch(): CircuitInputs; copy(): Poll; equals(p: Poll): boolean; - toJSON(): any; + toJSON(): IJsonPoll; setCoordinatorKeypair(serializedPrivateKey: string): void; } @@ -105,7 +104,6 @@ export interface IPoll { * This interface defines the JSON representation of a Poll */ export interface IJsonPoll { - duration: number; pollEndTimestamp: string; treeDepths: TreeDepths; batchSizes: BatchSizes; diff --git a/integrationTests/ts/__tests__/integration.test.ts b/integrationTests/ts/__tests__/integration.test.ts index bca6f58046..2762e21ff1 100644 --- a/integrationTests/ts/__tests__/integration.test.ts +++ b/integrationTests/ts/__tests__/integration.test.ts @@ -118,7 +118,6 @@ describe("integration tests", function test() { const messageBatchSize = 5 ** messageBatchDepth; pollId = maciState.deployPoll( - duration, BigInt(Date.now() + duration * 60000), maxValues, treeDepths, From 70398226c5d8285d8222ee8eefddc56a75e7c9fd Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Wed, 13 Dec 2023 23:36:28 +0000 Subject: [PATCH 04/37] ci(ceremony): setup nightly workflow to test ceremony artifacts --- .github/scripts/ceremony-param-tests.sh | 64 +++++++++++++++++++ .../scripts/download-ceremony-artifacts.sh | 15 +++++ .github/workflows/nightly-ceremony.yml | 54 ++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100755 .github/scripts/ceremony-param-tests.sh create mode 100755 .github/scripts/download-ceremony-artifacts.sh create mode 100644 .github/workflows/nightly-ceremony.yml diff --git a/.github/scripts/ceremony-param-tests.sh b/.github/scripts/ceremony-param-tests.sh new file mode 100755 index 0000000000..2f0b4feef8 --- /dev/null +++ b/.github/scripts/ceremony-param-tests.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +set -e + +cd "$(dirname "$0")" +cd ../../cli + +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js deployVkRegistry -q true +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js setVerifyingKeys \ + --state-tree-depth 6 \ + --int-state-tree-depth 2 \ + --msg-tree-depth 8 \ + --vote-option-tree-depth 3 \ + --msg-batch-depth 2 \ + --process-messages-zkey ./zkeys/processmessages_6-8-2-3_final.zkey \ + --tally-votes-zkey ./zkeys/tallyvotes_6-2-3_final.zkey \ + -q true +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js create -s 6 -q true +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js deployPoll \ + -pk macipk.c974f4f168b79727ac98bfd53a65ea0b4e45dc2552fe73df9f8b51ebb0930330 \ + -t 30 -g 25 -mv 25 -i 2 -m 8 -b 2 -v 3 -q true +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js signup \ + --pubkey macipk.3e7bb2d7f0a1b7e980f1b6f363d1e3b7a12b9ae354c2cd60a9cfa9fd12917391 \ + -q true +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js publish \ + --pubkey macipk.3e7bb2d7f0a1b7e980f1b6f363d1e3b7a12b9ae354c2cd60a9cfa9fd12917391 \ + --privkey macisk.fd7aa614ec4a82716ffc219c24fd7e7b52a2b63b5afb17e81c22fe21515539c \ + --state-index 1 \ + --vote-option-index 0 \ + --new-vote-weight 9 \ + --nonce 1 \ + --poll-id 0 \ + -q true +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js publish \ + --pubkey macipk.d5788ea6ccf1ec295df99aaef859031fe7bd359e7e03acb80eb6e8a192f2ce19 \ + --privkey macisk.fd7aa614ec4a82716ffc219c24fd7e7b52a2b63b5afb17e81c22fe21515539c \ + --state-index 1 \ + --vote-option-index 1 \ + --new-vote-weight 9 \ + --nonce 2 \ + --poll-id 0 \ + -q true +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js timeTravel -s 100 -q true +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js mergeSignups --poll-id 0 -q true +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js mergeMessages --poll-id 0 -q true +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js genProofs \ + --privkey macisk.49953af3585856f539d194b46c82f4ed54ec508fb9b882940cbe68bbc57e59e \ + --poll-id 0 \ + --rapidsnark ~/rapidsnark/build/prover \ + --process-zkey ./zkeys/processmessages_6-8-2-3_final.zkey \ + --tally-zkey ./zkeys/tallyvotes_6-2-3_final.zkey \ + --tally-file tally.json \ + --output proofs/ \ + --tally-witnessgen ./zkeys/tallyVotes_6-2-3 \ + --process-witnessgen ./zkeys/processMessages_6-8-2-3 \ + -q true +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js proveOnChain \ + --poll-id 0 \ + --proof-dir proofs/ \ + -q true +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js verify \ + --poll-id 0 \ + --tally-file tally.json \ + -q true diff --git a/.github/scripts/download-ceremony-artifacts.sh b/.github/scripts/download-ceremony-artifacts.sh new file mode 100755 index 0000000000..ae3a996824 --- /dev/null +++ b/.github/scripts/download-ceremony-artifacts.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e + +cd "$(dirname "$0")" +cd .. +mkdir -p ../cli/zkeys + +URL=https://maci-develop-fra.s3.eu-central-1.amazonaws.com/v1.2.0/maci_keys_6-8-2-3_ceremony.tar.gz +DIR_NAME="maci_keys.tar.gz" +OUT_DIR=../cli/ + +echo "downloading $URL" +curl $URL -o "$OUT_DIR/$DIR_NAME" +tar -xvf "$OUT_DIR/$DIR_NAME" -C "$OUT_DIR" diff --git a/.github/workflows/nightly-ceremony.yml b/.github/workflows/nightly-ceremony.yml new file mode 100644 index 0000000000..560072b7d5 --- /dev/null +++ b/.github/workflows/nightly-ceremony.yml @@ -0,0 +1,54 @@ +name: Nightly Ceremony + +on: + push: + pull_request: + +jobs: + test-with-ceremony-keys: + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v4 + + - name: Use Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install --yes \ + build-essential \ + libgmp-dev \ + libsodium-dev \ + nasm \ + nlohmann-json3-dev + + - name: Initialize Project + run: | + npm install + npm run bootstrap + npm run build + + - name: Compile contracts with ceremony params and run hardhat fork + run: | + cd contracts + npm run compileSol 6 + npm run hardhat & + + - name: Download rapidsnark (1c137) + run: | + mkdir -p ~/rapidsnark/build + wget -qO ~/rapidsnark/build/prover https://maci-devops-zkeys.s3.ap-northeast-2.amazonaws.com/rapidsnark-linux-amd64-1c137 + chmod +x ~/rapidsnark/build/prover + + - name: Download ceremony artifacts + run: ./.github/scripts/download-ceremony-artifacts.sh + + - name: Run tests + run: ./.github/scripts/ceremony-param-tests.sh + + - name: Stop Hardhat + run: kill $(lsof -t -i:8545) From 58611dbf62f2dc01cf978d6bf01cf15bdef77356 Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Thu, 14 Dec 2023 16:19:56 +0000 Subject: [PATCH 05/37] test(ceremony): add circuit tests with ceremony params Add processMessages and tallyVotes tests in the circuits package to ensure that we validate they work with the ceremony parameters --- ...s.sh => ceremony-param-tests-c-witness.sh} | 17 +- .../scripts/download-ceremony-artifacts.sh | 2 +- .github/workflows/nightly-ceremony.yml | 10 +- .../processMessages_test.circom | 10 + .../ceremonyParams/tallyVotes_test.circom | 7 + circuits/package.json | 3 +- circuits/ts/__tests__/CeremonyParams.test.ts | 285 ++++++++++++++++++ cli/ts/commands/genProofs.ts | 3 +- cli/ts/commands/setVerifyingKeys.ts | 6 +- cli/ts/index.ts | 1 + 10 files changed, 328 insertions(+), 16 deletions(-) rename .github/scripts/{ceremony-param-tests.sh => ceremony-param-tests-c-witness.sh} (85%) create mode 100644 circuits/circom/test/ceremonyParams/processMessages_test.circom create mode 100644 circuits/circom/test/ceremonyParams/tallyVotes_test.circom create mode 100644 circuits/ts/__tests__/CeremonyParams.test.ts diff --git a/.github/scripts/ceremony-param-tests.sh b/.github/scripts/ceremony-param-tests-c-witness.sh similarity index 85% rename from .github/scripts/ceremony-param-tests.sh rename to .github/scripts/ceremony-param-tests-c-witness.sh index 2f0b4feef8..bb4cfcffbf 100755 --- a/.github/scripts/ceremony-param-tests.sh +++ b/.github/scripts/ceremony-param-tests-c-witness.sh @@ -12,13 +12,20 @@ HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js setVerifyingKeys --msg-tree-depth 8 \ --vote-option-tree-depth 3 \ --msg-batch-depth 2 \ - --process-messages-zkey ./zkeys/processmessages_6-8-2-3_final.zkey \ - --tally-votes-zkey ./zkeys/tallyvotes_6-2-3_final.zkey \ + --process-messages-zkey ./zkeys/processMessages_6-8-2-3.zkey \ + --tally-votes-zkey ./zkeys/tallyVotes_6-2-3.zkey \ -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js create -s 6 -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js deployPoll \ -pk macipk.c974f4f168b79727ac98bfd53a65ea0b4e45dc2552fe73df9f8b51ebb0930330 \ - -t 30 -g 25 -mv 25 -i 2 -m 8 -b 2 -v 3 -q true + --duration 30 \ + --max-messages 390625 \ + --max-vote-options 125 \ + --int-state-tree-depth 2 \ + --msg-tree-depth 8 \ + --msg-batch-depth 2 \ + --vote-option-tree-depth 3 \ + -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js signup \ --pubkey macipk.3e7bb2d7f0a1b7e980f1b6f363d1e3b7a12b9ae354c2cd60a9cfa9fd12917391 \ -q true @@ -47,8 +54,8 @@ HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js genProofs \ --privkey macisk.49953af3585856f539d194b46c82f4ed54ec508fb9b882940cbe68bbc57e59e \ --poll-id 0 \ --rapidsnark ~/rapidsnark/build/prover \ - --process-zkey ./zkeys/processmessages_6-8-2-3_final.zkey \ - --tally-zkey ./zkeys/tallyvotes_6-2-3_final.zkey \ + --process-zkey ./zkeys/processMessages_6-8-2-3.zkey \ + --tally-zkey ./zkeys/tallyVotes_6-2-3.zkey \ --tally-file tally.json \ --output proofs/ \ --tally-witnessgen ./zkeys/tallyVotes_6-2-3 \ diff --git a/.github/scripts/download-ceremony-artifacts.sh b/.github/scripts/download-ceremony-artifacts.sh index ae3a996824..9c7bd3066b 100755 --- a/.github/scripts/download-ceremony-artifacts.sh +++ b/.github/scripts/download-ceremony-artifacts.sh @@ -6,7 +6,7 @@ cd "$(dirname "$0")" cd .. mkdir -p ../cli/zkeys -URL=https://maci-develop-fra.s3.eu-central-1.amazonaws.com/v1.2.0/maci_keys_6-8-2-3_ceremony.tar.gz +URL=https://maci-develop-fra.s3.eu-central-1.amazonaws.com/v1.2.0/maci-ceremony-artifacts-v1.2.0.tar.gz DIR_NAME="maci_keys.tar.gz" OUT_DIR=../cli/ diff --git a/.github/workflows/nightly-ceremony.yml b/.github/workflows/nightly-ceremony.yml index 560072b7d5..c156b23f38 100644 --- a/.github/workflows/nightly-ceremony.yml +++ b/.github/workflows/nightly-ceremony.yml @@ -1,8 +1,8 @@ name: Nightly Ceremony on: - push: - pull_request: + schedule: + - cron: 0 0 * * * jobs: test-with-ceremony-keys: @@ -10,6 +10,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + ref: dev - name: Use Node.js 20 uses: actions/setup-node@v4 @@ -47,8 +49,8 @@ jobs: - name: Download ceremony artifacts run: ./.github/scripts/download-ceremony-artifacts.sh - - name: Run tests - run: ./.github/scripts/ceremony-param-tests.sh + - name: Run e2e tests + run: ./.github/scripts/ceremony-param-tests-c-witness.sh - name: Stop Hardhat run: kill $(lsof -t -i:8545) diff --git a/circuits/circom/test/ceremonyParams/processMessages_test.circom b/circuits/circom/test/ceremonyParams/processMessages_test.circom new file mode 100644 index 0000000000..5bec01aca8 --- /dev/null +++ b/circuits/circom/test/ceremonyParams/processMessages_test.circom @@ -0,0 +1,10 @@ +pragma circom 2.0.0; +include "../../processMessages.circom"; +/* +stateTreeDepth, +msgTreeDepth, +msgSubTreeDepth +voteOptionTreeDepth, +*/ + +component main {public [inputHash]} = ProcessMessages(6, 8, 2, 3); diff --git a/circuits/circom/test/ceremonyParams/tallyVotes_test.circom b/circuits/circom/test/ceremonyParams/tallyVotes_test.circom new file mode 100644 index 0000000000..4000c82cab --- /dev/null +++ b/circuits/circom/test/ceremonyParams/tallyVotes_test.circom @@ -0,0 +1,7 @@ +pragma circom 2.0.0; +include "../../tallyVotes.circom"; + +component main {public [inputHash]} = TallyVotes(6, 2, 3); +/*stateTreeDepth,*/ +/*intStateTreeDepth,*/ +/*voteOptionTreeDepth*/ diff --git a/circuits/package.json b/circuits/package.json index 1b8548b2a3..019353cd6c 100644 --- a/circuits/package.json +++ b/circuits/package.json @@ -20,7 +20,8 @@ "test-privToPubKey": "ts-mocha --exit ts/__tests__/PrivToPubKey.test.ts", "test-calculateTotal": "ts-mocha --exit ts/__tests__/CalculateTotal.test.ts", "test-processMessages": "NODE_OPTIONS=--max-old-space-size=4096 ts-mocha --exit ts/__tests__/ProcessMessages.test.ts", - "test-tallyVotes": "NODE_OPTIONS=--max-old-space-size=4096 ts-mocha --exit ts/__tests__/TallyVotes.test.ts" + "test-tallyVotes": "NODE_OPTIONS=--max-old-space-size=4096 ts-mocha --exit ts/__tests__/TallyVotes.test.ts", + "test-ceremonyParams": "ts-mocha --exit ts/__tests__/CeremonyParams.test.ts" }, "dependencies": { "circomlib": "https://github.com/weijiekoh/circomlib#ac85e82c1914d47789e2032fb11ceb2cfdd38a2b", diff --git a/circuits/ts/__tests__/CeremonyParams.test.ts b/circuits/ts/__tests__/CeremonyParams.test.ts new file mode 100644 index 0000000000..342622072e --- /dev/null +++ b/circuits/ts/__tests__/CeremonyParams.test.ts @@ -0,0 +1,285 @@ +import { MaciState, Poll, packProcessMessageSmallVals, STATE_TREE_ARITY } from "maci-core"; +import { PrivKey, Keypair, PCommand, Message, Ballot } from "maci-domainobjs"; +import { hash5, IncrementalQuinTree, stringifyBigInts, NOTHING_UP_MY_SLEEVE, AccQueue } from "maci-crypto"; +import path from "path"; +import { expect } from "chai"; +import tester from "circom_tester"; +import { generateRandomIndex, getSignal } from "./utils/utils"; + +describe("Ceremony param tests", function () { + const params = { + // processMessages and Tally + stateTreeDepth: 6, + // processMessages + messageTreeDepth: 8, + // processMessages + messageBatchTreeDepth: 2, + // processMessages and Tally + voteOptionTreeDepth: 3, + // Tally + stateLeafBatchDepth: 2, + }; + + const maxValues = { + maxUsers: STATE_TREE_ARITY ** params.stateTreeDepth, + maxMessages: STATE_TREE_ARITY ** params.messageTreeDepth, + maxVoteOptions: STATE_TREE_ARITY ** params.voteOptionTreeDepth, + }; + + const treeDepths = { + intStateTreeDepth: params.messageBatchTreeDepth, + messageTreeDepth: params.messageTreeDepth, + messageTreeSubDepth: params.messageBatchTreeDepth, + voteOptionTreeDepth: params.voteOptionTreeDepth, + }; + + const messageBatchSize = STATE_TREE_ARITY ** params.messageBatchTreeDepth; + + const voiceCreditBalance = BigInt(100); + const duration = 30; + + const coordinatorKeypair = new Keypair(); + + describe("ProcessMessage circuit", function () { + this.timeout(900000); + + let circuit: tester.WasmTester; + let hasherCircuit: tester.WasmTester; + + before(async () => { + const circuitPath = path.resolve(__dirname, "../../circom/test/ceremonyParams", `processMessages_test.circom`); + circuit = await tester.wasm(circuitPath); + const hasherCircuitPath = path.resolve(__dirname, "../../circom/test/", `processMessagesInputHasher_test.circom`); + hasherCircuit = await tester.wasm(hasherCircuitPath); + }); + + describe("1 user, 2 messages", () => { + const maciState = new MaciState(params.stateTreeDepth); + const voteWeight = BigInt(9); + const voteOptionIndex = BigInt(0); + let stateIndex: bigint; + let pollId: number; + let poll: Poll; + const messages: Message[] = []; + const commands: PCommand[] = []; + + before(async () => { + // Sign up and publish + const userKeypair = new Keypair(new PrivKey(BigInt(1))); + stateIndex = BigInt( + maciState.signUp(userKeypair.pubKey, voiceCreditBalance, BigInt(Math.floor(Date.now() / 1000))), + ); + + pollId = maciState.deployPoll( + BigInt(Math.floor(Date.now() / 1000) + duration), + maxValues, + treeDepths, + messageBatchSize, + coordinatorKeypair, + ); + + poll = maciState.polls[pollId]; + + // First command (valid) + const command = new PCommand( + stateIndex, //BigInt(1), + userKeypair.pubKey, + voteOptionIndex, // voteOptionIndex, + voteWeight, // vote weight + BigInt(2), // nonce + BigInt(pollId), + ); + + const signature = command.sign(userKeypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + const message = command.encrypt(signature, sharedKey); + messages.push(message); + commands.push(command); + + poll.publishMessage(message, ecdhKeypair.pubKey); + + // Second command (valid) + const command2 = new PCommand( + stateIndex, + userKeypair.pubKey, + voteOptionIndex, // voteOptionIndex, + BigInt(1), // vote weight + BigInt(1), // nonce + BigInt(pollId), + ); + const signature2 = command2.sign(userKeypair.privKey); + + const ecdhKeypair2 = new Keypair(); + const sharedKey2 = Keypair.genEcdhSharedKey(ecdhKeypair2.privKey, coordinatorKeypair.pubKey); + const message2 = command2.encrypt(signature2, sharedKey2); + messages.push(message2); + commands.push(command2); + poll.publishMessage(message2, ecdhKeypair2.pubKey); + + // Use the accumulator queue to compare the root of the message tree + const accumulatorQueue: AccQueue = new AccQueue( + params.messageTreeDepth, + STATE_TREE_ARITY, + NOTHING_UP_MY_SLEEVE, + ); + accumulatorQueue.enqueue(message.hash(ecdhKeypair.pubKey)); + accumulatorQueue.enqueue(message2.hash(ecdhKeypair2.pubKey)); + accumulatorQueue.mergeSubRoots(0); + accumulatorQueue.merge(params.messageTreeDepth); + + expect(poll.messageTree.root.toString()).to.be.eq( + accumulatorQueue.mainRoots[params.messageTreeDepth].toString(), + ); + }); + + it("should produce the correct state root and ballot root", async () => { + // The current roots + const emptyBallot = new Ballot(poll.maxValues.maxVoteOptions, poll.treeDepths.voteOptionTreeDepth); + const emptyBallotHash = emptyBallot.hash(); + const ballotTree = new IncrementalQuinTree(params.stateTreeDepth, emptyBallot.hash(), STATE_TREE_ARITY, hash5); + ballotTree.insert(emptyBallot.hash()); + + for (let i = 0; i < poll.stateLeaves.length; i++) { + ballotTree.insert(emptyBallotHash); + } + + const currentStateRoot = maciState.stateTree.root; + const currentBallotRoot = ballotTree.root; + + const generatedInputs = poll.processMessages(pollId); + + // Calculate the witness + const witness = await circuit.calculateWitness(generatedInputs, true); + await circuit.checkConstraints(witness); + + // The new roots, which should differ, since at least one of the + // messages modified a Ballot or State Leaf + const newStateRoot = poll.stateTree.root; + const newBallotRoot = poll.ballotTree.root; + + expect(newStateRoot.toString()).not.to.be.eq(currentStateRoot.toString()); + expect(newBallotRoot.toString()).not.to.be.eq(currentBallotRoot.toString()); + + const packedVals = packProcessMessageSmallVals( + BigInt(maxValues.maxVoteOptions), + BigInt(poll.maciStateRef.numSignUps), + 0, + 2, + ); + + // Test the ProcessMessagesInputHasher circuit + const hasherCircuitInputs = stringifyBigInts({ + packedVals, + coordPubKey: generatedInputs.coordPubKey, + msgRoot: generatedInputs.msgRoot, + currentSbCommitment: generatedInputs.currentSbCommitment, + newSbCommitment: generatedInputs.newSbCommitment, + pollEndTimestamp: generatedInputs.pollEndTimestamp, + }); + + const hasherWitness = await hasherCircuit.calculateWitness(hasherCircuitInputs, true); + await hasherCircuit.checkConstraints(hasherWitness); + const hash = await getSignal(hasherCircuit, hasherWitness, "hash"); + expect(hash.toString()).to.be.eq(generatedInputs.inputHash.toString()); + }); + }); + + describe("TallyVotes circuit", function () { + this.timeout(900000); + + let circuit: tester.WasmTester; + + before(async () => { + const circuitPath = path.resolve(__dirname, "../../circom/test/ceremonyParams", `tallyVotes_test.circom`); + circuit = await tester.wasm(circuitPath); + }); + + describe("1 user, 2 messages", () => { + let stateIndex: bigint; + let pollId: number; + let poll: Poll; + let maciState: MaciState; + const voteWeight = BigInt(9); + const voteOptionIndex = BigInt(0); + + beforeEach(async () => { + maciState = new MaciState(params.stateTreeDepth); + const messages: Message[] = []; + const commands: PCommand[] = []; + // Sign up and publish + const userKeypair = new Keypair(); + stateIndex = BigInt( + maciState.signUp(userKeypair.pubKey, voiceCreditBalance, BigInt(Math.floor(Date.now() / 1000))), + ); + + pollId = maciState.deployPoll( + BigInt(Math.floor(Date.now() / 1000) + duration), + maxValues, + treeDepths, + messageBatchSize, + coordinatorKeypair, + ); + + poll = maciState.polls[pollId]; + + // First command (valid) + const command = new PCommand( + stateIndex, + userKeypair.pubKey, + voteOptionIndex, // voteOptionIndex, + voteWeight, // vote weight + BigInt(1), // nonce + BigInt(pollId), + ); + + const signature = command.sign(userKeypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + const message = command.encrypt(signature, sharedKey); + messages.push(message); + commands.push(command); + + poll.publishMessage(message, ecdhKeypair.pubKey); + // Use the accumulator queue to compare the root of the message tree + const accumulatorQueue: AccQueue = new AccQueue( + params.messageTreeDepth, + STATE_TREE_ARITY, + NOTHING_UP_MY_SLEEVE, + ); + accumulatorQueue.enqueue(message.hash(ecdhKeypair.pubKey)); + accumulatorQueue.mergeSubRoots(0); + accumulatorQueue.merge(params.messageTreeDepth); + + expect(poll.messageTree.root.toString()).to.be.eq( + accumulatorQueue.mainRoots[params.messageTreeDepth].toString(), + ); + // Process messages + poll.processMessages(pollId); + }); + + it("should produce the correct result commitments", async () => { + const generatedInputs = poll.tallyVotes(); + const witness = await circuit.calculateWitness(generatedInputs); + await circuit.checkConstraints(witness); + }); + + it("should produce the correct result if the inital tally is not zero", async () => { + const generatedInputs = poll.tallyVotes(); + + // Start the tally from non-zero value + let randIdx = generateRandomIndex(Object.keys(generatedInputs).length); + while (randIdx === 0) { + randIdx = generateRandomIndex(Object.keys(generatedInputs).length); + } + + generatedInputs.currentResults[randIdx] = "1"; + const witness = await circuit.calculateWitness(generatedInputs); + await circuit.checkConstraints(witness); + }); + }); + }); + }); +}); diff --git a/cli/ts/commands/genProofs.ts b/cli/ts/commands/genProofs.ts index 371fb537f2..ae30092135 100644 --- a/cli/ts/commands/genProofs.ts +++ b/cli/ts/commands/genProofs.ts @@ -174,7 +174,7 @@ export const genProofs = async ( // check that the main root is set const mainRoot = (await messageAqContract.getMainRoot(messageTreeDepth.toString())).toString(); if (mainRoot === "0") - logError("The message tree has not been merged yet. " + "Please use the mergeMessages subcommmand to do so."); + logError("The message tree has not been merged yet. Please use the mergeMessages subcommmand to do so."); let maciState: MaciState; if (stateFile) { @@ -223,7 +223,6 @@ export const genProofs = async ( while (poll.hasUnprocessedMessages()) { // process messages in batches const circuitInputs = poll.processMessages(pollId); - try { // generate the proof for this batch const r = await genProof({ diff --git a/cli/ts/commands/setVerifyingKeys.ts b/cli/ts/commands/setVerifyingKeys.ts index be798d441f..da1314669d 100644 --- a/cli/ts/commands/setVerifyingKeys.ts +++ b/cli/ts/commands/setVerifyingKeys.ts @@ -65,7 +65,7 @@ export const setVerifyingKeys = async ( if (stateTreeDepth < intStateTreeDepth) logError("Invalid state tree depth or intermediate state tree depth"); // Check the pm zkey filename against specified params - const pmMatch = processMessagesZkeyPath.match(/.+_(\d+)-(\d+)-(\d+)-(\d+)_/); + const pmMatch = processMessagesZkeyPath.match(/.+_(\d+)-(\d+)-(\d+)-(\d+)/); if (!pmMatch) logError(`${processMessagesZkeyPath} has an invalid filename`); const pmStateTreeDepth = Number(pmMatch[1]); @@ -73,7 +73,7 @@ export const setVerifyingKeys = async ( const pmMsgBatchDepth = Number(pmMatch[3]); const pmVoteOptionTreeDepth = Number(pmMatch[4]); - const tvMatch = tallyVotesZkeyPath.match(/.+_(\d+)-(\d+)-(\d+)_/); + const tvMatch = tallyVotesZkeyPath.match(/.+_(\d+)-(\d+)-(\d+)/); if (!tvMatch) logError(`${tallyVotesZkeyPath} has an invalid filename`); const tvStateTreeDepth = Number(tvMatch[1]); @@ -114,7 +114,7 @@ export const setVerifyingKeys = async ( // do the same for the subsidy vk if any if (subsidyZkeyPath) { - const ssMatch = subsidyZkeyPath.match(/.+_(\d+)-(\d+)-(\d+)_/); + const ssMatch = subsidyZkeyPath.match(/.+_(\d+)-(\d+)-(\d+)/); if (!ssMatch) logError(`${subsidyZkeyPath} has an invalid filename`); const ssStateTreeDepth = Number(ssMatch[1]); diff --git a/cli/ts/index.ts b/cli/ts/index.ts index d05a408da8..9dd22c204e 100644 --- a/cli/ts/index.ts +++ b/cli/ts/index.ts @@ -352,6 +352,7 @@ program await verify( cmdObj.pollId, cmdObj.tallyFile, + undefined, cmdObj.contract, cmdObj.tallyContract, cmdObj.subsidyContract, From 4baefd6f4c5ebda3168dd3a2565535fd878a85f1 Mon Sep 17 00:00:00 2001 From: Sam Richards Date: Mon, 11 Dec 2023 13:04:50 -0800 Subject: [PATCH 06/37] feat: add favicon --- website/docusaurus.config.ts | 2 +- website/static/img/maci-favicon.png | Bin 0 -> 25364 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 website/static/img/maci-favicon.png diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index d38a4d2c86..ab2eafa3e7 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -10,7 +10,7 @@ const GITHUB_URL = "https://github.com/privacy-scaling-explorations/maci"; const config: Config = { title: "MACI", tagline: "Minimal Anti-Collusion Infrastructure", - favicon: "img/maci-logo-2.png", + favicon: "img/maci-favicon.png", // Set the production url of your site here url: "https://maci.pse.dev", diff --git a/website/static/img/maci-favicon.png b/website/static/img/maci-favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..f55e8464335e53acdea358a042315eb68462e566 GIT binary patch literal 25364 zcmc$EV|%8-vUP0Rwr$(ColNYBZQHhO+qUgI$s`l|%s%@)zv2DRcYnE8S6zKouU=JM zkxB}Z@Gv+qKtMq7(o$k7|K^>4V+IQ1-xn)p7U$mt?4lwm0#rALcL@YU1SBmctma_= z=!H%(-&Du%*ncg5WtKeA(k@mjO_HH0^psf0m}H|{w(DuQwCB9x7z6DE*dt=iTp1WZ z*e=s|;r0v&1&06=!;KO_%a<0)kXN#$l+aY3F`v&w#2k(j?mK$lxZL{weB~z=$)skU zY4!#vNr-3HO`VUaWuT(pr zt``X7sOi*L-Cm_p0HW6lS%uyaMXLmSOT*y)q_O%BQ2qQLvrgbN1Nx(*b$eAh{{X85 z6&eRLb^mNtcWkWc{__R6ZVPl3MsM_=t>5UF-Cot!{{ZUV|KFXPf2y7HxjDAz+Z8gc zgLim4UG4R%gMCfEyI+<6l=V>ckUo12pGAG~!*XI9Ihvx;kzF6OAq@RJ+phTnV7%n_ z=15oH?Xhf@`2i;|z5PJ6I6hP?#BfI*V~^<(FByb63N^K&CkX3rfcbNwTmA83c(BKp z-(F+C@u1yH`?_-*{#`mb?~mSE5KVNKaKcVjFwjlj#_xp_$O+`r*Ma!Td=M_BLL?3~Vn=3-D{KQFdpdlF z84vUjen{Wn)m5MV_8)Y${mg&RuRLdw@!7TWUl3_M4*`=v$=B5%0tfeLo=n2<2ECES zX~d!Nc*sZ`qgU)0&|NmhX9xp^o~CZ`jK{s6eT?e6G3VVung?&a^S$G6gdePQ@48H# zknuzhE;g6W10GUeP*5NqehB;LrXXe%Le?f`!l)JW#L?->hJ6sbrkv z9sBd9Wi>btI&0R{y#SerpE;470`YG~h}im)%(mQojG_U00cl{&aC~6DqL`q7zS{|j zXMN4?zyro$N5I9kK&|OBwm?2R)kk2j@6r$lva4(M)w@bZxBo@)7VS4?Pd>MQJoi)O zOJU~=*VZ6V%>*5jrt?9RF>vL1ACD*q2SG5GC z8~Zg-7)aC%IshqT!uOj3No4fAe(71jja9@cfU@?D~n@}5|X)lq*t`x3*vXXGQ<4&Pu z;?rUSrr~BO4`KtT#1ZLVW!sDWmUR#5)ubP%J)%doEBn5aY6i~Ae;k(I-n|p%EtuniKRV;>p?w37DkS~ z&7By8?uB3>S3U#JPO!X@*~}%Dx?-H^lh`z2FH&e=xD0m`3Hy~zx!UW<;``3`+4PMiTL%JVn*8V=t zoR28;)fkT~j2E0A&S$UQv+IJ7gvf~bV>$bxxt*LI6D|}@q`;ZsNMqHsSiN#&hQPaW zC`7L0c7U=UJ7Fpo^y)#n;Kqg^U?lMiPwGz{*kR*{=R*f!$B+H$=P^!i*8ahVD)C;B z==a&4lD8|y49Gv<_#tl;I)g}V$ph0aiRQ>wg#mOy#FNC0S=MxwG{^zc40GRrMfH*o z>OM2-H@iT}Dzp#pZ+;kNC^)$dk+d1p+b+(b?x*nT-uu~|iT(rb)gpsH@h=Ml=kqy# z69u2sc;pZKl`mqPJmn?Q2(mvIuQREkQ*~+$c6a2Lspqq}Nc55OX@6{`M z0lWvby@en<=pFO_>#}bhki_!LZ-A%}~Q&6X8W)O6VBJ9AywDv8N>{1Jp8X zb^}vDvFBq9=Ej#GxX0W@B?;cz&noUh3<1|Cuod`U8Y>15FV(*HdJad;K0g0A#<{TW zWY~SqcP!^E*+1xYs257aTG%-ROv-))9nF2I9=0JPA0b256hL85L9bWg$qCB^$*0pI z1Z0_f7#g~)rEm?<(jL%a7UJX!c%R*mzdIwWdLBjZI$RwxC=B&&WBe#(rIi1>GOqM7 z)Ia)p3tGT@tSNUx20m7VcAx0U&cpzlc}1Z#qHe~mAh#m>iU5=%=UP74UCtkx z=I}$5oMjzBT7rv!;;PmyTTy<`T*y1^WJ6aOV9tvcN0kQB2jf_jx#FxP+ExA5OQ1i> z8WWO`#WZbkg&kV|M1;~X)V_(Hb}KG7DA(DbZE5)E1>|CeofWE{JNlSH?t)o?Q)@iH z)8+S~a^`;H^! zhUr_DBDqY}zZ{5MiP~pQlrVB%j8JyNYCmjTV?Xk6NWR0~4!PdYUi0Iau3(fLi_2fUW*4Yc>kN z5f+n9UrSm_j?n_4WGH(?QTZ#XM&(l@8`PW?z`_Kg@bDXi!z438H($V(XRBKv6tG2NmBaX>LJb(>J zr65t&$&RL#Zrn}Xu|Ty=<*(c4dKrAkWJ(?-ST3o0OhXYq-I34nDOcmWg^&4ZEtkG- zc>dEt{1;wO7 z)j0JH8kpNL1_g-18))FKK^>rIhH`SHktOPb4CDxtU|0)m%k28`^4&$y3rord!cquWD5kE8k6q0fS zB@)h7)aIH73?}Bt-`fPjDpzAaY0jKgvbIG#=ujJFA|U+xRf@K(#Nc?lior}Q9S8UW zXG^~iDofiBs%tfki`(Kh6p`*dNobEBw6*OMO1b%xNf1Q~kk==0iZTUuR%4tVJ z)`&0b&gYk|C!c+S0ejJs2EtWF;B4z9>FD?5eLpj`ec$>_+px?Rupm27F+1&pr4i!Y zITBh}Lj2lCEkXc7A!)_J20}<%3$eB>-%}g)!q8bwGr$i!@HKdBIh%}&>1do`65fct zO|XJHgpibVK++^>#t><}&MHQ)kVoG1HY#sMO30xQmNm=>+&!$tu+otyaYw1uv01>>XUb#k~OATCV3 z_+-eRE}+}{v!{((`r&!WB6sA=jGlOMlfOy`C?M<+d}hu_Cr5r^+Cfx`iwM4WR_zUI z)<^8EQ-4$2wZJ=Mfo{JnpJ$e{bv>?jC?ssVa6$C?)Rf{g9$3qR zq7IWb9+kJzHskUN*>J_(u+`z}^68oxnes=V^Qv}3$Ls(6zBl`b-KeQ8#$-d5jCsNm zvX-NgAHssfx#DRhO7m-GL!hOj@?TTPOteJ84c0g?ZrvRCo%CGOSCvO`%I`S;#{Y2g z2FumBJUGTA8ZXLX?N-u84*a{xo=FE!T5@}Y?U)t35R~Mn%(hQhYBIu&6g@$}`S?)i zM|#KkNKx7U5mZZ2(P(f#xNwFHZXw-(jQgqu5092eIQtPDMHS<$kX-4a%KDr^N60fn zON3ncBzv8N89x%!j^^Y@801#%*n-bvSa3x3!C}OpC7=+Kv?N=vDQ+ntuo4V)(l{~d zY?)|^Y@4zPOB++!W)uu z-tJ(?0Mom2FhM99_s#}BM#^UcqDqhMm(76tu}NS+4t^_`?bRRYYwnLDcL!Rhq|=Jk ztBia@A*?Yh1WB!Hfv_h?f7n>cz4+5bR4ub@u*hA$7%8=eFEa*(Dj#zLDqm9Q>IfmW z%#QrHR=i+&Dbw6@~u6x3R$y$>bjPWYzV(Jq8U{-P{P;+N!qwZto6GwOzobRBJiE@ye+2j z_TP6C&kSwLaKG%4M%-SVyKAf<7q@#MDiY zvJ%%^cwZK^IoI_zyBda!rbu&jD@&r9J>=5z4L#@yJSX?ZQD@f+Fk6{P4ln$DY``LS8|bBsB{`#EBakpV3pt(v!$0XE6{TX)tzUUuUqug} z`X~e6=EWv@nwWyl+u9j>GmR`DHjHOt(g9koJiVek=j1lI>Pr(d?U@>F%>*X!qN>Z1 z5XV&i`mg9+D#{cui!{#aD-?K%gaO>16ObJj!SVQ?&b9dcIoFaU8vuU_$J*}$fy)mY zW;+XeTkS|a(bE!7ln{UApUb#S$T@F>*P>z4m(hCC%Gq!3mLyNuz&RP8!h4*Q5sstA zY8oTW65nr#j_OFVRD&3R#2uK!l?NnK_zp#EwI)4`egph8VScgq769nin+e1xB<1Qp zQ2wy<2bWR}Z5s|SoWl}08tzZc+{e=MIr*Vldh-LYg7eOap+Qdqqr5z)lHboHl(^Be zUrt2axt0R$iGjy|mN#abuxhkXu_M3Gp^*zQq`#7hCKHGylgR#NwJJ@<*`}BfZw|2U z)|;BY0Mk7YjD23fS!*LQ^Abr4fC!3*Cl4i=X7RkL?qs}P`^R{e>Xp|q?zJ#MgI(#a(*g$kaU6n zS`nJ_!9^s7<gn6JHjLH#BJVA^@>6YT8ieFIUBk8 zN>2#_8cc>CxfSAs%vr2MWd3q7#jx%}XO7U>m1{%&;iQPf?SnkQ|{iAB$~JU{@ssT%4bb@9!bo_47Vj4B_6O;AA2`cC*5 zT921nqoO8Xm{A=eI6pWwx!1`H=WMlHznbMc=v(1D1Kj2{#GJeHY~aK!aN-T34M$sJ znZqzCuP^JEL&r?olA0L)@)*o+H36YZHRHbPgbR40ar^z?6tf7@>O7)B7Xrwj(DTR^~7g3nNbheHxL?dqaHTP}Jsv*P2VYxZw*{`v|u+ zNT6d(K}Q}5)oQ(_7XjTwl(?62`)m!EB=e-ge}2_7G6I1+BE>TJ+4XqcKs=s2@H!C= zh&V~?*zlnj2y}sGp^kuGaYyfz7^^|B#Tlw})0E|@GfCJ`kcn%Fk)kKi*SO|fV7Kgx z4^J{z=T=Kviw|TxHA~4F1s;J((l=+m<<)6c7h!7-_!zl_wJ1(MNK8IonD)hH5Im}! zMV2e6y+qO0(K})^MaSaH#MU%V(KUxEfzNF=O7mZelqmGcljt-dxGGM}yVtBYcs=TOX;NN`_OTV9|)|MFXz% zb11pbNLh3&E{o^^bJ~-nzbshm2J(L)3)(GT1PH{Yeye7%cHjN#6+x8CmyWSeX>1~~ zF2nt$o3W6(mJEtC!BIbcG4^M$Sn>xqC!!8~*GR|c84{MS%2F!9@o*(8%w!Qt%&jhsZ1hm9f13(XqaTm)12tZ^4i--4wSxG14^|8i{$o1BTO zzcI3vYv4D&R$gQ;A1bD{K)2s*aX#C55?&d5{MaW>PfZ*fI~E+|1tn-;3?aC4*Yp|Y z?-0&^n%fDsR+cJlmL=+HL+UW*%TPUWf|?EwbXNlYC?w-}{x2lOT#AVzeItoeN&;nO zhwx{59a{3F500s{fWRZE7)64-+5>hq*-~;+JZBiRMOGgW^|9R2g}_3XFzKfFhG3w^ z%deK-1c_P>EBk@@?u&QfRuI@%drHo3jk)j))bQ1#Xl1N-Oi*Wwb_Vf>vHQW{h+pem zs@)3uc2RZ66HiWj%=(t738iEQSm9Mg5>4@K_KI1PGGStqrOvQ&>1OL}q2O6LqB40% zdMu2>&hF2z$1%=H94&2+a3X|G6YNh+7ofShV7uQ0UBUEt_G7QQoCd6@-kuZ;O>iBA zU#&l8d6)2ue2!>0qwF=a^u>cs8C)Y&_{K~)5xS%DG;ainCYu?7Xgt3lPNh=hn<=X+ zg!QU)ppe1y{eH=D3Pe7&D+CT=DMZP1W~J?-(PorJ{FU1iHI-BbwgD{=%55eh=KdpX zE6&1d)-w{DQC&@20-}0vK^E}hqLYVbJdrp8Ix-wL;&qW5zRn$~^M_0)m^DL|lR5oQ zQR44KD3%dG4H0;Q4wP(KBO#+{yBnzlSGKm zx}&(T0rhNwZJ9l_d`CRF+3^$vZ_lcLg2eJ$Um8f{`2ZMqcReK3kP_IEUZ64poWy_u zqi{K|kUx`H5(2rK^Op~(pfg}V4se>;F~M@+2jKi!@Hu^i@KOd9-WhN%j&yI13@rt3 zIp4NoyFMyoTFfb>UJ9|-i({J=>!(Vh{8d+#QWKzrM0Be*0HW5Vok&E= zNg6_?0>!r$Y*9#n_3xldEPYLLM;jr|y28c|Vvl%JBDpCPtnmgn{6=VX#dO*e-&Ity zv=AFeFFbBv)b0U)oAw7nto6rKkd#!8h7Zc&ZbYIm4dM;Mm{%d2?O!Zh36@=P(`VRU=P|CN_g3K^q zXVwv(oql#t8lG-p!Z<%7-u3k}VPWC-_C+{!p3fa?zYr2hvQlw*97#BC)xNEzqct)# z1afwErW9>zCQZSNcg#HonkB0G65dDLY>pzBvO?0coHeiBr|;s(Ah67r6K&k1=0BeX zJrjQ_hZ+N6MKs<68Ohkwi-6-9Rr;KRH2}Mvy>WR%T)Vm$nI%=sja6UCPjyou-sDfQ z-j^gpL1xX&<*wzoB-d>_le0!C4zRq+$`S}VL^wLc80uYy;-Nfr5F|CyW8>9=^Rn{t zg&V?XOE(BR(Dj4*w`Y_J;NeKG(4Tao!_kT5<^#VN7C8H6a5SY`lBoGYTBdTyMW=MS z_;TW~8^L6R?O7yFms_3{Rq%`>xX$EUx^@N#cE|h(cgchWjmdp!7`j{RU--?m(`Ynz~rl()y_rLreE+zBF3i<-*VvtxEM{%*Oae>devYsd~FfkiD znBq@E#oZJ)_K0N3*Gvs!V35>ht-3*J=i0NRwx2dIlDkUUM}CVh>6#`?z$TJcj>Ulq zr4_`%LE^CEW!ez+Hvl_0VDgqL7;S70{+%L8(@bmF{&Q3byNy+cC$gp^uB5y03~NAW zKvay97#)wZeaXd#mXW>`1%9b5jmf;+INSvNOK@^5s4^6f{ap;!~DqjxHy&Lm$YIRT$Nynr=DL_wUm*o$8j2VB$=+|wVr zxJMBdOd!!2K5E)d)OW@KheLaDCLoc=(qHK|h;1reSS@=8YfMG~Gqw&IUq`>GN3%qb0%Y=u(EQJ!2q-G*N)>%g{P6N67>UWpNgeckV z{xQhzvp;1Uk#C9MDCjm0ISbkEChQ`lRWG)Q8-D_7zxtZ&eW?3Jr=zZIS%GqG~^i6%3(Y*Y?AMsxPX%A zH>3?-7nEJq`2+NIyg|Wtn|(@~&&OoNOjXLf!OREC(gD|}1z^CLfPm-E@xUj`)q~w@ zEQHE4b0UeRx|!4$K4(>`^RGDh7y{JkpV@JeRn@K(V(uly+ zHtEjhQTzo4^@WQC*YI%RU^-E^RO1HzA@=pvI%`TFwo6}%*xS;4b4mgB6=`_frHXP$ z?(X+tHt`4bb+cjbW@kVztp1O}4~-v$!ko6n`H&IE8$p4%%HFI=yChI6SJco$$?Q=i zY&h_df5_%+7N7JIu;Okhz{h@7F{CzICsA&l%MysDt9oT7)LF!oN?(}0fOM5B6baxR zm8GihcpMNF#qbO90o-}9GSMLGxPxw#qagFRqkEXc3zWl+XD)#(Kje6(3)w=yVv#h{o36@qC)O*gu%%7>FQ>8s5$bk9&ABBgH{0_)% z16Y@8NOf-Fs1PUaSeG9UU}ZbKP5_mSeT+qOq(*b#=riBHUAsMTIh;*=cS`tm_ zy`!VJs+DARXluuRiakgcQ>@i@^w6)e(%G1d{8s^T&j9n{Y4HvOPryS+Z!oqNHp%ee zh^I$F*JLpV+MC8qOWuxK^|mDfGJ=DeF$+=~X8~i3=0L574d0rr}NmjZO+e4!QNP(3Zc%lL}j&QBaj(y5usGbYhQ>U(^nA8=5|51VzuHrFKWUn!Y_LL_oy^tt*9meyEZ{hKvq!pJua)(q< z-f4FW#^Co2&)$@VCF>pgKUHclK5u}P_2P4J-0@LZ-pD$oR6lyPv=G|ZiR;FnB9$OO za+LMz{Ge7_mz`d2Ig7YZRoyMUu=p1_0t{_%_4=u1G`Yfrq>j{P43)cTeT7^+ECM$r zpc#ORE$DtklJ3A_?{0q5(U?Rg&Tn6#mTvc00tnr2t1qebQy%ENSHTgjDm_Mo;gV^` zy8r}fT^Y2-lgwacc^ZR!%JF@NUiGVY3o_D%L4ZvB86b$hlwp z%48^-hh&{&A-qdT$eo2}*t9Vj)|)mG9IJ<)-H%}>{{BbheJ!~eKRz$#PWzMaa9>!M z9P_ffIQnqF%4j4pB)o6StvCe&%HGUzs+(DaRc`?JqI*Kl=^Z`Uqn^@Iawow|YoZK@ z;65$B#Nf@%t(^t{Yo+dD>YoZZX?^9^5E54f)|HLOOd;I35p;}d@k#AOHckEHsjM23 z;a0x(@Q{ER@+JTmjrk`ONvpHQnIW4*LfaV#moHvx2@h0s!9(H+AI$|tQep{?#Ney} zU5m3^OE&?P26^Q#j?$ZG&{h_#?6ysVY3b8*M_?{nz&^R*a4OqqA$iq z7*B;56sFD739F}1t=JkrHoO>0`$C>%_oj;Rn> zZ0Ypm<ZB~oFcCB?`~gGjJ992l4wO7+W6>eZYk z2n_hfb0;3VjiMg7iJYK@tWJriZl5crmf((toekk7Yhv^;Ct*lvJ2SiXnA_dF7cUZD`!kyIir+QY94~TDZ;D!j(FRmnr6hXBUK(iperi zxEkC8&`!qLxSL|l7?Z!~C|{c(qg6<%@`!g8X-OnSu}EJ)W8^4Yds3#PuHCjvV|)!S z(8ZXu;1S)z#<>@6KyE=aJ4hGW8U z=nY8Y8vDA6AW5qq-?q{kQ?6xE={z7Dx(=!Kw5sWL(77E1K2FL!=OqOK75Usy7N@cv zyUS%KaizQbjh%$;2^{pwmj~z8+B!&%hNSO{-RSM0<5Ds=_G3S2b*f3x=Vcro-da3d znX%6kcg^DBndSQTMIE@*E;C{kM`D+0)N6s#?+3Re;!*@SV>&wOY$w_Xe#b_2G@36_ z=buBNGVA?&0zwQENvV}KiaewM92dbH`T&4k*JP!A!_VN!_5K zLpX7?X0L=&Mk#5Aw6(P>7Q`_T`n_G{Q4*#QavY;uTg?cmRWd{6@4#=WGv~@R;>aX4 zCmIzSn!%f!FWIXt`FjD?d9&X#s$>kqX~$mph&dD0-Yu_9MW#Ho)^15NP0$&|G@ z-ttTY|DeyuXT0ZwG=Bh+&>v;+s_VJGJ*6>irs7?X4x6vVZZ6gy>9}V$7T!&pZhOtD z-JG?fq+JPt1Nau`Jb)s5ibkP`3yoa17g<`z*v%6>+6C5X6{qPCYuL3*KO=$7pMl-W zbKY-Hk)_DaHg}knbRH{zcR2Hg!$pY`9h@V z;xzvmK^7UL8;4nKW!y+-y19A^^cBKj8dZCP4*<9=5>l8rW#C9no<-HD?wTsBCvKjg zStX~Imc*e05w8k11~g4;b+0GSw{vmEzdiGvZP`WkdOApu%8yH>`e@79>+(PW@e?Vi z(pmm%8;zj7GPw0SY#V=WSfVTP(?hIEZU6DPMQTvT+>?}5hDQ&#v_}4r}`us1aQuZO+kALt!dLLnA-Y zWG&mMb=o1NeeFNG0Nq7Bmjvn9_dWoAwYiSaBUQ1?1cae1iCWLC2q;Mp;ZAeK#E=4y z$xAHcZga)=_Vxy4o|K`Hixz;v`n%(*Tlr-}X$Fn{CGsQs1@6ar4NtdtnqzZ#7YM3y zJ$Aml3V8Bv(k@-2ZIf5m53EL;w9e)x<_KAIdEm!LOH#Rnu%>i?FZE_AE#z z(#VN-;b(4MgevwUoOC2Io1XfMl9rxsra#HCR5Y0$t$tGjVoXPFo|uY5y7}y zn1%QmoIWdYUr7+l`ugOs_u}+$`*91Zp{acSd8MW=5)?y^o>NLPup-m=(^uPJk&|fd zJPeK{+v1g&Kv%Aqk6aXLRKt#wR@*YFz2^L{e5av|a=G$F9+~s5kT~>mPR&61wu7gU zme$bL6!qq=A3!n{?ML`!1~tr8skcXBVn(}^DnV^(Q+iwK#%ae3qDe-}dRe1mC?8}o zqXt4@UT*DFV-^FTUa#R^7YUvv;y1FP9M5#g-na!63MRcnDyJ#|lY~V0cvMMm=qOoI zD6wj5`RF)YZsZVSE0s(4T7+rz#;ul;)6p|TL~mdJX2yyg*+pwxZCg(U>py{OWvr-S zMdw<>cfYSL!*&+?74!u3dY`UdGKn5~-~Tb(JyY*{Xy8$O9pU2c=$xB}1}Ece<%C+u%BYMN9g*?m-Xde-_R5o#PEuJQ zl)e}3gIM^%{tX31QLRv@<>mGZTM~g_WJ*Pq;%FfWKn_Y>owyQmAj+Nqk^#bIt*sZ@ zIYCaYKssTUr&~(-*GIfEC|3Qh5NJ@N_JK7K+Li-pH4ypw!9CCgxBG9VHuF4&=>((vwMmnW{aB4(1q{t@X$`)PxIZOFNLm7g3t#8FG7oGDu7q^pdhQd$8+t%feDD zr8~U4Si3EK?zaLiPAA889gMu5%vcd|Yu*aIg$n$BmTAqjGgiSetH=8zIN&)9giZRM zS#rW;Hz$e4*Pnn31s9g61w2Sg#{F9)j7~8TUSdK*?&QN{bzM_KoQ9H|leBgsL3FAs zYOZNhN)1t(^JVUgU{ndSeYUBF1zDq-(^@+y82IkDy#NdAhsVE-fa@^)9N<6G{PPC# zw^TiZjKG$NoMg{LZwV{pI0@HnHR=Z=X{hz#IUxqcN$`?pZoW0t%Gi9+z!Fnecl+Yj zZ8g=n)U%cXj&S=S(H-+Hbwi#zw{}9?Tm>f?X~#_YnpqW^d2J1&u}d!9Md2vVFCDJD znFVLqDLKm8!1|7@^Z;xcuqM8l;p%z@OnMww%Wf8f?tzlMsw2YzcnoOP_2%+7#`X3F zz0nvZcc?SzpuJN0?kD_?c{^3yfu*aL z9j%|^!_|aKvDtzN*z|k3?ceQ3*-w4*Texz^In#RP|}HE2(dayu$3Elu<( zq-RxeYQ138ZA*P)^a&E4R6+`O#L+r&d$3%4Bw^jj z7J(nGf|tP37kF)xO4BptwKUFNIOy;H(8_AcWpO4l4fVaM=rj14Pxy}Zxhe|7_4{Fj zl195hWk^e?qTO?73K@*0W0<^Owv|P{jf*)zV}yOhe3>K#XeeU zcdPBzn((eNB**!djNXKa?5_v;YVZ-`kWdX+NDU1qM{{)9=*AAaT!9672$qUO+<2pO zKO(y8LnEZFVZbOMgcXN1Nq5rt>A+hp8t!&CSAQ$1Z82e(iTVXc5^+gNG+C@zD@(Kj zBIG2QmeO<}@t#?fK{;vN@zfFv0wGU?ySKv5;^U#x3Wcx2U&G!8a-p5Cw?o?ZH5fINI)1 zRE84gQ}BbGeY0e)1q^rx+ek%d*CoTHm)eR_FTE|&-N#^ziAtlH#TZpl|oEA2Kh{UR|*d)#>BZ1bO zBsC@d*5-pZSGOlHru%aVFP8bI8SX9`AxjJ&(uS}cujF<}H+arOlWnSJ|GH%VIx5M@ zz!lBf`r5$1Bt9*)B+0!&pb(X)dqKAM%jqdtiv^ZT-(UCq+|Qk^<_WFlU(+lF(6~Wf zv4DMq@8@i~8r>;6_>Q-LcmEsbZy&I|DPUs$e-z0tMK(r_Uc!Uf%*9+=di*E%%1{b^ z6Ru4<*0*6+7HLW+<1dMix}l}^Wn(qQ58o9y!;!C{uQy7yH${_zDc$}< zERAYR^s7*u!RXYQkMB{*iJrFRecbJ?Y0|S%Z>iM_Z@5!{3S8UdPjP@eft6cf%SEw( z!4}j#r+tl7GA&HU{`bt++4&E^RO(E#Wj0GSJ>@--OMb zPHv*@My=1RVjP(d#{1CN&Pf_e2!)4)(MDop=k{RbO&&XQ1_c*^nYfgZnNatl^HPYT zR^i~(7I_R!LLfy#uBA^-3~_TchM{^@lt92y2?0&zGk1=m>#MHT{oIz*E{>Lt4iSC2 zs>@CNxBf>a+OnI>yV5z$)N!=3j;X^iPc}!n)k749W6!{QMSQj{^7s3by3Roq$nEa$ zeapS4!|p|!8QJ^dDF59`p18xDQWx9;A7$&=kxJ^K&|kA9u&>ek(dXunoHG2mh&0q4 z*qeEAmEcKqwAIzlf17hchAsyi80#qMq5KuYR3pNbqr95QJsEa0exP8yZprPkc;_{`Q?Yz!qmFc2^tM>OzuwCIS)>|9{c@_SGTLFH^;73*rap*IJQ z>)#xSj99OXSg&PuP>){?^jn;M=g-aq`h&mkh3duHw#ErBbV!r<@)B0MTCQ2&RDeqW z3P`DI7tdPbXCPh&TFP;MM=TlcXi&geG_;Yug-*zxf#$}nK|5{GZihztEL{O@GPTHd zGiio~$Tc1^Jy2Ojfn^hty* zi=<#$(&1=q8)Zw*vg++LTQt{A)YZpA7S$=^j}C9q8yT(gQG$4sYq%&dtSRx*Wr`S^JTwDKA(|kFKtQT{`RnF{4MZ^!M};pNoHZNvUx9a=3)3@;KMuVe+eJc@m@MR7en-=TX;F zanorvcUai3a(rRH5jS^=9)kWz*u(;$LQt>wmWki*NllI!O@y!>0s%-oyk6RvgP5 z*F%;lRO{v9=O>5;BH_rfWqft0DLwpo+a;Lc$)wb~QkH87AHE5j*{Lgo)8^DW4^C}b zN3(8s_Yy+TmnK+ATYI^!JN3;XsQ4CZ#~NbWU}A-UZ9Nu$M^5(z%4Xa%VRRYzrz&L5 z9^!Usrw9J*YR7n$yTqoYG2Njt1O9<-+WB2?xTb{#;rvW!8t_XXBmw8o_{Uy6tgt+< zaU||BUCvFPo(bw{88@`3_LliElV$3TbXR_8wiz$}!N!(?q8_GqM_F~;6$STD4kmlb z(DKG-T9snVjGz^Jw$;j2(|zXr_7$KgpJIuFG0KL8GxVjAsYgdD>CEB|xQZJYwAqd!?C&*~2u+6z+ zYCyll3%juBaeBZ-U^4dkg-8sULsG9zB3`Dem4e7ZE@$gK(CAg|7><8ni=z&-F7xj3 zb;Z|ryu;bHK(hsDOjs8t?v$p#pFng2{ZAe z?qv}s8;L@g#QLq}ZjEGTcx&MjFOB%53f-|3s7fIw1DPGNh>>8fGJ-q`GbasuZZVrm zpJS6(a)Yrl)a&F6?0-678&j2~J>YxPsCq`}|AFYpfT%8J3+hb{nPX<~9Ut*-O@-of_##RfK6-7d+j@<}p z<@AzE{$-6Oo<{;5XVN-NCA#Stx3%GE_cu1M|4%T7z1C6AW%xg5{~7g+YeItMoK@+X zTL7?hAGJ?YjdL zL(STab-zi_H>ka3aei$NoY&UZLtl@-*6-gGwXX~F$TV~{1r@L34JVH)%HWO3Z)Dh* z`29j|wGh3U)52(WGM3$0VqTu)!`{`M%U>Q7joIEgSJN-oP`dNgKh`}b>fi|KI%gkq zxhcuO$OAl=++u-(&)GsqDjhF z)VL0H$5t#Wup`&P|60A0nMX=AE6p(7=1PNM$4PRuIMzLTzKShVv-~g)dH##y^K65S zAhzE@xopK%krd^-%_9e+OC8WQyIhLTOJ6-_q@iEF^e!W3<&PPAxKr@qL{n1mx7Oi; zPRmJ4`&VYOwE4R85UJynFGK#7vr}k)y+ODOb*o)SxckyLZ+y++&A+mst&s;J{Z9Q4 z!rU3~m2K$xjua>5+|sj1ke0cqXS0n1f;S@UkSQQ4?uX?PqLP%gEd^#Pnih>hitEDw z+(sv0!JWlD*5IbhEnEG1X$&2p)`Em)t1?p7(gV|Y+nTlT28gEq`bbV3@%k)cN0;7w ztzu7VaVq~?+v0p|_V_wi$cwj$lGGFbg9TDpE{ z)GHK}dMMz&aBRNq%-m!9on)`8kL$m;9o!)!-agY0VBHUL`~%zirmgBBBU+#D zgV$y?3MDsMZ^T)_9*&MX^Tu(E`IiZyu8OvtCbisH&__r6M@L;9o%zhzrMC;{QY~6K zD<_N2+dHnqh%|@L)l2C%>x6#k|Mdbi#yB_42I)m6kj2S9S!#HwM8yMq+Lv0WYQpla$-vZIBZBu-T=5F5_BnRleIQRJ45jfQS6WKP0 zea;r+pASE;ydJjY;a=VbUWdF_hU%|6Ve_+hu{2N}$hk>H0C$CxNEnndR~^O35=sTT z^Dnv4fMv?==CnDSj+b^jeY54oiNVO*xR;*UsjPN3Z`W?<}9%@PfUM z7AO>oySqEVX>l5)(BfL8I1LWPDefMeQVPLcf(H!*`=LRLL-FDc4|ksXU)*i%`CgSin`9yd{W zY+P8_oTOg84kE5w*^VGDKOj$TPKZYMYh3m4Lk@D+gs}{6oW|}tQ!q&AI_SMZ>d z%K{>iy9r{|E<|kNHRc@C&o&k76ff1k+?I|nSvN-p8uwd2nM+z%Eed|9a)s zNi6qY<#}=LNvhrAVu{vw(-{|0t5SQT9gogo)`1$Grhcr7nHOXJoHrD6On#`XFP$>g z2e_ED=)HQ{k}UmMp3CN1-OQ|YVZ#m=10$6No?LcX{%C{IINA>}iA_Wzb>!im*6ww; zR673fbw6yO?<4t5Q@G!$j*9^%0RESDATmHwHX@LM+f%p zs9Ef0&#-nz#6OKc`Ss~;Ea9Ko(iRGI;JZR^N90`~yZms!`*8gyr9Y86(OK9yj)U30oRXtw`5>8E&H+A#le zK%I$AhQ8514c0!|9-V|#=kM>ojxO+-KlmT8^OZ}Tu-F> zc~*vRF1;st&ad|THQ${{HCi8j7SHnvYxfbU+Bqwui>lXxp6|A(D^im%xH8;>YG%Rx zVCWzEODlT?8P)$6t44zT{`tcn4)32ZyyYHP_Hnt<#IK8aih;!Q(o-ZA9AzA`U&|No z7YrqL%M*-6Os3k7+>Oi;GPB74#H!Ko{cM*Ddo)yAbQaaNN*FXK`Xs<91vxO{488u* z#UiC{647ee|4bW{Hu{+nan_U!Vb;G2A;px z$U~qV^t=*SW^CeX+c#PIt0JHLd`kG5@!FnG^#dpTA3{_n4UBkE0In%Ujyom|y|X-y zoV;s@iJT|jpcb{Bo|?zaqtO02Qk9G-e1; zN^dgQrpajvJf0ZnyZWLNOEFPmZY`OJ>0a28rHUR$DwFDH98+To;e&|O1xUrFMWa_V z(#|M%I+?rvH^K!=fA7i~^yJrl8oBesyu%!oeGyg`R=J%6LERP0>vy|n=_+VSZ}9Dk z?H~J82N$7S`{PZNwn!+ys>PsAllXyy^dz;r_ zMFz8hshOBq3SKw-(S(%Mh~l*2;GP(Xq|Ir6Z!)NYI6l6E(c--DPalk$&K#e=ojkgq z|49roLIKwaxc^dw%TB$%WHV@R4HlXl-O;IDZ)9!r5jMqxK2{}>QMrdCLhb)Pl( zl&gNbfA)O-4U}+RFF^&o`jiz;v%6W+vm;wz1n_)6@*Cj;jbNK(i+XV(Aj^=ciK)k6 zzIueYB3*j_TFQ?GG!*ZEB9WdtaoEIiV4pf=d{*1M(Av{L&{Nc{7X1@T_6Sx|>XX+~ zP?>2yGdALVpth4_p}O~R>GC+vb)$({J^i|%siDAQrW)AIL>I*QQPUV|sjxJtC`38? z?hM3tdZbERjjD$Eh}4Zg3c^5`Lx|R_5-Qlj9r39n!JFZAI7gnB*w6dA$cY)c{IXcyZ+Qi6o0{jx1b;Y#N9Kcr z%Gt&RjfFy0r2X5YuS-bm!8)~U^h9~5nQLOFPsld z?XNvJ!$PT`8^gWLy#R|PTDdp2(yg(ZHoESbzLoUkqbZWAQfS)D9+40Sto{Bx^;-)` z@!uPyN9e1zG$df-Wo*w#@q>PlKjgNGz+W8&EJUCW<)JEwUi}8t-nt+~+R?y2s(n#| zM(>C2^{UwxZe4GWS)6~mM|C;OFwGvIAtokgkJzrQ<m9P!~!g_rsaIMMPZ?s8)+gZaHBYmZ8|3gbeqDEYsc8z_Jg>7rhC5g#CkP z&7gGAr5Uug#yF{yQcU8=T+f#`z8}0#!ZuwU$HiRS>lBw)76yez*nEL01?e9&(2L`) z8A!}|&{UlkazmzE#ui1!VtyXkw6=*G8`tCwWRj^WLkmeaA?7dcP>ynJ>ix$taJ^+U zb}kz|*O|#0&M)yF>Hd7Ee=ThZ5B36`i6pMnwJn$KyYx1zzlg>b_cyUFuul%x_DIj{ zOP=nl-1xMej-rxxl73E-h1p zmg})qB=g6h-l9~5>LdIPnGjV^NeRo*Aa%70F( z7FLQ`DO}GJ8OJkGcQ1%HV4~$8|NkiLx@gM*JFDII-h@0=9BV%4HY{n)G8T!-_9S?S z;t!Il2ZK>>e*h-achz;x+o3j8pm9Vx?{ZlCXEYN^JFuqIUt$E=I8NNHKY48Qjys}P z0;YxsDJGEgLX4?#wEZw$CaB9aY)PaxY~HfEa?M5KAePv01M8rY)2beSBd#uM2zxcP zJJkyI`WShEIif&x5Zv4qQH%v1xj7frQrK{ z+p(IJQ&hYSwt9iNUS&TkL?t+H19DvAsc&s1A-S5-sot&??&-G8x=k^HhWHxM&1mm- z8ZD<(FP>5Jx%?AfA*Zo8W5Al)F5e(%nvaz?7o~bsN7J6mR|fNkZ?yFCg%Qa+-so5T zTvBSt&sDi-$hMH<^YoOh@QOE0Ah#h^dQY?wvW*yQ*qAB>w}wdCh!X5^U%~Mv5->Jy z5|Z_5xyFA#c1P~viQek%Taf6U?>dDV++%o;=QPJiB&$IAzlEMiHw2jt<7Te5#FZOu zur3zV+|0gy{m|pM>`?ERzyTKqL>ZqXOc43f6&uV9^yP%9LB0a@?0}xe+-o}n5-C>n z&&rBZte?b>bR=<)HfHU?Is^^FO*1im0h9GWKCD=0dcrB@3{RTSo&@rLU#F=rWo#H(j-R88X};31;{#LGzHg1c z^6eYpB`X1hwRtaovX)!3ZPPzM^D}vWhQKxx(DLw-BM^0L)J+YfGpv1y-e{00Og-Z(O45nM)m%VkP@BqTK zL*|#X#fvjNf6K&`t$tHr2juS4VN*DcXS)z1v=Hs_Pfg-vMk&uOjo{rOh=->R& zyRO#`Mc!uH!&WZWQg_%_FM&R_fZpX~s|~6vKlB^3s8YRY|6F>8rWE!)95f-T=3*Zg z7PU(EI*6t4Ncr%4$BJQo%(mFzmPE(Pc%FP{U_ugQ4p^RA*XuDie6vR$##>YQdhO+C ztBGeDkO*f7TZwmdyk$f5C8j?TW0t0dm{JP7B&c#ylN~{j>U!Y*+)w{n%2gO~k#f15 z;$J1~GnD){7pdJsNno7ybD!W7y=jK*s_#O4Rg zcrmubZ13>F{I5Uu-X2s=b9w*m@Gzz>uz2|-%7+DpF+?ev9Lv)OJ?urq*iE-$G z#(rJj02Xk;FESN***7Z8ERD|9bsvS~t5)HtaOTph@sP0N=GUUb;xsih1^9I)!YK&nrWiYyv9U;2Sa!@o|Do9j(1iaCKV$ z3IS-_;YUD^4dBAVN%*CBYAwi{Tf*XDj$1??#;`_41|AIl6p&V*R!pI3IyYRSc4Jx@ z$YET1_C@%OxCUdKDdOzT^kM;`gBjlPPAsL)E1&VF%j`rlo*(uU;f@SJjf@xX6Bya? zfZ3pBEwq|gYB>)K`9><}Jb^6~|Y%(&`hD{6n@`Nho3 z#$$rxbatKM$;GXaPYX0GC*91DAd6%ehtQ?$rfSaa)WmzYYaAv5DCzW6aX4zy5a_;aa_8jp;*3f6nZN zvQ?W{*%CRc90yo=AbPkt;`i-29w9%(;+E2udyb?R@ea7<_Sxwby9>mqQS4fR}j>G2N9(^QVj8s&J`6O5Hd^~C+TUXAZC8lt0^D~`?zXxWQp{t4fHv|TM?4Bo7j>QT(PAYu1W+*-C)iO&Vk~I}*+iTZy@`hsg zejx)M3R8oXnR4gawm!MilcPC@LCIpbrybmNZ^Q|7%?eIZi%V4)nYL1(C5z90{b|2- z?{Sy~9BD6iNgKx`m(|`FKJUi92AQPaOAY$p#a^!qo3{}p=1RxLk19~jD#fZ*kPJu{ zlKP`^53A`f8Sy4lxH=KJvG{To`CA!DPue=j8=6i|`Iv!ixvecWV_r3R?0ackST~~n zdaxRa-0F0$Bo~fwY!O7}!>`P)snPjTUuZD%@!qn1#b-WAr3zaQml6YM`*;^Qea3gq zSkdGRKojr*Uj9UMg=CKAU2M3Z8*wl)=ki{_uiefTohGYdy@|gSKWO)|#((mtn|uX} z@1*1U&wZ5dv+eOfDs>L@zZHcK651rp4kCmRqHz(N@`FC3+pY=`vTpn;F(eT#>^)g! zmnro`2MKEV6Kz3E3C&wEOsYeYKCzl8t0aOZPe90#x4OkX6*)k+Q*&b+mZRQr_WpG1la_u_rA+P4Ru`F(dRYj@hOxjh)>g{~!G$Htr3}<{SKr*n^T1mkEu^Mv9y{lWo~CJT69U z71{Rq%jYJBF%@bScX60+r_lamJK$Zj6I^t6w_L{-2e=uuc}9yat`=|Y@}X;5imD)E z58w;#oBL>_nPnK`AsS4gOK9@Hq}z~z!ONQVHo4RSCDfM|uViMX2=T{6PusxDQGnI& zxMmHXgS1at$uA=dUi~Quc(ixl1s}t0yPpKa{BVAKH4gP7LjCL-MZLF;eL&d3@s0^2 z_)3)#gci!nKGV2ilCuSMV=$tN2m61>w!X>z-2vB5al|;_Q=fY4unry0o9Z`&&Y4iR zcXkkK@zGxu2kS5VU_S6n4dRim9D=Ue)z zUq^+}c#iSdHNL}_KGRkF136#qKI}E%4|PRj=>;#@PRc(1H9Vi32v7_5?wIZ?oeM^~ zpu2{N0F$ZPvYVS@9Y}AYhSt@hqis%|E?d*GO0_ttKQ-oF?&1MN12_trekK7(^) zub;D-W8R!Og*nYfQeJ4&$Ahe^qXEkv%zr>5z|*_FBZtKFxmKgNZ=eq=e!r|_Zx;Mc zZ&m2v3Xlm)66MmCVFzWzoUg3VUUyG_6*FCB5_l^H`m@@woLK9;j*h9lN;n0t*}fe5 zb5lrPgFFod?tqGRt`qD|rfGNGjRG3)yqFK|LDMkRK{iZf{HwJ>=dDAj#*;SM#oM#M zN>*EA4XB)v?|3Q(tkc%Cz4>P7tn24k(5cIdXaM0Jf4_jX9*kUXjwH&2LjY2Lt!34n z@fq4Fk%u(SeH{(Z7}PO(x8cpnNW@ zu&DFK2qGN{C!GqX>Eld4=y@1x6kiB&dJ}T%VyN2k5BJnTu#-xn=K+Dixse!{|5@9k z4}LA%qBnFMLo+}|rc@0IQvH&pTC=E#SgMwaY3Vq#xw&F)&<%Oyae1~0P{oAq*5(!j zeVz6{>#A9gC6Eh&0K95t)I*@rKmWX|B4i#W#+xR5NMgY4ubQsw9t8^06*cmtu?SXK zRSo{W!_M#5%s$oen!dVyD+8%7SpJI-N)Tx!S;KbA=ujUjbL#zAY&Bjif?esDCD^JJ znq28HJo1ZgAJbs6_Yp@>Lu3z2#aHSj9bzjQZ4G*3-1TZqegNyP;&OVoKqZ2bw+NAuo z#p94i88);IMpF=UAddaisx+O;?LbRS zDyPj$W)a=4OSt+6KCRdAivwM1Z4I8*>OL4vxLy8{xF&op z7xfa7qx0T}LT8m71K$r38xe2`W(q)@Vu?5cC2T$z_VdgkGB70Uks|gRC~!C#Pw}j1 zATzAB5rqH^fAAkO{gI9p~va{UZeQgU%!T$6=S-i)^H8e8>-) zo#W)1$C+69k_i)mkBrODGs5Cc?U8pIuc?k$3Q zZrFfo#W-rj(d*v>)cl1z86@P`S@e#(Ye9U^gGkblW~{iMhg@y6zm0PY&fd6mKT&lY zy?jB17JafKw{MBBL0~_nYv0b*rw!(vP4hdUuA6_G^M~xE{FN3iu9!S9>-~3G@0>v_ z8Kb1Wi-Fl(ghioB++B{^VR{weUmL=YEyAkNX^8i-jX4k&iby-dk8NpaB0UV>0%CY* zEuikG?!FQFbW$#PNBXx3tId^6kJqXyTE;qG44A9FS@KKZ!506@XHYmxeS=P??47pVd(Kp4d*+#( z(6F}~w9qxQ%VeL>E)=3tQk_E8->hXEqnOxC@+A0{^74aOKWLW(jWqcb(wk#4mLAPn z$?5oOPOc%R^M2pJ+Y)9peO$wf@n==oP*3veC76p`zXgT0xAgYeCzm0bj``n7!#v)M zHmX^wejs6M`T-qE?T*CXE#ZSdV*%se4V=28D;gT0QSSj%O z`oP{Kgol_>DJ;gC@_}>+g#NYwpyd)p2++05>+t6O`XT)#m5UY)3a zWk4M$MEUxVzT^D7U=NUo@4~+V|4Px9eUT*TNmBJXMPQt)vT55CE%Ky0HJSd*MDs~( zUvy@l?|Yx=P2ZO*fldy7(d6iQtBp^g0*fO%w}wIxK0HDv&o7C0J^^e3{0PDVoIbO+tdn;?rT=+6CUjXf?^%71;k_^NA!Bryn>n6nUT^!OTJSCk z3R?O9><9pjFZ6g6#OQ_`wAIq!2F|NwDkdc}xn)rdsCiurQ**H?jBH^0b<)PY@j6}H z!`GR%Ah0tm-kF|NWsX1VU8`MD5`tosD>ob0*vyF#lLF)MuqC_lfFeR6 z?tykDX+wQr@IDsTAh$JGA`zV680|c>PxI>s!V-g=(3)JuiFwnwNaqvc zhof;W9%XwOU>p<-R7byRk#Jy@#U_;;Us2WonAzf-c00r-}ZbBsDrt1pNN<(4hRyFL|z zdkEG@ndSUauWwB_^|`bE#hlGfRzc|vHQ%nG^yGR#S66EFQ*%TXcw$|>A)(bZvR;Pp zeO^3e3ck0VXc|hmu!v7{l|pdu9>`W#0q3K*!VlXeNeqtM{~On9at5R$WKO?Zqh8ir Opr|QnDpt!|g#JHCwnx_h literal 0 HcmV?d00001 From be1ae0d38627cbe0c88785355b901578d2b8e58d Mon Sep 17 00:00:00 2001 From: Sam Richards Date: Mon, 11 Dec 2023 13:06:30 -0800 Subject: [PATCH 07/37] feat: add homepage metadata --- website/src/pages/index.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/website/src/pages/index.tsx b/website/src/pages/index.tsx index ff928e8617..0e0947488e 100644 --- a/website/src/pages/index.tsx +++ b/website/src/pages/index.tsx @@ -19,7 +19,10 @@ const Home = (): JSX.Element => { const { siteConfig } = useDocusaurusContext(); return ( - +
From 1056fe74f7dd265e7125c8031897980b83148816 Mon Sep 17 00:00:00 2001 From: yu-zhen Date: Thu, 28 Dec 2023 17:50:36 +0800 Subject: [PATCH 08/37] chore: update the favicon file --- website/docusaurus.config.ts | 2 +- website/static/img/favicon.ico | Bin 3626 -> 15086 bytes website/static/img/maci-favicon.png | Bin 25364 -> 0 bytes 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 website/static/img/maci-favicon.png diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index ab2eafa3e7..b1f4202469 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -10,7 +10,7 @@ const GITHUB_URL = "https://github.com/privacy-scaling-explorations/maci"; const config: Config = { title: "MACI", tagline: "Minimal Anti-Collusion Infrastructure", - favicon: "img/maci-favicon.png", + favicon: "img/favicon.ico", // Set the production url of your site here url: "https://maci.pse.dev", diff --git a/website/static/img/favicon.ico b/website/static/img/favicon.ico index c01d54bcd39a5f853428f3cd5aa0f383d963c484..f359138ec365a2d70c734af1077bc97bdf82d978 100644 GIT binary patch literal 15086 zcmeI32UJwoy2po@-e2x}D=+umyOOt__r|oVNi-ToQDa5L5)^xj4HcspG#W*u2-16R zLm!6@!^|)Y3^0^oDAIc`f`|fAhWdZs88j99_ETZb zE038I)%4$K3rt&J+5*!Sn6|*Pv_L~?+;h#fDK8HWHmg0$cBcB-P0eL9c%k|qMSE_) zDh%AikMiBQGbP^qovChTs-IVq%b5|$)}0gLve_}vM!hl8Vaa%s-zvmPYaKk62Ij z(HOrC^7!Bbdt}Kje|XwPh$J4k4I9Z<=er|yL1AqR*QX1=PG=! zeT+bhzky@(1-SO4-RWyYyDWy#XC<;Yn;;2Vij=@5NDf$xB=#aCQV~*rgaOM(6T`L^ zNO@=UO0(VGeOh}y>Hee$i+4ROwf1qr&0*|G?ewFYqz`2>xXEK++ycb`O7G_gJ^Z%Ek#2IF;x-LSz#}e?pmqWx}jpU$p;P)yhf$kveJ49|2g*c;P{`kgf&}st{$>;jX-q^qC=u^K zdFmciN)Mnq>oD2Cx}qzUb1lD*{b2T`4U zgtVVPBWZ6cWVHW?w(<*Tud$yp{Q{1Gda&)HekN8j@2Cjp3EMOAlIO|j|3(>eQi8R} ze>Ty3Y6H#R_2lzAP@8rPC1mpg@}b;#Z4?T2qAYnYD$@3&n(>(&#^1?jZj$!m^Jpvk z3AZY!RNGFOeqQiN^$^>y`@?L%B)_3KtF%4&j>l5)eO6J-TuWsQ#eDMrAbMw!?wX8K z=&CeEf3pql)?7t%-f>h=j49-AA^)d%Bc}N(J%+kmJv81tjh3QwXf3&jTV;l5uP`M4 zx0*WrfqKh>Z5Iqo=qKBg-Q#F&7S9xV*D~*{Zm_gBG4MmF;23l<~ z)aDFDyAyhw&2g((pZc~B<;l$4CI8PnO7_>E@EgYV>{-yEe{HtgyHbO_a3GP%{qPx}#-3@jaQ1-!* z{K*PKtrk#p*h6uf#-zoD`eH=ma(*KADCfW>+^KVvV6^1b$uy~Qp6jtwFUaysikDwQ zO6%eBKlVZ*xlW%}5(M1RnOkmG(!ETQ* zd}JlTAFbu!X8WS2@fz9vI`zQ@1MLn_bh=@v%OAttp-^-Oqp#f+cj_Ib9nE2{sbc5J zuC1>Mez&>U<@@SvLs3Qg>7G&v=@x&70?`5F^7lbTYn-gO-AIq!2}#U;uy0(2o|iY~ zTJi9vaW^F>>3J#=(DlsGD<7(HAQm z=!xGVPYamReT()6{%Z{dZi_2rS1c+re<-d@*Hu)eA40kGJBo#eP)#K(=?uQMj>e2D zd0-hALG4-@Se8{#vuVH#hZb0fBG6fN1$S%B(A{K#`!oi9?JoTToqoB4U7?o;@A2mM z_oh#Y-6tCljMb|(l?T3CmuIq}PX42Ro&0o5qg;2qIqxX)vh?w}gAgo}Qm9!}K+UQa zYPQXI-mx7oyWPckej;vF()_G39lG0KThZO>;d%ddux8I4!8^lfpHh2IrvI1cTkBGu zZzyy4s77vdyheUDp)gDT-ZGB_uq?7v(4+%KQ^TmHMP-0RiSJddTz*+peDY+LZAQwRRb{T@E_>BpA=BUl_dj@|Ji ztsy0SAO4m)pVanRPMiCm+&VGKs~2DTE1(`Uij^E-eI&3?FfweDr`Y(UXZ)7m9~E?+ z_{zT*3)w?h7BYr4+;MCm?K<(}I4T;2U4g>tx77EfwoRoy3pa8Gx|fsob=)y*iy6ar z{ITA%X~Tuq`9sd!ieUyp{%(&z+5I>7MGt1^M2!p_7Y=7#kq(O|+jOm$<+3 zYxgHH-u?xS=k~86UDvxL_-*9H_-@`Vi8FrYc^p!{^DA7B?Mnk~G<<@s7u<<*R)?7Q z1kX!-D9&efMqGf-&ZKC=DPPye1e|{()KPm&fR#p6!1Z}O4BzAu-(+}l8tre3*~IL9 z7lP-buHduRO2jwz9*`xOKXo3(4WIAd@w~ozyQkR#k&o%@!2se+43Cd+q`h`x@k|~; zM%enF8N67@;c4%hvvN2+T029UaA>DQaO#bJ#6Q@M`#vMKo9=4(vBI0Ubb!UDKex@W z^aLeGUyJPUO|<8{91J^8<9vgRaLR2UcAgVYEL6C8upoI?VsV!KQdKp0TW#3tbm^lp zFXGB<^G|7y`*Va7pNe%;f52ncAeC}JssLB^PDbTqH5kIAYO4;-O;lIfjL1g%h_**nzw_ zV$KW$C5~8_NDL^M7$ULHYS|HDD0*lvxy%^`W~ibe!gHqq+u{p^D%sQmCC6uYj)+b9 z2gF9CoXy0(x1*RiY(auHiio{3{IWDDRodseZ#D?F zCML<`K)5U`|be3Nv zR&j{hCw7&*huEhsal^C3-7XMwAm&qP%4?{KQK|hHpB+|Vb_~;8L|lznvd;?2kI+Uf zafYt)OSoTu4SkKo(VA^B*ycpV7WZn6&{BAs*wZo86aQnlCByvMt4su~HNh{cV*e=5 zZ{5Od=TW~kD4%32_4hbh@_rz$cxj|O+j6v?c+#yBGh#{C(N$}QTeVK;C$6Vxw?jYe z{okv%KzsRRw3QO`tuo8)>x@xp^_38?!zq(;bjp*D(EdGfmDJz3lA*R*WVu`_aM-1KZhJx71ePSkE4YqlmjeaV%UwhMOW}V#R zLZ$RU!1$&Sde+cJ%T=0c8AFrF`f_1GDv%T|CSxQ{3(Ok(620L8F ziQTjg^@MW=dZM*jYlBsqe-Fp1q0sxSYWdX_HQD-hwKBcR#++j#a;ZLM*@(e1EhmOS z9KgO6ANtiHx6lUn>dfx-v^XT+@9;U(e~0sN|J`Jj{O)19kJh&vQ=e-ny8h?-+#h$! zGk=Qw+%02J&AJJ%JKx5iyzXOB$bE2g5(4fwU7z38%6X=oB&8_tjXAz8;y)AjnBzBy zCA6Qa6*Z1Cl97v#>V8(AH-~rIE(%a!W!M-tM~~y6a8zNOJ?u!o(|(nG(BpCao3tZ_ z@9yV~WSvbJF)^19ui#bGyI*u z%(jc-eSq0+p{*8Xn}v$T-z%eZ{$WvWdq`+&L-7_cO81XaJ+6Vt4rZT%nLr;<`FWp$ z{;%0T)4>Zk`XVprh|0f1x$gU34YFOfBEorD2;XNVkLR~`YeLYzC;nccT;(^s%oc8D zTg;26HA-)sJLMe*Ql21t$)GrNwMZJPvo%X}Xwn=H*Q@i)yp2B@3ZMd8wIP zTGLVvEt5N&FWjOimF{p35@d0~N+8_ldsg?^NGOSvn#v0Icmls74- zjLAE!&pRn?DZl>MdoU{{?D-Ho^%!Pd%jDQG>seV8<<2GUrX0X+bnkxU+O@UpQeH=` z+heg+5^M7!$6+y_$?p_X4u4VNL39+;da%|Mw~Ef9o^tM*3k@h&?Mi-owe7z>>PHEo z=U*21YYAjA+fhcjDut;R$8x1+;HG#ZyU3k#Ppr^GYs#*AtD??&r~i2LeqUchwQ}i& zν8Ov+M^=1E1T23I)8;1#P1T;|7)^fg=7C^~(-2JeNfy3^wSe|qxWl5>CHNvyWc zbgONiNi6+9e7m%>!FA@y-QfTCJM_G`?S*xm!2s>(QTeHqvF{`5#vU89NBi*T=W`;( vdq(L)kJwe466MLe}z9@?|euc$Syw74ay!3eKrrnQmjfrc1dC&g>x&u-q literal 3626 zcmb`Je@s(X6vrR`EK3%b%orErlDW({vnABqA zcfaS{d+xbU5JKp0*;0YOg+;Fl!eT)XRuapIwFLL`=imZCSon$`se`_<%@MB=M~KG+ z=EW^FL`w|Bo>*ktlaS^(fut!95`iG5u=SZ8nfDHO#GaTlH1-XG^;vsjUb^gWTVz0+ z^=WR1wv9-2oeR=_;fL0H7rNWqAzGtO(D;`~cX(RcN0w2v24Y8)6t`cS^_ghs`_ho? z{0ka~1Dgo8TfAP$r*ua?>$_V+kZ!-(TvEJ7O2f;Y#tezt$&R4 zLI}=-y@Z!grf*h3>}DUL{km4R>ya_I5Ag#{h_&?+HpKS!;$x3LC#CqUQ8&nM?X))Q zXAy2?`YL4FbC5CgJu(M&Q|>1st8XXLZ|5MgwgjP$m_2Vt0(J z&Gu7bOlkbGzGm2sh?X`){7w69Y$1#@P@7DF{ZE=4%T0NDS)iH`tiPSKpDNW)zmtn( zw;4$f>k)4$LBc>eBAaTZeCM2(iD+sHlj!qd z2GjRJ>f_Qes(+mnzdA^NH?^NB(^o-%Gmg$c8MNMq&`vm@9Ut;*&$xSD)PKH{wBCEC z4P9%NQ;n2s59ffMn8*5)5AAg4-93gBXBDX`A7S& zH-|%S3Wd%T79fk-e&l`{!?lve8_epXhE{d3Hn$Cg!t=-4D(t$cK~7f&4s?t7wr3ZP z*!SRQ-+tr|e1|hbc__J`k3S!rMy<0PHy&R`v#aJv?`Y?2{avK5sQz%=Us()jcNuZV z*$>auD4cEw>;t`+m>h?f?%VFJZj8D|Y1e_SjxG%J4{-AkFtT2+ZZS5UScS~%;dp!V>)7zi`w(xwSd*FS;Lml=f6hn#jq)2is4nkp+aTrV?)F6N z>DY#SU0IZ;*?Hu%tSj4edd~kYNHMFvS&5}#3-M;mBCOCZL3&;2obdG?qZ>rD|zC|Lu|sny76pn2xl|6sk~Hs{X9{8iBW zwiwgQt+@hi`FYMEhX24V+IQ1-xn)p7U$mt?4lwm0#rALcL@YU1SBmctma_= z=!H%(-&Du%*ncg5WtKeA(k@mjO_HH0^psf0m}H|{w(DuQwCB9x7z6DE*dt=iTp1WZ z*e=s|;r0v&1&06=!;KO_%a<0)kXN#$l+aY3F`v&w#2k(j?mK$lxZL{weB~z=$)skU zY4!#vNr-3HO`VUaWuT(pr zt``X7sOi*L-Cm_p0HW6lS%uyaMXLmSOT*y)q_O%BQ2qQLvrgbN1Nx(*b$eAh{{X85 z6&eRLb^mNtcWkWc{__R6ZVPl3MsM_=t>5UF-Cot!{{ZUV|KFXPf2y7HxjDAz+Z8gc zgLim4UG4R%gMCfEyI+<6l=V>ckUo12pGAG~!*XI9Ihvx;kzF6OAq@RJ+phTnV7%n_ z=15oH?Xhf@`2i;|z5PJ6I6hP?#BfI*V~^<(FByb63N^K&CkX3rfcbNwTmA83c(BKp z-(F+C@u1yH`?_-*{#`mb?~mSE5KVNKaKcVjFwjlj#_xp_$O+`r*Ma!Td=M_BLL?3~Vn=3-D{KQFdpdlF z84vUjen{Wn)m5MV_8)Y${mg&RuRLdw@!7TWUl3_M4*`=v$=B5%0tfeLo=n2<2ECES zX~d!Nc*sZ`qgU)0&|NmhX9xp^o~CZ`jK{s6eT?e6G3VVung?&a^S$G6gdePQ@48H# zknuzhE;g6W10GUeP*5NqehB;LrXXe%Le?f`!l)JW#L?->hJ6sbrkv z9sBd9Wi>btI&0R{y#SerpE;470`YG~h}im)%(mQojG_U00cl{&aC~6DqL`q7zS{|j zXMN4?zyro$N5I9kK&|OBwm?2R)kk2j@6r$lva4(M)w@bZxBo@)7VS4?Pd>MQJoi)O zOJU~=*VZ6V%>*5jrt?9RF>vL1ACD*q2SG5GC z8~Zg-7)aC%IshqT!uOj3No4fAe(71jja9@cfU@?D~n@}5|X)lq*t`x3*vXXGQ<4&Pu z;?rUSrr~BO4`KtT#1ZLVW!sDWmUR#5)ubP%J)%doEBn5aY6i~Ae;k(I-n|p%EtuniKRV;>p?w37DkS~ z&7By8?uB3>S3U#JPO!X@*~}%Dx?-H^lh`z2FH&e=xD0m`3Hy~zx!UW<;``3`+4PMiTL%JVn*8V=t zoR28;)fkT~j2E0A&S$UQv+IJ7gvf~bV>$bxxt*LI6D|}@q`;ZsNMqHsSiN#&hQPaW zC`7L0c7U=UJ7Fpo^y)#n;Kqg^U?lMiPwGz{*kR*{=R*f!$B+H$=P^!i*8ahVD)C;B z==a&4lD8|y49Gv<_#tl;I)g}V$ph0aiRQ>wg#mOy#FNC0S=MxwG{^zc40GRrMfH*o z>OM2-H@iT}Dzp#pZ+;kNC^)$dk+d1p+b+(b?x*nT-uu~|iT(rb)gpsH@h=Ml=kqy# z69u2sc;pZKl`mqPJmn?Q2(mvIuQREkQ*~+$c6a2Lspqq}Nc55OX@6{`M z0lWvby@en<=pFO_>#}bhki_!LZ-A%}~Q&6X8W)O6VBJ9AywDv8N>{1Jp8X zb^}vDvFBq9=Ej#GxX0W@B?;cz&noUh3<1|Cuod`U8Y>15FV(*HdJad;K0g0A#<{TW zWY~SqcP!^E*+1xYs257aTG%-ROv-))9nF2I9=0JPA0b256hL85L9bWg$qCB^$*0pI z1Z0_f7#g~)rEm?<(jL%a7UJX!c%R*mzdIwWdLBjZI$RwxC=B&&WBe#(rIi1>GOqM7 z)Ia)p3tGT@tSNUx20m7VcAx0U&cpzlc}1Z#qHe~mAh#m>iU5=%=UP74UCtkx z=I}$5oMjzBT7rv!;;PmyTTy<`T*y1^WJ6aOV9tvcN0kQB2jf_jx#FxP+ExA5OQ1i> z8WWO`#WZbkg&kV|M1;~X)V_(Hb}KG7DA(DbZE5)E1>|CeofWE{JNlSH?t)o?Q)@iH z)8+S~a^`;H^! zhUr_DBDqY}zZ{5MiP~pQlrVB%j8JyNYCmjTV?Xk6NWR0~4!PdYUi0Iau3(fLi_2fUW*4Yc>kN z5f+n9UrSm_j?n_4WGH(?QTZ#XM&(l@8`PW?z`_Kg@bDXi!z438H($V(XRBKv6tG2NmBaX>LJb(>J zr65t&$&RL#Zrn}Xu|Ty=<*(c4dKrAkWJ(?-ST3o0OhXYq-I34nDOcmWg^&4ZEtkG- zc>dEt{1;wO7 z)j0JH8kpNL1_g-18))FKK^>rIhH`SHktOPb4CDxtU|0)m%k28`^4&$y3rord!cquWD5kE8k6q0fS zB@)h7)aIH73?}Bt-`fPjDpzAaY0jKgvbIG#=ujJFA|U+xRf@K(#Nc?lior}Q9S8UW zXG^~iDofiBs%tfki`(Kh6p`*dNobEBw6*OMO1b%xNf1Q~kk==0iZTUuR%4tVJ z)`&0b&gYk|C!c+S0ejJs2EtWF;B4z9>FD?5eLpj`ec$>_+px?Rupm27F+1&pr4i!Y zITBh}Lj2lCEkXc7A!)_J20}<%3$eB>-%}g)!q8bwGr$i!@HKdBIh%}&>1do`65fct zO|XJHgpibVK++^>#t><}&MHQ)kVoG1HY#sMO30xQmNm=>+&!$tu+otyaYw1uv01>>XUb#k~OATCV3 z_+-eRE}+}{v!{((`r&!WB6sA=jGlOMlfOy`C?M<+d}hu_Cr5r^+Cfx`iwM4WR_zUI z)<^8EQ-4$2wZJ=Mfo{JnpJ$e{bv>?jC?ssVa6$C?)Rf{g9$3qR zq7IWb9+kJzHskUN*>J_(u+`z}^68oxnes=V^Qv}3$Ls(6zBl`b-KeQ8#$-d5jCsNm zvX-NgAHssfx#DRhO7m-GL!hOj@?TTPOteJ84c0g?ZrvRCo%CGOSCvO`%I`S;#{Y2g z2FumBJUGTA8ZXLX?N-u84*a{xo=FE!T5@}Y?U)t35R~Mn%(hQhYBIu&6g@$}`S?)i zM|#KkNKx7U5mZZ2(P(f#xNwFHZXw-(jQgqu5092eIQtPDMHS<$kX-4a%KDr^N60fn zON3ncBzv8N89x%!j^^Y@801#%*n-bvSa3x3!C}OpC7=+Kv?N=vDQ+ntuo4V)(l{~d zY?)|^Y@4zPOB++!W)uu z-tJ(?0Mom2FhM99_s#}BM#^UcqDqhMm(76tu}NS+4t^_`?bRRYYwnLDcL!Rhq|=Jk ztBia@A*?Yh1WB!Hfv_h?f7n>cz4+5bR4ub@u*hA$7%8=eFEa*(Dj#zLDqm9Q>IfmW z%#QrHR=i+&Dbw6@~u6x3R$y$>bjPWYzV(Jq8U{-P{P;+N!qwZto6GwOzobRBJiE@ye+2j z_TP6C&kSwLaKG%4M%-SVyKAf<7q@#MDiY zvJ%%^cwZK^IoI_zyBda!rbu&jD@&r9J>=5z4L#@yJSX?ZQD@f+Fk6{P4ln$DY``LS8|bBsB{`#EBakpV3pt(v!$0XE6{TX)tzUUuUqug} z`X~e6=EWv@nwWyl+u9j>GmR`DHjHOt(g9koJiVek=j1lI>Pr(d?U@>F%>*X!qN>Z1 z5XV&i`mg9+D#{cui!{#aD-?K%gaO>16ObJj!SVQ?&b9dcIoFaU8vuU_$J*}$fy)mY zW;+XeTkS|a(bE!7ln{UApUb#S$T@F>*P>z4m(hCC%Gq!3mLyNuz&RP8!h4*Q5sstA zY8oTW65nr#j_OFVRD&3R#2uK!l?NnK_zp#EwI)4`egph8VScgq769nin+e1xB<1Qp zQ2wy<2bWR}Z5s|SoWl}08tzZc+{e=MIr*Vldh-LYg7eOap+Qdqqr5z)lHboHl(^Be zUrt2axt0R$iGjy|mN#abuxhkXu_M3Gp^*zQq`#7hCKHGylgR#NwJJ@<*`}BfZw|2U z)|;BY0Mk7YjD23fS!*LQ^Abr4fC!3*Cl4i=X7RkL?qs}P`^R{e>Xp|q?zJ#MgI(#a(*g$kaU6n zS`nJ_!9^s7<gn6JHjLH#BJVA^@>6YT8ieFIUBk8 zN>2#_8cc>CxfSAs%vr2MWd3q7#jx%}XO7U>m1{%&;iQPf?SnkQ|{iAB$~JU{@ssT%4bb@9!bo_47Vj4B_6O;AA2`cC*5 zT921nqoO8Xm{A=eI6pWwx!1`H=WMlHznbMc=v(1D1Kj2{#GJeHY~aK!aN-T34M$sJ znZqzCuP^JEL&r?olA0L)@)*o+H36YZHRHbPgbR40ar^z?6tf7@>O7)B7Xrwj(DTR^~7g3nNbheHxL?dqaHTP}Jsv*P2VYxZw*{`v|u+ zNT6d(K}Q}5)oQ(_7XjTwl(?62`)m!EB=e-ge}2_7G6I1+BE>TJ+4XqcKs=s2@H!C= zh&V~?*zlnj2y}sGp^kuGaYyfz7^^|B#Tlw})0E|@GfCJ`kcn%Fk)kKi*SO|fV7Kgx z4^J{z=T=Kviw|TxHA~4F1s;J((l=+m<<)6c7h!7-_!zl_wJ1(MNK8IonD)hH5Im}! zMV2e6y+qO0(K})^MaSaH#MU%V(KUxEfzNF=O7mZelqmGcljt-dxGGM}yVtBYcs=TOX;NN`_OTV9|)|MFXz% zb11pbNLh3&E{o^^bJ~-nzbshm2J(L)3)(GT1PH{Yeye7%cHjN#6+x8CmyWSeX>1~~ zF2nt$o3W6(mJEtC!BIbcG4^M$Sn>xqC!!8~*GR|c84{MS%2F!9@o*(8%w!Qt%&jhsZ1hm9f13(XqaTm)12tZ^4i--4wSxG14^|8i{$o1BTO zzcI3vYv4D&R$gQ;A1bD{K)2s*aX#C55?&d5{MaW>PfZ*fI~E+|1tn-;3?aC4*Yp|Y z?-0&^n%fDsR+cJlmL=+HL+UW*%TPUWf|?EwbXNlYC?w-}{x2lOT#AVzeItoeN&;nO zhwx{59a{3F500s{fWRZE7)64-+5>hq*-~;+JZBiRMOGgW^|9R2g}_3XFzKfFhG3w^ z%deK-1c_P>EBk@@?u&QfRuI@%drHo3jk)j))bQ1#Xl1N-Oi*Wwb_Vf>vHQW{h+pem zs@)3uc2RZ66HiWj%=(t738iEQSm9Mg5>4@K_KI1PGGStqrOvQ&>1OL}q2O6LqB40% zdMu2>&hF2z$1%=H94&2+a3X|G6YNh+7ofShV7uQ0UBUEt_G7QQoCd6@-kuZ;O>iBA zU#&l8d6)2ue2!>0qwF=a^u>cs8C)Y&_{K~)5xS%DG;ainCYu?7Xgt3lPNh=hn<=X+ zg!QU)ppe1y{eH=D3Pe7&D+CT=DMZP1W~J?-(PorJ{FU1iHI-BbwgD{=%55eh=KdpX zE6&1d)-w{DQC&@20-}0vK^E}hqLYVbJdrp8Ix-wL;&qW5zRn$~^M_0)m^DL|lR5oQ zQR44KD3%dG4H0;Q4wP(KBO#+{yBnzlSGKm zx}&(T0rhNwZJ9l_d`CRF+3^$vZ_lcLg2eJ$Um8f{`2ZMqcReK3kP_IEUZ64poWy_u zqi{K|kUx`H5(2rK^Op~(pfg}V4se>;F~M@+2jKi!@Hu^i@KOd9-WhN%j&yI13@rt3 zIp4NoyFMyoTFfb>UJ9|-i({J=>!(Vh{8d+#QWKzrM0Be*0HW5Vok&E= zNg6_?0>!r$Y*9#n_3xldEPYLLM;jr|y28c|Vvl%JBDpCPtnmgn{6=VX#dO*e-&Ity zv=AFeFFbBv)b0U)oAw7nto6rKkd#!8h7Zc&ZbYIm4dM;Mm{%d2?O!Zh36@=P(`VRU=P|CN_g3K^q zXVwv(oql#t8lG-p!Z<%7-u3k}VPWC-_C+{!p3fa?zYr2hvQlw*97#BC)xNEzqct)# z1afwErW9>zCQZSNcg#HonkB0G65dDLY>pzBvO?0coHeiBr|;s(Ah67r6K&k1=0BeX zJrjQ_hZ+N6MKs<68Ohkwi-6-9Rr;KRH2}Mvy>WR%T)Vm$nI%=sja6UCPjyou-sDfQ z-j^gpL1xX&<*wzoB-d>_le0!C4zRq+$`S}VL^wLc80uYy;-Nfr5F|CyW8>9=^Rn{t zg&V?XOE(BR(Dj4*w`Y_J;NeKG(4Tao!_kT5<^#VN7C8H6a5SY`lBoGYTBdTyMW=MS z_;TW~8^L6R?O7yFms_3{Rq%`>xX$EUx^@N#cE|h(cgchWjmdp!7`j{RU--?m(`Ynz~rl()y_rLreE+zBF3i<-*VvtxEM{%*Oae>devYsd~FfkiD znBq@E#oZJ)_K0N3*Gvs!V35>ht-3*J=i0NRwx2dIlDkUUM}CVh>6#`?z$TJcj>Ulq zr4_`%LE^CEW!ez+Hvl_0VDgqL7;S70{+%L8(@bmF{&Q3byNy+cC$gp^uB5y03~NAW zKvay97#)wZeaXd#mXW>`1%9b5jmf;+INSvNOK@^5s4^6f{ap;!~DqjxHy&Lm$YIRT$Nynr=DL_wUm*o$8j2VB$=+|wVr zxJMBdOd!!2K5E)d)OW@KheLaDCLoc=(qHK|h;1reSS@=8YfMG~Gqw&IUq`>GN3%qb0%Y=u(EQJ!2q-G*N)>%g{P6N67>UWpNgeckV z{xQhzvp;1Uk#C9MDCjm0ISbkEChQ`lRWG)Q8-D_7zxtZ&eW?3Jr=zZIS%GqG~^i6%3(Y*Y?AMsxPX%A zH>3?-7nEJq`2+NIyg|Wtn|(@~&&OoNOjXLf!OREC(gD|}1z^CLfPm-E@xUj`)q~w@ zEQHE4b0UeRx|!4$K4(>`^RGDh7y{JkpV@JeRn@K(V(uly+ zHtEjhQTzo4^@WQC*YI%RU^-E^RO1HzA@=pvI%`TFwo6}%*xS;4b4mgB6=`_frHXP$ z?(X+tHt`4bb+cjbW@kVztp1O}4~-v$!ko6n`H&IE8$p4%%HFI=yChI6SJco$$?Q=i zY&h_df5_%+7N7JIu;Okhz{h@7F{CzICsA&l%MysDt9oT7)LF!oN?(}0fOM5B6baxR zm8GihcpMNF#qbO90o-}9GSMLGxPxw#qagFRqkEXc3zWl+XD)#(Kje6(3)w=yVv#h{o36@qC)O*gu%%7>FQ>8s5$bk9&ABBgH{0_)% z16Y@8NOf-Fs1PUaSeG9UU}ZbKP5_mSeT+qOq(*b#=riBHUAsMTIh;*=cS`tm_ zy`!VJs+DARXluuRiakgcQ>@i@^w6)e(%G1d{8s^T&j9n{Y4HvOPryS+Z!oqNHp%ee zh^I$F*JLpV+MC8qOWuxK^|mDfGJ=DeF$+=~X8~i3=0L574d0rr}NmjZO+e4!QNP(3Zc%lL}j&QBaj(y5usGbYhQ>U(^nA8=5|51VzuHrFKWUn!Y_LL_oy^tt*9meyEZ{hKvq!pJua)(q< z-f4FW#^Co2&)$@VCF>pgKUHclK5u}P_2P4J-0@LZ-pD$oR6lyPv=G|ZiR;FnB9$OO za+LMz{Ge7_mz`d2Ig7YZRoyMUu=p1_0t{_%_4=u1G`Yfrq>j{P43)cTeT7^+ECM$r zpc#ORE$DtklJ3A_?{0q5(U?Rg&Tn6#mTvc00tnr2t1qebQy%ENSHTgjDm_Mo;gV^` zy8r}fT^Y2-lgwacc^ZR!%JF@NUiGVY3o_D%L4ZvB86b$hlwp z%48^-hh&{&A-qdT$eo2}*t9Vj)|)mG9IJ<)-H%}>{{BbheJ!~eKRz$#PWzMaa9>!M z9P_ffIQnqF%4j4pB)o6StvCe&%HGUzs+(DaRc`?JqI*Kl=^Z`Uqn^@Iawow|YoZK@ z;65$B#Nf@%t(^t{Yo+dD>YoZZX?^9^5E54f)|HLOOd;I35p;}d@k#AOHckEHsjM23 z;a0x(@Q{ER@+JTmjrk`ONvpHQnIW4*LfaV#moHvx2@h0s!9(H+AI$|tQep{?#Ney} zU5m3^OE&?P26^Q#j?$ZG&{h_#?6ysVY3b8*M_?{nz&^R*a4OqqA$iq z7*B;56sFD739F}1t=JkrHoO>0`$C>%_oj;Rn> zZ0Ypm<ZB~oFcCB?`~gGjJ992l4wO7+W6>eZYk z2n_hfb0;3VjiMg7iJYK@tWJriZl5crmf((toekk7Yhv^;Ct*lvJ2SiXnA_dF7cUZD`!kyIir+QY94~TDZ;D!j(FRmnr6hXBUK(iperi zxEkC8&`!qLxSL|l7?Z!~C|{c(qg6<%@`!g8X-OnSu}EJ)W8^4Yds3#PuHCjvV|)!S z(8ZXu;1S)z#<>@6KyE=aJ4hGW8U z=nY8Y8vDA6AW5qq-?q{kQ?6xE={z7Dx(=!Kw5sWL(77E1K2FL!=OqOK75Usy7N@cv zyUS%KaizQbjh%$;2^{pwmj~z8+B!&%hNSO{-RSM0<5Ds=_G3S2b*f3x=Vcro-da3d znX%6kcg^DBndSQTMIE@*E;C{kM`D+0)N6s#?+3Re;!*@SV>&wOY$w_Xe#b_2G@36_ z=buBNGVA?&0zwQENvV}KiaewM92dbH`T&4k*JP!A!_VN!_5K zLpX7?X0L=&Mk#5Aw6(P>7Q`_T`n_G{Q4*#QavY;uTg?cmRWd{6@4#=WGv~@R;>aX4 zCmIzSn!%f!FWIXt`FjD?d9&X#s$>kqX~$mph&dD0-Yu_9MW#Ho)^15NP0$&|G@ z-ttTY|DeyuXT0ZwG=Bh+&>v;+s_VJGJ*6>irs7?X4x6vVZZ6gy>9}V$7T!&pZhOtD z-JG?fq+JPt1Nau`Jb)s5ibkP`3yoa17g<`z*v%6>+6C5X6{qPCYuL3*KO=$7pMl-W zbKY-Hk)_DaHg}knbRH{zcR2Hg!$pY`9h@V z;xzvmK^7UL8;4nKW!y+-y19A^^cBKj8dZCP4*<9=5>l8rW#C9no<-HD?wTsBCvKjg zStX~Imc*e05w8k11~g4;b+0GSw{vmEzdiGvZP`WkdOApu%8yH>`e@79>+(PW@e?Vi z(pmm%8;zj7GPw0SY#V=WSfVTP(?hIEZU6DPMQTvT+>?}5hDQ&#v_}4r}`us1aQuZO+kALt!dLLnA-Y zWG&mMb=o1NeeFNG0Nq7Bmjvn9_dWoAwYiSaBUQ1?1cae1iCWLC2q;Mp;ZAeK#E=4y z$xAHcZga)=_Vxy4o|K`Hixz;v`n%(*Tlr-}X$Fn{CGsQs1@6ar4NtdtnqzZ#7YM3y zJ$Aml3V8Bv(k@-2ZIf5m53EL;w9e)x<_KAIdEm!LOH#Rnu%>i?FZE_AE#z z(#VN-;b(4MgevwUoOC2Io1XfMl9rxsra#HCR5Y0$t$tGjVoXPFo|uY5y7}y zn1%QmoIWdYUr7+l`ugOs_u}+$`*91Zp{acSd8MW=5)?y^o>NLPup-m=(^uPJk&|fd zJPeK{+v1g&Kv%Aqk6aXLRKt#wR@*YFz2^L{e5av|a=G$F9+~s5kT~>mPR&61wu7gU zme$bL6!qq=A3!n{?ML`!1~tr8skcXBVn(}^DnV^(Q+iwK#%ae3qDe-}dRe1mC?8}o zqXt4@UT*DFV-^FTUa#R^7YUvv;y1FP9M5#g-na!63MRcnDyJ#|lY~V0cvMMm=qOoI zD6wj5`RF)YZsZVSE0s(4T7+rz#;ul;)6p|TL~mdJX2yyg*+pwxZCg(U>py{OWvr-S zMdw<>cfYSL!*&+?74!u3dY`UdGKn5~-~Tb(JyY*{Xy8$O9pU2c=$xB}1}Ece<%C+u%BYMN9g*?m-Xde-_R5o#PEuJQ zl)e}3gIM^%{tX31QLRv@<>mGZTM~g_WJ*Pq;%FfWKn_Y>owyQmAj+Nqk^#bIt*sZ@ zIYCaYKssTUr&~(-*GIfEC|3Qh5NJ@N_JK7K+Li-pH4ypw!9CCgxBG9VHuF4&=>((vwMmnW{aB4(1q{t@X$`)PxIZOFNLm7g3t#8FG7oGDu7q^pdhQd$8+t%feDD zr8~U4Si3EK?zaLiPAA889gMu5%vcd|Yu*aIg$n$BmTAqjGgiSetH=8zIN&)9giZRM zS#rW;Hz$e4*Pnn31s9g61w2Sg#{F9)j7~8TUSdK*?&QN{bzM_KoQ9H|leBgsL3FAs zYOZNhN)1t(^JVUgU{ndSeYUBF1zDq-(^@+y82IkDy#NdAhsVE-fa@^)9N<6G{PPC# zw^TiZjKG$NoMg{LZwV{pI0@HnHR=Z=X{hz#IUxqcN$`?pZoW0t%Gi9+z!Fnecl+Yj zZ8g=n)U%cXj&S=S(H-+Hbwi#zw{}9?Tm>f?X~#_YnpqW^d2J1&u}d!9Md2vVFCDJD znFVLqDLKm8!1|7@^Z;xcuqM8l;p%z@OnMww%Wf8f?tzlMsw2YzcnoOP_2%+7#`X3F zz0nvZcc?SzpuJN0?kD_?c{^3yfu*aL z9j%|^!_|aKvDtzN*z|k3?ceQ3*-w4*Texz^In#RP|}HE2(dayu$3Elu<( zq-RxeYQ138ZA*P)^a&E4R6+`O#L+r&d$3%4Bw^jj z7J(nGf|tP37kF)xO4BptwKUFNIOy;H(8_AcWpO4l4fVaM=rj14Pxy}Zxhe|7_4{Fj zl195hWk^e?qTO?73K@*0W0<^Owv|P{jf*)zV}yOhe3>K#XeeU zcdPBzn((eNB**!djNXKa?5_v;YVZ-`kWdX+NDU1qM{{)9=*AAaT!9672$qUO+<2pO zKO(y8LnEZFVZbOMgcXN1Nq5rt>A+hp8t!&CSAQ$1Z82e(iTVXc5^+gNG+C@zD@(Kj zBIG2QmeO<}@t#?fK{;vN@zfFv0wGU?ySKv5;^U#x3Wcx2U&G!8a-p5Cw?o?ZH5fINI)1 zRE84gQ}BbGeY0e)1q^rx+ek%d*CoTHm)eR_FTE|&-N#^ziAtlH#TZpl|oEA2Kh{UR|*d)#>BZ1bO zBsC@d*5-pZSGOlHru%aVFP8bI8SX9`AxjJ&(uS}cujF<}H+arOlWnSJ|GH%VIx5M@ zz!lBf`r5$1Bt9*)B+0!&pb(X)dqKAM%jqdtiv^ZT-(UCq+|Qk^<_WFlU(+lF(6~Wf zv4DMq@8@i~8r>;6_>Q-LcmEsbZy&I|DPUs$e-z0tMK(r_Uc!Uf%*9+=di*E%%1{b^ z6Ru4<*0*6+7HLW+<1dMix}l}^Wn(qQ58o9y!;!C{uQy7yH${_zDc$}< zERAYR^s7*u!RXYQkMB{*iJrFRecbJ?Y0|S%Z>iM_Z@5!{3S8UdPjP@eft6cf%SEw( z!4}j#r+tl7GA&HU{`bt++4&E^RO(E#Wj0GSJ>@--OMb zPHv*@My=1RVjP(d#{1CN&Pf_e2!)4)(MDop=k{RbO&&XQ1_c*^nYfgZnNatl^HPYT zR^i~(7I_R!LLfy#uBA^-3~_TchM{^@lt92y2?0&zGk1=m>#MHT{oIz*E{>Lt4iSC2 zs>@CNxBf>a+OnI>yV5z$)N!=3j;X^iPc}!n)k749W6!{QMSQj{^7s3by3Roq$nEa$ zeapS4!|p|!8QJ^dDF59`p18xDQWx9;A7$&=kxJ^K&|kA9u&>ek(dXunoHG2mh&0q4 z*qeEAmEcKqwAIzlf17hchAsyi80#qMq5KuYR3pNbqr95QJsEa0exP8yZprPkc;_{`Q?Yz!qmFc2^tM>OzuwCIS)>|9{c@_SGTLFH^;73*rap*IJQ z>)#xSj99OXSg&PuP>){?^jn;M=g-aq`h&mkh3duHw#ErBbV!r<@)B0MTCQ2&RDeqW z3P`DI7tdPbXCPh&TFP;MM=TlcXi&geG_;Yug-*zxf#$}nK|5{GZihztEL{O@GPTHd zGiio~$Tc1^Jy2Ojfn^hty* zi=<#$(&1=q8)Zw*vg++LTQt{A)YZpA7S$=^j}C9q8yT(gQG$4sYq%&dtSRx*Wr`S^JTwDKA(|kFKtQT{`RnF{4MZ^!M};pNoHZNvUx9a=3)3@;KMuVe+eJc@m@MR7en-=TX;F zanorvcUai3a(rRH5jS^=9)kWz*u(;$LQt>wmWki*NllI!O@y!>0s%-oyk6RvgP5 z*F%;lRO{v9=O>5;BH_rfWqft0DLwpo+a;Lc$)wb~QkH87AHE5j*{Lgo)8^DW4^C}b zN3(8s_Yy+TmnK+ATYI^!JN3;XsQ4CZ#~NbWU}A-UZ9Nu$M^5(z%4Xa%VRRYzrz&L5 z9^!Usrw9J*YR7n$yTqoYG2Njt1O9<-+WB2?xTb{#;rvW!8t_XXBmw8o_{Uy6tgt+< zaU||BUCvFPo(bw{88@`3_LliElV$3TbXR_8wiz$}!N!(?q8_GqM_F~;6$STD4kmlb z(DKG-T9snVjGz^Jw$;j2(|zXr_7$KgpJIuFG0KL8GxVjAsYgdD>CEB|xQZJYwAqd!?C&*~2u+6z+ zYCyll3%juBaeBZ-U^4dkg-8sULsG9zB3`Dem4e7ZE@$gK(CAg|7><8ni=z&-F7xj3 zb;Z|ryu;bHK(hsDOjs8t?v$p#pFng2{ZAe z?qv}s8;L@g#QLq}ZjEGTcx&MjFOB%53f-|3s7fIw1DPGNh>>8fGJ-q`GbasuZZVrm zpJS6(a)Yrl)a&F6?0-678&j2~J>YxPsCq`}|AFYpfT%8J3+hb{nPX<~9Ut*-O@-of_##RfK6-7d+j@<}p z<@AzE{$-6Oo<{;5XVN-NCA#Stx3%GE_cu1M|4%T7z1C6AW%xg5{~7g+YeItMoK@+X zTL7?hAGJ?YjdL zL(STab-zi_H>ka3aei$NoY&UZLtl@-*6-gGwXX~F$TV~{1r@L34JVH)%HWO3Z)Dh* z`29j|wGh3U)52(WGM3$0VqTu)!`{`M%U>Q7joIEgSJN-oP`dNgKh`}b>fi|KI%gkq zxhcuO$OAl=++u-(&)GsqDjhF z)VL0H$5t#Wup`&P|60A0nMX=AE6p(7=1PNM$4PRuIMzLTzKShVv-~g)dH##y^K65S zAhzE@xopK%krd^-%_9e+OC8WQyIhLTOJ6-_q@iEF^e!W3<&PPAxKr@qL{n1mx7Oi; zPRmJ4`&VYOwE4R85UJynFGK#7vr}k)y+ODOb*o)SxckyLZ+y++&A+mst&s;J{Z9Q4 z!rU3~m2K$xjua>5+|sj1ke0cqXS0n1f;S@UkSQQ4?uX?PqLP%gEd^#Pnih>hitEDw z+(sv0!JWlD*5IbhEnEG1X$&2p)`Em)t1?p7(gV|Y+nTlT28gEq`bbV3@%k)cN0;7w ztzu7VaVq~?+v0p|_V_wi$cwj$lGGFbg9TDpE{ z)GHK}dMMz&aBRNq%-m!9on)`8kL$m;9o!)!-agY0VBHUL`~%zirmgBBBU+#D zgV$y?3MDsMZ^T)_9*&MX^Tu(E`IiZyu8OvtCbisH&__r6M@L;9o%zhzrMC;{QY~6K zD<_N2+dHnqh%|@L)l2C%>x6#k|Mdbi#yB_42I)m6kj2S9S!#HwM8yMq+Lv0WYQpla$-vZIBZBu-T=5F5_BnRleIQRJ45jfQS6WKP0 zea;r+pASE;ydJjY;a=VbUWdF_hU%|6Ve_+hu{2N}$hk>H0C$CxNEnndR~^O35=sTT z^Dnv4fMv?==CnDSj+b^jeY54oiNVO*xR;*UsjPN3Z`W?<}9%@PfUM z7AO>oySqEVX>l5)(BfL8I1LWPDefMeQVPLcf(H!*`=LRLL-FDc4|ksXU)*i%`CgSin`9yd{W zY+P8_oTOg84kE5w*^VGDKOj$TPKZYMYh3m4Lk@D+gs}{6oW|}tQ!q&AI_SMZ>d z%K{>iy9r{|E<|kNHRc@C&o&k76ff1k+?I|nSvN-p8uwd2nM+z%Eed|9a)s zNi6qY<#}=LNvhrAVu{vw(-{|0t5SQT9gogo)`1$Grhcr7nHOXJoHrD6On#`XFP$>g z2e_ED=)HQ{k}UmMp3CN1-OQ|YVZ#m=10$6No?LcX{%C{IINA>}iA_Wzb>!im*6ww; zR673fbw6yO?<4t5Q@G!$j*9^%0RESDATmHwHX@LM+f%p zs9Ef0&#-nz#6OKc`Ss~;Ea9Ko(iRGI;JZR^N90`~yZms!`*8gyr9Y86(OK9yj)U30oRXtw`5>8E&H+A#le zK%I$AhQ8514c0!|9-V|#=kM>ojxO+-KlmT8^OZ}Tu-F> zc~*vRF1;st&ad|THQ${{HCi8j7SHnvYxfbU+Bqwui>lXxp6|A(D^im%xH8;>YG%Rx zVCWzEODlT?8P)$6t44zT{`tcn4)32ZyyYHP_Hnt<#IK8aih;!Q(o-ZA9AzA`U&|No z7YrqL%M*-6Os3k7+>Oi;GPB74#H!Ko{cM*Ddo)yAbQaaNN*FXK`Xs<91vxO{488u* z#UiC{647ee|4bW{Hu{+nan_U!Vb;G2A;px z$U~qV^t=*SW^CeX+c#PIt0JHLd`kG5@!FnG^#dpTA3{_n4UBkE0In%Ujyom|y|X-y zoV;s@iJT|jpcb{Bo|?zaqtO02Qk9G-e1; zN^dgQrpajvJf0ZnyZWLNOEFPmZY`OJ>0a28rHUR$DwFDH98+To;e&|O1xUrFMWa_V z(#|M%I+?rvH^K!=fA7i~^yJrl8oBesyu%!oeGyg`R=J%6LERP0>vy|n=_+VSZ}9Dk z?H~J82N$7S`{PZNwn!+ys>PsAllXyy^dz;r_ zMFz8hshOBq3SKw-(S(%Mh~l*2;GP(Xq|Ir6Z!)NYI6l6E(c--DPalk$&K#e=ojkgq z|49roLIKwaxc^dw%TB$%WHV@R4HlXl-O;IDZ)9!r5jMqxK2{}>QMrdCLhb)Pl( zl&gNbfA)O-4U}+RFF^&o`jiz;v%6W+vm;wz1n_)6@*Cj;jbNK(i+XV(Aj^=ciK)k6 zzIueYB3*j_TFQ?GG!*ZEB9WdtaoEIiV4pf=d{*1M(Av{L&{Nc{7X1@T_6Sx|>XX+~ zP?>2yGdALVpth4_p}O~R>GC+vb)$({J^i|%siDAQrW)AIL>I*QQPUV|sjxJtC`38? z?hM3tdZbERjjD$Eh}4Zg3c^5`Lx|R_5-Qlj9r39n!JFZAI7gnB*w6dA$cY)c{IXcyZ+Qi6o0{jx1b;Y#N9Kcr z%Gt&RjfFy0r2X5YuS-bm!8)~U^h9~5nQLOFPsld z?XNvJ!$PT`8^gWLy#R|PTDdp2(yg(ZHoESbzLoUkqbZWAQfS)D9+40Sto{Bx^;-)` z@!uPyN9e1zG$df-Wo*w#@q>PlKjgNGz+W8&EJUCW<)JEwUi}8t-nt+~+R?y2s(n#| zM(>C2^{UwxZe4GWS)6~mM|C;OFwGvIAtokgkJzrQ<m9P!~!g_rsaIMMPZ?s8)+gZaHBYmZ8|3gbeqDEYsc8z_Jg>7rhC5g#CkP z&7gGAr5Uug#yF{yQcU8=T+f#`z8}0#!ZuwU$HiRS>lBw)76yez*nEL01?e9&(2L`) z8A!}|&{UlkazmzE#ui1!VtyXkw6=*G8`tCwWRj^WLkmeaA?7dcP>ynJ>ix$taJ^+U zb}kz|*O|#0&M)yF>Hd7Ee=ThZ5B36`i6pMnwJn$KyYx1zzlg>b_cyUFuul%x_DIj{ zOP=nl-1xMej-rxxl73E-h1p zmg})qB=g6h-l9~5>LdIPnGjV^NeRo*Aa%70F( z7FLQ`DO}GJ8OJkGcQ1%HV4~$8|NkiLx@gM*JFDII-h@0=9BV%4HY{n)G8T!-_9S?S z;t!Il2ZK>>e*h-achz;x+o3j8pm9Vx?{ZlCXEYN^JFuqIUt$E=I8NNHKY48Qjys}P z0;YxsDJGEgLX4?#wEZw$CaB9aY)PaxY~HfEa?M5KAePv01M8rY)2beSBd#uM2zxcP zJJkyI`WShEIif&x5Zv4qQH%v1xj7frQrK{ z+p(IJQ&hYSwt9iNUS&TkL?t+H19DvAsc&s1A-S5-sot&??&-G8x=k^HhWHxM&1mm- z8ZD<(FP>5Jx%?AfA*Zo8W5Al)F5e(%nvaz?7o~bsN7J6mR|fNkZ?yFCg%Qa+-so5T zTvBSt&sDi-$hMH<^YoOh@QOE0Ah#h^dQY?wvW*yQ*qAB>w}wdCh!X5^U%~Mv5->Jy z5|Z_5xyFA#c1P~viQek%Taf6U?>dDV++%o;=QPJiB&$IAzlEMiHw2jt<7Te5#FZOu zur3zV+|0gy{m|pM>`?ERzyTKqL>ZqXOc43f6&uV9^yP%9LB0a@?0}xe+-o}n5-C>n z&&rBZte?b>bR=<)HfHU?Is^^FO*1im0h9GWKCD=0dcrB@3{RTSo&@rLU#F=rWo#H(j-R88X};31;{#LGzHg1c z^6eYpB`X1hwRtaovX)!3ZPPzM^D}vWhQKxx(DLw-BM^0L)J+YfGpv1y-e{00Og-Z(O45nM)m%VkP@BqTK zL*|#X#fvjNf6K&`t$tHr2juS4VN*DcXS)z1v=Hs_Pfg-vMk&uOjo{rOh=->R& zyRO#`Mc!uH!&WZWQg_%_FM&R_fZpX~s|~6vKlB^3s8YRY|6F>8rWE!)95f-T=3*Zg z7PU(EI*6t4Ncr%4$BJQo%(mFzmPE(Pc%FP{U_ugQ4p^RA*XuDie6vR$##>YQdhO+C ztBGeDkO*f7TZwmdyk$f5C8j?TW0t0dm{JP7B&c#ylN~{j>U!Y*+)w{n%2gO~k#f15 z;$J1~GnD){7pdJsNno7ybD!W7y=jK*s_#O4Rg zcrmubZ13>F{I5Uu-X2s=b9w*m@Gzz>uz2|-%7+DpF+?ev9Lv)OJ?urq*iE-$G z#(rJj02Xk;FESN***7Z8ERD|9bsvS~t5)HtaOTph@sP0N=GUUb;xsih1^9I)!YK&nrWiYyv9U;2Sa!@o|Do9j(1iaCKV$ z3IS-_;YUD^4dBAVN%*CBYAwi{Tf*XDj$1??#;`_41|AIl6p&V*R!pI3IyYRSc4Jx@ z$YET1_C@%OxCUdKDdOzT^kM;`gBjlPPAsL)E1&VF%j`rlo*(uU;f@SJjf@xX6Bya? zfZ3pBEwq|gYB>)K`9><}Jb^6~|Y%(&`hD{6n@`Nho3 z#$$rxbatKM$;GXaPYX0GC*91DAd6%ehtQ?$rfSaa)WmzYYaAv5DCzW6aX4zy5a_;aa_8jp;*3f6nZN zvQ?W{*%CRc90yo=AbPkt;`i-29w9%(;+E2udyb?R@ea7<_Sxwby9>mqQS4fR}j>G2N9(^QVj8s&J`6O5Hd^~C+TUXAZC8lt0^D~`?zXxWQp{t4fHv|TM?4Bo7j>QT(PAYu1W+*-C)iO&Vk~I}*+iTZy@`hsg zejx)M3R8oXnR4gawm!MilcPC@LCIpbrybmNZ^Q|7%?eIZi%V4)nYL1(C5z90{b|2- z?{Sy~9BD6iNgKx`m(|`FKJUi92AQPaOAY$p#a^!qo3{}p=1RxLk19~jD#fZ*kPJu{ zlKP`^53A`f8Sy4lxH=KJvG{To`CA!DPue=j8=6i|`Iv!ixvecWV_r3R?0ackST~~n zdaxRa-0F0$Bo~fwY!O7}!>`P)snPjTUuZD%@!qn1#b-WAr3zaQml6YM`*;^Qea3gq zSkdGRKojr*Uj9UMg=CKAU2M3Z8*wl)=ki{_uiefTohGYdy@|gSKWO)|#((mtn|uX} z@1*1U&wZ5dv+eOfDs>L@zZHcK651rp4kCmRqHz(N@`FC3+pY=`vTpn;F(eT#>^)g! zmnro`2MKEV6Kz3E3C&wEOsYeYKCzl8t0aOZPe90#x4OkX6*)k+Q*&b+mZRQr_WpG1la_u_rA+P4Ru`F(dRYj@hOxjh)>g{~!G$Htr3}<{SKr*n^T1mkEu^Mv9y{lWo~CJT69U z71{Rq%jYJBF%@bScX60+r_lamJK$Zj6I^t6w_L{-2e=uuc}9yat`=|Y@}X;5imD)E z58w;#oBL>_nPnK`AsS4gOK9@Hq}z~z!ONQVHo4RSCDfM|uViMX2=T{6PusxDQGnI& zxMmHXgS1at$uA=dUi~Quc(ixl1s}t0yPpKa{BVAKH4gP7LjCL-MZLF;eL&d3@s0^2 z_)3)#gci!nKGV2ilCuSMV=$tN2m61>w!X>z-2vB5al|;_Q=fY4unry0o9Z`&&Y4iR zcXkkK@zGxu2kS5VU_S6n4dRim9D=Ue)z zUq^+}c#iSdHNL}_KGRkF136#qKI}E%4|PRj=>;#@PRc(1H9Vi32v7_5?wIZ?oeM^~ zpu2{N0F$ZPvYVS@9Y}AYhSt@hqis%|E?d*GO0_ttKQ-oF?&1MN12_trekK7(^) zub;D-W8R!Og*nYfQeJ4&$Ahe^qXEkv%zr>5z|*_FBZtKFxmKgNZ=eq=e!r|_Zx;Mc zZ&m2v3Xlm)66MmCVFzWzoUg3VUUyG_6*FCB5_l^H`m@@woLK9;j*h9lN;n0t*}fe5 zb5lrPgFFod?tqGRt`qD|rfGNGjRG3)yqFK|LDMkRK{iZf{HwJ>=dDAj#*;SM#oM#M zN>*EA4XB)v?|3Q(tkc%Cz4>P7tn24k(5cIdXaM0Jf4_jX9*kUXjwH&2LjY2Lt!34n z@fq4Fk%u(SeH{(Z7}PO(x8cpnNW@ zu&DFK2qGN{C!GqX>Eld4=y@1x6kiB&dJ}T%VyN2k5BJnTu#-xn=K+Dixse!{|5@9k z4}LA%qBnFMLo+}|rc@0IQvH&pTC=E#SgMwaY3Vq#xw&F)&<%Oyae1~0P{oAq*5(!j zeVz6{>#A9gC6Eh&0K95t)I*@rKmWX|B4i#W#+xR5NMgY4ubQsw9t8^06*cmtu?SXK zRSo{W!_M#5%s$oen!dVyD+8%7SpJI-N)Tx!S;KbA=ujUjbL#zAY&Bjif?esDCD^JJ znq28HJo1ZgAJbs6_Yp@>Lu3z2#aHSj9bzjQZ4G*3-1TZqegNyP;&OVoKqZ2bw+NAuo z#p94i88);IMpF=UAddaisx+O;?LbRS zDyPj$W)a=4OSt+6KCRdAivwM1Z4I8*>OL4vxLy8{xF&op z7xfa7qx0T}LT8m71K$r38xe2`W(q)@Vu?5cC2T$z_VdgkGB70Uks|gRC~!C#Pw}j1 zATzAB5rqH^fAAkO{gI9p~va{UZeQgU%!T$6=S-i)^H8e8>-) zo#W)1$C+69k_i)mkBrODGs5Cc?U8pIuc?k$3Q zZrFfo#W-rj(d*v>)cl1z86@P`S@e#(Ye9U^gGkblW~{iMhg@y6zm0PY&fd6mKT&lY zy?jB17JafKw{MBBL0~_nYv0b*rw!(vP4hdUuA6_G^M~xE{FN3iu9!S9>-~3G@0>v_ z8Kb1Wi-Fl(ghioB++B{^VR{weUmL=YEyAkNX^8i-jX4k&iby-dk8NpaB0UV>0%CY* zEuikG?!FQFbW$#PNBXx3tId^6kJqXyTE;qG44A9FS@KKZ!506@XHYmxeS=P??47pVd(Kp4d*+#( z(6F}~w9qxQ%VeL>E)=3tQk_E8->hXEqnOxC@+A0{^74aOKWLW(jWqcb(wk#4mLAPn z$?5oOPOc%R^M2pJ+Y)9peO$wf@n==oP*3veC76p`zXgT0xAgYeCzm0bj``n7!#v)M zHmX^wejs6M`T-qE?T*CXE#ZSdV*%se4V=28D;gT0QSSj%O z`oP{Kgol_>DJ;gC@_}>+g#NYwpyd)p2++05>+t6O`XT)#m5UY)3a zWk4M$MEUxVzT^D7U=NUo@4~+V|4Px9eUT*TNmBJXMPQt)vT55CE%Ky0HJSd*MDs~( zUvy@l?|Yx=P2ZO*fldy7(d6iQtBp^g0*fO%w}wIxK0HDv&o7C0J^^e3{0PDVoIbO+tdn;?rT=+6CUjXf?^%71;k_^NA!Bryn>n6nUT^!OTJSCk z3R?O9><9pjFZ6g6#OQ_`wAIq!2F|NwDkdc}xn)rdsCiurQ**H?jBH^0b<)PY@j6}H z!`GR%Ah0tm-kF|NWsX1VU8`MD5`tosD>ob0*vyF#lLF)MuqC_lfFeR6 z?tykDX+wQr@IDsTAh$JGA`zV680|c>PxI>s!V-g=(3)JuiFwnwNaqvc zhof;W9%XwOU>p<-R7byRk#Jy@#U_;;Us2WonAzf-c00r-}ZbBsDrt1pNN<(4hRyFL|z zdkEG@ndSUauWwB_^|`bE#hlGfRzc|vHQ%nG^yGR#S66EFQ*%TXcw$|>A)(bZvR;Pp zeO^3e3ck0VXc|hmu!v7{l|pdu9>`W#0q3K*!VlXeNeqtM{~On9at5R$WKO?Zqh8ir Opr|QnDpt!|g#JHCwnx_h From 3db370ef876213b1cefce39fb98b00640d9750e9 Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Fri, 15 Dec 2023 15:49:14 +0000 Subject: [PATCH 09/37] test(core): process messages test --- core/ts/__tests__/MaciState.test.ts | 37 +++++------------------------ 1 file changed, 6 insertions(+), 31 deletions(-) diff --git a/core/ts/__tests__/MaciState.test.ts b/core/ts/__tests__/MaciState.test.ts index 595f25faad..3c209bf162 100644 --- a/core/ts/__tests__/MaciState.test.ts +++ b/core/ts/__tests__/MaciState.test.ts @@ -5,37 +5,12 @@ import { expect } from "chai"; import { PCommand, Message, Keypair, StateLeaf, blankStateLeafHash } from "maci-domainobjs"; import { hash5, NOTHING_UP_MY_SLEEVE, IncrementalQuinTree, AccQueue } from "maci-crypto"; -import { - STATE_TREE_DEPTH, - STATE_TREE_ARITY, - STATE_TREE_SUBDEPTH, - MaciState, - packProcessMessageSmallVals, - unpackProcessMessageSmallVals, - Poll, -} from "../"; - -const voiceCreditBalance = BigInt(100); - -const duration = 30; -const maxValues = { - maxUsers: 25, - maxMessages: 25, - maxVoteOptions: 25, -}; - -const treeDepths = { - intStateTreeDepth: 2, - messageTreeDepth: 3, - messageTreeSubDepth: 2, - voteOptionTreeDepth: 4, -}; - -const messageBatchSize = 25; - -const coordinatorKeypair = new Keypair(); - -const calculateTotal = (tallyResult: bigint[]): bigint => tallyResult.reduce((acc, v) => acc + v, BigInt(0)); +import { STATE_TREE_DEPTH, STATE_TREE_ARITY, STATE_TREE_SUBDEPTH } from "../utils/constants"; +import { MaciState } from "../MaciState"; +import { packProcessMessageSmallVals, unpackProcessMessageSmallVals } from "../utils/utils"; +import { Poll } from "../Poll"; +import { calculateTotal } from "./utils"; +import { coordinatorKeypair, duration, maxValues, messageBatchSize, treeDepths, voiceCreditBalance } from "./constants"; describe("MaciState", function () { this.timeout(100000); From c78e1b4c4a7acea9e18beef7291c8258b7b08c65 Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Fri, 15 Dec 2023 16:59:21 +0000 Subject: [PATCH 10/37] test(core): add unit tests for the process messages functions of the core package --- core/ts/Poll.ts | 2 +- core/ts/__tests__/MaciState.test.ts | 413 +++++++++++++++++++++++++++- 2 files changed, 413 insertions(+), 2 deletions(-) diff --git a/core/ts/Poll.ts b/core/ts/Poll.ts index 0b46aa1ed2..1abca9a6b9 100644 --- a/core/ts/Poll.ts +++ b/core/ts/Poll.ts @@ -148,7 +148,7 @@ export class Poll implements IPoll { /** * Copy the state from the MaciState instance. */ - private copyStateFromMaci = (): void => { + public copyStateFromMaci = (): void => { // Copy the state tree, ballot tree, state leaves, and ballot leaves assert(this.maciStateRef.stateLeaves.length === this.maciStateRef.stateTree.nextIndex); diff --git a/core/ts/__tests__/MaciState.test.ts b/core/ts/__tests__/MaciState.test.ts index 3c209bf162..29dc599867 100644 --- a/core/ts/__tests__/MaciState.test.ts +++ b/core/ts/__tests__/MaciState.test.ts @@ -2,7 +2,7 @@ import { existsSync, readFileSync, unlinkSync, writeFileSync } from "fs"; import { expect } from "chai"; -import { PCommand, Message, Keypair, StateLeaf, blankStateLeafHash } from "maci-domainobjs"; +import { PCommand, Message, Keypair, StateLeaf, blankStateLeafHash, PrivKey, Ballot } from "maci-domainobjs"; import { hash5, NOTHING_UP_MY_SLEEVE, IncrementalQuinTree, AccQueue } from "maci-crypto"; import { STATE_TREE_DEPTH, STATE_TREE_ARITY, STATE_TREE_SUBDEPTH } from "../utils/constants"; @@ -14,6 +14,7 @@ import { coordinatorKeypair, duration, maxValues, messageBatchSize, treeDepths, describe("MaciState", function () { this.timeout(100000); + describe("Process and tally 1 message from 1 user", () => { let maciState: MaciState; let pollId: number; @@ -719,4 +720,414 @@ describe("MaciState", function () { }); }); }); + + describe("processMessage", () => { + const maciState = new MaciState(STATE_TREE_DEPTH); + const pollId = maciState.deployPoll( + BigInt(Math.floor(Date.now() / 1000) + duration), + maxValues, + treeDepths, + messageBatchSize, + coordinatorKeypair, + ); + + const poll = maciState.polls[pollId]; + + const user1Keypair = new Keypair(); + // signup the user + const user1StateIndex = maciState.signUp( + user1Keypair.pubKey, + voiceCreditBalance, + BigInt(Math.floor(Date.now() / 1000)), + ); + + // copy the state from the MaciState ref + poll.copyStateFromMaci(); + + it("should throw if a message has an invalid state index", () => { + const command = new PCommand( + // invalid state index as it is one more than the number of state leaves + BigInt(user1StateIndex + 1), + user1Keypair.pubKey, + BigInt(0), + BigInt(1), + BigInt(0), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + expect(() => { + poll.processMessage(message, ecdhKeypair.pubKey); + }).to.throw("invalid state leaf index"); + }); + + it("should throw if a message has an invalid nonce", () => { + const command = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + BigInt(0), + BigInt(0), + BigInt(0), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + + expect(() => { + poll.processMessage(message, ecdhKeypair.pubKey); + }).to.throw("invalid nonce"); + }); + + it("should throw if a message has an invalid signature", () => { + const command = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + BigInt(0), + BigInt(0), + BigInt(0), + BigInt(pollId), + ); + + const signature = command.sign(new PrivKey(BigInt(0))); + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + + expect(() => { + poll.processMessage(message, ecdhKeypair.pubKey); + }).to.throw("invalid signature"); + }); + + it("should throw if a message consumes more than the available voice credits for a user", () => { + const command = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + BigInt(0), + // voice credits spent would be this value ** this value + BigInt(Math.sqrt(parseInt(voiceCreditBalance.toString())) + 1), + BigInt(1), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + + expect(() => { + poll.processMessage(message, ecdhKeypair.pubKey); + }).to.throw("insufficient voice credits"); + }); + + it("should throw if a message has an invalid vote option index (>= max vote options)", () => { + const command = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + BigInt(maxValues.maxVoteOptions), + // voice credits spent would be this value ** this value + BigInt(1), + BigInt(1), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + + expect(() => { + poll.processMessage(message, ecdhKeypair.pubKey); + }).to.throw("invalid vote option index"); + }); + + it("should throw if a message has an invalid vote option index (< 0)", () => { + const command = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + BigInt(-1), + BigInt(1), + BigInt(1), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + + expect(() => { + poll.processMessage(message, ecdhKeypair.pubKey); + }).to.throw("invalid vote option index"); + }); + + it("should throw when passed a message that cannot be decrypted (wrong encPubKey)", () => { + const command = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + BigInt(0), + BigInt(1), + BigInt(1), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(new Keypair().privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + + expect(() => { + poll.processMessage(message, user1Keypair.pubKey); + }).to.throw("failed decryption due to either wrong encryption public key or corrupted ciphertext"); + }); + + it("should throw when passed a corrupted message", () => { + const command = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + BigInt(0), + BigInt(1), + BigInt(1), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(user1Keypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + + message.data[0] = BigInt(0); + + expect(() => { + poll.processMessage(message, user1Keypair.pubKey); + }).to.throw("failed decryption due to either wrong encryption public key or corrupted ciphertext"); + }); + }); + + describe("processMessages", () => { + const maciState = new MaciState(STATE_TREE_DEPTH); + const pollId = maciState.deployPoll( + BigInt(Math.floor(Date.now() / 1000) + duration), + maxValues, + treeDepths, + messageBatchSize, + coordinatorKeypair, + ); + + const poll = maciState.polls[pollId]; + + const user1Keypair = new Keypair(); + // signup the user + const user1StateIndex = maciState.signUp( + user1Keypair.pubKey, + voiceCreditBalance, + BigInt(Math.floor(Date.now() / 1000)), + ); + + it("should throw if this is the first batch and currentMessageBatchIndex is defined", () => { + const command = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + BigInt(0), + BigInt(1), + BigInt(0), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + + poll.publishMessage(message, ecdhKeypair.pubKey); + + // mock + poll.currentMessageBatchIndex = 0; + expect(() => poll.processMessages(pollId)).to.throw( + "The current message batch index should not be defined if this is the first batch", + ); + poll.currentMessageBatchIndex = undefined; + }); + + it("should succeed even if send an invalid message", () => { + const command = new PCommand( + // we only signed up one user so the state index is invalid + BigInt(user1StateIndex + 1), + user1Keypair.pubKey, + BigInt(0), + BigInt(1), + BigInt(0), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + + poll.publishMessage(message, ecdhKeypair.pubKey); + poll.copyStateFromMaci(); + expect(() => { + poll.processMessage(message, ecdhKeypair.pubKey); + }).to.throw("invalid state leaf index"); + + expect(() => poll.processMessages(pollId)).to.not.throw; + }); + + it("should throw when called after all messages have been processed", () => { + const command = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + BigInt(0), + BigInt(1), + BigInt(0), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + + poll.publishMessage(message, ecdhKeypair.pubKey); + + poll.processMessages(pollId); + + expect(() => poll.processMessages(pollId)).to.throw("No more messages to process"); + }); + }); + + describe("processAllMessages", () => { + const maciState = new MaciState(STATE_TREE_DEPTH); + const pollId = maciState.deployPoll( + BigInt(Math.floor(Date.now() / 1000) + duration), + maxValues, + treeDepths, + messageBatchSize, + coordinatorKeypair, + ); + + const poll = maciState.polls[pollId]; + + const user1Keypair = new Keypair(); + // signup the user + const user1StateIndex = maciState.signUp( + user1Keypair.pubKey, + voiceCreditBalance, + BigInt(Math.floor(Date.now() / 1000)), + ); + + it("it should succeed even if send an invalid message", () => { + const command = new PCommand( + // we only signed up one user so the state index is invalid + BigInt(user1StateIndex + 1), + user1Keypair.pubKey, + BigInt(0), + BigInt(1), + BigInt(0), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + expect(() => { + poll.processMessage(message, ecdhKeypair.pubKey); + }).to.throw("invalid state leaf index"); + + expect(() => poll.processAllMessages()).to.not.throw; + }); + + it("should return the correct state leaves and ballots", () => { + const command = new PCommand( + BigInt(user1StateIndex + 1), + user1Keypair.pubKey, + BigInt(0), + BigInt(1), + BigInt(0), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + expect(() => { + poll.processMessage(message, ecdhKeypair.pubKey); + }).to.throw("invalid state leaf index"); + + const { stateLeaves, ballots } = poll.processAllMessages(); + + stateLeaves.forEach((leaf: StateLeaf, index: number) => expect(leaf.equals(poll.stateLeaves[index])).to.eq(true)); + ballots.forEach((ballot: Ballot, index: number) => expect(ballot.equals(poll.ballots[index])).to.eq(true)); + }); + + it("should have processed all messages", () => { + const command = new PCommand( + BigInt(user1StateIndex + 1), + user1Keypair.pubKey, + BigInt(0), + BigInt(1), + BigInt(0), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + + // publish batch size + 1 + for (let i = 0; i <= messageBatchSize; i += 1) { + poll.publishMessage(message, ecdhKeypair.pubKey); + } + + poll.processAllMessages(); + + expect(poll.hasUnprocessedMessages()).to.eq(false); + }); + }); }); From f4e6964b3e268e4d3f2819b85e6abf3e34bcb10e Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Sat, 16 Dec 2023 15:20:44 +0000 Subject: [PATCH 11/37] test(coverage): setup coverage for TS packages setup code coverage for TS packages using istanbul (nyc) --- cli/package-lock.json | 1897 ++++++++++++++++++++++++++++++++-- cli/package.json | 24 +- core/package-lock.json | 1770 ++++++++++++++++++++++++++++++- core/package.json | 22 +- crypto/package-lock.json | 911 ++++++++++++++-- crypto/package.json | 22 +- domainobjs/package-lock.json | 1770 ++++++++++++++++++++++++++++++- domainobjs/package.json | 22 +- 8 files changed, 6210 insertions(+), 228 deletions(-) diff --git a/cli/package-lock.json b/cli/package-lock.json index 6603b8c705..53a2d1ed87 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -27,6 +27,7 @@ "@types/node": "^18.11.9", "chai": "^4.3.10", "mocha": "^10.2.0", + "nyc": "^15.1.0", "ts-mocha": "^10.0.0", "typescript": "^5.3.2" } @@ -36,6 +37,335 @@ "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz", "integrity": "sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==" }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz", + "integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.6", + "@babel/parser": "^7.23.6", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/@babel/core/node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz", + "integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", + "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@chainsafe/as-sha256": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz", @@ -859,97 +1189,265 @@ "ffjavascript": "^0.2.48" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "peer": true, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, "engines": { - "node": ">=6.0.0" + "node": ">=8" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "peer": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "peer": true, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "sprintf-js": "~1.0.2" } }, - "node_modules/@metamask/eth-sig-util": { + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/esprima": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", - "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", - "dependencies": { - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^6.2.1", - "ethjs-util": "^0.1.6", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.1" + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" }, "engines": { - "node": ">=12.0.0" + "node": ">=4" } }, - "node_modules/@metamask/eth-sig-util/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, "dependencies": { - "@types/node": "*" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@metamask/eth-sig-util/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/@metamask/eth-sig-util/node_modules/ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@noble/curves": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", - "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, "dependencies": { - "@noble/hashes": "1.3.2" + "p-locate": "^4.1.0" }, - "funding": { - "url": "https://paulmillr.com/funding/" + "engines": { + "node": ">=8" } }, - "node_modules/@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, "engines": { - "node": ">= 16" + "node": ">=6" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@noble/secp256k1": { - "version": "1.7.1", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@metamask/eth-sig-util": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", + "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", + "dependencies": { + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^6.2.1", + "ethjs-util": "^0.1.6", + "tweetnacl": "^1.0.3", + "tweetnacl-util": "^0.15.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@metamask/eth-sig-util/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@metamask/eth-sig-util/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/@metamask/eth-sig-util/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/secp256k1": { + "version": "1.7.1", "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", "funding": [ @@ -2080,6 +2578,24 @@ "node": ">= 8" } }, + "node_modules/append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "dependencies": { + "default-require-extensions": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", + "dev": true + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -2340,6 +2856,38 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, "node_modules/bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", @@ -2391,6 +2939,20 @@ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" }, + "node_modules/bufferutil": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", + "hasInstallScript": true, + "optional": true, + "peer": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -2399,6 +2961,21 @@ "node": ">= 0.8" } }, + "node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", @@ -2424,6 +3001,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/caniuse-lite": { + "version": "1.0.30001570", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", + "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, "node_modules/case": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/case/-/case-1.6.3.tgz", @@ -2747,6 +3344,12 @@ "node": ">=16" } }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2797,6 +3400,12 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, "node_modules/cookie": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", @@ -2853,6 +3462,35 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "peer": true }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/crypt": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", @@ -2928,6 +3566,30 @@ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, + "node_modules/default-require-extensions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", + "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", + "dev": true, + "dependencies": { + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-require-extensions/node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/define-data-property": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", @@ -3030,6 +3692,12 @@ "node": ">=0.10.0" } }, + "node_modules/electron-to-chromium": { + "version": "1.4.614", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.614.tgz", + "integrity": "sha512-X4ze/9Sc3QWs6h92yerwqv7aB/uU8vCjZcrMjA8N9R1pjMFRe44dLsck5FzLilOYvcXuDn93B+bpGYyufc70gQ==", + "dev": true + }, "node_modules/elliptic": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", @@ -3074,6 +3742,12 @@ "node": ">=6" } }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -3539,6 +4213,23 @@ "node": ">=8" } }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, "node_modules/find-replace": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", @@ -3594,6 +4285,19 @@ } } }, + "node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -3613,11 +4317,31 @@ "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==" }, - "node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "peer": true, + "node_modules/fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "peer": true, "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -3666,6 +4390,15 @@ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==" }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -3697,6 +4430,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/get-port": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", @@ -3775,6 +4517,15 @@ "node": ">=6" } }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/globby": { "version": "10.0.2", "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", @@ -4093,6 +4844,31 @@ "minimalistic-assert": "^1.0.1" } }, + "node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasha/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/hasown": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", @@ -4137,6 +4913,12 @@ "node": ">= 6.0.0" } }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, "node_modules/http-basic": { "version": "8.1.3", "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", @@ -4238,6 +5020,15 @@ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==" }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, "node_modules/indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", @@ -4368,6 +5159,24 @@ "node": ">=8" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -4379,6 +5188,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -4388,14 +5206,212 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "peer": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "dependencies": { + "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", + "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", + "dev": true, + "dependencies": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-report/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jake": { "version": "10.8.7", "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", @@ -4491,6 +5507,12 @@ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -4502,6 +5524,18 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -4660,6 +5694,12 @@ "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", "peer": true }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", + "dev": true + }, "node_modules/lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", @@ -4777,6 +5817,21 @@ "yallist": "^3.0.2" } }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -5157,60 +6212,365 @@ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.7.1.tgz", "integrity": "sha512-wTSrZ+8lsRRa3I3H8Xr65dLWSgCvY2l4AOnaeKdPA9TB/WYMPaTcrzf3rXvFoVvjKNVnu0CcWSx54qq9GKRUYg==", "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "dependencies": { + "process-on-spawn": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/nofilter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", + "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", + "peer": true, + "engines": { + "node": ">=12.19" + } + }, + "node_modules/nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", + "peer": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", + "peer": true, + "dependencies": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/number-to-bn/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "peer": true + }, + "node_modules/nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "dependencies": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/nyc/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/nyc/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/nyc/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/nyc/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/nyc/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/nyc/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/nyc/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/nofilter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", - "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", - "peer": true, + "node_modules/nyc/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, "engines": { - "node": ">=12.19" + "node": ">=8" } }, - "node_modules/nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", - "peer": true, + "node_modules/nyc/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, "dependencies": { - "abbrev": "1" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, - "bin": { - "nopt": "bin/nopt.js" + "engines": { + "node": ">=8" } }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "node_modules/nyc/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/nyc/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", - "peer": true, + "node_modules/nyc/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, "dependencies": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" }, "engines": { - "node": ">=6.5.0", - "npm": ">=3" + "node": ">=6" } }, - "node_modules/number-to-bn/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "peer": true - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -5316,6 +6676,21 @@ "node": ">=4" } }, + "node_modules/package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/parse-cache-control": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", @@ -5338,6 +6713,15 @@ "node": ">=0.10.0" } }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -5375,6 +6759,12 @@ "node": ">=0.12" } }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -5395,6 +6785,88 @@ "node": ">=6" } }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -5424,6 +6896,18 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "peer": true }, + "node_modules/process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/promise": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", @@ -5613,6 +7097,18 @@ "node": ">=6" } }, + "node_modules/release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", + "dev": true, + "dependencies": { + "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/req-cwd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", @@ -5653,6 +7149,12 @@ "node": ">=0.10.0" } }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, "node_modules/resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", @@ -5953,6 +7455,12 @@ "randombytes": "^2.1.0" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, "node_modules/set-function-length": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", @@ -6003,6 +7511,27 @@ "node": "*" } }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/shelljs": { "version": "0.8.5", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", @@ -6033,6 +7562,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -6313,11 +7848,57 @@ "node": ">=0.10.0" } }, + "node_modules/spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "dependencies": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/spawn-wrap/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/spawn-wrap/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "peer": true + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "node_modules/stack-trace": { "version": "0.0.10", @@ -6560,6 +8141,20 @@ "node": ">=8" } }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/then-request": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", @@ -6613,6 +8208,15 @@ "node": ">=0.6.0" } }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -7001,6 +8605,15 @@ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "peer": true }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, "node_modules/typescript": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", @@ -7073,6 +8686,36 @@ "node": ">= 0.8" } }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -7082,6 +8725,20 @@ "punycode": "^2.1.0" } }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "hasInstallScript": true, + "optional": true, + "peer": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, "node_modules/utf8": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", @@ -7192,6 +8849,12 @@ "which": "bin/which" } }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true + }, "node_modules/winston": { "version": "2.4.7", "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.7.tgz", @@ -7337,6 +9000,18 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, "node_modules/ws": { "version": "8.5.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", diff --git a/cli/package.json b/cli/package.json index ab6a26e981..ab04432518 100644 --- a/cli/package.json +++ b/cli/package.json @@ -14,7 +14,7 @@ "watch": "tsc --watch", "build": "tsc", "postbuild": "cp package.json ./build", - "test": "ts-mocha --exit tests/*.test.ts", + "test": "nyc ts-mocha --exit tests/*.test.ts", "test:e2e": "ts-mocha --exit tests/e2e.test.ts", "test:e2e-subsidy": "ts-mocha --exit tests/e2e.subsidy.test.ts", "test:keyChange": "ts-mocha --exit tests/keyChange.test.ts" @@ -41,8 +41,28 @@ "@types/node": "^18.11.9", "chai": "^4.3.10", "mocha": "^10.2.0", + "nyc": "^15.1.0", "ts-mocha": "^10.0.0", "typescript": "^5.3.2" }, - "gitHead": "f567a17293114ba2d5e89c711d00a9f4c197f070" + "nyc": { + "reporter": [ + "text", + "lcov" + ], + "extensions": [ + ".ts" + ], + "all": true, + "exclude": [ + "**/tests/*.ts", + "**/*.js", + "**/*.d.ts", + "hardhat.config.ts" + ], + "branches": ">50%", + "lines": ">50%", + "functions": ">50%", + "statements": ">50%" + } } diff --git a/core/package-lock.json b/core/package-lock.json index 61d893f8ac..1a282e4090 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -13,9 +13,627 @@ "@types/node": "^18.11.9", "chai": "^4.3.10", "mocha": "^10.2.0", + "nyc": "^15.1.0", "ts-mocha": "^10.0.0" } }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz", + "integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.6", + "@babel/parser": "^7.23.6", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/@babel/core/node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz", + "integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", + "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@types/chai": { "version": "4.3.11", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.11.tgz", @@ -44,6 +662,19 @@ "undici-types": "~5.26.4" } }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", @@ -90,6 +721,24 @@ "node": ">= 8" } }, + "node_modules/append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "dependencies": { + "default-require-extensions": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", + "dev": true + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -156,12 +805,59 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "node_modules/browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -174,6 +870,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/caniuse-lite": { + "version": "1.0.30001570", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", + "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, "node_modules/chai": { "version": "4.3.10", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", @@ -259,6 +975,15 @@ "fsevents": "~2.3.2" } }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -288,12 +1013,38 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -341,6 +1092,30 @@ "node": ">=6" } }, + "node_modules/default-require-extensions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", + "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", + "dev": true, + "dependencies": { + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-require-extensions/node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", @@ -350,12 +1125,24 @@ "node": ">=0.3.1" } }, + "node_modules/electron-to-chromium": { + "version": "1.4.614", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.614.tgz", + "integrity": "sha512-X4ze/9Sc3QWs6h92yerwqv7aB/uU8vCjZcrMjA8N9R1pjMFRe44dLsck5FzLilOYvcXuDn93B+bpGYyufc70gQ==", + "dev": true + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -377,6 +1164,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -389,6 +1189,23 @@ "node": ">=8" } }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -414,6 +1231,39 @@ "flat": "cli.js" } }, + "node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -434,6 +1284,15 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -452,6 +1311,15 @@ "node": "*" } }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -506,6 +1374,21 @@ "node": "*" } }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -515,13 +1398,53 @@ "node": ">=8" } }, + "node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, - "bin": { - "he": "bin/he" + "bin": { + "he": "bin/he" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" } }, "node_modules/inflight": { @@ -600,6 +1523,24 @@ "node": ">=8" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -612,6 +1553,181 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "dependencies": { + "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", + "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", + "dev": true, + "dependencies": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-report/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -624,6 +1740,18 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/json5": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", @@ -652,6 +1780,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", + "dev": true + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -677,6 +1811,30 @@ "get-func-name": "^2.0.1" } }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -751,36 +1909,231 @@ "engines": { "node": ">= 14.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "dependencies": { + "process-on-spawn": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "dependencies": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/nyc/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/nyc/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/nyc/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "node_modules/nyc/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, - "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "node_modules/nyc/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": ">=8" } }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "node_modules/nyc/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, "node_modules/once": { @@ -822,6 +2175,42 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -840,6 +2229,15 @@ "node": ">=0.10.0" } }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", @@ -849,6 +2247,12 @@ "node": "*" } }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -861,6 +2265,82 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -882,6 +2362,18 @@ "node": ">=8.10.0" } }, + "node_modules/release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", + "dev": true, + "dependencies": { + "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -891,6 +2383,36 @@ "node": ">=0.10.0" } }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -911,6 +2433,15 @@ } ] }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", @@ -920,6 +2451,39 @@ "randombytes": "^2.1.0" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -939,6 +2503,29 @@ "source-map": "^0.6.0" } }, + "node_modules/spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "dependencies": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -1002,6 +2589,51 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -1088,12 +2720,90 @@ "node": ">=4" } }, + "node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true + }, "node_modules/workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", @@ -1123,6 +2833,18 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -1132,6 +2854,12 @@ "node": ">=10" } }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", diff --git a/core/package.json b/core/package.json index 96be8ebebf..400d9a0335 100644 --- a/core/package.json +++ b/core/package.json @@ -9,7 +9,7 @@ "build": "tsc", "test-processMessage": "ts-mocha --exit ts/__tests__/ProcessMessage.test.ts", "test-maciState": "ts-mocha --exit ts/__tests__/MaciState.test.ts", - "test": "ts-mocha --exit ts/__tests__/*.test.ts" + "test": "nyc ts-mocha --exit ts/__tests__/*.test.ts" }, "dependencies": { "maci-crypto": "^1.1.2", @@ -21,6 +21,26 @@ "@types/node": "^18.11.9", "chai": "^4.3.10", "mocha": "^10.2.0", + "nyc": "^15.1.0", "ts-mocha": "^10.0.0" + }, + "nyc": { + "reporter": [ + "text", + "lcov" + ], + "extensions": [ + ".ts" + ], + "all": true, + "exclude": [ + "**/__tests__/*.ts", + "**/*.js", + "**/*.d.ts" + ], + "branches": ">50%", + "lines": ">50%", + "functions": ">50%", + "statements": ">50%" } } diff --git a/crypto/package-lock.json b/crypto/package-lock.json index c8be5e8c62..d1a87de3dd 100644 --- a/crypto/package-lock.json +++ b/crypto/package-lock.json @@ -21,6 +21,7 @@ "@types/node": "^18.11.9", "chai": "^4.3.10", "mocha": "^10.2.0", + "nyc": "^15.1.0", "ts-mocha": "^10.0.0", "typescript": "^5.3.2" } @@ -40,7 +41,6 @@ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", "dev": true, - "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -54,7 +54,6 @@ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, - "peer": true, "dependencies": { "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" @@ -68,7 +67,6 @@ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", "dev": true, - "peer": true, "engines": { "node": ">=6.9.0" } @@ -78,7 +76,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz", "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==", "dev": true, - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.23.5", @@ -127,7 +124,6 @@ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", "dev": true, - "peer": true, "dependencies": { "@babel/types": "^7.23.5", "@jridgewell/gen-mapping": "^0.3.2", @@ -143,7 +139,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", "dev": true, - "peer": true, "dependencies": { "@babel/compat-data": "^7.22.9", "@babel/helper-validator-option": "^7.22.15", @@ -160,7 +155,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, - "peer": true, "engines": { "node": ">=6.9.0" } @@ -170,7 +164,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, - "peer": true, "dependencies": { "@babel/template": "^7.22.15", "@babel/types": "^7.23.0" @@ -184,7 +177,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, - "peer": true, "dependencies": { "@babel/types": "^7.22.5" }, @@ -197,7 +189,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dev": true, - "peer": true, "dependencies": { "@babel/types": "^7.22.15" }, @@ -210,7 +201,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-module-imports": "^7.22.15", @@ -230,7 +220,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, - "peer": true, "dependencies": { "@babel/types": "^7.22.5" }, @@ -243,7 +232,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, - "peer": true, "dependencies": { "@babel/types": "^7.22.5" }, @@ -256,7 +244,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "dev": true, - "peer": true, "engines": { "node": ">=6.9.0" } @@ -266,7 +253,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, - "peer": true, "engines": { "node": ">=6.9.0" } @@ -276,7 +262,6 @@ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", "dev": true, - "peer": true, "engines": { "node": ">=6.9.0" } @@ -286,7 +271,6 @@ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz", "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==", "dev": true, - "peer": true, "dependencies": { "@babel/template": "^7.22.15", "@babel/traverse": "^7.23.5", @@ -301,7 +285,6 @@ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", @@ -316,7 +299,6 @@ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", "dev": true, - "peer": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -329,7 +311,6 @@ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, - "peer": true, "dependencies": { "@babel/code-frame": "^7.22.13", "@babel/parser": "^7.22.15", @@ -344,7 +325,6 @@ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz", "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==", "dev": true, - "peer": true, "dependencies": { "@babel/code-frame": "^7.23.5", "@babel/generator": "^7.23.5", @@ -366,7 +346,6 @@ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", "dev": true, - "peer": true, "dependencies": { "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", @@ -1219,12 +1198,128 @@ "resolved": "https://registry.npmjs.org/@iden3/bigarray/-/bigarray-0.0.2.tgz", "integrity": "sha512-Xzdyxqm1bOFF6pdIsiHLLl3HkSLjbhqJHVyqaTxXt3RqXBEnmsUmEW47H7VOi/ak7TdkRpNkxjyK5Zbkm+y52g==" }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, - "peer": true, "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -1239,7 +1334,6 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, - "peer": true, "engines": { "node": ">=6.0.0" } @@ -1249,7 +1343,6 @@ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true, - "peer": true, "engines": { "node": ">=6.0.0" } @@ -1258,15 +1351,13 @@ "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.20", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dev": true, - "peer": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -1536,6 +1627,19 @@ "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -1572,7 +1676,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "peer": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -1592,6 +1695,24 @@ "node": ">= 8" } }, + "node_modules/append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "dependencies": { + "default-require-extensions": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", + "dev": true + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1913,7 +2034,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001565", "electron-to-chromium": "^1.4.601", @@ -2051,6 +2171,21 @@ "node": ">=8" } }, + "node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", @@ -2103,8 +2238,7 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ], - "peer": true + ] }, "node_modules/caseless": { "version": "0.12.0", @@ -2133,7 +2267,6 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -2680,6 +2813,15 @@ "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==" }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -2706,7 +2848,6 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "peer": true, "dependencies": { "color-name": "1.1.3" } @@ -2715,8 +2856,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/combined-stream": { "version": "1.0.8", @@ -2729,6 +2869,12 @@ "node": ">= 0.8" } }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2767,8 +2913,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/cookie": { "version": "0.5.0", @@ -2849,7 +2994,6 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "peer": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -2955,6 +3099,30 @@ "dev": true, "peer": true }, + "node_modules/default-require-extensions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", + "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", + "dev": true, + "dependencies": { + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-require-extensions/node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/defer-to-connect": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", @@ -3075,8 +3243,7 @@ "version": "1.4.608", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.608.tgz", "integrity": "sha512-J2f/3iIIm3Mo0npneITZ2UPe4B1bg8fTNrFjD8715F/k1BvbviRuqYGkET1PgprrczXYTHFvotbBOmUp6KE0uA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/elliptic": { "version": "6.5.4", @@ -3132,6 +3299,12 @@ "node": ">=0.10" } }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, "node_modules/es6-iterator": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", @@ -3174,7 +3347,6 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "peer": true, "engines": { "node": ">=0.8.0" } @@ -3433,6 +3605,19 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/esquery": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", @@ -3958,6 +4143,23 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -4016,6 +4218,19 @@ "is-callable": "^1.1.3" } }, + "node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -4058,6 +4273,26 @@ "node": ">= 0.6" } }, + "node_modules/fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/fs-extra": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", @@ -4107,7 +4342,6 @@ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, - "peer": true, "engines": { "node": ">=6.9.0" } @@ -4142,6 +4376,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -4207,7 +4450,6 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -4295,7 +4537,6 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -4369,19 +4610,44 @@ "minimalistic-assert": "^1.0.1" } }, - "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, "dependencies": { - "function-bind": "^1.1.2" + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" }, "engines": { - "node": ">= 0.4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/he": { - "version": "1.2.0", + "node_modules/hasha/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "bin": { @@ -4398,6 +4664,12 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, "node_modules/http-cache-semantics": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", @@ -4530,11 +4802,19 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "peer": true, "engines": { "node": ">=0.8.19" } }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -4690,6 +4970,18 @@ "node": ">=8" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-typed-array": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", @@ -4721,6 +5013,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -4731,6 +5032,178 @@ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "dependencies": { + "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", + "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", + "dev": true, + "dependencies": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-report/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jake": { "version": "10.8.7", "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", @@ -4821,8 +5294,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/js-yaml": { "version": "4.1.0", @@ -4846,7 +5318,6 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, - "peer": true, "bin": { "jsesc": "bin/jsesc" }, @@ -4886,7 +5357,6 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, - "peer": true, "bin": { "json5": "lib/cli.js" }, @@ -4971,6 +5441,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", + "dev": true + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -5088,11 +5564,25 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, - "peer": true, "dependencies": { "yallist": "^3.0.2" } }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -5571,12 +6061,23 @@ "node-gyp-build-test": "build-test.js" } }, + "node_modules/node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "dependencies": { + "process-on-spawn": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/node-releases": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/normalize-path": { "version": "3.0.0", @@ -5615,6 +6116,114 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" }, + "node_modules/nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "dependencies": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/nyc/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -5770,6 +6379,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -5778,6 +6399,21 @@ "node": ">=6" } }, + "node_modules/package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -5825,7 +6461,6 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -5867,8 +6502,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/picomatch": { "version": "2.3.1", @@ -5881,6 +6515,70 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -5899,6 +6597,18 @@ "node": ">= 0.6.0" } }, + "node_modules/process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -6076,6 +6786,18 @@ "node": ">=8.10.0" } }, + "node_modules/release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", + "dev": true, + "dependencies": { + "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -6178,7 +6900,6 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, - "peer": true, "dependencies": { "glob": "^7.1.3" }, @@ -6415,7 +7136,6 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "peer": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -6428,7 +7148,6 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -6446,6 +7165,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, "node_modules/simple-concat": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", @@ -6505,6 +7230,29 @@ "source-map": "^0.6.0" } }, + "node_modules/spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "dependencies": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, "node_modules/sshpk": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", @@ -6615,7 +7363,6 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "peer": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -6729,6 +7476,20 @@ "node": ">=4.5" } }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -6779,7 +7540,6 @@ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -7031,7 +7791,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -7704,6 +8463,18 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, "node_modules/ws": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", diff --git a/crypto/package.json b/crypto/package.json index 74807c13a3..1f488000ba 100644 --- a/crypto/package.json +++ b/crypto/package.json @@ -6,7 +6,7 @@ "scripts": { "watch": "tsc --watch", "build": "tsc", - "test": "ts-mocha --exit ts/__tests__/*.test.ts", + "test": "nyc ts-mocha --exit ts/__tests__/*.test.ts", "test-crypto": "ts-mocha --exit ts/__tests__/Crypto.test.ts", "test-accQueue": "ts-mocha --exit ts/__tests__/AccQueue.test.ts" }, @@ -24,7 +24,27 @@ "@types/node": "^18.11.9", "chai": "^4.3.10", "mocha": "^10.2.0", + "nyc": "^15.1.0", "ts-mocha": "^10.0.0", "typescript": "^5.3.2" + }, + "nyc": { + "reporter": [ + "text", + "lcov" + ], + "extensions": [ + ".ts" + ], + "all": true, + "exclude": [ + "**/__tests__/*.ts", + "**/*.js", + "**/*.d.ts" + ], + "branches": ">50%", + "lines": ">50%", + "functions": ">50%", + "statements": ">50%" } } diff --git a/domainobjs/package-lock.json b/domainobjs/package-lock.json index 6035ea8dbd..1fed510194 100644 --- a/domainobjs/package-lock.json +++ b/domainobjs/package-lock.json @@ -16,9 +16,627 @@ "@types/node": "^18.11.9", "chai": "^4.3.10", "mocha": "^10.2.0", + "nyc": "^15.1.0", "ts-mocha": "^10.0.0" } }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz", + "integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.6", + "@babel/parser": "^7.23.6", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/@babel/core/node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz", + "integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", + "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@types/chai": { "version": "4.3.11", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.11.tgz", @@ -47,6 +665,19 @@ "undici-types": "~5.26.4" } }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", @@ -93,6 +724,24 @@ "node": ">= 8" } }, + "node_modules/append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "dependencies": { + "default-require-extensions": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", + "dev": true + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -167,12 +816,59 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "node_modules/browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -185,6 +881,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/caniuse-lite": { + "version": "1.0.30001570", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", + "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, "node_modules/chai": { "version": "4.3.10", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", @@ -270,6 +986,15 @@ "fsevents": "~2.3.2" } }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -299,12 +1024,38 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -352,6 +1103,30 @@ "node": ">=6" } }, + "node_modules/default-require-extensions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", + "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", + "dev": true, + "dependencies": { + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-require-extensions/node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", @@ -361,12 +1136,24 @@ "node": ">=0.3.1" } }, + "node_modules/electron-to-chromium": { + "version": "1.4.614", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.614.tgz", + "integrity": "sha512-X4ze/9Sc3QWs6h92yerwqv7aB/uU8vCjZcrMjA8N9R1pjMFRe44dLsck5FzLilOYvcXuDn93B+bpGYyufc70gQ==", + "dev": true + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -388,6 +1175,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -400,6 +1200,23 @@ "node": ">=8" } }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -425,6 +1242,39 @@ "flat": "cli.js" } }, + "node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -445,6 +1295,15 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -463,6 +1322,15 @@ "node": "*" } }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -517,6 +1385,21 @@ "node": "*" } }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -526,13 +1409,53 @@ "node": ">=8" } }, + "node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, - "bin": { - "he": "bin/he" + "bin": { + "he": "bin/he" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" } }, "node_modules/inflight": { @@ -611,6 +1534,24 @@ "node": ">=8" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -623,6 +1564,181 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "dependencies": { + "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", + "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", + "dev": true, + "dependencies": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-report/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -635,6 +1751,18 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/json5": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", @@ -663,6 +1791,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", + "dev": true + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -688,6 +1822,30 @@ "get-func-name": "^2.0.1" } }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -762,36 +1920,231 @@ "engines": { "node": ">= 14.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "dependencies": { + "process-on-spawn": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "dependencies": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/nyc/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/nyc/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/nyc/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "node_modules/nyc/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, - "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "node_modules/nyc/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": ">=8" } }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "node_modules/nyc/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, "node_modules/once": { @@ -833,6 +2186,42 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -851,6 +2240,15 @@ "node": ">=0.10.0" } }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", @@ -860,6 +2258,12 @@ "node": "*" } }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -872,6 +2276,82 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -893,6 +2373,18 @@ "node": ">=8.10.0" } }, + "node_modules/release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", + "dev": true, + "dependencies": { + "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -902,6 +2394,36 @@ "node": ">=0.10.0" } }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -922,6 +2444,15 @@ } ] }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", @@ -931,6 +2462,39 @@ "randombytes": "^2.1.0" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -950,6 +2514,29 @@ "source-map": "^0.6.0" } }, + "node_modules/spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "dependencies": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -1013,6 +2600,51 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -1099,12 +2731,90 @@ "node": ">=4" } }, + "node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true + }, "node_modules/workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", @@ -1134,6 +2844,18 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -1143,6 +2865,12 @@ "node": ">=10" } }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", diff --git a/domainobjs/package.json b/domainobjs/package.json index fa910d94f6..dc90d30f69 100644 --- a/domainobjs/package.json +++ b/domainobjs/package.json @@ -6,7 +6,7 @@ "scripts": { "watch": "tsc --watch", "build": "tsc", - "test": "ts-mocha --exit ts/__tests__/**.test.ts" + "test": "nyc ts-mocha --exit ts/__tests__/**.test.ts" }, "devDependencies": { "@types/chai": "^4.3.11", @@ -14,10 +14,30 @@ "@types/node": "^18.11.9", "chai": "^4.3.10", "mocha": "^10.2.0", + "nyc": "^15.1.0", "ts-mocha": "^10.0.0" }, "dependencies": { "base64url": "^3.0.1", "maci-crypto": "^1.1.2" + }, + "nyc": { + "reporter": [ + "text", + "lcov" + ], + "extensions": [ + ".ts" + ], + "all": true, + "exclude": [ + "**/__tests__/*.ts", + "**/*.js", + "**/*.d.ts" + ], + "branches": ">50%", + "lines": ">50%", + "functions": ">50%", + "statements": ">50%" } } From 80bd832e49613172ef2b3972986f6e85c768c963 Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Sat, 16 Dec 2023 16:38:29 +0000 Subject: [PATCH 12/37] test(crypto): complete unit tests for the crypto package Add unit tests for functions within the crypto package and fix errors that arised by the test cases. Note that babyJubAddPoint seem to not work, however this is not used by the codebase --- crypto/package.json | 7 +- crypto/ts/__tests__/Crypto.test.ts | 818 ++++++++++++++++++++++++----- crypto/ts/crypto.ts | 4 +- crypto/ts/index.ts | 1 - crypto/ts/utils.ts | 1 + 5 files changed, 704 insertions(+), 127 deletions(-) diff --git a/crypto/package.json b/crypto/package.json index 1f488000ba..aec38fbed8 100644 --- a/crypto/package.json +++ b/crypto/package.json @@ -7,8 +7,8 @@ "watch": "tsc --watch", "build": "tsc", "test": "nyc ts-mocha --exit ts/__tests__/*.test.ts", - "test-crypto": "ts-mocha --exit ts/__tests__/Crypto.test.ts", - "test-accQueue": "ts-mocha --exit ts/__tests__/AccQueue.test.ts" + "test:crypto": "ts-mocha --exit ts/__tests__/Crypto.test.ts", + "test:accQueue": "ts-mocha --exit ts/__tests__/AccQueue.test.ts" }, "dependencies": { "blake-hash": "^1.1.0", @@ -40,7 +40,8 @@ "exclude": [ "**/__tests__/*.ts", "**/*.js", - "**/*.d.ts" + "**/*.d.ts", + "ts/index.ts" ], "branches": ">50%", "lines": ">50%", diff --git a/crypto/ts/__tests__/Crypto.test.ts b/crypto/ts/__tests__/Crypto.test.ts index 427dd4dd9c..88932f90fe 100644 --- a/crypto/ts/__tests__/Crypto.test.ts +++ b/crypto/ts/__tests__/Crypto.test.ts @@ -1,5 +1,7 @@ import { expect } from "chai"; +import { babyJub } from "circomlib"; +import { SNARK_FIELD_SIZE } from "../constants"; import { genPubKey, genKeypair, @@ -8,137 +10,734 @@ import { decrypt, sign, sha256Hash, + hash2, + hash3, + hash4, hash5, hash13, + hashLeftRight, + hashN, + poseidonT3, + poseidonT4, + poseidonT5, + poseidonT6, verifySignature, genRandomSalt, - SNARK_FIELD_SIZE, - genTreeCommitment, -} from ".."; - -describe("Cryptographic operations", function test() { + G1Point, + G2Point, + hashOne, + bigInt2Buffer, + genRandomBabyJubValue, + genPrivKey, + packPubKey, + unpackPubKey, + bitToCurve, + curveToBit, +} from "../crypto"; +import { genTreeCommitment } from "../utils"; + +describe("Crypto", function test() { this.timeout(100000); - const { privKey, pubKey } = genKeypair(); - const k = genKeypair(); - - const privKey1 = k.privKey; - const pubKey1 = k.pubKey; - - const ecdhSharedKey = genEcdhSharedKey(privKey, pubKey1); - const ecdhSharedKey1 = genEcdhSharedKey(privKey1, pubKey); - - const plaintext: bigint[] = []; - - for (let i = 0; i < 5; i += 1) { - plaintext.push(genRandomSalt()); - } - - const nonce = BigInt(123); - - const ciphertext = encrypt(plaintext, ecdhSharedKey, nonce); - const decryptedCiphertext = decrypt(ciphertext, ecdhSharedKey, nonce, plaintext.length); - - describe("Hashing", () => { - it("The hash of a plaintext should be smaller than the snark field size", () => { - const h = hash5([0, 1, 2, 3, 4].map((x) => BigInt(x))); - expect(h < SNARK_FIELD_SIZE).to.eq(true); - - const s = sha256Hash(plaintext); - expect(s < SNARK_FIELD_SIZE).to.eq(true); + describe("G1Point", () => { + it("should create a new G1Point", () => { + const g1 = new G1Point(BigInt(1), BigInt(2)); + expect(g1.x).to.eq(BigInt(1)); + expect(g1.y).to.eq(BigInt(2)); + }); + it("equals should return true for equal G1Point instances", () => { + const g1 = new G1Point(BigInt(1), BigInt(2)); + const g2 = new G1Point(BigInt(1), BigInt(2)); + expect(g1.equals(g2)).to.eq(true); + }); + it("equals should return false for different G1Point instances", () => { + const g1 = new G1Point(BigInt(1), BigInt(2)); + const g2 = new G1Point(BigInt(2), BigInt(1)); + expect(g1.equals(g2)).to.eq(false); + }); + it("asContractParam should return the G1Point instance as an object with x and y properties", () => { + const g1 = new G1Point(BigInt(1), BigInt(2)); + const g1Obj = g1.asContractParam(); + expect(g1Obj.x).to.eq("1"); + expect(g1Obj.y).to.eq("2"); + expect(Object.keys(g1Obj).length).to.eq(2); + expect(Object.keys(g1Obj)).to.deep.eq(["x", "y"]); }); }); - - describe("sha256Hash([0, 1])", () => { - const s = sha256Hash([BigInt(0), BigInt(1)]); - expect(s.toString()).to.eq("21788914573420223731318033363701224062123674814818143146813863227479480390499"); + describe("G2Point", () => { + it("should create a new G2Point", () => { + const g2 = new G2Point([BigInt(1)], [BigInt(2)]); + expect(g2.x).to.deep.eq([BigInt(1)]); + expect(g2.y).to.deep.eq([BigInt(2)]); + }); + it("equals should return true for equal G2Point instances", () => { + const g1 = new G2Point([BigInt(1)], [BigInt(2)]); + const g2 = new G2Point([BigInt(1)], [BigInt(2)]); + expect(g1.equals(g2)).to.eq(true); + }); + it("equals should return false for different G2Point instances", () => { + const g1 = new G2Point([BigInt(1)], [BigInt(2)]); + const g2 = new G2Point([BigInt(2)], [BigInt(1)]); + expect(g1.equals(g2)).to.eq(false); + }); + it("asContractParam should return the G2Point instance as an object with x and y properties", () => { + const g2 = new G2Point([BigInt(1)], [BigInt(2)]); + const g2Obj = g2.asContractParam(); + expect(g2Obj.x).to.deep.eq(["1"]); + expect(g2Obj.y).to.deep.eq(["2"]); + expect(Object.keys(g2Obj).length).to.eq(2); + expect(Object.keys(g2Obj)).to.deep.eq(["x", "y"]); + }); }); - - describe("hash13", () => { - it("Hashing a smaller array should work", () => { - const h = hash13([BigInt(1), BigInt(2), BigInt(3)]); - expect(h < SNARK_FIELD_SIZE).to.eq(true); + describe("sha256Hash", () => { + it("should return a hash of the input", () => { + const res = sha256Hash([BigInt(1), BigInt(2)]); + expect(res).to.not.eq(BigInt(0)); }); - - it("Hashing more than 13 elements should throw", () => { - const arr: bigint[] = []; - - for (let i = 0; i < 14; i += 1) { - arr.push(BigInt(i)); - } - - expect(() => hash13(arr)).to.throw(); + it("should produce the same hash for the same input", () => { + const res1 = sha256Hash([BigInt(1), BigInt(2)]); + const res2 = sha256Hash([BigInt(1), BigInt(2)]); + expect(res1).to.eq(res2); + }); + it("should produce different hashes for different inputs", () => { + const res1 = sha256Hash([BigInt(1), BigInt(2)]); + const res2 = sha256Hash([BigInt(2), BigInt(1)]); + expect(res1).to.not.eq(res2); + }); + it("should produce an output smaller than the snark field size", () => { + const hash = sha256Hash([BigInt(1), BigInt(2)]); + expect(hash < SNARK_FIELD_SIZE).to.eq(true); + }); + it("should produce the correct output", () => { + const s = sha256Hash([BigInt(0), BigInt(1)]); + expect(s.toString()).to.eq("21788914573420223731318033363701224062123674814818143146813863227479480390499"); }); }); - - describe("Public and private keys", () => { - it("A private key should be smaller than the snark field size", () => { - expect(privKey < SNARK_FIELD_SIZE).to.eq(true); - // TODO: add tests to ensure that the prune buffer step worked + describe("poseidon", () => { + describe("poseidonT3", () => { + it("should produce the same output for the same input", () => { + const res1 = poseidonT3([BigInt(1), BigInt(2)]); + const res2 = poseidonT3([BigInt(1), BigInt(2)]); + expect(res1).to.eq(res2); + }); + it("should produce different outputs for different inputs", () => { + const res1 = poseidonT3([BigInt(1), BigInt(2)]); + const res2 = poseidonT3([BigInt(2), BigInt(1)]); + expect(res1).to.not.eq(res2); + }); + it("should produce a non zero value", () => { + const hash = poseidonT3([BigInt(1), BigInt(2)]); + expect(hash).to.not.eq(BigInt(0)); + }); + it("should only accept two inputs", () => { + expect(() => poseidonT3([BigInt(1), BigInt(2), BigInt(3)])).to.throw(); + }); }); - - it("A public key's constitutent values should be smaller than the snark field size", () => { - // TODO: Figure out if these checks are correct and enough - expect(pubKey[0] < SNARK_FIELD_SIZE).to.eq(true); - expect(pubKey[1] < SNARK_FIELD_SIZE).to.eq(true); + describe("poseidonT4", () => { + it("should produce the same output for the same input", () => { + const res1 = poseidonT4([BigInt(1), BigInt(2), BigInt(3)]); + const res2 = poseidonT4([BigInt(1), BigInt(2), BigInt(3)]); + expect(res1).to.eq(res2); + }); + it("should produce different outputs for different inputs", () => { + const res1 = poseidonT4([BigInt(1), BigInt(2), BigInt(3)]); + const res2 = poseidonT4([BigInt(2), BigInt(1), BigInt(3)]); + expect(res1).to.not.eq(res2); + }); + it("should produce a non zero value", () => { + const hash = poseidonT4([BigInt(1), BigInt(2), BigInt(3)]); + expect(hash).to.not.eq(BigInt(0)); + }); + it("should only accept three inputs", () => { + expect(() => poseidonT4([BigInt(1), BigInt(2)])).to.throw(); + expect(() => poseidonT4([BigInt(1), BigInt(2), BigInt(3), BigInt(4)])).to.throw(); + }); + }); + describe("poseidonT5", () => { + it("should produce the same output for the same input", () => { + const res1 = poseidonT5([BigInt(1), BigInt(2), BigInt(3), BigInt(4)]); + const res2 = poseidonT5([BigInt(1), BigInt(2), BigInt(3), BigInt(4)]); + expect(res1).to.eq(res2); + }); + it("should produce different outputs for different inputs", () => { + const res1 = poseidonT5([BigInt(1), BigInt(2), BigInt(3), BigInt(4)]); + const res2 = poseidonT5([BigInt(2), BigInt(1), BigInt(3), BigInt(4)]); + expect(res1).to.not.eq(res2); + }); + it("should produce a non zero value", () => { + const hash = poseidonT5([BigInt(1), BigInt(2), BigInt(3), BigInt(4)]); + expect(hash).to.not.eq(BigInt(0)); + }); + it("should only accept four inputs", () => { + expect(() => poseidonT5([BigInt(1), BigInt(2)])).to.throw(); + expect(() => poseidonT5([BigInt(1), BigInt(2), BigInt(3)])).to.throw(); + expect(() => poseidonT5([BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5)])).to.throw(); + }); + }); + describe("poseidonT6", () => { + it("should produce the same output for the same input", () => { + const res1 = poseidonT6([BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5)]); + const res2 = poseidonT6([BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5)]); + expect(res1).to.eq(res2); + }); + it("should produce different outputs for different inputs", () => { + const res1 = poseidonT6([BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5)]); + const res2 = poseidonT6([BigInt(2), BigInt(1), BigInt(3), BigInt(4), BigInt(5)]); + expect(res1).to.not.eq(res2); + }); + it("should produce a non zero value", () => { + const hash = poseidonT6([BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5)]); + expect(hash).to.not.eq(BigInt(0)); + }); + it("should only accept five inputs", () => { + expect(() => poseidonT6([BigInt(1), BigInt(2)])).to.throw(); + expect(() => poseidonT6([BigInt(1), BigInt(2), BigInt(3)])).to.throw(); + expect(() => poseidonT6([BigInt(1), BigInt(2), BigInt(3), BigInt(4)])).to.throw(); + expect(() => poseidonT6([BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5), BigInt(6)])).to.throw(); + }); + }); + describe("hashLeftRight", () => { + it("should produce the same output for the same input", () => { + const res1 = hashLeftRight(BigInt(1), BigInt(2)); + const res2 = hashLeftRight(BigInt(1), BigInt(2)); + expect(res1).to.eq(res2); + }); + it("should produce different outputs for different inputs", () => { + const res1 = hashLeftRight(BigInt(1), BigInt(2)); + const res2 = hashLeftRight(BigInt(2), BigInt(1)); + expect(res1).to.not.eq(res2); + }); + it("should produce a non zero value", () => { + const hash = hashLeftRight(BigInt(1), BigInt(2)); + expect(hash).to.not.eq(BigInt(0)); + }); + }); + describe("hashN", () => { + it("should produce the same output for the same input", () => { + const res1 = hashN(5, [BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5)]); + const res2 = hashN(5, [BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5)]); + expect(res1).to.eq(res2); + }); + it("should produce different outputs for different inputs", () => { + const res1 = hashN(5, [BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5)]); + const res2 = hashN(5, [BigInt(2), BigInt(1), BigInt(3), BigInt(4), BigInt(5)]); + expect(res1).to.not.eq(res2); + }); + it("should produce a non zero value", () => { + const hash = hashN(5, [BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5)]); + expect(hash).to.not.eq(BigInt(0)); + }); + it("should throw when elements is more than numElement", () => { + expect(() => hashN(5, [BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5), BigInt(6)])).to.throw( + "the length of the elements array should be at most 5; got 6", + ); + }); + it("should work (and apply padding) when passed less than numElement elements", () => { + const hash = hashN(5, [BigInt(1), BigInt(2), BigInt(3), BigInt(4)]); + expect(hash).to.not.eq(BigInt(0)); + }); + }); + describe("hash2", () => { + it("should produce the same output for the same input", () => { + const res1 = hash2([BigInt(1), BigInt(2)]); + const res2 = hash2([BigInt(1), BigInt(2)]); + expect(res1).to.eq(res2); + }); + it("should produce different outputs for different inputs", () => { + const res1 = hash2([BigInt(1), BigInt(2)]); + const res2 = hash2([BigInt(2), BigInt(1)]); + expect(res1).to.not.eq(res2); + }); + it("should produce a non zero value", () => { + const hash = hash2([BigInt(1), BigInt(2)]); + expect(hash).to.not.eq(BigInt(0)); + }); + it("should throw when elements is more than numElement", () => { + expect(() => hash2([BigInt(1), BigInt(2), BigInt(3)])).to.throw( + "the length of the elements array should be at most 2; got 3", + ); + }); + it("should work (and apply padding) when passed less than numElement elements", () => { + const hash = hash2([BigInt(1)]); + expect(hash).to.not.eq(BigInt(0)); + }); + }); + describe("hash3", () => { + it("should produce the same output for the same input", () => { + const res1 = hash3([BigInt(1), BigInt(2), BigInt(3)]); + const res2 = hash3([BigInt(1), BigInt(2), BigInt(3)]); + expect(res1).to.eq(res2); + }); + it("should produce different outputs for different inputs", () => { + const res1 = hash3([BigInt(1), BigInt(2), BigInt(3)]); + const res2 = hash3([BigInt(2), BigInt(1), BigInt(3)]); + expect(res1).to.not.eq(res2); + }); + it("should produce a non zero value", () => { + const hash = hash3([BigInt(1), BigInt(2), BigInt(3)]); + expect(hash).to.not.eq(BigInt(0)); + }); + it("should throw when elements is more than numElement", () => { + expect(() => hash3([BigInt(1), BigInt(2), BigInt(3), BigInt(4)])).to.throw( + "the length of the elements array should be at most 3; got 4", + ); + }); + it("should work (and apply padding) when passed less than numElement elements", () => { + const hash = hash3([BigInt(1), BigInt(2)]); + expect(hash).to.not.eq(BigInt(0)); + }); + }); + describe("hash4", () => { + it("should produce the same output for the same input", () => { + const res1 = hash4([BigInt(1), BigInt(2), BigInt(3), BigInt(4)]); + const res2 = hash4([BigInt(1), BigInt(2), BigInt(3), BigInt(4)]); + expect(res1).to.eq(res2); + }); + it("should produce different outputs for different inputs", () => { + const res1 = hash4([BigInt(1), BigInt(2), BigInt(3), BigInt(4)]); + const res2 = hash4([BigInt(2), BigInt(1), BigInt(3), BigInt(4)]); + expect(res1).to.not.eq(res2); + }); + it("should produce a non zero value", () => { + const hash = hash4([BigInt(1), BigInt(2), BigInt(3), BigInt(4)]); + expect(hash).to.not.eq(BigInt(0)); + }); + it("should throw when elements is more than numElement", () => { + expect(() => hash4([BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5)])).to.throw( + "the length of the elements array should be at most 4; got 5", + ); + }); + it("should work (and apply padding) when passed less than numElement elements", () => { + const hash = hash4([BigInt(1), BigInt(2)]); + expect(hash).to.not.eq(BigInt(0)); + }); + }); + describe("hash5", () => { + it("should produce the same output for the same input", () => { + const res1 = hash5([BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5)]); + const res2 = hash5([BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5)]); + expect(res1).to.eq(res2); + }); + it("should produce different outputs for different inputs", () => { + const res1 = hash5([BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5)]); + const res2 = hash5([BigInt(2), BigInt(1), BigInt(3), BigInt(4), BigInt(5)]); + expect(res1).to.not.eq(res2); + }); + it("should produce a non zero value", () => { + const hash = hash5([BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5)]); + expect(hash).to.not.eq(BigInt(0)); + }); + it("should throw when elements is more than numElement", () => { + expect(() => hash5([BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5), BigInt(6)])).to.throw( + "the length of the elements array should be at most 5; got 6", + ); + }); + it("should work (and apply padding) when passed less than numElement elements", () => { + const hash = hash5([BigInt(1), BigInt(2)]); + expect(hash).to.not.eq(BigInt(0)); + }); + }); + describe("hash13", () => { + it("should produce the same output for the same input", () => { + const res1 = hash13([ + BigInt(1), + BigInt(2), + BigInt(3), + BigInt(4), + BigInt(5), + BigInt(6), + BigInt(7), + BigInt(8), + BigInt(9), + BigInt(10), + BigInt(11), + BigInt(12), + BigInt(13), + ]); + const res2 = hash13([ + BigInt(1), + BigInt(2), + BigInt(3), + BigInt(4), + BigInt(5), + BigInt(6), + BigInt(7), + BigInt(8), + BigInt(9), + BigInt(10), + BigInt(11), + BigInt(12), + BigInt(13), + ]); + expect(res1).to.eq(res2); + }); + it("should produce different outputs for different inputs", () => { + const res1 = hash13([ + BigInt(1), + BigInt(2), + BigInt(3), + BigInt(4), + BigInt(5), + BigInt(6), + BigInt(7), + BigInt(8), + BigInt(9), + BigInt(10), + BigInt(11), + BigInt(12), + BigInt(13), + ]); + const res2 = hash13([ + BigInt(2), + BigInt(1), + BigInt(3), + BigInt(4), + BigInt(5), + BigInt(6), + BigInt(7), + BigInt(8), + BigInt(9), + BigInt(10), + BigInt(11), + BigInt(12), + BigInt(13), + ]); + expect(res1).to.not.eq(res2); + }); + it("should produce a non zero value", () => { + const hash = hash13([ + BigInt(1), + BigInt(2), + BigInt(3), + BigInt(4), + BigInt(5), + BigInt(6), + BigInt(7), + BigInt(8), + BigInt(9), + BigInt(10), + BigInt(11), + BigInt(12), + BigInt(13), + ]); + expect(hash).to.not.eq(BigInt(0)); + }); + it("should throw when elements is more than numElement", () => { + expect(() => + hash13([ + BigInt(1), + BigInt(2), + BigInt(3), + BigInt(4), + BigInt(5), + BigInt(6), + BigInt(7), + BigInt(8), + BigInt(9), + BigInt(10), + BigInt(11), + BigInt(12), + BigInt(13), + BigInt(14), + ]), + ).to.throw("the length of the elements array should be at most 13; got 14"); + }); + it("should work (and apply padding) when passed less than numElement elements", () => { + const hash = hash13([BigInt(1), BigInt(2)]); + expect(hash).to.not.eq(BigInt(0)); + }); + }); + describe("hashOne", () => { + it("should produce the same output for the same input", () => { + const res1 = hashOne(BigInt(1)); + const res2 = hashOne(BigInt(1)); + expect(res1).to.eq(res2); + }); + it("should produce different outputs for different inputs", () => { + const res1 = hashOne(BigInt(1)); + const res2 = hashOne(BigInt(2)); + expect(res1).to.not.eq(res2); + }); + it("should produce a non zero value", () => { + const hash = hashOne(BigInt(1)); + expect(hash).to.not.eq(BigInt(0)); + }); }); }); - describe("ECDH shared key generation", () => { - it("The shared keys should match", () => { - expect(ecdhSharedKey[0].toString()).to.eq(ecdhSharedKey1[0].toString()); - expect(ecdhSharedKey[1].toString()).to.eq(ecdhSharedKey1[1].toString()); + describe("utils", () => { + describe("genRandomSalt", () => { + it("should produce a random salt", () => { + const salt1 = genRandomSalt(); + const salt2 = genRandomSalt(); + expect(salt1).to.not.eq(salt2); + }); + it("should produce a salt smaller than the snark field size", () => { + const salt = genRandomSalt(); + expect(salt < SNARK_FIELD_SIZE).to.eq(true); + }); + it("should produce a non zero value", () => { + const salt = genRandomSalt(); + expect(salt).to.not.eq(BigInt(0)); + }); }); + describe("bigInt2Buffer", () => { + it("should convert a BigInt to a Buffer", () => { + const bigInt = BigInt(123456789); + const buffer = bigInt2Buffer(bigInt); + expect(buffer).to.be.instanceOf(Buffer); + }); - it("A shared key should be smaller than the snark field size", () => { - // TODO: Figure out if this check is correct and enough - expect(ecdhSharedKey[0] < SNARK_FIELD_SIZE).to.eq(true); - expect(ecdhSharedKey[1] < SNARK_FIELD_SIZE).to.eq(true); + it("should produce a Buffer with the correct value", () => { + const bigInt = BigInt(123456789); + const buffer = bigInt2Buffer(bigInt); + const expectedBuffer = Buffer.from(bigInt.toString(16), "hex"); + expect(buffer.equals(expectedBuffer)).to.eq(true); + }); }); - }); + describe("genTreeCommitment", () => { + const leaves = [BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5)]; + const salt = BigInt(6); + const depth = 3; + it("should generate a commitment to the tree root using the provided salt", () => { + const commitment = genTreeCommitment(leaves, salt, depth); + expect(commitment).to.satisfy((num: bigint) => num > 0); + expect(commitment).to.satisfy((num: bigint) => num < SNARK_FIELD_SIZE); + }); - describe("Encryption and decryption", () => { - it("The ciphertext should be of the correct format", () => { - const expectedLength = plaintext.length <= 3 ? 4 : 1 + (plaintext.length % 3) * 3; + it("should always generate the same commitment for the same inputs", () => { + const commitment = genTreeCommitment(leaves, salt, depth); + expect(commitment).to.satisfy((num: bigint) => num > 0); + expect(commitment).to.satisfy((num: bigint) => num < SNARK_FIELD_SIZE); - expect(ciphertext.length).to.eq(expectedLength); + const commitment2 = genTreeCommitment(leaves, salt, depth); + expect(commitment2).to.satisfy((num: bigint) => num > 0); + expect(commitment2).to.satisfy((num: bigint) => num < SNARK_FIELD_SIZE); + expect(commitment).to.eq(commitment2); + }); }); + describe("bitToCurve", () => { + it("should map bit 0 to point [0, 1] on the curve", () => { + const point = bitToCurve(BigInt(0)); + expect(point).to.deep.eq([BigInt(0), BigInt(1)]); + }); - it("The ciphertext should differ from the plaintext", () => { - for (let i = 0; i < plaintext.length; i += 1) { - expect(plaintext[i] !== ciphertext[i + 1]).to.eq(true); - } + it("should map bit 1 to the base point of the curve", () => { + const point = bitToCurve(BigInt(1)); + expect(point).to.eq(babyJub.Base8); + }); + + it("should throw error for bit values other than 0 or 1", () => { + expect(() => bitToCurve(BigInt(2))).to.throw("Invalid bit value"); + expect(() => bitToCurve(BigInt(-1))).to.throw("Invalid bit value"); + }); }); + describe("curveToBit", () => { + it("should map point [0, 1] on the curve to bit 0", () => { + const bit = curveToBit([BigInt(0), BigInt(1)]); + expect(bit).to.eq(BigInt(0)); + }); + + it("should map the base point of the curve to bit 1", () => { + const bit = curveToBit(babyJub.Base8); + expect(bit).to.eq(BigInt(1)); + }); - it("The ciphertext should be smaller than the snark field size", () => { - ciphertext.forEach((ct) => { - // TODO: Figure out if this check is correct and enough - expect(ct < SNARK_FIELD_SIZE).to.eq(true); + it("should throw error for points not on the curve", () => { + expect(() => curveToBit([BigInt(1), BigInt(2)])).to.throw("Invalid point"); }); }); + }); - it("The decrypted ciphertext should be correct", () => { - for (let i = 0; i < decryptedCiphertext.length; i += 1) { - expect(decryptedCiphertext[i]).to.eq(plaintext[i]); - } + describe("babyjub", () => { + describe("genRandomBabyJubValue", () => { + it("should generate a value what is < SNARK_FIELD_SIZE", () => { + const p = genRandomBabyJubValue(); + expect(p < SNARK_FIELD_SIZE).to.eq(true); + }); + it("should generate a random value", () => { + const p1 = genRandomBabyJubValue(); + const p2 = genRandomBabyJubValue(); + expect(p1).to.not.eq(p2); + }); + it("should generate a non zero value", () => { + const p = genRandomBabyJubValue(); + expect(p).to.not.eq(BigInt(0)); + }); + }); + describe("genPrivKey", () => { + it("should generate a private key that is < SNARK_FIELD_SIZE", () => { + const sk = genPrivKey(); + expect(sk < SNARK_FIELD_SIZE).to.eq(true); + }); + it("should generate a random private key", () => { + const sk1 = genPrivKey(); + const sk2 = genPrivKey(); + expect(sk1).to.not.eq(sk2); + }); + it("should generate a non zero private key", () => { + const sk = genPrivKey(); + expect(sk).to.not.eq(BigInt(0)); + }); + }); + describe("genRandomSalt", () => { + it("should generate a salt that is < SNARK_FIELD_SIZE", () => { + const salt = genRandomSalt(); + expect(salt < SNARK_FIELD_SIZE).to.eq(true); + }); + it("should generate a random salt", () => { + const salt1 = genRandomSalt(); + const salt2 = genRandomSalt(); + expect(salt1).to.not.eq(salt2); + }); + it("should generate a non zero salt", () => { + const salt = genRandomSalt(); + expect(salt).to.not.eq(BigInt(0)); + }); }); + describe("packPubKey", () => { + it("should pack a public key into a Buffer", () => { + const pk = genPubKey(genPrivKey()); + const pkBuff = packPubKey(pk); + expect(pkBuff).to.be.instanceOf(Buffer); + }); + }); + describe("unpackPubKey", () => { + it("should unpack a Buffer into a public key", () => { + const pk = genPubKey(genPrivKey()); + const pkBuff = packPubKey(pk); + const pkUnpacked = unpackPubKey(pkBuff); + expect(pkUnpacked).to.deep.eq(pk); + }); + it("should produce a result which is < SNARK_FIELD_SIZE", () => { + const pk = genPubKey(genPrivKey()); + const pkBuff = packPubKey(pk); + const pkUnpacked = unpackPubKey(pkBuff); + expect(pkUnpacked[0] < SNARK_FIELD_SIZE).to.eq(true); + expect(pkUnpacked[1] < SNARK_FIELD_SIZE).to.eq(true); + }); + }); + describe("genPubKey", () => { + it("should produce a public key which is < SNARK_FIELD_SIZE", () => { + const pk = genPubKey(genPrivKey()); + expect(pk[0] < SNARK_FIELD_SIZE).to.eq(true); + expect(pk[1] < SNARK_FIELD_SIZE).to.eq(true); + }); + it("should throw when given a private key which is >= SNARK_FIELD_SIZE", () => { + expect(() => genPubKey(SNARK_FIELD_SIZE)).to.throw(); + }); + }); + describe("genKeypair", () => { + it("should produce a public key which is < SNARK_FIELD_SIZE", () => { + const { pubKey } = genKeypair(); + expect(pubKey[0] < SNARK_FIELD_SIZE).to.eq(true); + expect(pubKey[1] < SNARK_FIELD_SIZE).to.eq(true); + }); + it("should produce a private key which is < SNARK_FIELD_SIZE", () => { + const { privKey } = genKeypair(); + expect(privKey < SNARK_FIELD_SIZE).to.eq(true); + }); + }); + describe("genEcdhSharedKey", () => { + it("should produce a shared key which is < SNARK_FIELD_SIZE", () => { + const { privKey, pubKey } = genKeypair(); + const sharedKey = genEcdhSharedKey(privKey, pubKey); + expect(sharedKey[0] < SNARK_FIELD_SIZE).to.eq(true); + expect(sharedKey[1] < SNARK_FIELD_SIZE).to.eq(true); + }); + it("should generate a key which is different than the both privKey and pubKey", () => { + const { privKey, pubKey } = genKeypair(); + const sharedKey = genEcdhSharedKey(privKey, pubKey); + expect(sharedKey[0]).to.not.eq(privKey); + expect(sharedKey[1]).to.not.eq(privKey); + expect(sharedKey[0]).to.not.eq(pubKey[0]); + expect(sharedKey[1]).to.not.eq(pubKey[1]); + }); + it("should generate non zero points", () => { + const { privKey, pubKey } = genKeypair(); + const sharedKey = genEcdhSharedKey(privKey, pubKey); + expect(sharedKey[0]).to.not.eq(BigInt(0)); + expect(sharedKey[1]).to.not.eq(BigInt(0)); + }); + it("should produce consistent results", () => { + const { privKey: privKey1, pubKey: pubKey1 } = genKeypair(); + const { privKey: privKey2, pubKey: pubKey2 } = genKeypair(); - it("The plaintext should be incorrect if decrypted with a different key", () => { - const sk = BigInt(1); - const pk = genPubKey(sk); - const differentKey = genEcdhSharedKey(sk, pk); + const sharedKey1 = genEcdhSharedKey(privKey1, pubKey2); + const sharedKey2 = genEcdhSharedKey(privKey2, pubKey1); - expect(() => { - decrypt(ciphertext, differentKey, nonce, plaintext.length); - }).to.throw(); + expect(sharedKey1[0]).to.eq(sharedKey2[0]); + expect(sharedKey1[1]).to.eq(sharedKey2[1]); + }); + }); + }); + describe("encryption/decryption", () => { + const nonce = BigInt(123); + + describe("encrypt", () => { + it("should encrypt a plaintext", () => { + const { privKey } = genKeypair(); + const pubKey = genPubKey(genPrivKey()); + const sharedKey = genEcdhSharedKey(privKey, pubKey); + const plaintext = [BigInt(1), BigInt(2), BigInt(3)]; + const ciphertext = encrypt(plaintext, sharedKey, nonce); + expect(ciphertext).to.be.instanceOf(Array); + expect(ciphertext.length).to.eq(4); + }); + it("should produce a cihertext that is different from the plaintext", () => { + const { privKey } = genKeypair(); + const pubKey = genPubKey(genPrivKey()); + const sharedKey = genEcdhSharedKey(privKey, pubKey); + const plaintext = [BigInt(1), BigInt(2), BigInt(3)]; + const ciphertext = encrypt(plaintext, sharedKey, nonce); + for (let i = 0; i < plaintext.length; i += 1) { + expect(plaintext[i] !== ciphertext[i + 1]).to.eq(true); + } + }); + it("should produce ciphertext that is < SNARK_FIELD_SIZE", () => { + const { privKey } = genKeypair(); + const pubKey = genPubKey(genPrivKey()); + const sharedKey = genEcdhSharedKey(privKey, pubKey); + const plaintext = [BigInt(1), BigInt(2), BigInt(3)]; + const ciphertext = encrypt(plaintext, sharedKey, nonce); + ciphertext.forEach((c) => { + expect(c < SNARK_FIELD_SIZE).to.eq(true); + }); + }); + }); + describe("decrypt", () => { + it("should decrypt a ciphertext", () => { + const { privKey } = genKeypair(); + const pubKey = genPubKey(genPrivKey()); + const sharedKey = genEcdhSharedKey(privKey, pubKey); + const plaintext = [BigInt(1), BigInt(2), BigInt(3)]; + const ciphertext = encrypt(plaintext, sharedKey, nonce); + const decryptedCiphertext = decrypt(ciphertext, sharedKey, nonce, plaintext.length); + expect(decryptedCiphertext).to.be.instanceOf(Array); + expect(decryptedCiphertext.length).to.eq(3); + expect(plaintext).to.deep.eq(decryptedCiphertext); + }); + it("should fail to decrypt if given the wrong key", () => { + const { privKey } = genKeypair(); + const pubKey = genPubKey(genPrivKey()); + const sharedKey = genEcdhSharedKey(privKey, pubKey); + const plaintext = [BigInt(1), BigInt(2), BigInt(3)]; + const ciphertext = encrypt(plaintext, sharedKey, nonce); + const differentKey = genEcdhSharedKey(BigInt(1), pubKey); + + expect(() => { + decrypt(ciphertext, differentKey, nonce, plaintext.length); + }).to.throw(); + }); }); }); - describe("Signature generation and verification", () => { + describe("signatures", () => { + const { privKey, pubKey } = genKeypair(); const message = BigInt(Math.floor(Math.random() * 1000000000)); const signature = sign(privKey, message); - it("The signature should have the correct format and it constitutent parts should be smaller than the snark field size", () => { + it("should have the correct format and its constituent parts should be smaller than the snark field size", () => { expect(signature).to.haveOwnProperty("R8"); expect(signature).to.haveOwnProperty("S"); expect(signature.R8[0] < SNARK_FIELD_SIZE).to.eq(true); @@ -146,17 +745,17 @@ describe("Cryptographic operations", function test() { expect(signature.S < SNARK_FIELD_SIZE).to.eq(true); }); - it("The signature should be valid", () => { + it("should be valid", () => { const valid = verifySignature(message, signature, pubKey); expect(valid).to.eq(true); }); - it("The signature should be invalid for a different message", () => { + it("should be invalid for a different message", () => { const valid = verifySignature(message + BigInt(1), signature, pubKey); expect(valid).to.eq(false); }); - it("The signature should be invalid if tampered with", () => { + it("should be invalid if tampered with", () => { const valid = verifySignature( message, { @@ -168,31 +767,10 @@ describe("Cryptographic operations", function test() { expect(valid).to.eq(false); }); - it("The signature should be invalid for a different public key", () => { + it("should be invalid for a different public key", () => { + const pubKey1 = genPubKey(genPrivKey()); const valid = verifySignature(message, signature, pubKey1); expect(valid).to.eq(false); }); }); - - describe("genTreeCommitment", () => { - const leaves = [BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5)]; - const salt = BigInt(6); - const depth = 3; - it("should generate a commitment to the tree root using the provided salt", () => { - const commitment = genTreeCommitment(leaves, salt, depth); - expect(commitment).to.satisfy((num: bigint) => num > 0); - expect(commitment).to.satisfy((num: bigint) => num < SNARK_FIELD_SIZE); - }); - - it("should always generate the same commitment for the same inputs", () => { - const commitment = genTreeCommitment(leaves, salt, depth); - expect(commitment).to.satisfy((num: bigint) => num > 0); - expect(commitment).to.satisfy((num: bigint) => num < SNARK_FIELD_SIZE); - - const commitment2 = genTreeCommitment(leaves, salt, depth); - expect(commitment).to.satisfy((num: bigint) => num > 0); - expect(commitment).to.satisfy((num: bigint) => num < SNARK_FIELD_SIZE); - expect(commitment).to.eq(commitment2); - }); - }); }); diff --git a/crypto/ts/crypto.ts b/crypto/ts/crypto.ts index 0dfbec17db..d7328ece4a 100644 --- a/crypto/ts/crypto.ts +++ b/crypto/ts/crypto.ts @@ -198,7 +198,7 @@ export const hashN = (numElements: number, elements: Plaintext): bigint => { 5: poseidonT6, }; - return funcs[numElements](elements); + return funcs[numElements](elementsPadded); }; // hash functions @@ -206,8 +206,6 @@ export const hash2 = (elements: Plaintext): bigint => hashN(2, elements); export const hash3 = (elements: Plaintext): bigint => hashN(3, elements); export const hash4 = (elements: Plaintext): bigint => hashN(4, elements); export const hash5 = (elements: Plaintext): bigint => hashN(5, elements); -// @todo look to make this work -export const hash9 = (elements: Plaintext): bigint => hashN(9, elements); /** * A convenience function to use Poseidon to hash a Plaintext with diff --git a/crypto/ts/index.ts b/crypto/ts/index.ts index 6ed7f3a139..75457d89c9 100644 --- a/crypto/ts/index.ts +++ b/crypto/ts/index.ts @@ -23,7 +23,6 @@ export { hash3, hash4, hash5, - hash9, hash13, hashOne, genRandomBabyJubValue, diff --git a/crypto/ts/utils.ts b/crypto/ts/utils.ts index 29dee31034..7f2b433ce1 100644 --- a/crypto/ts/utils.ts +++ b/crypto/ts/utils.ts @@ -47,6 +47,7 @@ export const calcDepthFromNumLeaves = (hashLength: number, numLeaves: number): n * hash. * @param leaves A list of values * @param salt A random salt + * @param depth The tree depth * @returns The hash of the leaves and the salt, with the salt last */ export const genTreeCommitment = (leaves: bigint[], salt: bigint, depth: number): bigint => { From 93e8a657fccb3232b18bf191984c6bea5ccabf85 Mon Sep 17 00:00:00 2001 From: 0xmad <0xmad@users.noreply.github.com> Date: Tue, 2 Jan 2024 11:49:22 -0600 Subject: [PATCH 13/37] chore(circuits): integrate linter - [x] Apply linter and type fixes - [x] Dependency management --- circuits/.eslintrc.js | 107 ++++++++++++++++++ circuits/package.json | 8 +- circuits/ts/__tests__/CalculateTotal.test.ts | 9 +- circuits/ts/__tests__/CeremonyParams.test.ts | 38 ++++--- circuits/ts/__tests__/Ecdh.test.ts | 6 +- circuits/ts/__tests__/Hasher.test.ts | 42 ++++--- .../ts/__tests__/MessageToCommand.test.ts | 16 ++- .../ts/__tests__/MessageValidator.test.ts | 25 ++-- circuits/ts/__tests__/PrivToPubKey.test.ts | 11 +- circuits/ts/__tests__/ProcessMessages.test.ts | 78 ++++++------- circuits/ts/__tests__/Splicer.test.ts | 13 ++- .../StateLeafAndBallotTransformer.test.ts | 8 +- circuits/ts/__tests__/TallyVotes.test.ts | 33 +++--- circuits/ts/__tests__/UnpackElement.test.ts | 26 +++-- circuits/ts/__tests__/VerifySignature.test.ts | 18 +-- circuits/ts/__tests__/utils/utils.ts | 10 +- circuits/ts/proofs.ts | 38 ++++--- circuits/ts/types.ts | 2 +- circuits/ts/types/circom_tester.d.ts | 12 +- circuits/ts/types/snarkjs.d.ts | 9 +- circuits/ts/utils.ts | 29 +++-- circuits/tsconfig.json | 28 ++++- 22 files changed, 380 insertions(+), 186 deletions(-) create mode 100644 circuits/.eslintrc.js diff --git a/circuits/.eslintrc.js b/circuits/.eslintrc.js new file mode 100644 index 0000000000..a22d4fb52c --- /dev/null +++ b/circuits/.eslintrc.js @@ -0,0 +1,107 @@ +const fs = require("fs"); +const path = require("path"); + +const prettierConfig = fs.readFileSync(path.resolve(__dirname, "../.prettierrc"), "utf8"); +const prettierOptions = JSON.parse(prettierConfig); +const isProduction = process.env.NODE_ENV === "production"; + +module.exports = { + root: true, + extends: [ + "airbnb", + "prettier", + "plugin:import/recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-type-checked", + "plugin:@typescript-eslint/strict", + "plugin:@typescript-eslint/strict-type-checked", + "plugin:@typescript-eslint/stylistic", + "plugin:@typescript-eslint/stylistic-type-checked", + "plugin:import/typescript", + ], + plugins: ["json", "prettier", "unused-imports", "import", "@typescript-eslint"], + parser: "@typescript-eslint/parser", + env: { + node: true, + mocha: true, + es2022: true, + }, + settings: { + react: { + version: "999.999.999", + }, + "import/resolver": { + typescript: {}, + node: { + extensions: [".ts", ".js"], + moduleDirectory: ["node_modules", "ts", "src"], + }, + }, + }, + parserOptions: { + project: path.resolve(__dirname, "./tsconfig.json"), + sourceType: "module", + typescript: true, + ecmaVersion: 2022, + experimentalDecorators: true, + requireConfigFile: false, + ecmaFeatures: { + classes: true, + impliedStrict: true, + }, + warnOnUnsupportedTypeScriptVersion: true, + }, + reportUnusedDisableDirectives: isProduction, + rules: { + "import/no-cycle": ["error"], + "unused-imports/no-unused-imports": "error", + "import/no-extraneous-dependencies": [ + "error", + { + devDependencies: ["**/*.test.ts"], + }, + ], + "no-debugger": isProduction ? "error" : "off", + "no-console": "error", + "no-underscore-dangle": "error", + "no-redeclare": ["error", { builtinGlobals: true }], + "import/order": [ + "error", + { + groups: ["external", "builtin", "internal", "type", "parent", "sibling", "index", "object"], + alphabetize: { + order: "asc", + caseInsensitive: true, + }, + warnOnUnassignedImports: true, + "newlines-between": "always", + }, + ], + "prettier/prettier": ["error", prettierOptions], + "import/prefer-default-export": "off", + "import/extensions": ["error", { json: "always" }], + "class-methods-use-this": "off", + "prefer-promise-reject-errors": "off", + "max-classes-per-file": "off", + "no-use-before-define": ["off"], + "no-shadow": "off", + curly: ["error", "all"], + + "@typescript-eslint/explicit-member-accessibility": ["error", { accessibility: "no-public" }], + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/prefer-nullish-coalescing": "off", + "@typescript-eslint/no-floating-promises": "off", + "@typescript-eslint/no-explicit-any": "error", + "@typescript-eslint/explicit-module-boundary-types": "error", + "@typescript-eslint/no-use-before-define": ["error", { functions: false, classes: false }], + "@typescript-eslint/no-misused-promises": ["error", { checksVoidReturn: false }], + "@typescript-eslint/no-shadow": [ + "error", + { + builtinGlobals: true, + allow: ["location", "event", "history", "name", "status", "Option", "test", "expect"], + }, + ], + }, +}; diff --git a/circuits/package.json b/circuits/package.json index 019353cd6c..32e67f2185 100644 --- a/circuits/package.json +++ b/circuits/package.json @@ -2,7 +2,7 @@ "name": "maci-circuits", "version": "1.1.2", "description": "zk-SNARK circuits for MACI", - "main": "build/index.js", + "main": "build/ts/index.js", "scripts": { "build-test-circuits-c": "bash ./scripts/build_intel.sh", "build-test-circuits-wasm": "bash ./scripts/build_arm.sh", @@ -25,6 +25,9 @@ }, "dependencies": { "circomlib": "https://github.com/weijiekoh/circomlib#ac85e82c1914d47789e2032fb11ceb2cfdd38a2b", + "maci-core": "^1.1.2", + "maci-crypto": "^1.1.2", + "maci-domainobjs": "^1.1.2", "snarkjs": "^0.5.0" }, "devDependencies": { @@ -33,9 +36,6 @@ "@types/node": "^18.11.9", "chai": "^4.3.10", "circom_tester": "^0.0.20", - "maci-core": "^1.1.2", - "maci-crypto": "^1.1.2", - "maci-domainobjs": "^1.1.2", "mocha": "^10.2.0", "ts-mocha": "^10.0.0", "typescript": "^5.3.2" diff --git a/circuits/ts/__tests__/CalculateTotal.test.ts b/circuits/ts/__tests__/CalculateTotal.test.ts index 7d2f81ca65..4d96c56fb9 100644 --- a/circuits/ts/__tests__/CalculateTotal.test.ts +++ b/circuits/ts/__tests__/CalculateTotal.test.ts @@ -1,6 +1,8 @@ -import path from "path"; -import tester from "circom_tester"; import { expect } from "chai"; +import tester from "circom_tester"; + +import path from "path"; + import { getSignal } from "./utils/utils"; describe("CalculateTotal circuit", () => { @@ -13,9 +15,10 @@ describe("CalculateTotal circuit", () => { it("should correctly sum a list of values", async () => { const nums: number[] = []; - for (let i = 0; i < 6; i++) { + for (let i = 0; i < 6; i += 1) { nums.push(Math.floor(Math.random() * 100)); } + const sum = nums.reduce((a, b) => a + b, 0); const circuitInputs = { diff --git a/circuits/ts/__tests__/CeremonyParams.test.ts b/circuits/ts/__tests__/CeremonyParams.test.ts index 342622072e..5ed90a29b5 100644 --- a/circuits/ts/__tests__/CeremonyParams.test.ts +++ b/circuits/ts/__tests__/CeremonyParams.test.ts @@ -1,12 +1,14 @@ +import { expect } from "chai"; +import tester from "circom_tester"; import { MaciState, Poll, packProcessMessageSmallVals, STATE_TREE_ARITY } from "maci-core"; -import { PrivKey, Keypair, PCommand, Message, Ballot } from "maci-domainobjs"; import { hash5, IncrementalQuinTree, stringifyBigInts, NOTHING_UP_MY_SLEEVE, AccQueue } from "maci-crypto"; +import { PrivKey, Keypair, PCommand, Message, Ballot } from "maci-domainobjs"; + import path from "path"; -import { expect } from "chai"; -import tester from "circom_tester"; + import { generateRandomIndex, getSignal } from "./utils/utils"; -describe("Ceremony param tests", function () { +describe("Ceremony param tests", () => { const params = { // processMessages and Tally stateTreeDepth: 6, @@ -40,7 +42,7 @@ describe("Ceremony param tests", function () { const coordinatorKeypair = new Keypair(); - describe("ProcessMessage circuit", function () { + describe("ProcessMessage circuit", function test() { this.timeout(900000); let circuit: tester.WasmTester; @@ -63,7 +65,7 @@ describe("Ceremony param tests", function () { const messages: Message[] = []; const commands: PCommand[] = []; - before(async () => { + before(() => { // Sign up and publish const userKeypair = new Keypair(new PrivKey(BigInt(1))); stateIndex = BigInt( @@ -82,7 +84,7 @@ describe("Ceremony param tests", function () { // First command (valid) const command = new PCommand( - stateIndex, //BigInt(1), + stateIndex, // BigInt(1), userKeypair.pubKey, voteOptionIndex, // voteOptionIndex, voteWeight, // vote weight @@ -141,9 +143,9 @@ describe("Ceremony param tests", function () { const ballotTree = new IncrementalQuinTree(params.stateTreeDepth, emptyBallot.hash(), STATE_TREE_ARITY, hash5); ballotTree.insert(emptyBallot.hash()); - for (let i = 0; i < poll.stateLeaves.length; i++) { + poll.stateLeaves.forEach(() => { ballotTree.insert(emptyBallotHash); - } + }); const currentStateRoot = maciState.stateTree.root; const currentBallotRoot = ballotTree.root; @@ -186,14 +188,14 @@ describe("Ceremony param tests", function () { }); }); - describe("TallyVotes circuit", function () { + describe("TallyVotes circuit", function test() { this.timeout(900000); - let circuit: tester.WasmTester; + let testCircuit: tester.WasmTester; before(async () => { const circuitPath = path.resolve(__dirname, "../../circom/test/ceremonyParams", `tallyVotes_test.circom`); - circuit = await tester.wasm(circuitPath); + testCircuit = await tester.wasm(circuitPath); }); describe("1 user, 2 messages", () => { @@ -204,7 +206,7 @@ describe("Ceremony param tests", function () { const voteWeight = BigInt(9); const voteOptionIndex = BigInt(0); - beforeEach(async () => { + beforeEach(() => { maciState = new MaciState(params.stateTreeDepth); const messages: Message[] = []; const commands: PCommand[] = []; @@ -262,8 +264,8 @@ describe("Ceremony param tests", function () { it("should produce the correct result commitments", async () => { const generatedInputs = poll.tallyVotes(); - const witness = await circuit.calculateWitness(generatedInputs); - await circuit.checkConstraints(witness); + const witness = await testCircuit.calculateWitness(generatedInputs); + await testCircuit.checkConstraints(witness); }); it("should produce the correct result if the inital tally is not zero", async () => { @@ -275,9 +277,9 @@ describe("Ceremony param tests", function () { randIdx = generateRandomIndex(Object.keys(generatedInputs).length); } - generatedInputs.currentResults[randIdx] = "1"; - const witness = await circuit.calculateWitness(generatedInputs); - await circuit.checkConstraints(witness); + (generatedInputs.currentResults as string[])[randIdx] = "1"; + const witness = await testCircuit.calculateWitness(generatedInputs); + await testCircuit.checkConstraints(witness); }); }); }); diff --git a/circuits/ts/__tests__/Ecdh.test.ts b/circuits/ts/__tests__/Ecdh.test.ts index c6e979bd15..4461c3bcdb 100644 --- a/circuits/ts/__tests__/Ecdh.test.ts +++ b/circuits/ts/__tests__/Ecdh.test.ts @@ -1,8 +1,10 @@ +import { expect } from "chai"; +import tester from "circom_tester"; import { stringifyBigInts } from "maci-crypto"; import { Keypair } from "maci-domainobjs"; + import path from "path"; -import tester from "circom_tester"; -import { expect } from "chai"; + import { getSignal } from "./utils/utils"; describe("Public key derivation circuit", () => { diff --git a/circuits/ts/__tests__/Hasher.test.ts b/circuits/ts/__tests__/Hasher.test.ts index 33c3434f6b..c566e37c37 100644 --- a/circuits/ts/__tests__/Hasher.test.ts +++ b/circuits/ts/__tests__/Hasher.test.ts @@ -1,11 +1,13 @@ -import { PCommand, Keypair } from "maci-domainobjs"; +import { expect } from "chai"; import tester from "circom_tester"; import { stringifyBigInts, genRandomSalt, sha256Hash, hashLeftRight, hash13, hash5, hash4, hash3 } from "maci-crypto"; +import { PCommand, Keypair } from "maci-domainobjs"; + import path from "path"; -import { expect } from "chai"; + import { getSignal } from "./utils/utils"; -describe("Poseidon hash circuits", function () { +describe("Poseidon hash circuits", function test() { this.timeout(30000); let circuit: tester.WasmTester; @@ -40,8 +42,8 @@ describe("Poseidon hash circuits", function () { }); it("correctly hashes 4 random values", async () => { - const preImages: any = []; - for (let i = 0; i < 4; i++) { + const preImages: bigint[] = []; + for (let i = 0; i < 4; i += 1) { preImages.push(genRandomSalt()); } @@ -65,8 +67,8 @@ describe("Poseidon hash circuits", function () { circuit = await tester.wasm(circuitPath); }); it("correctly hashes 6 random values", async () => { - const preImages: any = []; - for (let i = 0; i < 6; i++) { + const preImages: bigint[] = []; + for (let i = 0; i < 6; i += 1) { preImages.push(genRandomSalt()); } @@ -92,8 +94,8 @@ describe("Poseidon hash circuits", function () { circuit = await tester.wasm(circuitPath); }); it("correctly hashes 5 random values", async () => { - const preImages: any = []; - for (let i = 0; i < 5; i++) { + const preImages: bigint[] = []; + for (let i = 0; i < 5; i += 1) { preImages.push(genRandomSalt()); } @@ -116,9 +118,10 @@ describe("Poseidon hash circuits", function () { const circuitPath = path.resolve(__dirname, "../../circom/test", `hasher4_test.circom`); circuit = await tester.wasm(circuitPath); }); + it("correctly hashes 4 random values", async () => { - const preImages: any = []; - for (let i = 0; i < 4; i++) { + const preImages: bigint[] = []; + for (let i = 0; i < 4; i += 1) { preImages.push(genRandomSalt()); } @@ -143,8 +146,8 @@ describe("Poseidon hash circuits", function () { }); it("correctly hashes 3 random values", async () => { - const preImages: any = []; - for (let i = 0; i < 3; i++) { + const preImages: bigint[] = []; + for (let i = 0; i < 3; i += 1) { preImages.push(genRandomSalt()); } @@ -167,9 +170,10 @@ describe("Poseidon hash circuits", function () { const circuitPath = path.resolve(__dirname, "../../circom/test", `hasher13_test.circom`); circuit = await tester.wasm(circuitPath); }); + it("correctly hashes 13 random values", async () => { - const preImages: any = []; - for (let i = 0; i < 13; i++) { + const preImages: bigint[] = []; + for (let i = 0; i < 13; i += 1) { preImages.push(genRandomSalt()); } const circuitInputs = stringifyBigInts({ @@ -191,6 +195,7 @@ describe("Poseidon hash circuits", function () { const circuitPath = path.resolve(__dirname, "../../circom/test", `hashleftright_test.circom`); circuit = await tester.wasm(circuitPath); }); + it("correctly hashes two random values", async () => { const left = genRandomSalt(); const right = genRandomSalt(); @@ -213,11 +218,12 @@ describe("Poseidon hash circuits", function () { const circuitPath = path.resolve(__dirname, "../../circom/test", `messageHasher_test.circom`); circuit = await tester.wasm(circuitPath); }); + it("correctly hashes a message", async () => { const k = new Keypair(); - const random50bitBigInt = (): bigint => { - return ((BigInt(1) << BigInt(50)) - BigInt(1)) & BigInt(genRandomSalt().toString()); - }; + const random50bitBigInt = (): bigint => + // eslint-disable-next-line no-bitwise + ((BigInt(1) << BigInt(50)) - BigInt(1)) & BigInt(genRandomSalt().toString()); const command: PCommand = new PCommand( random50bitBigInt(), diff --git a/circuits/ts/__tests__/MessageToCommand.test.ts b/circuits/ts/__tests__/MessageToCommand.test.ts index 264eb81f74..4a5e6c6127 100644 --- a/circuits/ts/__tests__/MessageToCommand.test.ts +++ b/circuits/ts/__tests__/MessageToCommand.test.ts @@ -1,16 +1,20 @@ +import { expect } from "chai"; +import tester from "circom_tester"; import { stringifyBigInts, genRandomSalt } from "maci-crypto"; import { Keypair, PCommand } from "maci-domainobjs"; + import path from "path"; -import { expect } from "chai"; -import tester from "circom_tester"; + import { getSignal } from "./utils/utils"; describe("MessageToCommand circuit", () => { let circuit: tester.WasmTester; + before(async () => { const circuitPath = path.resolve(__dirname, "../../circom/test", `messageToCommand_test.circom`); circuit = await tester.wasm(circuitPath); }); + it("Should decrypt a Message and output the fields of a Command", async () => { const { privKey } = new Keypair(); const k = new Keypair(); @@ -20,9 +24,9 @@ describe("MessageToCommand circuit", () => { const newPubKey = k.pubKey; const ecdhSharedKey = Keypair.genEcdhSharedKey(privKey, pubKey1); - const random50bitBigInt = (): bigint => { - return ((BigInt(1) << BigInt(50)) - BigInt(1)) & BigInt(genRandomSalt().toString()); - }; + const random50bitBigInt = (): bigint => + // eslint-disable-next-line no-bitwise + ((BigInt(1) << BigInt(50)) - BigInt(1)) & BigInt(genRandomSalt().toString()); const command: PCommand = new PCommand( random50bitBigInt(), @@ -31,7 +35,7 @@ describe("MessageToCommand circuit", () => { random50bitBigInt(), random50bitBigInt(), random50bitBigInt(), - //genRandomSalt(), + // genRandomSalt(), BigInt(123), ); const signature = command.sign(privKey); diff --git a/circuits/ts/__tests__/MessageValidator.test.ts b/circuits/ts/__tests__/MessageValidator.test.ts index feadf563a1..978e08d213 100644 --- a/circuits/ts/__tests__/MessageValidator.test.ts +++ b/circuits/ts/__tests__/MessageValidator.test.ts @@ -1,14 +1,19 @@ +import { expect } from "chai"; +import tester from "circom_tester"; import { stringifyBigInts, genRandomSalt } from "maci-crypto"; import { PCommand, Keypair } from "maci-domainobjs"; + import path from "path"; -import { expect } from "chai"; -import tester from "circom_tester"; + +import type { CircuitInputs } from "maci-core"; + import { getSignal } from "./utils/utils"; -describe("MessageValidator circuit", function () { +describe("MessageValidator circuit", function test() { this.timeout(90000); - let circuitInputs; + let circuitInputs: CircuitInputs; let circuit: tester.WasmTester; + before(async () => { const circuitPath = path.resolve(__dirname, "../../circom/test", `messageValidator_test.circom`); circuit = await tester.wasm(circuitPath); @@ -46,7 +51,7 @@ describe("MessageValidator circuit", function () { voteWeight: 9, slTimestamp: 1, pollEndTimestamp: 2, - }); + }) as CircuitInputs; }); it("Should pass if all inputs are valid", async () => { @@ -67,7 +72,7 @@ describe("MessageValidator circuit", function () { it("Should be invalid if the pubkey is invalid", async () => { const circuitInputs2 = circuitInputs; - circuitInputs2.pubKey = [0, 1]; + circuitInputs2.pubKey = [0n, 1n]; const witness = await circuit.calculateWitness(circuitInputs2, true); await circuit.checkConstraints(witness); const isValid = await getSignal(circuit, witness, "isValid"); @@ -76,7 +81,7 @@ describe("MessageValidator circuit", function () { it("Should be invalid if there are insufficient voice credits", async () => { const circuitInputs2 = circuitInputs; - circuitInputs2.voteWeight = 11; + circuitInputs2.voteWeight = 11n; const witness = await circuit.calculateWitness(circuitInputs2, true); await circuit.checkConstraints(witness); const isValid = await getSignal(circuit, witness, "isValid"); @@ -85,7 +90,7 @@ describe("MessageValidator circuit", function () { it("Should be invalid if the nonce is invalid", async () => { const circuitInputs2 = circuitInputs; - circuitInputs2.nonce = 3; + circuitInputs2.nonce = 3n; const witness = await circuit.calculateWitness(circuitInputs2, true); await circuit.checkConstraints(witness); const isValid = await getSignal(circuit, witness, "isValid"); @@ -94,7 +99,7 @@ describe("MessageValidator circuit", function () { it("Should be invalid if the state leaf index is invalid", async () => { const circuitInputs2 = circuitInputs; - circuitInputs2.stateTreeIndex = 2; + circuitInputs2.stateTreeIndex = 2n; const witness = await circuit.calculateWitness(circuitInputs2, true); await circuit.checkConstraints(witness); const isValid = await getSignal(circuit, witness, "isValid"); @@ -103,7 +108,7 @@ describe("MessageValidator circuit", function () { it("Should be invalid if the vote option index is invalid", async () => { const circuitInputs2 = circuitInputs; - circuitInputs2.voteOptionIndex = 1; + circuitInputs2.voteOptionIndex = 1n; const witness = await circuit.calculateWitness(circuitInputs2, true); await circuit.checkConstraints(witness); const isValid = await getSignal(circuit, witness, "isValid"); diff --git a/circuits/ts/__tests__/PrivToPubKey.test.ts b/circuits/ts/__tests__/PrivToPubKey.test.ts index cb144fa4de..b14c00423d 100644 --- a/circuits/ts/__tests__/PrivToPubKey.test.ts +++ b/circuits/ts/__tests__/PrivToPubKey.test.ts @@ -1,13 +1,16 @@ -import { Keypair } from "maci-domainobjs"; -import { stringifyBigInts } from "maci-crypto"; -import path from "path"; import { expect } from "chai"; import tester from "circom_tester"; +import { stringifyBigInts } from "maci-crypto"; +import { Keypair } from "maci-domainobjs"; + +import path from "path"; + import { getSignal } from "./utils/utils"; -describe("Public key derivation circuit", function () { +describe("Public key derivation circuit", function test() { this.timeout(90000); let circuit: tester.WasmTester; + before(async () => { const circuitPath = path.resolve(__dirname, "../../circom/test", `privToPubKey_test.circom`); circuit = await tester.wasm(circuitPath); diff --git a/circuits/ts/__tests__/ProcessMessages.test.ts b/circuits/ts/__tests__/ProcessMessages.test.ts index 0f04b32ef7..0f4ff90665 100644 --- a/circuits/ts/__tests__/ProcessMessages.test.ts +++ b/circuits/ts/__tests__/ProcessMessages.test.ts @@ -1,13 +1,15 @@ +import { expect } from "chai"; +import tester from "circom_tester"; import { MaciState, Poll, packProcessMessageSmallVals, STATE_TREE_ARITY } from "maci-core"; -import { PrivKey, Keypair, PCommand, Message, Ballot } from "maci-domainobjs"; import { hash5, IncrementalQuinTree, stringifyBigInts, NOTHING_UP_MY_SLEEVE, AccQueue } from "maci-crypto"; +import { PrivKey, Keypair, PCommand, Message, Ballot } from "maci-domainobjs"; + import path from "path"; -import { expect } from "chai"; -import tester from "circom_tester"; -import { getSignal } from "./utils/utils"; + import { STATE_TREE_DEPTH } from "./utils/constants"; +import { getSignal } from "./utils/utils"; -describe("ProcessMessage circuit", function () { +describe("ProcessMessage circuit", function test() { this.timeout(900000); const voiceCreditBalance = BigInt(100); @@ -48,7 +50,7 @@ describe("ProcessMessage circuit", function () { const messages: Message[] = []; const commands: PCommand[] = []; - before(async () => { + before(() => { // Sign up and publish const userKeypair = new Keypair(new PrivKey(BigInt(1))); stateIndex = BigInt( @@ -72,7 +74,7 @@ describe("ProcessMessage circuit", function () { // First command (valid) const command = new PCommand( - stateIndex, //BigInt(1), + stateIndex, // BigInt(1), userKeypair.pubKey, voteOptionIndex, // voteOptionIndex, voteWeight, // vote weight @@ -131,9 +133,10 @@ describe("ProcessMessage circuit", function () { ballotTree.insert(emptyBallot.hash()); - for (let i = 0; i < poll.stateLeaves.length; i++) { + poll.stateLeaves.forEach(() => { ballotTree.insert(emptyBallotHash); - } + }); + const currentStateRoot = maciState.stateTree.root; const currentBallotRoot = ballotTree.root; @@ -182,7 +185,7 @@ describe("ProcessMessage circuit", function () { const messages: Message[] = []; const commands: PCommand[] = []; - before(async () => { + before(() => { // Sign up and publish const userKeypair = new Keypair(new PrivKey(BigInt(123))); const userKeypair2 = new Keypair(new PrivKey(BigInt(456))); @@ -190,16 +193,16 @@ describe("ProcessMessage circuit", function () { maciState.signUp( userKeypair.pubKey, voiceCreditBalance, - BigInt(1), //BigInt(Math.floor(Date.now() / 1000)), + BigInt(1), // BigInt(Math.floor(Date.now() / 1000)), ); maciState.signUp( userKeypair2.pubKey, voiceCreditBalance, - BigInt(1), //BigInt(Math.floor(Date.now() / 1000)), + BigInt(1), // BigInt(Math.floor(Date.now() / 1000)), ); pollId = maciState.deployPoll( - BigInt(2 + duration), //BigInt(Math.floor(Date.now() / 1000) + duration), + BigInt(2 + duration), // BigInt(Math.floor(Date.now() / 1000) + duration), maxValues, treeDepths, messageBatchSize, @@ -238,7 +241,7 @@ describe("ProcessMessage circuit", function () { accumulatorQueue.merge(treeDepths.messageTreeDepth); expect(poll.messageTree.root.toString()).to.be.eq( - accumulatorQueue.getRoot(treeDepths.messageTreeDepth).toString(), + accumulatorQueue.getRoot(treeDepths.messageTreeDepth)?.toString(), ); }); @@ -250,9 +253,10 @@ describe("ProcessMessage circuit", function () { ballotTree.insert(emptyBallot.hash()); - for (let i = 0; i < poll.stateLeaves.length; i++) { + poll.stateLeaves.forEach(() => { ballotTree.insert(emptyBallotHash); - } + }); + const currentStateRoot = maciState.stateTree.root; const currentBallotRoot = ballotTree.root; @@ -281,7 +285,7 @@ describe("ProcessMessage circuit", function () { const messages: Message[] = []; const commands: PCommand[] = []; - before(async () => { + before(() => { // Sign up and publish const userKeypair = new Keypair(new PrivKey(BigInt(123))); const userKeypair2 = new Keypair(new PrivKey(BigInt(456))); @@ -289,11 +293,11 @@ describe("ProcessMessage circuit", function () { stateIndex = maciState.signUp( userKeypair.pubKey, voiceCreditBalance, - BigInt(1), //BigInt(Math.floor(Date.now() / 1000)), + BigInt(1), // BigInt(Math.floor(Date.now() / 1000)), ); pollId = maciState.deployPoll( - BigInt(2 + duration), //BigInt(Math.floor(Date.now() / 1000) + duration), + BigInt(2 + duration), // BigInt(Math.floor(Date.now() / 1000) + duration), maxValues, treeDepths, messageBatchSize, @@ -304,7 +308,7 @@ describe("ProcessMessage circuit", function () { // Vote for option 0 const command = new PCommand( - stateIndex, //BigInt(1), + BigInt(stateIndex), // BigInt(1), userKeypair.pubKey, BigInt(0), // voteOptionIndex, voteWeight, // vote weight @@ -324,7 +328,7 @@ describe("ProcessMessage circuit", function () { // Vote for option 1 const command2 = new PCommand( - stateIndex, + BigInt(stateIndex), userKeypair2.pubKey, BigInt(1), // voteOptionIndex, voteWeight, // vote weight @@ -342,7 +346,7 @@ describe("ProcessMessage circuit", function () { // Change key const command3 = new PCommand( - stateIndex, //BigInt(1), + BigInt(stateIndex), // BigInt(1), userKeypair2.pubKey, BigInt(1), // voteOptionIndex, BigInt(0), // vote weight @@ -371,23 +375,19 @@ describe("ProcessMessage circuit", function () { accumulatorQueue.merge(treeDepths.messageTreeDepth); expect(poll.messageTree.root.toString()).to.be.eq( - accumulatorQueue.getRoot(treeDepths.messageTreeDepth).toString(), + accumulatorQueue.getRoot(treeDepths.messageTreeDepth)?.toString(), ); }); const NUM_BATCHES = 2; describe(`1 user, ${messageBatchSize * NUM_BATCHES} messages`, () => { it("should produce the correct state root and ballot root", async () => { - const maciState = new MaciState(STATE_TREE_DEPTH); + const state = new MaciState(STATE_TREE_DEPTH); const userKeypair = new Keypair(); - const stateIndex = maciState.signUp( - userKeypair.pubKey, - voiceCreditBalance, - BigInt(Math.floor(Date.now() / 1000)), - ); + const index = state.signUp(userKeypair.pubKey, voiceCreditBalance, BigInt(Math.floor(Date.now() / 1000))); // Sign up and publish - const pollId = maciState.deployPoll( + const id = state.deployPoll( BigInt(Math.floor(Date.now() / 1000) + duration), maxValues, treeDepths, @@ -395,18 +395,18 @@ describe("ProcessMessage circuit", function () { coordinatorKeypair, ); - const poll = maciState.polls[pollId]; + const selectedPoll = state.polls[id]; // Second batch is not a full batch const numMessages = messageBatchSize * NUM_BATCHES - 1; - for (let i = 0; i < numMessages; i++) { + for (let i = 0; i < numMessages; i += 1) { const command = new PCommand( - BigInt(stateIndex), + BigInt(index), userKeypair.pubKey, - BigInt(i), //vote option index + BigInt(i), // vote option index BigInt(1), // vote weight BigInt(numMessages - i), // nonce - BigInt(pollId), + BigInt(id), ); const signature = command.sign(userKeypair.privKey); @@ -414,12 +414,14 @@ describe("ProcessMessage circuit", function () { const ecdhKeypair = new Keypair(); const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); const message = command.encrypt(signature, sharedKey); - poll.publishMessage(message, ecdhKeypair.pubKey); + selectedPoll.publishMessage(message, ecdhKeypair.pubKey); } - for (let i = 0; i < NUM_BATCHES; i++) { - const generatedInputs = poll.processMessages(pollId); + for (let i = 0; i < NUM_BATCHES; i += 1) { + const generatedInputs = selectedPoll.processMessages(id); + // eslint-disable-next-line no-await-in-loop const witness = await circuit.calculateWitness(generatedInputs, true); + // eslint-disable-next-line no-await-in-loop await circuit.checkConstraints(witness); } }); diff --git a/circuits/ts/__tests__/Splicer.test.ts b/circuits/ts/__tests__/Splicer.test.ts index 53e7f83088..9250cfc18d 100644 --- a/circuits/ts/__tests__/Splicer.test.ts +++ b/circuits/ts/__tests__/Splicer.test.ts @@ -1,7 +1,9 @@ -import { stringifyBigInts } from "maci-crypto"; -import path from "path"; import { expect } from "chai"; import tester from "circom_tester"; +import { stringifyBigInts } from "maci-crypto"; + +import path from "path"; + import { getSignal } from "./utils/utils"; describe("Splice circuit", () => { @@ -12,16 +14,19 @@ describe("Splice circuit", () => { }); it("Should output the correct reconstructed level", async () => { - for (let index = 0; index < 5; index++) { + for (let index = 0; index < 5; index += 1) { const items = [0, 20, 30, 40]; const leaf = 10; const circuitInputs = stringifyBigInts({ in: items, leaf, index }); + // eslint-disable-next-line no-await-in-loop const witness = await circuit.calculateWitness(circuitInputs); + // eslint-disable-next-line no-await-in-loop await circuit.checkConstraints(witness); const output: bigint[] = []; - for (let i = 0; i < items.length + 1; i++) { + for (let i = 0; i < items.length + 1; i += 1) { + // eslint-disable-next-line no-await-in-loop const selected = await getSignal(circuit, witness, `out[${i}]`); output.push(BigInt(selected)); } diff --git a/circuits/ts/__tests__/StateLeafAndBallotTransformer.test.ts b/circuits/ts/__tests__/StateLeafAndBallotTransformer.test.ts index 8619796f79..59cfb61485 100644 --- a/circuits/ts/__tests__/StateLeafAndBallotTransformer.test.ts +++ b/circuits/ts/__tests__/StateLeafAndBallotTransformer.test.ts @@ -1,11 +1,13 @@ +import { expect } from "chai"; +import tester from "circom_tester"; import { stringifyBigInts, genRandomSalt } from "maci-crypto"; import { PCommand, Keypair } from "maci-domainobjs"; + import path from "path"; -import { expect } from "chai"; -import tester from "circom_tester"; + import { getSignal } from "./utils/utils"; -describe("StateLeafAndBallotTransformer circuit", function () { +describe("StateLeafAndBallotTransformer circuit", function test() { this.timeout(90000); // variables needed for testing diff --git a/circuits/ts/__tests__/TallyVotes.test.ts b/circuits/ts/__tests__/TallyVotes.test.ts index 0e665147e9..60683417c4 100644 --- a/circuits/ts/__tests__/TallyVotes.test.ts +++ b/circuits/ts/__tests__/TallyVotes.test.ts @@ -1,14 +1,15 @@ +import { expect } from "chai"; +import tester from "circom_tester"; import { MaciState, Poll, STATE_TREE_ARITY } from "maci-core"; +import { AccQueue, NOTHING_UP_MY_SLEEVE } from "maci-crypto"; import { Keypair, PCommand, Message } from "maci-domainobjs"; + import path from "path"; -import { expect } from "chai"; -import { beforeEach } from "mocha"; -import tester from "circom_tester"; + import { STATE_TREE_DEPTH } from "./utils/constants"; import { generateRandomIndex } from "./utils/utils"; -import { AccQueue, NOTHING_UP_MY_SLEEVE } from "maci-crypto"; -describe("TallyVotes circuit", function () { +describe("TallyVotes circuit", function test() { this.timeout(900000); const voiceCreditBalance = BigInt(100); @@ -45,7 +46,7 @@ describe("TallyVotes circuit", function () { const voteWeight = BigInt(9); const voteOptionIndex = BigInt(0); - beforeEach(async () => { + beforeEach(() => { maciState = new MaciState(STATE_TREE_DEPTH); const messages: Message[] = []; const commands: PCommand[] = []; @@ -116,7 +117,7 @@ describe("TallyVotes circuit", function () { randIdx = generateRandomIndex(Object.keys(generatedInputs).length); } - generatedInputs.currentResults[randIdx] = "1"; + (generatedInputs.currentResults as string[])[randIdx] = "1"; const witness = await circuit.calculateWitness(generatedInputs); await circuit.checkConstraints(witness); }); @@ -129,7 +130,7 @@ describe("TallyVotes circuit", function () { it("should produce the correct state root and ballot root", async () => { const maciState = new MaciState(STATE_TREE_DEPTH); const userKeypairs: Keypair[] = []; - for (let i = 0; i < x; i++) { + for (let i = 0; i < x; i += 1) { const k = new Keypair(); userKeypairs.push(k); maciState.signUp(k.pubKey, voiceCreditBalance, BigInt(Math.floor(Date.now() / 1000) + duration)); @@ -146,11 +147,11 @@ describe("TallyVotes circuit", function () { const poll = maciState.polls[pollId]; const numMessages = messageBatchSize * NUM_BATCHES; - for (let i = 0; i < numMessages; i++) { + for (let i = 0; i < numMessages; i += 1) { const command = new PCommand( BigInt(i), userKeypairs[i].pubKey, - BigInt(i), //vote option index + BigInt(i), // vote option index BigInt(1), // vote weight BigInt(1), // nonce BigInt(pollId), @@ -164,21 +165,25 @@ describe("TallyVotes circuit", function () { poll.publishMessage(message, ecdhKeypair.pubKey); } - for (let i = 0; i < NUM_BATCHES; i++) poll.processMessages(pollId); + for (let i = 0; i < NUM_BATCHES; i += 1) { + poll.processMessages(pollId); + } - for (let i = 0; i < NUM_BATCHES; i++) { + for (let i = 0; i < NUM_BATCHES; i += 1) { const generatedInputs = poll.tallyVotes(); // For the 0th batch, the circuit should ignore currentResults, // currentSpentVoiceCreditSubtotal, and // currentPerVOSpentVoiceCredits if (i === 0) { - generatedInputs.currentResults[0] = "123"; + (generatedInputs.currentResults as string[])[0] = "123"; generatedInputs.currentSpentVoiceCreditSubtotal = "456"; - generatedInputs.currentPerVOSpentVoiceCredits[0] = "789"; + (generatedInputs.currentPerVOSpentVoiceCredits as string[])[0] = "789"; } + // eslint-disable-next-line no-await-in-loop const witness = await circuit.calculateWitness(generatedInputs); + // eslint-disable-next-line no-await-in-loop await circuit.checkConstraints(witness); } }); diff --git a/circuits/ts/__tests__/UnpackElement.test.ts b/circuits/ts/__tests__/UnpackElement.test.ts index 18a6d4cd55..972d7bf7f2 100644 --- a/circuits/ts/__tests__/UnpackElement.test.ts +++ b/circuits/ts/__tests__/UnpackElement.test.ts @@ -1,7 +1,9 @@ -import { genRandomSalt, stringifyBigInts } from "maci-crypto"; import { expect } from "chai"; import tester from "circom_tester"; +import { genRandomSalt, stringifyBigInts } from "maci-crypto"; + import path from "path"; + import { getSignal } from "./utils/utils"; describe("UnpackElement circuit", () => { @@ -15,24 +17,25 @@ describe("UnpackElement circuit", () => { it("Should unpack a field element with 5 packed values correctly", async () => { const elements: string[] = []; - for (let i = 0; i < 5; i++) { + for (let i = 0; i < 5; i += 1) { let e = (BigInt(genRandomSalt().toString()) % BigInt(2 ** 50)).toString(2); while (e.length < 50) { - e = "0" + e; + e = `0${e}`; } elements.push(e); } const circuitInputs = stringifyBigInts({ - in: BigInt("0b" + elements.join("")), + in: BigInt(`0b${elements.join("")}`), }); const witness = await circuit.calculateWitness(circuitInputs); await circuit.checkConstraints(witness); - for (let i = 0; i < 5; i++) { + for (let i = 0; i < 5; i += 1) { + // eslint-disable-next-line no-await-in-loop const out = await getSignal(circuit, witness, `out[${i}]`); - expect(BigInt("0b" + BigInt(out).toString(2)).toString()).to.be.eq(BigInt("0b" + elements[i]).toString()); + expect(BigInt(`0b${BigInt(out).toString(2)}`).toString()).to.be.eq(BigInt(`0b${elements[i]}`).toString()); } }); }); @@ -45,24 +48,25 @@ describe("UnpackElement circuit", () => { it("Should unpack a field element with 4 packed values correctly", async () => { const elements: string[] = []; - for (let i = 0; i < 4; i++) { + for (let i = 0; i < 4; i += 1) { let e = (BigInt(genRandomSalt().toString()) % BigInt(2 ** 50)).toString(2); while (e.length < 50) { - e = "0" + e; + e = `0${e}`; } elements.push(e); } const circuitInputs = stringifyBigInts({ - in: BigInt("0b" + elements.join("")), + in: BigInt(`0b${elements.join("")}`), }); const witness = await circuit.calculateWitness(circuitInputs); await circuit.checkConstraints(witness); - for (let i = 0; i < 4; i++) { + for (let i = 0; i < 4; i += 1) { + // eslint-disable-next-line no-await-in-loop const out = await getSignal(circuit, witness, `out[${i}]`); - expect(BigInt("0b" + BigInt(out).toString(2)).toString()).to.be.eq(BigInt("0b" + elements[i]).toString()); + expect(BigInt(`0b${BigInt(out).toString(2)}`).toString()).to.be.eq(BigInt(`0b${elements[i]}`).toString()); } }); }); diff --git a/circuits/ts/__tests__/VerifySignature.test.ts b/circuits/ts/__tests__/VerifySignature.test.ts index 010a059ac3..f18a42f7c7 100644 --- a/circuits/ts/__tests__/VerifySignature.test.ts +++ b/circuits/ts/__tests__/VerifySignature.test.ts @@ -1,11 +1,13 @@ +import { expect } from "chai"; +import tester from "circom_tester"; import { stringifyBigInts, verifySignature, hash4 } from "maci-crypto"; import { Keypair, PCommand } from "maci-domainobjs"; + import path from "path"; -import { expect } from "chai"; -import tester from "circom_tester"; + import { getSignal } from "./utils/utils"; -describe("Signature verification circuit", function () { +describe("Signature verification circuit", function test() { this.timeout(90000); let circuit: tester.WasmTester; @@ -22,7 +24,7 @@ describe("Signature verification circuit", function () { const sig = command.sign(signer.privKey); const plaintext = hash4(command.asArray()); - expect(verifySignature(plaintext, sig, signer.pubKey.rawPubKey)).to.be.true; + expect(verifySignature(plaintext, sig, signer.pubKey.rawPubKey)).to.eq(true); const circuitInputs = stringifyBigInts({ pubKey: signer.pubKey.asCircuitInputs(), @@ -51,10 +53,10 @@ describe("Signature verification circuit", function () { const plaintext = hash4(command.asArray()); // The signature is signed by `signer` - expect(verifySignature(plaintext, sig, signer.pubKey.rawPubKey)).to.be.true; + expect(verifySignature(plaintext, sig, signer.pubKey.rawPubKey)).to.eq(true); // The signature is not signed by `wrongSigner` - expect(verifySignature(plaintext, sig, wrongSigner.pubKey.rawPubKey)).to.be.false; + expect(verifySignature(plaintext, sig, wrongSigner.pubKey.rawPubKey)).to.eq(false); const circuitInputs = stringifyBigInts({ pubKey: wrongSigner.pubKey.asCircuitInputs(), @@ -78,7 +80,7 @@ describe("Signature verification circuit", function () { const sig = command.sign(signer.privKey); const plaintext = hash4(command.asArray()); - expect(verifySignature(plaintext, sig, signer.pubKey.rawPubKey)).to.be.true; + expect(verifySignature(plaintext, sig, signer.pubKey.rawPubKey)).to.eq(true); const circuitInputs = stringifyBigInts({ pubKey: signer.pubKey.asCircuitInputs(), @@ -87,7 +89,7 @@ describe("Signature verification circuit", function () { preimage: command.asCircuitInputs(), }); - expect(verifySignature(plaintext, sig, signer.pubKey.rawPubKey)).to.be.true; + expect(verifySignature(plaintext, sig, signer.pubKey.rawPubKey)).to.eq(true); const witness = await circuit.calculateWitness(circuitInputs); await circuit.checkConstraints(witness); diff --git a/circuits/ts/__tests__/utils/utils.ts b/circuits/ts/__tests__/utils/utils.ts index a494c9d53a..6585002a12 100644 --- a/circuits/ts/__tests__/utils/utils.ts +++ b/circuits/ts/__tests__/utils/utils.ts @@ -1,13 +1,11 @@ -import { WasmTester } from "circom_tester"; +import type { WasmTester } from "circom_tester"; /** * Convert a string to a bigint * @param s - the string to convert * @returns the bigint representation of the string */ -export const str2BigInt = (s: string): bigint => { - return BigInt(parseInt(Buffer.from(s).toString("hex"), 16)); -}; +export const str2BigInt = (s: string): bigint => BigInt(parseInt(Buffer.from(s).toString("hex"), 16)); // @note thanks https://github.com/Rate-Limiting-Nullifier/circom-rln/blob/main/test/utils.ts // for the code below @@ -39,6 +37,4 @@ export const getSignal = async (wasmTester: WasmTester, witness: bigint[], name: * @param upper - the upper bound * @returns the random index */ -export const generateRandomIndex = (upper: number): number => { - return Math.floor(Math.random() * (upper - 1)); -}; +export const generateRandomIndex = (upper: number): number => Math.floor(Math.random() * (upper - 1)); diff --git a/circuits/ts/proofs.ts b/circuits/ts/proofs.ts index 91fd88a74e..55acb8a929 100644 --- a/circuits/ts/proofs.ts +++ b/circuits/ts/proofs.ts @@ -1,11 +1,13 @@ -import { readFileSync, writeFileSync, unlinkSync, existsSync, mkdirSync, rmdirSync } from "fs"; -import path from "path"; +import { stringifyBigInts } from "maci-crypto"; +import { zKey, groth16, FullProveResult, PublicSignals, Groth16Proof, ISnarkJSVerificationKey } from "snarkjs"; + import { execSync } from "child_process"; +import fs from "fs"; import { tmpdir } from "os"; -import { zKey, groth16, FullProveResult, PublicSignals, Groth16Proof, ISnarkJSVerificationKey } from "snarkjs"; -import { stringifyBigInts } from "maci-crypto"; -import { cleanThreads, isArm } from "./utils"; +import path from "path"; + import { IGenProofOptions } from "./types"; +import { cleanThreads, isArm } from "./utils"; /** * Generate a zk-SNARK proof @@ -30,13 +32,13 @@ export const genProof = async ({ }: IGenProofOptions): Promise => { // if we are running on an arm chip we can use snarkjs directly if (isArm()) { - const { proof, publicSignals } = await groth16.fullProve(inputs, wasmPath, zkeyPath); + const { proof, publicSignals } = await groth16.fullProve(inputs, wasmPath!, zkeyPath); return { proof, publicSignals }; } // intel chip flow (use rapidnsark) // Create tmp directory const tmpPath = path.resolve(tmpdir(), `tmp-${Date.now()}`); - mkdirSync(tmpPath, { recursive: true }); + fs.mkdirSync(tmpPath, { recursive: true }); const inputJsonPath = path.resolve(tmpPath, "input.json"); const outputWtnsPath = path.resolve(tmpPath, "output.wtns"); @@ -45,15 +47,15 @@ export const genProof = async ({ // Write input.json const jsonData = JSON.stringify(stringifyBigInts(inputs)); - writeFileSync(inputJsonPath, jsonData); + fs.writeFileSync(inputJsonPath, jsonData); // Generate the witness const witnessGenCmd = `${witnessExePath} ${inputJsonPath} ${outputWtnsPath}`; execSync(witnessGenCmd, { stdio: silent ? "ignore" : "pipe" }); - if (!existsSync(outputWtnsPath)) { - throw new Error("Error executing " + witnessGenCmd); + if (!fs.existsSync(outputWtnsPath)) { + throw new Error(`Error executing ${witnessGenCmd}`); } // Generate the proof @@ -61,19 +63,23 @@ export const genProof = async ({ execSync(proofGenCmd, { stdio: silent ? "ignore" : "pipe" }); - if (!existsSync(proofJsonPath)) { - throw new Error("Error executing " + proofGenCmd); + if (!fs.existsSync(proofJsonPath)) { + throw new Error(`Error executing ${proofGenCmd}`); } // Read the proof and public inputs - const proof = JSON.parse(readFileSync(proofJsonPath).toString()) as Groth16Proof; - const publicSignals = JSON.parse(readFileSync(publicJsonPath).toString()) as PublicSignals; + const proof = JSON.parse(fs.readFileSync(proofJsonPath).toString()) as Groth16Proof; + const publicSignals = JSON.parse(fs.readFileSync(publicJsonPath).toString()) as PublicSignals; // remove all artifacts - for (const f of [proofJsonPath, publicJsonPath, inputJsonPath, outputWtnsPath]) if (existsSync(f)) unlinkSync(f); + [proofJsonPath, publicJsonPath, inputJsonPath, outputWtnsPath].forEach((f) => { + if (fs.existsSync(f)) { + fs.unlinkSync(f); + } + }); // remove tmp directory - rmdirSync(tmpPath); + fs.rmdirSync(tmpPath); return { proof, publicSignals }; }; diff --git a/circuits/ts/types.ts b/circuits/ts/types.ts index b34ebabdd2..ae1c2f863e 100644 --- a/circuits/ts/types.ts +++ b/circuits/ts/types.ts @@ -1,4 +1,4 @@ -import { CircuitInputs } from "maci-core"; +import type { CircuitInputs } from "maci-core"; /** * Parameters for the genProof function diff --git a/circuits/ts/types/circom_tester.d.ts b/circuits/ts/types/circom_tester.d.ts index 85076445f1..329981d923 100644 --- a/circuits/ts/types/circom_tester.d.ts +++ b/circuits/ts/types/circom_tester.d.ts @@ -21,21 +21,23 @@ declare module "circom_tester" { componentIdx: number; } - interface Symbols { - [key: string]: CircuitSymbol; - } + type Symbols = Record; interface WitnessCalculator { - calculateWitness(input: any, sanityCheck?: boolean): Promise; + calculateWitness(input: unknown, sanityCheck?: boolean): Promise; } class WasmTester { constructor(dir: string, baseName: string, witnessCalculator: WitnessCalculator); + symbols: Symbols; + calculateWitness(input: unknown, sanityCheck?: boolean): Promise; + loadSymbols(): Promise; + checkConstraints(witness: bigint[]): Promise; } - export function wasm(circomInput: string, _options?: Options): Promise; + export function wasm(circomInput: string, options?: Options): Promise; } diff --git a/circuits/ts/types/snarkjs.d.ts b/circuits/ts/types/snarkjs.d.ts index 6783c946c3..19cb66ae44 100644 --- a/circuits/ts/types/snarkjs.d.ts +++ b/circuits/ts/types/snarkjs.d.ts @@ -1,5 +1,5 @@ declare module "snarkjs" { - export type NumericString = `${number}` | string; + export type NumericString = string; export type PublicSignals = Record; export type BigNumberish = number | string | bigint; @@ -29,7 +29,7 @@ declare module "snarkjs" { } export namespace zKey { - function exportVerificationKey(zkeyName: string, logger?: any): Promise; + function exportVerificationKey(zkeyName: string, logger?: unknown): Promise; } export namespace groth16 { @@ -37,13 +37,14 @@ declare module "snarkjs" { vk_verifier: ISnarkJSVerificationKey, publicSignals: PublicSignals, proof: Groth16Proof, - logger?: any, + logger?: unknown, ): Promise; + function fullProve( input: PublicSignals, wasmFile: string, zkeyFileName: string, - logger?: any, + logger?: unknown, ): Promise; } } diff --git a/circuits/ts/utils.ts b/circuits/ts/utils.ts index a80d9ea975..31a24837b9 100644 --- a/circuits/ts/utils.ts +++ b/circuits/ts/utils.ts @@ -1,24 +1,35 @@ -import { arch } from "os"; +import os from "os"; + +declare global { + interface ITerminatable { + terminate: () => Promise; + } + + // eslint-disable-next-line vars-on-top, no-var, camelcase + var curve_bn128: ITerminatable | undefined; + + // eslint-disable-next-line vars-on-top, no-var, camelcase + var curve_bls12381: ITerminatable | undefined; +} /** * Check if we are running on an arm chip * @returns whether we are running on an arm chip */ -export const isArm = (): boolean => { - return arch().includes("arm"); -}; +export const isArm = (): boolean => os.arch().includes("arm"); /* * https://github.com/iden3/snarkjs/issues/152 * Need to cleanup the threads to avoid stalling */ -export const cleanThreads = async () => { +export const cleanThreads = async (): Promise => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (!globalThis) { - return Promise.resolve(true); + return; } const curves = ["curve_bn128", "curve_bls12381"]; - const promises = Promise.all(curves.map((curve) => globalThis[curve]?.terminate?.()).filter(Boolean)); - - return promises; + await Promise.all( + curves.map((curve) => globalThis[curve as "curve_bn128" | "curve_bls12381"]?.terminate()).filter(Boolean), + ); }; diff --git a/circuits/tsconfig.json b/circuits/tsconfig.json index 1243fccb26..cba918a45a 100644 --- a/circuits/tsconfig.json +++ b/circuits/tsconfig.json @@ -1,7 +1,33 @@ { "extends": "../tsconfig.json", "compilerOptions": { - "outDir": "./build" + "outDir": "./build", + "declaration": true, + "allowJs": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "target": "ES2020", + "lib": ["es2020"], + "experimentalDecorators": true, + "strict": true, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "strictPropertyInitialization": true, + "strictNullChecks": true, + "module": "commonjs", + "moduleResolution": "node", + "resolveJsonModule": true, + "skipLibCheck": true, + "esModuleInterop": true, + "isolatedModules": true, + "forceConsistentCasingInFileNames": true, + "allowSyntheticDefaultImports": true, + "composite": true, + "incremental": true, + "declarationMap": true, + "sourceMap": true, + "stripInternal": true }, "include": ["./ts"] } From 614e76b1b1de5d2c9876b11f15439e92b86db8f6 Mon Sep 17 00:00:00 2001 From: 0xmad <0xmad@users.noreply.github.com> Date: Tue, 2 Jan 2024 14:34:28 -0600 Subject: [PATCH 14/37] chore(core): integrate linter - [x] Apply linter and type fixes - [x] Dependency management --- circuits/ts/__tests__/CeremonyParams.test.ts | 8 +- circuits/ts/__tests__/ProcessMessages.test.ts | 16 +- core/.eslintrc.js | 107 + core/package-lock.json | 8059 +++++++++++++---- core/package.json | 7 +- core/ts/MaciState.ts | 49 +- core/ts/Poll.ts | 374 +- core/ts/__tests__/MaciState.test.ts | 116 +- core/ts/__tests__/ProcessMessage.test.ts | 20 - core/ts/index.ts | 2 +- core/ts/utils/types.ts | 8 +- core/ts/utils/utils.ts | 69 +- core/tsconfig.json | 28 +- 13 files changed, 6912 insertions(+), 1951 deletions(-) create mode 100644 core/.eslintrc.js delete mode 100644 core/ts/__tests__/ProcessMessage.test.ts diff --git a/circuits/ts/__tests__/CeremonyParams.test.ts b/circuits/ts/__tests__/CeremonyParams.test.ts index 5ed90a29b5..9dc8ba2609 100644 --- a/circuits/ts/__tests__/CeremonyParams.test.ts +++ b/circuits/ts/__tests__/CeremonyParams.test.ts @@ -158,11 +158,11 @@ describe("Ceremony param tests", () => { // The new roots, which should differ, since at least one of the // messages modified a Ballot or State Leaf - const newStateRoot = poll.stateTree.root; - const newBallotRoot = poll.ballotTree.root; + const newStateRoot = poll.stateTree?.root; + const newBallotRoot = poll.ballotTree?.root; - expect(newStateRoot.toString()).not.to.be.eq(currentStateRoot.toString()); - expect(newBallotRoot.toString()).not.to.be.eq(currentBallotRoot.toString()); + expect(newStateRoot?.toString()).not.to.be.eq(currentStateRoot.toString()); + expect(newBallotRoot?.toString()).not.to.be.eq(currentBallotRoot.toString()); const packedVals = packProcessMessageSmallVals( BigInt(maxValues.maxVoteOptions), diff --git a/circuits/ts/__tests__/ProcessMessages.test.ts b/circuits/ts/__tests__/ProcessMessages.test.ts index 0f4ff90665..e76cd69a53 100644 --- a/circuits/ts/__tests__/ProcessMessages.test.ts +++ b/circuits/ts/__tests__/ProcessMessages.test.ts @@ -148,11 +148,11 @@ describe("ProcessMessage circuit", function test() { // The new roots, which should differ, since at least one of the // messages modified a Ballot or State Leaf - const newStateRoot = poll.stateTree.root; - const newBallotRoot = poll.ballotTree.root; + const newStateRoot = poll.stateTree?.root; + const newBallotRoot = poll.ballotTree?.root; - expect(newStateRoot.toString()).not.to.be.eq(currentStateRoot.toString()); - expect(newBallotRoot.toString()).not.to.be.eq(currentBallotRoot.toString()); + expect(newStateRoot?.toString()).not.to.be.eq(currentStateRoot.toString()); + expect(newBallotRoot?.toString()).not.to.be.eq(currentBallotRoot.toString()); const packedVals = packProcessMessageSmallVals( BigInt(maxValues.maxVoteOptions), @@ -268,11 +268,11 @@ describe("ProcessMessage circuit", function test() { // The new roots, which should differ, since at least one of the // messages modified a Ballot or State Leaf - const newStateRoot = poll.stateTree.root; - const newBallotRoot = poll.ballotTree.root; + const newStateRoot = poll.stateTree?.root; + const newBallotRoot = poll.ballotTree?.root; - expect(newStateRoot.toString()).not.to.be.eq(currentStateRoot.toString()); - expect(newBallotRoot.toString()).not.to.be.eq(currentBallotRoot.toString()); + expect(newStateRoot?.toString()).not.to.be.eq(currentStateRoot.toString()); + expect(newBallotRoot?.toString()).not.to.be.eq(currentBallotRoot.toString()); }); }); diff --git a/core/.eslintrc.js b/core/.eslintrc.js new file mode 100644 index 0000000000..a22d4fb52c --- /dev/null +++ b/core/.eslintrc.js @@ -0,0 +1,107 @@ +const fs = require("fs"); +const path = require("path"); + +const prettierConfig = fs.readFileSync(path.resolve(__dirname, "../.prettierrc"), "utf8"); +const prettierOptions = JSON.parse(prettierConfig); +const isProduction = process.env.NODE_ENV === "production"; + +module.exports = { + root: true, + extends: [ + "airbnb", + "prettier", + "plugin:import/recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-type-checked", + "plugin:@typescript-eslint/strict", + "plugin:@typescript-eslint/strict-type-checked", + "plugin:@typescript-eslint/stylistic", + "plugin:@typescript-eslint/stylistic-type-checked", + "plugin:import/typescript", + ], + plugins: ["json", "prettier", "unused-imports", "import", "@typescript-eslint"], + parser: "@typescript-eslint/parser", + env: { + node: true, + mocha: true, + es2022: true, + }, + settings: { + react: { + version: "999.999.999", + }, + "import/resolver": { + typescript: {}, + node: { + extensions: [".ts", ".js"], + moduleDirectory: ["node_modules", "ts", "src"], + }, + }, + }, + parserOptions: { + project: path.resolve(__dirname, "./tsconfig.json"), + sourceType: "module", + typescript: true, + ecmaVersion: 2022, + experimentalDecorators: true, + requireConfigFile: false, + ecmaFeatures: { + classes: true, + impliedStrict: true, + }, + warnOnUnsupportedTypeScriptVersion: true, + }, + reportUnusedDisableDirectives: isProduction, + rules: { + "import/no-cycle": ["error"], + "unused-imports/no-unused-imports": "error", + "import/no-extraneous-dependencies": [ + "error", + { + devDependencies: ["**/*.test.ts"], + }, + ], + "no-debugger": isProduction ? "error" : "off", + "no-console": "error", + "no-underscore-dangle": "error", + "no-redeclare": ["error", { builtinGlobals: true }], + "import/order": [ + "error", + { + groups: ["external", "builtin", "internal", "type", "parent", "sibling", "index", "object"], + alphabetize: { + order: "asc", + caseInsensitive: true, + }, + warnOnUnassignedImports: true, + "newlines-between": "always", + }, + ], + "prettier/prettier": ["error", prettierOptions], + "import/prefer-default-export": "off", + "import/extensions": ["error", { json: "always" }], + "class-methods-use-this": "off", + "prefer-promise-reject-errors": "off", + "max-classes-per-file": "off", + "no-use-before-define": ["off"], + "no-shadow": "off", + curly: ["error", "all"], + + "@typescript-eslint/explicit-member-accessibility": ["error", { accessibility: "no-public" }], + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/prefer-nullish-coalescing": "off", + "@typescript-eslint/no-floating-promises": "off", + "@typescript-eslint/no-explicit-any": "error", + "@typescript-eslint/explicit-module-boundary-types": "error", + "@typescript-eslint/no-use-before-define": ["error", { functions: false, classes: false }], + "@typescript-eslint/no-misused-promises": ["error", { checksVoidReturn: false }], + "@typescript-eslint/no-shadow": [ + "error", + { + builtinGlobals: true, + allow: ["location", "event", "history", "name", "status", "Option", "test", "expect"], + }, + ], + }, +}; diff --git a/core/package-lock.json b/core/package-lock.json index 1a282e4090..e32c2a02f5 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -7,6 +7,11 @@ "": { "name": "maci-core", "version": "1.1.2", + "dependencies": { + "maci-crypto": "^1.1.2", + "maci-domainobjs": "^1.1.2", + "optimisedmt": "^0.0.9" + }, "devDependencies": { "@types/chai": "^4.3.11", "@types/mocha": "^10.0.6", @@ -478,742 +483,5127 @@ "node": ">=6.9.0" } }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, + "node_modules/@ethereumjs/common": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.5.tgz", + "integrity": "sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==", "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" + "crc-32": "^1.2.0", + "ethereumjs-util": "^7.1.5" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "bin": { + "rlp": "bin/rlp" }, "engines": { - "node": ">=8" + "node": ">=14" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, + "node_modules/@ethereumjs/tx": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.2.tgz", + "integrity": "sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "@ethereumjs/common": "^2.6.4", + "ethereumjs-util": "^7.1.5" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, + "node_modules/@ethereumjs/util": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", + "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", "dependencies": { - "p-locate": "^4.1.0" + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" }, "engines": { - "node": ">=8" + "node": ">=14" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, + "node_modules/@ethersproject/abi": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", + "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "engines": { - "node": ">=8" + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", + "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true, - "engines": { - "node": ">=6.0.0" + "node_modules/@ethersproject/address": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/rlp": "^5.7.0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" + "node_modules/@ethersproject/base64": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", + "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", - "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", - "dev": true, + "node_modules/@ethersproject/basex": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", + "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/properties": "^5.7.0" } }, - "node_modules/@types/chai": { - "version": "4.3.11", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.11.tgz", - "integrity": "sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ==", - "dev": true - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, - "optional": true - }, - "node_modules/@types/mocha": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.6.tgz", - "integrity": "sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==", - "dev": true - }, - "node_modules/@types/node": { - "version": "18.19.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.3.tgz", - "integrity": "sha512-k5fggr14DwAytoA/t8rPrIz++lXK7/DqckthCmoZOKNsEbJkId4Z//BqgApXBUGrGddrigYa1oqheo/7YmW4rg==", - "dev": true, + "node_modules/@ethersproject/bignumber": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", + "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "undici-types": "~5.26.4" + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" } }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, + "node_modules/@ethersproject/bytes": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" + "@ethersproject/logger": "^5.7.0" } }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" + "node_modules/@ethersproject/constants": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } + "node_modules/@ethersproject/contracts": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", + "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/hdnode": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", + "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/json-wallets": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", + "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", + "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", + "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ] + }, + "node_modules/@ethersproject/networks": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/pbkdf2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", + "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/sha2": "^5.7.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", + "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/providers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "node_modules/@ethersproject/random": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", + "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", + "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/sha2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", + "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", + "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/solidity": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", + "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", + "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" + } + }, + "node_modules/@ethersproject/units": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", + "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/wallet": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", + "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/json-wallets": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", + "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/wordlists": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", + "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@iden3/bigarray": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@iden3/bigarray/-/bigarray-0.0.2.tgz", + "integrity": "sha512-Xzdyxqm1bOFF6pdIsiHLLl3HkSLjbhqJHVyqaTxXt3RqXBEnmsUmEW47H7VOi/ak7TdkRpNkxjyK5Zbkm+y52g==" + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@noble/curves": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", + "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", + "dependencies": { + "@noble/hashes": "1.3.1" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/base": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.5.tgz", + "integrity": "sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ==", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz", + "integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==", + "dependencies": { + "@noble/curves": "~1.1.0", + "@noble/hashes": "~1.3.1", + "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", + "integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==", + "dependencies": { + "@noble/hashes": "~1.3.0", + "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/@types/bn.js": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", + "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/chai": { + "version": "4.3.11", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.11.tgz", + "integrity": "sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ==", + "dev": true + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "optional": true + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/mocha": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.6.tgz", + "integrity": "sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.3.tgz", + "integrity": "sha512-k5fggr14DwAytoA/t8rPrIz++lXK7/DqckthCmoZOKNsEbJkId4Z//BqgApXBUGrGddrigYa1oqheo/7YmW4rg==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/secp256k1": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", + "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==" + }, + "node_modules/abortcontroller-polyfill": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz", + "integrity": "sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "dependencies": { + "default-require-extensions": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", + "dev": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", + "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", + "dependencies": { + "call-bind": "^1.0.2", + "is-nan": "^1.3.2", + "object-is": "^1.1.5", + "object.assign": "^4.1.4", + "util": "^0.12.5" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "engines": { + "node": "*" + } + }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + }, + "node_modules/async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" + }, + "node_modules/b4a": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", + "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/blake-hash": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/blake-hash/-/blake-hash-1.1.1.tgz", + "integrity": "sha512-V93H+FEJuXXZi1eEsMtbcBFP9oL5Ept7SLw3cbXYlPC3nocm9Fr4m18ZhbhdJrZVS9J/Z0oNE4L3oDZvmorHNA==", + "hasInstallScript": true, + "dependencies": { + "bindings": "^1.2.1", + "inherits": "^2.0.3", + "nan": "^2.2.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/blake2b": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/blake2b/-/blake2b-2.1.4.tgz", + "integrity": "sha512-AyBuuJNI64gIvwx13qiICz6H6hpmjvYS5DGkG6jbXMOT8Z3WUJ3V1X0FlhIoT1b/5JtHE3ki+xjtMvu1nn+t9A==", + "dependencies": { + "blake2b-wasm": "^2.4.0", + "nanoassert": "^2.0.0" + } + }, + "node_modules/blake2b-wasm": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/blake2b-wasm/-/blake2b-wasm-2.4.0.tgz", + "integrity": "sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w==", + "dependencies": { + "b4a": "^1.0.1", + "nanoassert": "^2.0.0" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/buffer-to-arraybuffer": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", + "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==" + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" + }, + "node_modules/bufferutil": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacheable-lookup": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz", + "integrity": "sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==", + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001570", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", + "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + }, + "node_modules/chai": { + "version": "4.3.10", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", + "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "node_modules/cids": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", + "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", + "deprecated": "This module has been superseded by the multiformats module", + "dependencies": { + "buffer": "^5.5.0", + "class-is": "^1.1.0", + "multibase": "~0.6.0", + "multicodec": "^1.0.0", + "multihashes": "~0.4.15" + }, + "engines": { + "node": ">=4.0.0", + "npm": ">=3.0.0" + } + }, + "node_modules/cids/node_modules/multicodec": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", + "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", + "deprecated": "This module has been superseded by the multiformats module", + "dependencies": { + "buffer": "^5.6.0", + "varint": "^5.0.0" + } + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/circom": { + "version": "0.5.45", + "resolved": "https://registry.npmjs.org/circom/-/circom-0.5.45.tgz", + "integrity": "sha512-5Ixp6UjwrhBWnnFBO/mTns+eeEDOpi5UoN4znAUWy5rklCUWYt2Ezl9QVUswBXjMP5kpfEtGUY2XSsYRAp6uMg==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dependencies": { + "chai": "^4.2.0", + "circom_runtime": "0.1.12", + "fastfile": "0.0.18", + "ffiasm": "0.1.1", + "ffjavascript": "0.2.22", + "ffwasm": "0.0.7", + "fnv-plus": "^1.3.1", + "r1csfile": "0.0.16", + "tmp-promise": "^2.0.2", + "wasmbuilder": "0.0.10" + }, + "bin": { + "circom": "cli.js" + } + }, + "node_modules/circom_runtime": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.1.12.tgz", + "integrity": "sha512-R+QT9HS9w71cmGmWIn+PSyD3aHyR5JZBiVvxOjCfn12wwnpuFwBjdMG7he+v8h/oQD1mDRAu2KrBeL4mAt5s4A==", + "dependencies": { + "ffjavascript": "0.2.34", + "fnv-plus": "^1.3.1" + }, + "bin": { + "calcwit": "calcwit.js" + } + }, + "node_modules/circom_runtime/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/circom_runtime/node_modules/chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dependencies": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.1" + } + }, + "node_modules/circom_runtime/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/circom_runtime/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/circom_runtime/node_modules/ffjavascript": { + "version": "0.2.34", + "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.34.tgz", + "integrity": "sha512-fq/qfJluC4spiOD1lp5jfckZVnS0o0kI5eKXVLw7UKwIwbNr+NBMBveBVcidSfMizF87T6wb7NBtLSdckQiAnQ==", + "dependencies": { + "big-integer": "^1.6.48", + "mocha": "^8.2.1", + "wasmcurves": "0.0.14", + "worker-threads": "^1.0.0" + } + }, + "node_modules/circom_runtime/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/circom_runtime/node_modules/js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/circom_runtime/node_modules/log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dependencies": { + "chalk": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/circom_runtime/node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/circom_runtime/node_modules/mocha": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", + "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.0.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.1.20", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 10.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/circom_runtime/node_modules/nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/circom_runtime/node_modules/readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/circom_runtime/node_modules/serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/circom_runtime/node_modules/wasmcurves": { + "version": "0.0.14", + "resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.0.14.tgz", + "integrity": "sha512-G1iMkxlRaQSdqQ1JrwHcU+awLmwyH6kFKfT8g9obd8MWe+u5oSdFXrODB0zmSI5aGGvJPG+4cAmqCGYv9R+7qg==", + "dependencies": { + "big-integer": "^1.6.42", + "blakejs": "^1.1.0" + } + }, + "node_modules/circom_runtime/node_modules/workerpool": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==" + }, + "node_modules/circom/node_modules/ffjavascript": { + "version": "0.2.22", + "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.22.tgz", + "integrity": "sha512-EsVqap2Txm17bKW0z/jXCX3M7rQ++nQUAJY8alWDpyhjRj90xjl6GLeVSKZQ8rOFDQ/SFFXcEB8w9X8Boxid+w==", + "dependencies": { + "big-integer": "^1.6.48", + "wasmcurves": "0.0.12", + "worker-threads": "^1.0.0" + } + }, + "node_modules/circom/node_modules/wasmcurves": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.0.12.tgz", + "integrity": "sha512-1Jl9mkatyHSNj80ILjf85SZUNuZQBCkTjJlhzqHnZQXUmIimCIWkugaVaYNjozLs1Gun4h/keZe1MBeBN0sRpg==", + "dependencies": { + "big-integer": "^1.6.42", + "blakejs": "^1.1.0" + } + }, + "node_modules/circomlib": { + "version": "0.5.2", + "resolved": "git+ssh://git@github.com/weijiekoh/circomlib.git#24ed08eee0bb613b8c0135d66c1013bd9f78d50a", + "integrity": "sha512-oWrlNshOYpXszPIaMlWA/Dq7kv18nhsYyBK8C9etCvec5i7huQC17yelbKZCayxbhhDulNbs+GMXw9IG1iARuw==", + "license": "GPL-3.0", + "dependencies": { + "blake-hash": "^1.1.0", + "blake2b": "^2.1.3", + "circom": "0.5.45", + "ffjavascript": "0.1.0", + "web3-utils": "^1.3.0" + } + }, + "node_modules/circomlib/node_modules/ffjavascript": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.1.0.tgz", + "integrity": "sha512-dmKlUasSfvUcxBm8nCSKl2x7EFJsXA7OVP8XLFA03T2+6mAc3IiVLC2ambEVOcMOhyhl0vJfVZjM9f9d38D1rw==", + "dependencies": { + "big-integer": "^1.6.48" + } + }, + "node_modules/circomlibjs": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/circomlibjs/-/circomlibjs-0.0.8.tgz", + "integrity": "sha512-oZFYapLO0mfiA+i2GU/V7bRNEEPjVcwV4M444nU5lNsdSJpqLwD57m9zxTD5m/KeY7WQ3lEAC9NNKEPQHu7s1w==", + "dependencies": { + "blake-hash": "^2.0.0", + "blake2b": "^2.1.3", + "ffjavascript": "^0.2.38", + "web3": "^1.6.0", + "web3-utils": "^1.6.0" + } + }, + "node_modules/circomlibjs/node_modules/blake-hash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/blake-hash/-/blake-hash-2.0.0.tgz", + "integrity": "sha512-Igj8YowDu1PRkRsxZA7NVkdFNxH5rKv5cpLxQ0CVXSIA77pVYwCPRQJ2sMew/oneUpfuYRyjG6r8SmmmnbZb1w==", + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^3.0.0", + "node-gyp-build": "^4.2.2", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/class-is": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", + "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==" + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-hash": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", + "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", + "dependencies": { + "cids": "^0.7.1", + "multicodec": "^0.5.5", + "multihashes": "^0.4.15" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/cross-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/default-require-extensions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", + "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", + "dev": true, + "dependencies": { + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-require-extensions/node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/ejs": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.614", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.614.tgz", + "integrity": "sha512-X4ze/9Sc3QWs6h92yerwqv7aB/uU8vCjZcrMjA8N9R1pjMFRe44dLsck5FzLilOYvcXuDn93B+bpGYyufc70gQ==", + "dev": true + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eth-ens-namehash": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", + "integrity": "sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==", + "dependencies": { + "idna-uts46-hx": "^2.3.1", + "js-sha3": "^0.5.7" + } + }, + "node_modules/eth-ens-namehash/node_modules/js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==" + }, + "node_modules/eth-lib": { + "version": "0.1.29", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", + "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/eth-lib/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/eth-lib/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/eth-lib/node_modules/ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dependencies": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + }, + "node_modules/ethereum-bloom-filters": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", + "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", + "dependencies": { + "js-sha3": "^0.8.0" + } + }, + "node_modules/ethereum-cryptography": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz", + "integrity": "sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==", + "dependencies": { + "@noble/curves": "1.1.0", + "@noble/hashes": "1.3.1", + "@scure/bip32": "1.3.1", + "@scure/bip39": "1.2.1" + } + }, + "node_modules/ethereumjs-util": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", + "dependencies": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ethereumjs-util/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, + "node_modules/ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", + "dependencies": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" + }, + "node_modules/eventemitter3": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", + "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==" + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/express/node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fastfile": { + "version": "0.0.18", + "resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.18.tgz", + "integrity": "sha512-q03PTKc+wptis4WmuFOwPNQx2p5myFUrl/dMgRlW9mymc1Egyc14JPHgiGnWK+sJ0+dBl2Vwtfh5GfSQltYOpw==" + }, + "node_modules/ffiasm": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ffiasm/-/ffiasm-0.1.1.tgz", + "integrity": "sha512-irMMHiR9JJ7BVBrAhtliUawxVdPYSdyl81taUYJ4C1mJ0iw2ueThE/qtr0J8B83tsIY8HJvh0lg5F+6ClK4xpA==", + "dependencies": { + "big-integer": "^1.6.48", + "ejs": "^3.0.1", + "yargs": "^15.3.1" + }, + "bin": { + "buildzqfield": "src/buildzqfield.js" + } + }, + "node_modules/ffiasm/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ffiasm/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/ffiasm/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ffiasm/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ffiasm/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ffiasm/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ffiasm/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ffiasm/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ffiasm/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" + }, + "node_modules/ffiasm/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ffiasm/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ffjavascript": { + "version": "0.2.62", + "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.62.tgz", + "integrity": "sha512-uJ7MTrdzhX/3f+hxn0XhdXbJCqYZJSBB6y2/ui4t21vKYVjyTMlU80pPXu40ir6qpqbrdzUeKdlOdJ0aFG9UNA==", + "dependencies": { + "wasmbuilder": "0.0.16", + "wasmcurves": "0.2.2", + "web-worker": "^1.2.0" + } + }, + "node_modules/ffjavascript/node_modules/wasmbuilder": { + "version": "0.0.16", + "resolved": "https://registry.npmjs.org/wasmbuilder/-/wasmbuilder-0.0.16.tgz", + "integrity": "sha512-Qx3lEFqaVvp1cEYW7Bfi+ebRJrOiwz2Ieu7ZG2l7YyeSJIok/reEQCQCuicj/Y32ITIJuGIM9xZQppGx5LrQdA==" + }, + "node_modules/ffwasm": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ffwasm/-/ffwasm-0.0.7.tgz", + "integrity": "sha512-17cTLzv7HHAKqZbX8MvHxjSrR0yDdn1sh4TVsTbAvO9e6klhFicnyoVXc/sCuViV/M8g65sCmVrAmoPCZp1YkQ==", + "dependencies": { + "big-integer": "^1.6.48", + "wasmbuilder": "0.0.10" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/fnv-plus": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/fnv-plus/-/fnv-plus-1.3.1.tgz", + "integrity": "sha512-Gz1EvfOneuFfk4yG458dJ3TLJ7gV19q3OM/vVvvHf7eT02Hm1DleB4edsia6ahbKgAYxO9gvyQ1ioWZR+a00Yw==" + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/form-data-encoder": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz", + "integrity": "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==" + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "dependencies": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "dependencies": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/got/-/got-12.1.0.tgz", + "integrity": "sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==", + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "@szmarczak/http-timer": "^5.0.1", + "@types/cacheable-request": "^6.0.2", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^6.0.4", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "form-data-encoder": "1.7.1", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "engines": { + "node": ">=4.x" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-https": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", + "integrity": "sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg==" + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/idna-uts46-hx": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", + "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", + "dependencies": { + "punycode": "2.1.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/idna-uts46-hx/node_modules/punycode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dependencies": { + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "dependencies": { + "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", + "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", + "dev": true, + "dependencies": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-report/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jake": { + "version": "10.8.7", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", + "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/jake/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, + "optional": true, "dependencies": { - "color-convert": "^2.0.1" + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" }, "engines": { - "node": ">=8" + "node": ">=0.6.0" + } + }, + "node_modules/keccak": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", + "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/keccak/node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" }, "engines": { - "node": ">= 8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "dependencies": { - "default-require-extensions": "^3.0.0" + "yallist": "^3.0.2" + } + }, + "node_modules/maci-crypto": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/maci-crypto/-/maci-crypto-1.1.2.tgz", + "integrity": "sha512-/eaWVItoLFl32OcANn/6UhTzhe0zyXEAvSsBxH8ZsuI1TpBad3uw4wLh4AMVfehKI2IflMmTLriSedS3vQiwQw==", + "deprecated": "1.1.2 is no longer supported. Please use 1.1.1 instead.", + "dependencies": { + "blake-hash": "^1.1.0", + "circomlib": "git+https://github.com/weijiekoh/circomlib.git#24ed08eee0bb613b8c0135d66c1013bd9f78d50a", + "ethers": "^5.0.32", + "ffjavascript": "^0.2.57", + "optimisedmt": "^0.0.7" + } + }, + "node_modules/maci-crypto/node_modules/optimisedmt": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/optimisedmt/-/optimisedmt-0.0.7.tgz", + "integrity": "sha512-yVlKMmP/egqiAtg12KFZxqKx35STm+RB5kSSvo9q0B0sIx/7HbWj7fJcFLUFtWzbYp2IvdOhx31s4IC7RmU5pQ==", + "dependencies": { + "assert": "^2.0.0", + "circomlibjs": "0.0.8", + "ffjavascript": "^0.2.39" + } + }, + "node_modules/maci-domainobjs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/maci-domainobjs/-/maci-domainobjs-1.1.2.tgz", + "integrity": "sha512-4HIBMe173DFQ9TZh68Yuf/eYNHA2Uzt/Ucqf53R3BOZ3tcmuEGIgEiKyzQZPlNQshAOOHeBZqlPlsuDge7t51A==", + "deprecated": "1.1.2 is no longer supported. Please use 1.1.1 instead.", + "dependencies": { + "base64url": "^3.0.1" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } }, - "node_modules/arrify": { + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true, + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "engines": { - "node": ">=0.10.0" + "node": ">= 0.6" } }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "node_modules/micro-ftch": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", + "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==" + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", + "dependencies": { + "dom-walk": "^0.1.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "node_modules/minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mkdirp-promise": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", + "integrity": "sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w==", + "deprecated": "This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that.", + "dependencies": { + "mkdirp": "*" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mocha": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", "dev": true, + "dependencies": { + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, "engines": { - "node": "*" + "node": ">= 14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "node_modules/mock-fs": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz", + "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==" }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, + "node_modules/multibase": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", + "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", + "deprecated": "This module has been superseded by the multiformats module", "dependencies": { - "balanced-match": "^1.0.0" + "base-x": "^3.0.8", + "buffer": "^5.5.0" } }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, + "node_modules/multicodec": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", + "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", + "deprecated": "This module has been superseded by the multiformats module", "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" + "varint": "^5.0.0" } }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true + "node_modules/multihashes": { + "version": "0.4.21", + "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", + "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", + "dependencies": { + "buffer": "^5.5.0", + "multibase": "^0.7.0", + "varint": "^5.0.0" + } }, - "node_modules/browserslist": { - "version": "4.22.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", - "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], + "node_modules/multihashes/node_modules/multibase": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", + "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", + "deprecated": "This module has been superseded by the multiformats module", "dependencies": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "base-x": "^3.0.8", + "buffer": "^5.5.0" } }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "node_modules/nan": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", + "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==" }, - "node_modules/caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "node_modules/nano-json-stream-parser": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", + "integrity": "sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==" + }, + "node_modules/nanoassert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-2.0.0.tgz", + "integrity": "sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==" + }, + "node_modules/nanoid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", "dev": true, - "dependencies": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" + "bin": { + "nanoid": "bin/nanoid.cjs" }, "engines": { - "node": ">=8" + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.6" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001570", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", - "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" }, - "node_modules/chai": { - "version": "4.3.10", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", - "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", - "dev": true, + "node_modules/node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" + "whatwg-url": "^5.0.0" }, "engines": { - "node": ">=4" + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } } }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/node-gyp-build": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.7.1.tgz", + "integrity": "sha512-wTSrZ+8lsRRa3I3H8Xr65dLWSgCvY2l4AOnaeKdPA9TB/WYMPaTcrzf3rXvFoVvjKNVnu0CcWSx54qq9GKRUYg==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "process-on-spawn": "^1.0.0" }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, + "node_modules/number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", "dependencies": { - "has-flag": "^4.0.0" + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" }, "engines": { - "node": ">=8" + "node": ">=6.5.0", + "npm": ">=3" } }, - "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.2" - }, - "engines": { - "node": "*" - } + "node_modules/number-to-bn/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "node_modules/nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" }, - "engines": { - "node": ">= 8.10.0" + "bin": { + "nyc": "bin/nyc.js" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "engines": { + "node": ">=8.9" } }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "node_modules/nyc/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, "engines": { "node": ">=6" } }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "node_modules/nyc/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "wrap-ansi": "^6.2.0" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/nyc/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, "engines": { - "node": ">=7.0.0" + "node": ">=0.10.0" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">= 8" + "node": ">=8" } }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "dependencies": { - "ms": "2.1.2" + "p-locate": "^4.1.0" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=8" } }, - "node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "node_modules/nyc/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, "engines": { - "node": ">=10" + "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "dependencies": { - "type-detect": "^4.0.0" + "p-limit": "^2.2.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/default-require-extensions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", - "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", + "node_modules/nyc/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, "dependencies": { - "strip-bom": "^4.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/default-require-extensions/node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "node_modules/nyc/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/nyc/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, "engines": { "node": ">=8" } }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "node_modules/nyc/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, "engines": { - "node": ">=0.3.1" + "node": ">=6" } }, - "node_modules/electron-to-chromium": { - "version": "1.4.614", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.614.tgz", - "integrity": "sha512-X4ze/9Sc3QWs6h92yerwqv7aB/uU8vCjZcrMjA8N9R1pjMFRe44dLsck5FzLilOYvcXuDn93B+bpGYyufc70gQ==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "engines": { + "node": "*" + } }, - "node_modules/es6-error": { + "node_modules/object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" }, "engines": { - "node": ">=4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, + "node_modules/oboe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", + "integrity": "sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA==", "dependencies": { - "to-regex-range": "^5.0.1" + "http-https": "^1.0.0" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" }, "engines": { - "node": ">=8" + "node": ">= 0.8" } }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optimisedmt": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/optimisedmt/-/optimisedmt-0.0.9.tgz", + "integrity": "sha512-NgpgliUnd8hY8HG3i+mUJ8n+g4zuv/GrcMQDciOZC8OEOYSiBr2gUlM/trnh28YFKKm0VInMECEOA6nr1swoEg==", + "dependencies": { + "assert": "^2.0.0", + "circomlibjs": "0.0.8", + "ffjavascript": "^0.2.39" + } + }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/find-up": { + "node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" + "p-limit": "^3.0.2" }, "engines": { "node": ">=10" @@ -1222,330 +5612,278 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", "dev": true, "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" + "aggregate-error": "^3.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=8" } }, - "node_modules/fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=6" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "node_modules/package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, "engines": { - "node": ">=6.9.0" + "node": ">=8" } }, - "node_modules/get-caller-file": { + "node_modules/parse-headers": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", + "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==" }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "engines": { - "node": "*" + "node": ">= 0.8" } }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "engines": { - "node": ">=8.0.0" + "node": ">=8" } }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=0.10.0" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, "engines": { - "node": ">= 6" + "node": ">=8" } }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "engines": { + "node": "*" } }, - "node_modules/glob/node_modules/minimatch": { + "node_modules/pbkdf2": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", "dependencies": { - "brace-expansion": "^1.1.7" + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" }, "engines": { - "node": "*" + "node": ">=0.12" } }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "engines": { - "node": ">=8" + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "dependencies": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" + "find-up": "^4.0.0" }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" } }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, "engines": { - "node": ">=0.8.19" + "node": ">=8" } }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, "engines": { "node": ">=8" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "dependencies": { - "binary-extensions": "^2.0.0" + "p-limit": "^2.2.0" }, "engines": { "node": ">=8" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "engines": { - "node": ">=0.10.0" + "node": ">= 0.6.0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", "dev": true, + "dependencies": { + "fromentries": "^1.2.0" + }, "engines": { "node": ">=8" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dependencies": { - "is-extglob": "^2.1.1" + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.10" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, "engines": { - "node": ">=8" + "node": ">=0.6" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true + "node_modules/query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "dependencies": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", "engines": { "node": ">=10" }, @@ -1553,1241 +5891,1570 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node_modules/r1csfile": { + "version": "0.0.16", + "resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.16.tgz", + "integrity": "sha512-A2jRVWzGgmXeG2lVAc0H4suJmzt50it5UvBnycJgBCpMXM3tH/M6RguP7nvs6suY/yYnkN6jX6iTScSiDUF3FA==", + "dependencies": { + "@iden3/bigarray": "0.0.2", + "fastfile": "0.0.18", + "ffjavascript": "0.2.22" } }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "node_modules/r1csfile/node_modules/ffjavascript": { + "version": "0.2.22", + "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.22.tgz", + "integrity": "sha512-EsVqap2Txm17bKW0z/jXCX3M7rQ++nQUAJY8alWDpyhjRj90xjl6GLeVSKZQ8rOFDQ/SFFXcEB8w9X8Boxid+w==", + "dependencies": { + "big-integer": "^1.6.48", + "wasmcurves": "0.0.12", + "worker-threads": "^1.0.0" + } }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "engines": { - "node": ">=8" + "node_modules/r1csfile/node_modules/wasmcurves": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.0.12.tgz", + "integrity": "sha512-1Jl9mkatyHSNj80ILjf85SZUNuZQBCkTjJlhzqHnZQXUmIimCIWkugaVaYNjozLs1Gun4h/keZe1MBeBN0sRpg==", + "dependencies": { + "big-integer": "^1.6.42", + "blakejs": "^1.1.0" } }, - "node_modules/istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "dev": true, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dependencies": { - "append-transform": "^2.0.0" - }, + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "engines": { - "node": ">=8" + "node": ">= 0.6" } }, - "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" }, "engines": { - "node": ">=8" + "node": ">= 0.8" } }, - "node_modules/istanbul-lib-processinfo": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", - "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", - "dev": true, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dependencies": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.3", - "istanbul-lib-coverage": "^3.2.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^8.3.2" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" }, "engines": { - "node": ">=8" + "node": ">= 6" } }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" + "picomatch": "^2.2.1" }, "engines": { - "node": ">=10" + "node": ">=8.10.0" } }, - "node_modules/istanbul-lib-report/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", "dev": true, "dependencies": { - "yallist": "^4.0.0" + "es6-error": "^4.0.1" }, "engines": { - "node": ">=10" + "node": ">=4" } }, - "node_modules/istanbul-lib-report/node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "dependencies": { - "semver": "^7.5.3" + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 6" } }, - "node_modules/istanbul-lib-report/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "engines": { - "node": ">=10" + "node": ">=0.6" } }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/istanbul-lib-report/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", - "dev": true, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" + "lowercase-keys": "^2.0.0" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/responselike/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", "engines": { "node": ">=8" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "dependencies": { - "argparse": "^2.0.1" + "glob": "^7.1.3" }, "bin": { - "js-yaml": "bin/js-yaml.js" + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" } }, - "node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "optional": true, + "node_modules/rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", "dependencies": { - "minimist": "^1.2.0" + "bn.js": "^5.2.0" }, "bin": { - "json5": "lib/cli.js" + "rlp": "bin/rlp" } }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, + "node_modules/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "hasInstallScript": true, "dependencies": { - "p-locate": "^5.0.0" + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=10.0.0" } }, - "node_modules/lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", - "dev": true + "node_modules/secp256k1/node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.8.0" } }, - "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "dev": true, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "get-func-name": "^2.0.1" + "ms": "2.0.0" } }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, "dependencies": { - "yallist": "^3.0.2" + "randombytes": "^2.1.0" } }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dependencies": { - "semver": "^6.0.0" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" }, "engines": { - "node": ">=8" + "node": ">= 0.8.0" + } + }, + "node_modules/servify": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", + "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", + "dependencies": { + "body-parser": "^1.16.0", + "cors": "^2.8.1", + "express": "^4.14.0", + "request": "^2.79.0", + "xhr": "^2.3.3" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=6" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, - "node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", - "dev": true, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", "dependencies": { - "brace-expansion": "^2.0.1" + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" }, "engines": { - "node": ">=10" + "node": ">= 0.4" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dependencies": { - "minimist": "^1.2.6" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" }, "bin": { - "mkdirp": "bin/cmd.js" + "sha.js": "bin.js" } }, - "node_modules/mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" + "shebang-regex": "^3.0.0" }, "engines": { - "node": ">= 14.0.0" + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, - "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", + "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", + "dependencies": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" } }, - "node_modules/node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "dev": true, + "node_modules/simple-get/node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", "dependencies": { - "process-on-spawn": "^1.0.0" + "mimic-response": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", "dev": true, "dependencies": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", + "is-windows": "^1.0.2", "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", "rimraf": "^3.0.0", "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" + "which": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" }, "bin": { - "nyc": "bin/nyc.js" + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" }, "engines": { - "node": ">=8.9" + "node": ">=0.10.0" } }, - "node_modules/nyc/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "engines": { - "node": ">=6" + "node": ">= 0.8" } }, - "node_modules/nyc/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, + "node_modules/strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" + "safe-buffer": "~5.2.0" } }, - "node_modules/nyc/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/nyc/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, - "node_modules/nyc/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", "dependencies": { - "p-locate": "^4.1.0" + "is-hex-prefixed": "1.0.0" }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/nyc/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dependencies": { - "p-try": "^2.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/nyc/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, + "node_modules/swarm-js": { + "version": "0.1.42", + "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.42.tgz", + "integrity": "sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ==", "dependencies": { - "p-limit": "^2.2.0" + "bluebird": "^3.5.0", + "buffer": "^5.0.5", + "eth-lib": "^0.1.26", + "fs-extra": "^4.0.2", + "got": "^11.8.5", + "mime-types": "^2.1.16", + "mkdirp-promise": "^5.0.1", + "mock-fs": "^4.1.0", + "setimmediate": "^1.0.5", + "tar": "^4.0.2", + "xhr-request": "^1.0.1" + } + }, + "node_modules/swarm-js/node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/swarm-js/node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/swarm-js/node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/swarm-js/node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/swarm-js/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", "engines": { "node": ">=8" } }, - "node_modules/nyc/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "node_modules/swarm-js/node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/tar": { + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "dependencies": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" }, "engines": { "node": ">=8" } }, - "node_modules/nyc/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } }, - "node_modules/nyc/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/nyc/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, + "node_modules/timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tmp": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz", + "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==", "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "rimraf": "^2.6.3" }, "engines": { "node": ">=6" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, + "node_modules/tmp-promise": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-2.1.1.tgz", + "integrity": "sha512-Z048AOz/w9b6lCbJUpevIJpRpUztENl8zdv1bmAKVHimfqRFl92ROkmT9rp7TVBnrEw2gtMTol/2Cp2S2kJa4Q==", "dependencies": { - "wrappy": "1" + "tmp": "0.1.0" } }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, + "node_modules/tmp/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" + "glob": "^7.1.3" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "bin": { + "rimraf": "bin.js" } }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, - "node_modules/p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dependencies": { - "aggregate-error": "^3.0.0" + "is-number": "^7.0.0" }, "engines": { - "node": ">=8" + "node": ">=8.0" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "engines": { - "node": ">=6" + "node": ">=0.6" } }, - "node_modules/package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", - "dev": true, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dependencies": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" + "psl": "^1.1.28", + "punycode": "^2.1.1" }, "engines": { - "node": ">=8" + "node": ">=0.8" } }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/ts-mocha": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/ts-mocha/-/ts-mocha-10.0.0.tgz", + "integrity": "sha512-VRfgDO+iiuJFlNB18tzOfypJ21xn2xbuZyDvJvqpTbWgkAgD17ONGr8t+Tl8rcBtOBdjXp5e/Rk+d39f7XBHRw==", "dev": true, + "dependencies": { + "ts-node": "7.0.1" + }, + "bin": { + "ts-mocha": "bin/ts-mocha" + }, "engines": { - "node": ">=8" + "node": ">= 6.X.X" + }, + "optionalDependencies": { + "tsconfig-paths": "^3.5.0" + }, + "peerDependencies": { + "mocha": "^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "node_modules/ts-node": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", + "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", "dev": true, + "dependencies": { + "arrify": "^1.0.0", + "buffer-from": "^1.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map-support": "^0.5.6", + "yn": "^2.0.0" + }, + "bin": { + "ts-node": "dist/bin.js" + }, "engines": { - "node": ">=0.10.0" + "node": ">=4.2.0" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/ts-node/node_modules/diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=0.3.1" } }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "node_modules/tsconfig-paths": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", "dev": true, + "optional": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, "engines": { "node": "*" } }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "node": ">=4" } }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, "engines": { "node": ">=8" } }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "media-typer": "0.3.0", + "mime-types": "~2.1.24" }, "engines": { - "node": ">=8" + "node": ">= 0.6" } }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dependencies": { - "p-locate": "^4.1.0" - }, + "is-typedarray": "^1.0.0" + } + }, + "node_modules/ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "engines": { - "node": ">=8" + "node": ">= 4.0.0" } }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "p-try": "^2.0.0" + "escalade": "^3.1.1", + "picocolors": "^1.0.0" }, - "engines": { - "node": ">=6" + "bin": { + "update-browserslist-db": "cli.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" + "punycode": "^2.1.0" } }, - "node_modules/process-on-spawn": { + "node_modules/url-set-query": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", - "dev": true, + "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", + "integrity": "sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==" + }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "hasInstallScript": true, "dependencies": { - "fromentries": "^1.2.0" + "node-gyp-build": "^4.3.0" }, "engines": { - "node": ">=8" + "node": ">=6.14.2" } }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } + "node_modules/utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" } }, - "node_modules/release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", - "dev": true, - "dependencies": { - "es6-error": "^4.0.1" - }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "engines": { - "node": ">=4" + "node": ">= 0.4.0" } }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true, - "engines": { - "node": ">=0.10.0" + "bin": { + "uuid": "dist/bin/uuid" } }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true + "node_modules/varint": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", + "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==" }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "engines": { - "node": ">=8" + "node": ">= 0.8" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "engines": [ + "node >=0.6.0" + ], "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" + "node_modules/wasmbuilder": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/wasmbuilder/-/wasmbuilder-0.0.10.tgz", + "integrity": "sha512-zQSvZ7d74d9OvN+mCN6ucNne4QS5/cBBYTHldX0Oe+u9gStY21orapvuX1ajisA7RVIpuFhYg+ZgdySsPfeh0A==", + "dependencies": { + "big-integer": "^1.6.48" } }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, + "node_modules/wasmcurves": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.2.2.tgz", + "integrity": "sha512-JRY908NkmKjFl4ytnTu5ED6AwPD+8VJ9oc94kdq7h5bIwbj0L4TDJ69mG+2aLs2SoCmGfqIesMWTEJjtYsoQXQ==", "dependencies": { - "randombytes": "^2.1.0" + "wasmbuilder": "0.0.16" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true + "node_modules/wasmcurves/node_modules/wasmbuilder": { + "version": "0.0.16", + "resolved": "https://registry.npmjs.org/wasmbuilder/-/wasmbuilder-0.0.16.tgz", + "integrity": "sha512-Qx3lEFqaVvp1cEYW7Bfi+ebRJrOiwz2Ieu7ZG2l7YyeSJIok/reEQCQCuicj/Y32ITIJuGIM9xZQppGx5LrQdA==" }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, + "node_modules/web-worker": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", + "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" + }, + "node_modules/web3": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.10.3.tgz", + "integrity": "sha512-DgUdOOqC/gTqW+VQl1EdPxrVRPB66xVNtuZ5KD4adVBtko87hkgM8BTZ0lZ8IbUfnQk6DyjcDujMiH3oszllAw==", + "hasInstallScript": true, "dependencies": { - "shebang-regex": "^3.0.0" + "web3-bzz": "1.10.3", + "web3-core": "1.10.3", + "web3-eth": "1.10.3", + "web3-eth-personal": "1.10.3", + "web3-net": "1.10.3", + "web3-shh": "1.10.3", + "web3-utils": "1.10.3" }, "engines": { - "node": ">=8" + "node": ">=8.0.0" } }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, + "node_modules/web3-bzz": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.10.3.tgz", + "integrity": "sha512-XDIRsTwekdBXtFytMpHBuun4cK4x0ZMIDXSoo1UVYp+oMyZj07c7gf7tNQY5qZ/sN+CJIas4ilhN25VJcjSijQ==", + "hasInstallScript": true, + "dependencies": { + "@types/node": "^12.12.6", + "got": "12.1.0", + "swarm-js": "^0.1.40" + }, "engines": { - "node": ">=8" + "node": ">=8.0.0" } }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "node_modules/web3-bzz/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, + "node_modules/web3-core": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.10.3.tgz", + "integrity": "sha512-Vbk0/vUNZxJlz3RFjAhNNt7qTpX8yE3dn3uFxfX5OHbuon5u65YEOd3civ/aQNW745N0vGUlHFNxxmn+sG9DIw==", + "dependencies": { + "@types/bn.js": "^5.1.1", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.10.3", + "web3-core-method": "1.10.3", + "web3-core-requestmanager": "1.10.3", + "web3-utils": "1.10.3" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8.0.0" } }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, + "node_modules/web3-core-helpers": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.3.tgz", + "integrity": "sha512-Yv7dQC3B9ipOc5sWm3VAz1ys70Izfzb8n9rSiQYIPjpqtJM+3V4EeK6ghzNR6CO2es0+Yu9CtCkw0h8gQhrTxA==", "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "web3-eth-iban": "1.10.3", + "web3-utils": "1.10.3" + }, + "engines": { + "node": ">=8.0.0" } }, - "node_modules/spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", - "dev": true, + "node_modules/web3-core-method": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.10.3.tgz", + "integrity": "sha512-VZ/Dmml4NBmb0ep5PTSg9oqKoBtG0/YoMPei/bq/tUdlhB2dMB79sbeJPwx592uaV0Vpk7VltrrrBv5hTM1y4Q==", "dependencies": { - "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", - "make-dir": "^3.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "which": "^2.0.1" + "@ethersproject/transactions": "^5.6.2", + "web3-core-helpers": "1.10.3", + "web3-core-promievent": "1.10.3", + "web3-core-subscriptions": "1.10.3", + "web3-utils": "1.10.3" }, "engines": { - "node": ">=8" + "node": ">=8.0.0" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "node_modules/web3-core-promievent": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.10.3.tgz", + "integrity": "sha512-HgjY+TkuLm5uTwUtaAfkTgRx/NzMxvVradCi02gy17NxDVdg/p6svBHcp037vcNpkuGeFznFJgULP+s2hdVgUQ==", + "dependencies": { + "eventemitter3": "4.0.4" + }, + "engines": { + "node": ">=8.0.0" + } }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, + "node_modules/web3-core-requestmanager": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.10.3.tgz", + "integrity": "sha512-VT9sKJfgM2yBOIxOXeXiDuFMP4pxzF6FT+y8KTLqhDFHkbG3XRe42Vm97mB/IvLQCJOmokEjl3ps8yP1kbggyw==", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "util": "^0.12.5", + "web3-core-helpers": "1.10.3", + "web3-providers-http": "1.10.3", + "web3-providers-ipc": "1.10.3", + "web3-providers-ws": "1.10.3" }, "engines": { - "node": ">=8" + "node": ">=8.0.0" } }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, + "node_modules/web3-core-subscriptions": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.10.3.tgz", + "integrity": "sha512-KW0Mc8sgn70WadZu7RjQ4H5sNDJ5Lx8JMI3BWos+f2rW0foegOCyWhRu33W1s6ntXnqeBUw5rRCXZRlA3z+HNA==", "dependencies": { - "ansi-regex": "^5.0.1" + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.10.3" }, "engines": { - "node": ">=8" + "node": ">=8.0.0" } }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "optional": true, + "node_modules/web3-core/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" + }, + "node_modules/web3-eth": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.10.3.tgz", + "integrity": "sha512-Uk1U2qGiif2mIG8iKu23/EQJ2ksB1BQXy3wF3RvFuyxt8Ft9OEpmGlO7wOtAyJdoKzD5vcul19bJpPcWSAYZhA==", + "dependencies": { + "web3-core": "1.10.3", + "web3-core-helpers": "1.10.3", + "web3-core-method": "1.10.3", + "web3-core-subscriptions": "1.10.3", + "web3-eth-abi": "1.10.3", + "web3-eth-accounts": "1.10.3", + "web3-eth-contract": "1.10.3", + "web3-eth-ens": "1.10.3", + "web3-eth-iban": "1.10.3", + "web3-eth-personal": "1.10.3", + "web3-net": "1.10.3", + "web3-utils": "1.10.3" + }, "engines": { - "node": ">=4" + "node": ">=8.0.0" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, + "node_modules/web3-eth-abi": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.10.3.tgz", + "integrity": "sha512-O8EvV67uhq0OiCMekqYsDtb6FzfYzMXT7VMHowF8HV6qLZXCGTdB/NH4nJrEh2mFtEwVdS6AmLFJAQd2kVyoMQ==", + "dependencies": { + "@ethersproject/abi": "^5.6.3", + "web3-utils": "1.10.3" + }, "engines": { - "node": ">=8" + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.10.3.tgz", + "integrity": "sha512-8MipGgwusDVgn7NwKOmpeo3gxzzd+SmwcWeBdpXknuyDiZSQy9tXe+E9LeFGrmys/8mLLYP79n3jSbiTyv+6pQ==", + "dependencies": { + "@ethereumjs/common": "2.6.5", + "@ethereumjs/tx": "3.5.2", + "@ethereumjs/util": "^8.1.0", + "eth-lib": "0.2.8", + "scrypt-js": "^3.0.1", + "uuid": "^9.0.0", + "web3-core": "1.10.3", + "web3-core-helpers": "1.10.3", + "web3-core-method": "1.10.3", + "web3-utils": "1.10.3" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/web3-eth-accounts/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-eth-accounts/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" } }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, + "node_modules/web3-eth-contract": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.10.3.tgz", + "integrity": "sha512-Y2CW61dCCyY4IoUMD4JsEQWrILX4FJWDWC/Txx/pr3K/+fGsBGvS9kWQN5EsVXOp4g7HoFOfVh9Lf7BmVVSRmg==", "dependencies": { - "has-flag": "^4.0.0" + "@types/bn.js": "^5.1.1", + "web3-core": "1.10.3", + "web3-core-helpers": "1.10.3", + "web3-core-method": "1.10.3", + "web3-core-promievent": "1.10.3", + "web3-core-subscriptions": "1.10.3", + "web3-eth-abi": "1.10.3", + "web3-utils": "1.10.3" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "node": ">=8.0.0" } }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, + "node_modules/web3-eth-ens": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.10.3.tgz", + "integrity": "sha512-hR+odRDXGqKemw1GFniKBEXpjYwLgttTES+bc7BfTeoUyUZXbyDHe5ifC+h+vpzxh4oS0TnfcIoarK0Z9tFSiQ==", "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" + "content-hash": "^2.5.2", + "eth-ens-namehash": "2.0.8", + "web3-core": "1.10.3", + "web3-core-helpers": "1.10.3", + "web3-core-promievent": "1.10.3", + "web3-eth-abi": "1.10.3", + "web3-eth-contract": "1.10.3", + "web3-utils": "1.10.3" }, "engines": { - "node": ">=8" + "node": ">=8.0.0" } }, - "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, + "node_modules/web3-eth-iban": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.3.tgz", + "integrity": "sha512-ZCfOjYKAjaX2TGI8uif5ah+J3BYFuo+47JOIV1RIz2l7kD9VfnxvRH5UiQDRyMALQC7KFd2hUqIEtHklapNyKA==", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "bn.js": "^5.2.1", + "web3-utils": "1.10.3" + }, + "engines": { + "node": ">=8.0.0" } }, - "node_modules/test-exclude/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, + "node_modules/web3-eth-personal": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.10.3.tgz", + "integrity": "sha512-avrQ6yWdADIvuNQcFZXmGLCEzulQa76hUOuVywN7O3cklB4nFc/Gp3yTvD3bOAaE7DhjLQfhUTCzXL7WMxVTsw==", "dependencies": { - "brace-expansion": "^1.1.7" + "@types/node": "^12.12.6", + "web3-core": "1.10.3", + "web3-core-helpers": "1.10.3", + "web3-core-method": "1.10.3", + "web3-net": "1.10.3", + "web3-utils": "1.10.3" }, "engines": { - "node": "*" + "node": ">=8.0.0" } }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } + "node_modules/web3-eth-personal/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, + "node_modules/web3-net": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.10.3.tgz", + "integrity": "sha512-IoSr33235qVoI1vtKssPUigJU9Fc/Ph0T9CgRi15sx+itysmvtlmXMNoyd6Xrgm9LuM4CIhxz7yDzH93B79IFg==", "dependencies": { - "is-number": "^7.0.0" + "web3-core": "1.10.3", + "web3-core-method": "1.10.3", + "web3-utils": "1.10.3" }, "engines": { - "node": ">=8.0" + "node": ">=8.0.0" } }, - "node_modules/ts-mocha": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/ts-mocha/-/ts-mocha-10.0.0.tgz", - "integrity": "sha512-VRfgDO+iiuJFlNB18tzOfypJ21xn2xbuZyDvJvqpTbWgkAgD17ONGr8t+Tl8rcBtOBdjXp5e/Rk+d39f7XBHRw==", - "dev": true, + "node_modules/web3-providers-http": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.10.3.tgz", + "integrity": "sha512-6dAgsHR3MxJ0Qyu3QLFlQEelTapVfWNTu5F45FYh8t7Y03T1/o+YAkVxsbY5AdmD+y5bXG/XPJ4q8tjL6MgZHw==", "dependencies": { - "ts-node": "7.0.1" - }, - "bin": { - "ts-mocha": "bin/ts-mocha" + "abortcontroller-polyfill": "^1.7.5", + "cross-fetch": "^4.0.0", + "es6-promise": "^4.2.8", + "web3-core-helpers": "1.10.3" }, "engines": { - "node": ">= 6.X.X" - }, - "optionalDependencies": { - "tsconfig-paths": "^3.5.0" - }, - "peerDependencies": { - "mocha": "^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X" + "node": ">=8.0.0" } }, - "node_modules/ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, + "node_modules/web3-providers-ipc": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.10.3.tgz", + "integrity": "sha512-vP5WIGT8FLnGRfswTxNs9rMfS1vCbMezj/zHbBe/zB9GauBRTYVrUo2H/hVrhLg8Ut7AbsKZ+tCJ4mAwpKi2hA==", "dependencies": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "bin": { - "ts-node": "dist/bin.js" + "oboe": "2.1.5", + "web3-core-helpers": "1.10.3" }, "engines": { - "node": ">=4.2.0" + "node": ">=8.0.0" } }, - "node_modules/ts-node/node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, + "node_modules/web3-providers-ws": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.10.3.tgz", + "integrity": "sha512-/filBXRl48INxsh6AuCcsy4v5ndnTZ/p6bl67kmO9aK1wffv7CT++DrtclDtVMeDGCgB3van+hEf9xTAVXur7Q==", + "dependencies": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.10.3", + "websocket": "^1.0.32" + }, "engines": { - "node": ">=0.3.1" + "node": ">=8.0.0" } }, - "node_modules/tsconfig-paths": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", - "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", - "dev": true, - "optional": true, + "node_modules/web3-shh": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.10.3.tgz", + "integrity": "sha512-cAZ60CPvs9azdwMSQ/PSUdyV4PEtaW5edAZhu3rCXf6XxQRliBboic+AvwUvB6j3eswY50VGa5FygfVmJ1JVng==", + "hasInstallScript": true, "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" + "web3-core": "1.10.3", + "web3-core-method": "1.10.3", + "web3-core-subscriptions": "1.10.3", + "web3-net": "1.10.3" + }, + "engines": { + "node": ">=8.0.0" } }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, + "node_modules/web3-utils": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.3.tgz", + "integrity": "sha512-OqcUrEE16fDBbGoQtZXWdavsPzbGIDc5v3VrRTZ0XrIpefC/viZ1ZU9bGEemazyS0catk/3rkOOxpzTfY+XsyQ==", + "dependencies": { + "@ethereumjs/util": "^8.1.0", + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereum-cryptography": "^2.1.2", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, "engines": { - "node": ">=4" + "node": ">=8.0.0" } }, - "node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/websocket": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", + "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", + "dependencies": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, "engines": { - "node": ">=8" + "node": ">=4.0.0" } }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, + "node_modules/websocket/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "is-typedarray": "^1.0.0" + "ms": "2.0.0" } }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "node_modules/websocket/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" } }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -2801,8 +7468,77 @@ "node_modules/which-module": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==" + }, + "node_modules/which-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", + "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.4", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/wide-align/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/worker-threads": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/worker-threads/-/worker-threads-1.0.0.tgz", + "integrity": "sha512-vK6Hhvph8oLxocEJIlc3YfGAZhm210uGzjZsXSu+JYLAQ/s/w4Tqgl60JrdH58hW8NSGP4m3bp8a92qPXgX05w==" }, "node_modules/workerpool": { "version": "6.2.1", @@ -2814,7 +7550,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -2830,8 +7565,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/write-file-atomic": { "version": "3.0.3", @@ -2845,26 +7579,92 @@ "typedarray-to-buffer": "^3.1.5" } }, + "node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xhr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", + "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", + "dependencies": { + "global": "~4.4.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/xhr-request": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", + "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", + "dependencies": { + "buffer-to-arraybuffer": "^0.0.5", + "object-assign": "^4.1.1", + "query-string": "^5.0.1", + "simple-get": "^2.7.0", + "timed-out": "^4.0.1", + "url-set-query": "^1.0.0", + "xhr": "^2.0.4" + } + }, + "node_modules/xhr-request-promise": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", + "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", + "dependencies": { + "xhr-request": "^1.1.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, "engines": { "node": ">=10" } }, + "node_modules/yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", + "engines": { + "node": ">=0.10.32" + } + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -2882,7 +7682,6 @@ "version": "20.2.4", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, "engines": { "node": ">=10" } @@ -2891,7 +7690,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", @@ -2915,7 +7713,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, "engines": { "node": ">=10" }, diff --git a/core/package.json b/core/package.json index 400d9a0335..a2183854c9 100644 --- a/core/package.json +++ b/core/package.json @@ -2,8 +2,8 @@ "name": "maci-core", "version": "1.1.2", "description": "", - "main": "build/index.js", - "types": "build/index.d.ts", + "main": "build/ts/index.js", + "types": "build/ts/index.d.ts", "scripts": { "watch": "tsc --watch", "build": "tsc", @@ -13,7 +13,8 @@ }, "dependencies": { "maci-crypto": "^1.1.2", - "maci-domainobjs": "^1.1.2" + "maci-domainobjs": "^1.1.2", + "optimisedmt": "^0.0.9" }, "devDependencies": { "@types/chai": "^4.3.11", diff --git a/core/ts/MaciState.ts b/core/ts/MaciState.ts index 53ffedf8a3..38ae59652d 100644 --- a/core/ts/MaciState.ts +++ b/core/ts/MaciState.ts @@ -10,20 +10,23 @@ import { IJsonMaciState, IJsonPoll, IMaciState, MaxValues, TreeDepths } from "./ */ export class MaciState implements IMaciState { // a MaciState can hold multiple polls - public polls: Poll[] = []; + polls: Poll[] = []; // in this quinary tree we hold all signups (hash of a state leaf) - public stateTree: IncrementalQuinTree; + stateTree: IncrementalQuinTree; + // the leaves of the state tree - public stateLeaves: StateLeaf[] = []; + stateLeaves: StateLeaf[] = []; + // how deep the state tree is - public stateTreeDepth: number; + stateTreeDepth: number; - public numSignUps = 0; + numSignUps = 0; // to keep track if a poll is currently being processed - public pollBeingProcessed: boolean; - public currentPollBeingProcessed: number; + pollBeingProcessed?: boolean; + + currentPollBeingProcessed?: number; /** * Constructs a new MaciState object. @@ -45,8 +48,8 @@ export class MaciState implements IMaciState { * @param timestamp - The timestamp of the sign-up. * @returns The index of the newly signed-up user in the state tree. */ - public signUp(pubKey: PubKey, initialVoiceCreditBalance: bigint, timestamp: bigint): number { - this.numSignUps++; + signUp(pubKey: PubKey, initialVoiceCreditBalance: bigint, timestamp: bigint): number { + this.numSignUps += 1; const stateLeaf = new StateLeaf(pubKey, initialVoiceCreditBalance, timestamp); const hash = stateLeaf.hash(); this.stateTree.insert(hash); @@ -63,7 +66,7 @@ export class MaciState implements IMaciState { * @param coordinatorKeypair - The keypair of the MACI round coordinator. * @returns The index of the newly deployed poll. */ - public deployPoll( + deployPoll( pollEndTimestamp: bigint, maxValues: MaxValues, treeDepths: TreeDepths, @@ -75,7 +78,7 @@ export class MaciState implements IMaciState { coordinatorKeypair, treeDepths, { - messageBatchSize: messageBatchSize, + messageBatchSize, subsidyBatchSize: STATE_TREE_ARITY ** treeDepths.intStateTreeDepth, tallyBatchSize: STATE_TREE_ARITY ** treeDepths.intStateTreeDepth, }, @@ -90,19 +93,19 @@ export class MaciState implements IMaciState { /** * Deploy a null poll. */ - public deployNullPoll(): void { - this.polls.push(null); + deployNullPoll(): void { + this.polls.push(null as unknown as Poll); } /** * Create a deep copy of the MaciState object. * @returns A new instance of the MaciState object with the same properties. */ - public copy = (): MaciState => { + copy = (): MaciState => { const copied = new MaciState(this.stateTreeDepth); copied.stateLeaves = this.stateLeaves.map((x: StateLeaf) => x.copy()); - copied.polls = this.polls.map((x: Poll) => x.copy()); + copied.polls = this.polls.map((x) => x.copy()); return copied; }; @@ -112,20 +115,22 @@ export class MaciState implements IMaciState { * @param m - The MaciState object to compare. * @returns True if the two MaciState objects are equal, false otherwise. */ - public equals = (m: MaciState): boolean => { + equals = (m: MaciState): boolean => { const result = this.stateTreeDepth === m.stateTreeDepth && this.polls.length === m.polls.length && this.stateLeaves.length === m.stateLeaves.length; - if (!result) return false; + if (!result) { + return false; + } - for (let i = 0; i < this.polls.length; i++) { + for (let i = 0; i < this.polls.length; i += 1) { if (!this.polls[i].equals(m.polls[i])) { return false; } } - for (let i = 0; i < this.stateLeaves.length; i++) { + for (let i = 0; i < this.stateLeaves.length; i += 1) { if (!this.stateLeaves[i].equals(m.stateLeaves[i])) { return false; } @@ -143,7 +148,7 @@ export class MaciState implements IMaciState { stateTreeDepth: this.stateTreeDepth, polls: this.polls.map((poll) => poll.toJSON()), stateLeaves: this.stateLeaves.map((leaf) => leaf.toJSON()), - pollBeingProcessed: this.pollBeingProcessed, + pollBeingProcessed: Boolean(this.pollBeingProcessed), currentPollBeingProcessed: this.currentPollBeingProcessed ? this.currentPollBeingProcessed.toString() : "", numSignUps: this.numSignUps, }; @@ -160,11 +165,11 @@ export class MaciState implements IMaciState { // assign the json values to the new instance maciState.stateLeaves = json.stateLeaves.map((leaf) => StateLeaf.fromJSON(leaf)); maciState.pollBeingProcessed = json.pollBeingProcessed; - maciState.currentPollBeingProcessed = parseInt(json.currentPollBeingProcessed); + maciState.currentPollBeingProcessed = Number.parseInt(json.currentPollBeingProcessed, 10); maciState.numSignUps = json.numSignUps; // re create the state tree (start from index 1 as in the constructor we already add the blank leaf) - for (let i = 1; i < json.stateLeaves.length; i++) { + for (let i = 1; i < json.stateLeaves.length; i += 1) { const leaf = StateLeaf.fromJSON(json.stateLeaves[i]); const leafHash = leaf.hash(); maciState.stateTree.insert(leafHash); diff --git a/core/ts/Poll.ts b/core/ts/Poll.ts index 1abca9a6b9..74f9cd3dcd 100644 --- a/core/ts/Poll.ts +++ b/core/ts/Poll.ts @@ -1,4 +1,3 @@ -import assert from "assert"; import { IncrementalQuinTree, genRandomSalt, @@ -28,8 +27,13 @@ import { IJsonTCommand, } from "maci-domainobjs"; -import { MaciState } from "./MaciState"; -import { packTallyVotesSmallVals, packSubsidySmallVals } from "./utils/utils"; +import assert from "assert"; + +import type { MaciState } from "./MaciState"; +import type { PathElements } from "optimisedmt"; + +import { STATE_TREE_ARITY, MESSAGE_TREE_ARITY, VOTE_OPTION_TREE_ARITY } from "./utils/constants"; +import { ProcessMessageErrors, ProcessMessageError } from "./utils/errors"; import { CircuitInputs, TreeDepths, @@ -39,9 +43,7 @@ import { IJsonPoll, IProcessMessagesOutput, } from "./utils/types"; -import { ProcessMessageErrors, ProcessMessageError } from "./utils/errors"; -import { STATE_TREE_ARITY, MESSAGE_TREE_ARITY, VOTE_OPTION_TREE_ARITY } from "./utils/constants"; -import { PathElements } from "optimisedmt"; +import { packTallyVotesSmallVals, packSubsidySmallVals } from "./utils/utils"; /** * A representation of the Poll contract. @@ -49,59 +51,81 @@ import { PathElements } from "optimisedmt"; export class Poll implements IPoll { // Note that we only store the PubKey on-chain while this class stores the // Keypair for the sake of convenience - public coordinatorKeypair: Keypair; - public treeDepths: TreeDepths; - public batchSizes: BatchSizes; - public maxValues: MaxValues; + coordinatorKeypair: Keypair; + + treeDepths: TreeDepths; + + batchSizes: BatchSizes; + + maxValues: MaxValues; // the depth of the state tree - public stateTreeDepth: number; + stateTreeDepth: number; + + pollEndTimestamp: bigint; + + ballots: Ballot[] = []; + + ballotTree?: IncrementalQuinTree; - public pollEndTimestamp: bigint; + messages: Message[] = []; - public ballots: Ballot[] = []; - public ballotTree: IncrementalQuinTree; + messageTree: IncrementalQuinTree; - public messages: Message[] = []; - public messageTree: IncrementalQuinTree; - public commands: ICommand[] = []; + commands: ICommand[] = []; - public encPubKeys: PubKey[] = []; + encPubKeys: PubKey[] = []; - public stateCopied = false; - public stateLeaves: StateLeaf[] = [blankStateLeaf]; - public stateTree: IncrementalQuinTree; + stateCopied = false; + + stateLeaves: StateLeaf[] = [blankStateLeaf]; + + stateTree?: IncrementalQuinTree; // For message processing - public numBatchesProcessed = 0; - public currentMessageBatchIndex: number; - public maciStateRef: MaciState; - public pollId: number; + numBatchesProcessed = 0; + + currentMessageBatchIndex?: number; + + maciStateRef: MaciState; + + pollId: number; + + sbSalts: Record = {}; + + resultRootSalts: Record = {}; + + preVOSpentVoiceCreditsRootSalts: Record = {}; - public sbSalts: { [key: number]: bigint } = {}; - public resultRootSalts: { [key: number]: bigint } = {}; - public preVOSpentVoiceCreditsRootSalts: { [key: number]: bigint } = {}; - public spentVoiceCreditSubtotalSalts: { [key: number]: bigint } = {}; + spentVoiceCreditSubtotalSalts: Record = {}; // For vote tallying - public tallyResult: bigint[] = []; - public perVOSpentVoiceCredits: bigint[] = []; - public numBatchesTallied = 0; + tallyResult: bigint[] = []; - public totalSpentVoiceCredits = BigInt(0); + perVOSpentVoiceCredits: bigint[] = []; + + numBatchesTallied = 0; + + totalSpentVoiceCredits = BigInt(0); // For coefficient and subsidy calculation - public subsidy: bigint[] = []; // size: M, M is number of vote options - public subsidySalts: { [key: number]: bigint } = {}; - public rbi = 0; // row batch index - public cbi = 0; // column batch index - public MM = 50; // adjustable parameter - public WW = 4; // number of digits for float representation + subsidy: bigint[] = []; // size: M, M is number of vote options + + subsidySalts: Record = {}; + + rbi = 0; // row batch index + + cbi = 0; // column batch index + + MM = 50; // adjustable parameter + + WW = 4; // number of digits for float representation // an empty ballot and its hash to be used as zero value in the // ballot tree - public emptyBallot: Ballot; - public emptyBallotHash: bigint; + emptyBallot: Ballot; + + emptyBallotHash?: bigint; /** * Constructs a new Poll object. @@ -136,9 +160,9 @@ export class Poll implements IPoll { hash5, ); - this.tallyResult = new Array(this.maxValues.maxVoteOptions).fill(BigInt(0)); - this.perVOSpentVoiceCredits = new Array(this.maxValues.maxVoteOptions).fill(BigInt(0)); - this.subsidy = new Array(this.maxValues.maxVoteOptions).fill(BigInt(0)); + this.tallyResult = new Array(this.maxValues.maxVoteOptions).fill(BigInt(0)) as bigint[]; + this.perVOSpentVoiceCredits = new Array(this.maxValues.maxVoteOptions).fill(BigInt(0)) as bigint[]; + this.subsidy = new Array(this.maxValues.maxVoteOptions).fill(BigInt(0)) as bigint[]; // we put a blank state leaf to prevent a DoS attack this.emptyBallot = Ballot.genBlankBallot(this.maxValues.maxVoteOptions, treeDepths.voteOptionTreeDepth); @@ -148,7 +172,7 @@ export class Poll implements IPoll { /** * Copy the state from the MaciState instance. */ - public copyStateFromMaci = (): void => { + copyStateFromMaci = (): void => { // Copy the state tree, ballot tree, state leaves, and ballot leaves assert(this.maciStateRef.stateLeaves.length === this.maciStateRef.stateTree.nextIndex); @@ -175,7 +199,7 @@ export class Poll implements IPoll { * @param encPubKey - The public key associated with the encryption private key. * @returns A number of variables which will be used in the zk-SNARK circuit. */ - public processMessage = (message: Message, encPubKey: PubKey): IProcessMessagesOutput => { + processMessage = (message: Message, encPubKey: PubKey): IProcessMessagesOutput => { try { // Decrypt the message const sharedKey = Keypair.genEcdhSharedKey(this.coordinatorKeypair.privKey, encPubKey); @@ -188,7 +212,7 @@ export class Poll implements IPoll { if ( stateLeafIndex >= BigInt(this.ballots.length) || stateLeafIndex < BigInt(1) || - stateLeafIndex >= BigInt(this.stateTree.nextIndex) + stateLeafIndex >= BigInt(this.stateTree?.nextIndex || -1) ) { throw new ProcessMessageError(ProcessMessageErrors.InvalidStateLeafIndex); } @@ -225,9 +249,9 @@ export class Poll implements IPoll { // particular vote option with the new one // but we need to ensure that we are not going >= balance const voiceCreditsLeft = - BigInt(`${stateLeaf.voiceCreditBalance}`) + - BigInt(`${originalVoteWeight}`) * BigInt(`${originalVoteWeight}`) - - BigInt(`${command.newVoteWeight}`) * BigInt(`${command.newVoteWeight}`); + BigInt(stateLeaf.voiceCreditBalance) + + BigInt(originalVoteWeight) * BigInt(originalVoteWeight) - + BigInt(command.newVoteWeight) * BigInt(command.newVoteWeight); // If the remaining voice credits is insufficient, do nothing if (voiceCreditsLeft < BigInt(0)) { @@ -250,14 +274,14 @@ export class Poll implements IPoll { // calculate the path elements for the state tree given the original state tree (before any changes) // changes could effectively be made by this new vote - either a key change or vote change // would result in a different state leaf - const originalStateLeafPathElements = this.stateTree.genMerklePath(Number(stateLeafIndex)).pathElements; + const originalStateLeafPathElements = this.stateTree?.genMerklePath(Number(stateLeafIndex)).pathElements; // calculate the path elements for the ballot tree given the original ballot tree (before any changes) // changes could effectively be made by this new ballot - const originalBallotPathElements = this.ballotTree.genMerklePath(Number(stateLeafIndex)).pathElements; + const originalBallotPathElements = this.ballotTree?.genMerklePath(Number(stateLeafIndex)).pathElements; // create a new quinary tree where we insert the votes of the origin (up until this message is processed) ballot const vt = new IncrementalQuinTree(this.treeDepths.voteOptionTreeDepth, BigInt(0), STATE_TREE_ARITY, hash5); - for (let i = 0; i < this.ballots[0].votes.length; i++) { + for (let i = 0; i < this.ballots[0].votes.length; i += 1) { vt.insert(ballot.votes[i]); } // calculate the path elements for the vote option tree given the original vote option tree (before any changes) @@ -289,12 +313,13 @@ export class Poll implements IPoll { * Top up the voice credit balance of a user. * @param message - The message to top up the voice credit balance */ - public topupMessage = (message: Message): void => { - assert(message.msgType == BigInt(2), "A Topup message must have msgType 2"); + topupMessage = (message: Message): void => { + assert(message.msgType === BigInt(2), "A Topup message must have msgType 2"); - for (const d of message.data) { + message.data.forEach((d) => { assert(d < SNARK_FIELD_SIZE, "The message data is not in the correct range"); - } + }); + const padKey = new PubKey([ BigInt("10457101036533406547632367118273992217979173478358440826365724437999023779287"), BigInt("19824078218392094440610104313265183977899662750282163392862422243483260492317"), @@ -318,15 +343,16 @@ export class Poll implements IPoll { * @param message - The message to insert * @param encPubKey - The public key used to encrypt the message */ - public publishMessage = (message: Message, encPubKey: PubKey): void => { - assert(message.msgType == BigInt(1), "A vote or key change message must have msgType 1"); + publishMessage = (message: Message, encPubKey: PubKey): void => { + assert(message.msgType === BigInt(1), "A vote or key change message must have msgType 1"); assert( encPubKey.rawPubKey[0] < SNARK_FIELD_SIZE && encPubKey.rawPubKey[1] < SNARK_FIELD_SIZE, "The public key is not in the correct range", ); - for (const d of message.data) { + + message.data.forEach((d) => { assert(d < SNARK_FIELD_SIZE, "The message data is not in the correct range"); - } + }); // store the encryption pub key this.encPubKeys.push(encPubKey); @@ -356,13 +382,13 @@ export class Poll implements IPoll { * @returns Returns true if the number of processed batches is * less than the total number of batches, false otherwise. */ - public hasUnprocessedMessages = (): boolean => { + hasUnprocessedMessages = (): boolean => { const batchSize = this.batchSizes.messageBatchSize; let totalBatches = this.messages.length <= batchSize ? 1 : Math.floor(this.messages.length / batchSize); if (this.messages.length > batchSize && this.messages.length % batchSize > 0) { - totalBatches++; + totalBatches += 1; } return this.numBatchesProcessed < totalBatches; @@ -381,7 +407,7 @@ export class Poll implements IPoll { * process * @returns stringified circuit inputs */ - public processMessages = (pollId: number): CircuitInputs => { + processMessages = (pollId: number): CircuitInputs => { assert(this.hasUnprocessedMessages(), "No more messages to process"); const batchSize = this.batchSizes.messageBatchSize; @@ -392,7 +418,7 @@ export class Poll implements IPoll { // e.g if there are 8 messages and the batch size is 5, then // the starting index should be 5. assert( - this.currentMessageBatchIndex == undefined, + this.currentMessageBatchIndex === undefined, "The current message batch index should not be defined if this is the first batch", ); // Prevent other polls from being processed until this poll has @@ -424,8 +450,8 @@ export class Poll implements IPoll { } // The starting index must be valid - assert(this.currentMessageBatchIndex >= 0, "The starting index must be >= 0"); - assert(this.currentMessageBatchIndex % batchSize === 0, "The starting index must be a multiple of the batch size"); + assert(this.currentMessageBatchIndex! >= 0, "The starting index must be >= 0"); + assert(this.currentMessageBatchIndex! % batchSize === 0, "The starting index must be a multiple of the batch size"); // ensure we copy the state from MACI when we start processing the // first batch @@ -435,7 +461,7 @@ export class Poll implements IPoll { // Generate circuit inputs const circuitInputs = stringifyBigInts( - this.genProcessMessagesCircuitInputsPartial(this.currentMessageBatchIndex), + this.genProcessMessagesCircuitInputsPartial(this.currentMessageBatchIndex!), ) as CircuitInputs; // we want to store the state leaves at this point in time @@ -454,9 +480,9 @@ export class Poll implements IPoll { const currentVoteWeightsPathElements: PathElements[] = []; // loop through the batch of messages - for (let i = 0; i < batchSize; i++) { + for (let i = 0; i < batchSize; i += 1) { // we process the messages in reverse order - const idx = this.currentMessageBatchIndex + batchSize - i - 1; + const idx = this.currentMessageBatchIndex! + batchSize - i - 1; assert(idx >= 0, "The message index must be >= 0"); let message: Message; let encPubKey: PubKey; @@ -470,24 +496,24 @@ export class Poll implements IPoll { try { // check if the command is valid const r = this.processMessage(message, encPubKey); - const index = r.stateLeafIndex; + const index = r.stateLeafIndex!; // we add at position 0 the original data - currentStateLeaves.unshift(r.originalStateLeaf); - currentBallots.unshift(r.originalBallot); - currentVoteWeights.unshift(r.originalVoteWeight); - currentVoteWeightsPathElements.unshift(r.originalVoteWeightsPathElements); - currentStateLeavesPathElements.unshift(r.originalStateLeafPathElements); - currentBallotsPathElements.unshift(r.originalBallotPathElements); + currentStateLeaves.unshift(r.originalStateLeaf!); + currentBallots.unshift(r.originalBallot!); + currentVoteWeights.unshift(r.originalVoteWeight!); + currentVoteWeightsPathElements.unshift(r.originalVoteWeightsPathElements!); + currentStateLeavesPathElements.unshift(r.originalStateLeafPathElements!); + currentBallotsPathElements.unshift(r.originalBallotPathElements!); // update the state leaves with the new state leaf (result of processing the message) - this.stateLeaves[index] = r.newStateLeaf.copy(); + this.stateLeaves[index] = r.newStateLeaf!.copy(); // we also update the state tree with the hash of the new state leaf - this.stateTree.update(index, r.newStateLeaf.hash()); + this.stateTree?.update(index, r.newStateLeaf!.hash()); // store the new ballot - this.ballots[index] = r.newBallot; + this.ballots[index] = r.newBallot!; // update the ballot tree - this.ballotTree.update(index, r.newBallot.hash()); + this.ballotTree?.update(index, r.newBallot!.hash()); } catch (e) { // if the error is not a ProcessMessageError we throw it and exit here // otherwise we continue processing but add the default blank data instead of @@ -495,10 +521,10 @@ export class Poll implements IPoll { if (e instanceof ProcessMessageError) { // Since the command is invalid, use a blank state leaf currentStateLeaves.unshift(this.stateLeaves[0].copy()); - currentStateLeavesPathElements.unshift(this.stateTree.genMerklePath(0).pathElements); + currentStateLeavesPathElements.unshift(this.stateTree!.genMerklePath(0).pathElements); // since the command is invliad we use the blank ballot currentBallots.unshift(this.ballots[0].copy()); - currentBallotsPathElements.unshift(this.ballotTree.genMerklePath(0).pathElements); + currentBallotsPathElements.unshift(this.ballotTree!.genMerklePath(0).pathElements); // Since the command is invalid, we use a zero vote weight currentVoteWeights.unshift(this.ballots[0].votes[0]); @@ -526,21 +552,21 @@ export class Poll implements IPoll { const amount = message.data[0] >= BigInt(this.ballots.length) ? BigInt(0) : message.data[1]; currentStateLeaves.unshift(this.stateLeaves[stateIndex].copy()); - currentStateLeavesPathElements.unshift(this.stateTree.genMerklePath(stateIndex).pathElements); + currentStateLeavesPathElements.unshift(this.stateTree!.genMerklePath(stateIndex).pathElements); // create a copy of the state leaf const newStateLeaf = this.stateLeaves[stateIndex].copy(); // update the voice credit balance - newStateLeaf.voiceCreditBalance = newStateLeaf.voiceCreditBalance + amount; + newStateLeaf.voiceCreditBalance += amount; // save it this.stateLeaves[stateIndex] = newStateLeaf; // update the state tree - this.stateTree.update(stateIndex, newStateLeaf.hash()); + this.stateTree?.update(stateIndex, newStateLeaf.hash()); // we still need them as placeholder for vote command const currentBallot = this.ballots[stateIndex].copy(); currentBallots.unshift(currentBallot); - currentBallotsPathElements.unshift(this.ballotTree.genMerklePath(Number(stateIndex)).pathElements); + currentBallotsPathElements.unshift(this.ballotTree!.genMerklePath(Number(stateIndex)).pathElements); currentVoteWeights.unshift(currentBallot.votes[0]); // create a quinary tree to fill with the votes of the current ballot @@ -550,14 +576,16 @@ export class Poll implements IPoll { STATE_TREE_ARITY, hash5, ); - for (let i = 0; i < this.ballots[0].votes.length; i++) { - vt.insert(currentBallot.votes[i]); + + for (let j = 0; j < this.ballots[0].votes.length; j += 1) { + vt.insert(currentBallot.votes[j]); } // add to the first position the path elements of the vote weight tree currentVoteWeightsPathElements.unshift(vt.genMerklePath(0).pathElements); } catch (e) { - console.log("Error processing topup message: ", e.message); + // eslint-disable-next-line no-console + console.log("Error processing topup message: ", (e as Error).message); throw e; } break; @@ -567,10 +595,10 @@ export class Poll implements IPoll { } else { // Since we don't have a command at that position, use a blank state leaf currentStateLeaves.unshift(this.stateLeaves[0].copy()); - currentStateLeavesPathElements.unshift(this.stateTree.genMerklePath(0).pathElements); + currentStateLeavesPathElements.unshift(this.stateTree!.genMerklePath(0).pathElements); // since the command is invliad we use the blank ballot currentBallots.unshift(this.ballots[0].copy()); - currentBallotsPathElements.unshift(this.ballotTree.genMerklePath(0).pathElements); + currentBallotsPathElements.unshift(this.ballotTree!.genMerklePath(0).pathElements); // Since the command is invalid, we use a zero vote weight currentVoteWeights.unshift(this.ballots[0].votes[0]); @@ -593,23 +621,23 @@ export class Poll implements IPoll { circuitInputs.currentVoteWeightsPathElements = currentVoteWeightsPathElements; // record that we processed one batch - this.numBatchesProcessed++; + this.numBatchesProcessed += 1; - if (this.currentMessageBatchIndex > 0) { - this.currentMessageBatchIndex -= batchSize; + if (this.currentMessageBatchIndex! > 0) { + this.currentMessageBatchIndex! -= batchSize; } // ensure newSbSalt differs from currentSbSalt let newSbSalt = genRandomSalt(); - while (this.sbSalts[this.currentMessageBatchIndex] === newSbSalt) { + while (this.sbSalts[this.currentMessageBatchIndex!] === newSbSalt) { newSbSalt = genRandomSalt(); } - this.sbSalts[this.currentMessageBatchIndex] = newSbSalt; + this.sbSalts[this.currentMessageBatchIndex!] = newSbSalt; // store the salt in the circuit inputs circuitInputs.newSbSalt = newSbSalt; - const newStateRoot = this.stateTree.root; - const newBallotRoot = this.ballotTree.root; + const newStateRoot = this.stateTree!.root; + const newBallotRoot = this.ballotTree!.root; // create a commitment to the state and ballot tree roots // this will be the hash of the roots with a salt circuitInputs.newSbCommitment = hash3([newStateRoot, newBallotRoot, newSbSalt]); @@ -641,7 +669,7 @@ export class Poll implements IPoll { * @returns stringified partial circuit inputs */ private genProcessMessagesCircuitInputsPartial = (index: number): CircuitInputs => { - const messageBatchSize = this.batchSizes.messageBatchSize; + const { messageBatchSize } = this.batchSizes; assert(index <= this.messages.length, "The index must be <= the number of messages"); assert(index % messageBatchSize === 0, "The index must be a multiple of the message batch size"); @@ -671,7 +699,7 @@ export class Poll implements IPoll { const messageSubrootPath = this.messageTree.genMerkleSubrootPath(index, index + messageBatchSize); assert( - IncrementalQuinTree.verifyMerklePath(messageSubrootPath, this.messageTree.hashFunc) === true, + IncrementalQuinTree.verifyMerklePath(messageSubrootPath, this.messageTree.hashFunc), "The message subroot path is invalid", ); @@ -691,23 +719,25 @@ export class Poll implements IPoll { encPubKeys = encPubKeys.slice(index, index + messageBatchSize); const msgRoot = this.messageTree.root; - const currentStateRoot = this.stateTree.root; - const currentBallotRoot = this.ballotTree.root; + const currentStateRoot = this.stateTree!.root; + const currentBallotRoot = this.ballotTree!.root; // calculate the current state and ballot root // commitment which is the hash of the state tree // root, the ballot tree root and a salt const currentSbCommitment = hash3([ currentStateRoot, currentBallotRoot, - this.sbSalts[this.currentMessageBatchIndex], + this.sbSalts[this.currentMessageBatchIndex!], ]); // Generate a SHA256 hash of inputs which the contract provides + /* eslint-disable no-bitwise */ const packedVals = BigInt(this.maxValues.maxVoteOptions) + (BigInt(this.maciStateRef.numSignUps) << BigInt(50)) + (BigInt(index) << BigInt(100)) + (BigInt(batchEndIndex) << BigInt(150)); + /* eslint-enable no-bitwise */ return stringifyBigInts({ pollEndTimestamp: this.pollEndTimestamp, @@ -721,7 +751,7 @@ export class Poll implements IPoll { currentStateRoot, currentBallotRoot, currentSbCommitment, - currentSbSalt: this.sbSalts[this.currentMessageBatchIndex], + currentSbSalt: this.sbSalts[this.currentMessageBatchIndex!], }) as CircuitInputs; }; @@ -731,7 +761,7 @@ export class Poll implements IPoll { * to test the result of multiple processMessage() invocations. * @returns The state leaves and ballots of the poll */ - public processAllMessages = (): { stateLeaves: StateLeaf[]; ballots: Ballot[] } => { + processAllMessages = (): { stateLeaves: StateLeaf[]; ballots: Ballot[] } => { const stateLeaves = this.stateLeaves.map((x) => x.copy()); const ballots = this.ballots.map((x) => x.copy()); @@ -747,7 +777,7 @@ export class Poll implements IPoll { * Checks whether there are any untallied ballots. * @returns Whether there are any untallied ballots */ - public hasUntalliedBallots = (): boolean => { + hasUntalliedBallots = (): boolean => { const batchSize = this.batchSizes.tallyBatchSize; return this.numBatchesTallied * batchSize < this.ballots.length; }; @@ -759,7 +789,7 @@ export class Poll implements IPoll { * of the ballots array, indicating that there are still ballots left to be processed. * Otherwise, it returns false. */ - public hasUnfinishedSubsidyCalculation = (): boolean => { + hasUnfinishedSubsidyCalculation = (): boolean => { const batchSize = this.batchSizes.subsidyBatchSize; return this.rbi * batchSize < this.ballots.length && this.cbi * batchSize < this.ballots.length; }; @@ -768,14 +798,14 @@ export class Poll implements IPoll { * This method calculates the subsidy per batch. * @returns Returns an array of big integers which represent the circuit inputs for the subsidy calculation. */ - public subsidyPerBatch = (): CircuitInputs => { + subsidyPerBatch = (): CircuitInputs => { const batchSize = this.batchSizes.subsidyBatchSize; assert(this.hasUnfinishedSubsidyCalculation(), "No more subsidy batches to calculate"); - const stateRoot = this.stateTree.root; - const ballotRoot = this.ballotTree.root; - const sbSalt = this.sbSalts[this.currentMessageBatchIndex]; + const stateRoot = this.stateTree!.root; + const ballotRoot = this.ballotTree!.root; + const sbSalt = this.sbSalts[this.currentMessageBatchIndex!]; const sbCommitment = hash3([stateRoot, ballotRoot, sbSalt]); const currentSubsidy = this.subsidy.map((x) => BigInt(x.toString())); @@ -794,11 +824,11 @@ export class Poll implements IPoll { const colStartIndex = this.cbi * batchSize; const [ballots1, ballots2] = this.subsidyCalculation(rowStartIndex, colStartIndex); - const ballotSubrootProof1 = this.ballotTree.genMerkleSubrootPath(rowStartIndex, rowStartIndex + batchSize); - const ballotSubrootProof2 = this.ballotTree.genMerkleSubrootPath(colStartIndex, colStartIndex + batchSize); + const ballotSubrootProof1 = this.ballotTree?.genMerkleSubrootPath(rowStartIndex, rowStartIndex + batchSize); + const ballotSubrootProof2 = this.ballotTree?.genMerkleSubrootPath(colStartIndex, colStartIndex + batchSize); const newSubsidySalt = genRandomSalt(); - saltIndex = this.rbi.toString() + "-" + this.cbi.toString(); + saltIndex = `${this.rbi.toString()}-${this.cbi.toString()}`; this.subsidySalts[saltIndex] = newSubsidySalt; const newSubsidyCommitment = genTreeCommitment(this.subsidy, newSubsidySalt, this.treeDepths.voteOptionTreeDepth); @@ -826,8 +856,8 @@ export class Poll implements IPoll { ballots2: ballots2.map((x) => x.asCircuitInputs()), votes1: ballots1.map((x) => x.votes), votes2: ballots2.map((x) => x.votes), - ballotPathElements1: ballotSubrootProof1.pathElements, - ballotPathElements2: ballotSubrootProof2.pathElements, + ballotPathElements1: ballotSubrootProof1?.pathElements, + ballotPathElements2: ballotSubrootProof2?.pathElements, }); this.increaseSubsidyIndex(); @@ -840,9 +870,9 @@ export class Poll implements IPoll { private increaseSubsidyIndex = (): void => { const batchSize = this.batchSizes.subsidyBatchSize; if (this.cbi * batchSize + batchSize < this.ballots.length) { - this.cbi++; + this.cbi += 1; } else { - this.rbi++; + this.rbi += 1; this.cbi = this.rbi; } }; @@ -856,17 +886,17 @@ export class Poll implements IPoll { private previousSubsidyIndexToString = (): string => { const batchSize = this.batchSizes.subsidyBatchSize; const numBatches = Math.ceil(this.ballots.length / batchSize); - let cbi = this.cbi; - let rbi = this.rbi; + let { cbi } = this; + let { rbi } = this; if (this.cbi === 0 && this.rbi === 0) { return "0-0"; } if (this.cbi > this.rbi) { - cbi--; + cbi -= 1; } else { - rbi--; + rbi -= 1; cbi = numBatches - 1; } return `${rbi.toString()}-${cbi.toString()}`; @@ -881,7 +911,7 @@ export class Poll implements IPoll { */ private coefficientCalculation = (rowBallot: Ballot, colBallot: Ballot): bigint => { let sum = BigInt(0); - for (let p = 0; p < this.maxValues.maxVoteOptions; p++) { + for (let p = 0; p < this.maxValues.maxVoteOptions; p += 1) { sum += BigInt(rowBallot.votes[p].valueOf()) * BigInt(colBallot.votes[p].valueOf()); } const res = BigInt(this.MM * 10 ** this.WW) / (BigInt(this.MM) + BigInt(sum)); @@ -900,7 +930,7 @@ export class Poll implements IPoll { const ballots2: Ballot[] = []; const emptyBallot = new Ballot(this.maxValues.maxVoteOptions, this.treeDepths.voteOptionTreeDepth); - for (let i = 0; i < batchSize; i++) { + for (let i = 0; i < batchSize; i += 1) { const row = rowStartIndex + i; const col = colStartIndex + i; const rowBallot = row < this.ballots.length ? this.ballots[row] : emptyBallot; @@ -908,15 +938,15 @@ export class Poll implements IPoll { ballots1.push(rowBallot); ballots2.push(colBallot); } - for (let i = 0; i < batchSize; i++) { - for (let j = 0; j < batchSize; j++) { + for (let i = 0; i < batchSize; i += 1) { + for (let j = 0; j < batchSize; j += 1) { const row = rowStartIndex + i; const col = colStartIndex + j; const rowBallot = row < this.ballots.length ? this.ballots[row] : emptyBallot; const colBallot = col < this.ballots.length ? this.ballots[col] : emptyBallot; const kij = this.coefficientCalculation(rowBallot, colBallot); - for (let p = 0; p < this.maxValues.maxVoteOptions; p++) { + for (let p = 0; p < this.maxValues.maxVoteOptions; p += 1) { const vip = BigInt(rowBallot.votes[p].valueOf()); const vjp = BigInt(colBallot.votes[p].valueOf()); if (rowStartIndex !== colStartIndex || (rowStartIndex === colStartIndex && i < j)) { @@ -933,7 +963,7 @@ export class Poll implements IPoll { * This method tallies a ballots and updates the tally results. * @returns the circuit inputs for the TallyVotes circuit. */ - public tallyVotes = (): CircuitInputs => { + tallyVotes = (): CircuitInputs => { const batchSize = this.batchSizes.tallyBatchSize; assert(this.hasUntalliedBallots(), "No more ballots to tally"); @@ -975,14 +1005,14 @@ export class Poll implements IPoll { const currentPerVOSpentVoiceCredits = this.perVOSpentVoiceCredits.map((x) => BigInt(x.toString())); const currentSpentVoiceCreditSubtotal = BigInt(this.totalSpentVoiceCredits.toString()); - for (let i = this.numBatchesTallied * batchSize; i < this.numBatchesTallied * batchSize + batchSize; i++) { + for (let i = this.numBatchesTallied * batchSize; i < this.numBatchesTallied * batchSize + batchSize; i += 1) { if (i >= this.ballots.length) { break; } ballots.push(this.ballots[i]); - for (let j = 0; j < this.maxValues.maxVoteOptions; j++) { + for (let j = 0; j < this.maxValues.maxVoteOptions; j += 1) { const v = BigInt(`${this.ballots[i].votes[j]}`); this.tallyResult[j] = BigInt(`${this.tallyResult[j]}`) + v; @@ -1025,15 +1055,15 @@ export class Poll implements IPoll { newPerVOSpentVoiceCreditsCommitment, ]); - const stateRoot = this.stateTree.root; - const ballotRoot = this.ballotTree.root; - const sbSalt = this.sbSalts[this.currentMessageBatchIndex]; + const stateRoot = this.stateTree!.root; + const ballotRoot = this.ballotTree!.root; + const sbSalt = this.sbSalts[this.currentMessageBatchIndex!]; const sbCommitment = hash3([stateRoot, ballotRoot, sbSalt]); const packedVals = packTallyVotesSmallVals(batchStartIndex, batchSize, this.maciStateRef.numSignUps); const inputHash = sha256Hash([packedVals, sbCommitment, currentTallyCommitment, newTallyCommitment]); - const ballotSubrootProof = this.ballotTree.genMerkleSubrootPath(batchStartIndex, batchStartIndex + batchSize); + const ballotSubrootProof = this.ballotTree?.genMerkleSubrootPath(batchStartIndex, batchStartIndex + batchSize); const votes = ballots.map((x) => x.votes); @@ -1050,7 +1080,7 @@ export class Poll implements IPoll { inputHash, ballots: ballots.map((x) => x.asCircuitInputs()), - ballotPathElements: ballotSubrootProof.pathElements, + ballotPathElements: ballotSubrootProof?.pathElements, votes, currentResults, @@ -1067,7 +1097,7 @@ export class Poll implements IPoll { newSpentVoiceCreditSubtotalSalt, }); - this.numBatchesTallied++; + this.numBatchesTallied += 1; return circuitInputs as CircuitInputs; }; @@ -1086,9 +1116,9 @@ export class Poll implements IPoll { hash5, ); - for (const r of this.tallyResult) { + this.tallyResult.forEach((r) => { resultsTree.insert(r); - } + }); return hashLeftRight(resultsTree.root, salt); }; @@ -1103,11 +1133,12 @@ export class Poll implements IPoll { */ private genSpentVoiceCreditSubtotalCommitment = (salt: bigint, numBallotsToCount: number): bigint => { let subtotal = BigInt(0); - for (let i = 0; i < numBallotsToCount; i++) { + for (let i = 0; i < numBallotsToCount; i += 1) { if (this.ballots.length <= i) { break; } - for (let j = 0; j < this.tallyResult.length; j++) { + + for (let j = 0; j < this.tallyResult.length; j += 1) { const v = BigInt(`${this.ballots[i].votes[j]}`); subtotal = BigInt(subtotal) + v * v; } @@ -1134,23 +1165,23 @@ export class Poll implements IPoll { const leaves: bigint[] = []; - for (let i = 0; i < this.tallyResult.length; i++) { + this.tallyResult.forEach(() => { leaves.push(BigInt(0)); - } + }); - for (let i = 0; i < numBallotsToCount; i++) { + for (let i = 0; i < numBallotsToCount; i += 1) { if (i >= this.ballots.length) { break; } - for (let j = 0; j < this.tallyResult.length; j++) { + for (let j = 0; j < this.tallyResult.length; j += 1) { const v = BigInt(`${this.ballots[i].votes[j]}`); leaves[j] = BigInt(`${leaves[j]}`) + v * v; } } - for (let i = 0; i < leaves.length; i++) { - resultsTree.insert(leaves[i]); - } + leaves.forEach((leaf) => { + resultsTree.insert(leaf); + }); return hashLeftRight(resultsTree.root, salt); }; @@ -1159,7 +1190,7 @@ export class Poll implements IPoll { * Create a deep copy of the Poll object. * @returns A new instance of the Poll object with the same properties. */ - public copy = (): Poll => { + copy = (): Poll => { const copied = new Poll( BigInt(this.pollEndTimestamp.toString()), this.coordinatorKeypair.copy(), @@ -1207,18 +1238,21 @@ export class Poll implements IPoll { copied.preVOSpentVoiceCreditsRootSalts = {}; copied.spentVoiceCreditSubtotalSalts = {}; - for (const k of Object.keys(this.sbSalts)) { + Object.keys(this.sbSalts).forEach((k) => { copied.sbSalts[k] = BigInt(this.sbSalts[k].toString()); - } - for (const k of Object.keys(this.resultRootSalts)) { + }); + + Object.keys(this.resultRootSalts).forEach((k) => { copied.resultRootSalts[k] = BigInt(this.resultRootSalts[k].toString()); - } - for (const k of Object.keys(this.preVOSpentVoiceCreditsRootSalts)) { + }); + + Object.keys(this.preVOSpentVoiceCreditsRootSalts).forEach((k) => { copied.preVOSpentVoiceCreditsRootSalts[k] = BigInt(this.preVOSpentVoiceCreditsRootSalts[k].toString()); - } - for (const k of Object.keys(this.spentVoiceCreditSubtotalSalts)) { + }); + + Object.keys(this.spentVoiceCreditSubtotalSalts).forEach((k) => { copied.spentVoiceCreditSubtotalSalts[k] = BigInt(this.spentVoiceCreditSubtotalSalts[k].toString()); - } + }); // subsidy related copy copied.subsidy = this.subsidy.map((x: bigint) => BigInt(x.toString())); @@ -1226,9 +1260,11 @@ export class Poll implements IPoll { copied.cbi = Number(this.cbi.toString()); copied.MM = Number(this.MM.toString()); copied.WW = Number(this.WW.toString()); - for (const k of Object.keys(this.subsidySalts)) { + + Object.keys(this.subsidySalts).forEach((k) => { copied.subsidySalts[k] = BigInt(this.subsidySalts[k].toString()); - } + }); + return copied; }; @@ -1237,7 +1273,7 @@ export class Poll implements IPoll { * @param p - The Poll object to compare. * @returns True if the two Poll objects are equal, false otherwise. */ - public equals = (p: Poll): boolean => { + equals = (p: Poll): boolean => { const result = this.coordinatorKeypair.equals(p.coordinatorKeypair) && this.treeDepths.intStateTreeDepth === p.treeDepths.intStateTreeDepth && @@ -1251,14 +1287,16 @@ export class Poll implements IPoll { this.messages.length === p.messages.length && this.encPubKeys.length === p.encPubKeys.length; - if (!result) return false; + if (!result) { + return false; + } - for (let i = 0; i < this.messages.length; i++) { + for (let i = 0; i < this.messages.length; i += 1) { if (!this.messages[i].equals(p.messages[i])) { return false; } } - for (let i = 0; i < this.encPubKeys.length; i++) { + for (let i = 0; i < this.encPubKeys.length; i += 1) { if (!this.encPubKeys[i].equals(p.encPubKeys[i])) { return false; } @@ -1280,7 +1318,7 @@ export class Poll implements IPoll { commands: this.commands.map((command) => command.toJSON() as IJsonCommand), ballots: this.ballots.map((ballot) => ballot.toJSON()), encPubKeys: this.encPubKeys.map((encPubKey) => encPubKey.serialize()), - currentMessageBatchIndex: this.currentMessageBatchIndex, + currentMessageBatchIndex: this.currentMessageBatchIndex!, stateLeaves: this.stateLeaves.map((leaf) => leaf.toJSON()), results: this.tallyResult.map((result) => result.toString()), numBatchesProcessed: this.numBatchesProcessed, @@ -1304,7 +1342,7 @@ export class Poll implements IPoll { ); // set all properties - poll.ballots = json.ballots.map((ballot: Ballot) => Ballot.fromJSON(ballot)); + poll.ballots = json.ballots.map((ballot) => Ballot.fromJSON(ballot)); poll.encPubKeys = json.encPubKeys.map((key: string) => PubKey.deserialize(key)); poll.messages = json.messages.map((message) => Message.fromJSON(message as IMessageContractParams)); poll.commands = json.commands.map((command: IJsonCommand) => { @@ -1312,9 +1350,11 @@ export class Poll implements IPoll { case "1": { return PCommand.fromJSON(command as IJsonPCommand) as ICommand; } + case "2": { return TCommand.fromJSON(command as IJsonTCommand) as ICommand; } + default: { return { cmdType: command.cmdType } as unknown as ICommand; } @@ -1325,7 +1365,7 @@ export class Poll implements IPoll { poll.numBatchesProcessed = json.numBatchesProcessed; // fill the trees - for (let i = 0; i < poll.messages.length; i++) { + for (let i = 0; i < poll.messages.length; i += 1) { const messageLeaf = poll.messages[i].hash(poll.encPubKeys[i]); poll.messageTree.insert(messageLeaf); } @@ -1340,7 +1380,7 @@ export class Poll implements IPoll { * Set the coordinator's keypair * @param serializedPrivateKey - the serialized private key */ - public setCoordinatorKeypair = (serializedPrivateKey: string): void => { + setCoordinatorKeypair = (serializedPrivateKey: string): void => { this.coordinatorKeypair = new Keypair(PrivKey.deserialize(serializedPrivateKey)); }; } diff --git a/core/ts/__tests__/MaciState.test.ts b/core/ts/__tests__/MaciState.test.ts index 29dc599867..f2d023f730 100644 --- a/core/ts/__tests__/MaciState.test.ts +++ b/core/ts/__tests__/MaciState.test.ts @@ -1,18 +1,19 @@ -import { existsSync, readFileSync, unlinkSync, writeFileSync } from "fs"; - import { expect } from "chai"; - -import { PCommand, Message, Keypair, StateLeaf, blankStateLeafHash, PrivKey, Ballot } from "maci-domainobjs"; import { hash5, NOTHING_UP_MY_SLEEVE, IncrementalQuinTree, AccQueue } from "maci-crypto"; +import { PCommand, Message, Keypair, StateLeaf, blankStateLeafHash, PrivKey, Ballot } from "maci-domainobjs"; + +import { existsSync, readFileSync, unlinkSync, writeFileSync } from "fs"; -import { STATE_TREE_DEPTH, STATE_TREE_ARITY, STATE_TREE_SUBDEPTH } from "../utils/constants"; import { MaciState } from "../MaciState"; -import { packProcessMessageSmallVals, unpackProcessMessageSmallVals } from "../utils/utils"; import { Poll } from "../Poll"; -import { calculateTotal } from "./utils"; +import { STATE_TREE_DEPTH, STATE_TREE_ARITY, STATE_TREE_SUBDEPTH } from "../utils/constants"; +import { IJsonMaciState } from "../utils/types"; +import { packProcessMessageSmallVals, unpackProcessMessageSmallVals } from "../utils/utils"; + import { coordinatorKeypair, duration, maxValues, messageBatchSize, treeDepths, voiceCreditBalance } from "./constants"; +import { calculateTotal } from "./utils"; -describe("MaciState", function () { +describe("MaciState", function test() { this.timeout(100000); describe("Process and tally 1 message from 1 user", () => { @@ -45,7 +46,7 @@ describe("MaciState", function () { stateIndex = maciState.signUp(userKeypair.pubKey, voiceCreditBalance, timestamp); expect(stateIndex.toString()).to.eq("1"); - expect(accumulatorQueue.getRoot(STATE_TREE_DEPTH).toString()).to.eq(maciState.stateTree.root.toString()); + expect(accumulatorQueue.getRoot(STATE_TREE_DEPTH)?.toString()).to.eq(maciState.stateTree.root.toString()); }); it("the message root should be correct", () => { @@ -87,7 +88,7 @@ describe("MaciState", function () { accumulatorQueue.mergeSubRoots(0); accumulatorQueue.merge(treeDepths.messageTreeDepth); - expect(accumulatorQueue.getRoot(treeDepths.messageTreeDepth).toString()).to.eq(msgTree.root.toString()); + expect(accumulatorQueue.getRoot(treeDepths.messageTreeDepth)?.toString()).to.eq(msgTree.root.toString()); }); it("packProcessMessageSmallVals and unpackProcessMessageSmallVals", () => { @@ -119,7 +120,7 @@ describe("MaciState", function () { const initialTotal = calculateTotal(maciState.polls[pollId].tallyResult); expect(initialTotal.toString()).to.eq("0"); - expect(poll.hasUntalliedBallots()).to.be.true; + expect(poll.hasUntalliedBallots()).to.eq(true); poll.tallyVotes(); @@ -139,7 +140,7 @@ describe("MaciState", function () { before(() => { maciState = new MaciState(STATE_TREE_DEPTH); // Sign up and vote - for (let i = 0; i < messageBatchSize - 1; i++) { + for (let i = 0; i < messageBatchSize - 1; i += 1) { const userKeypair = new Keypair(); users.push(userKeypair); @@ -158,7 +159,7 @@ describe("MaciState", function () { it("should process votes correctly", () => { // 24 valid votes - for (let i = 0; i < messageBatchSize - 1; i++) { + for (let i = 0; i < messageBatchSize - 1; i += 1) { const userKeypair = users[i]; const command = new PCommand( @@ -181,7 +182,7 @@ describe("MaciState", function () { expect(poll.messages.length).to.eq(messageBatchSize - 1); // 24 invalid votes - for (let i = 0; i < messageBatchSize - 1; i++) { + for (let i = 0; i < messageBatchSize - 1; i += 1) { const userKeypair = users[i]; const command = new PCommand( BigInt(i + 1), @@ -220,7 +221,7 @@ describe("MaciState", function () { expect(poll.currentMessageBatchIndex).to.eq(0); expect(poll.numBatchesProcessed).to.eq(2); - for (let i = 1; i < messageBatchSize; i++) { + for (let i = 1; i < messageBatchSize; i += 1) { const leaf = poll.ballots[i].votes[i - 1]; expect(leaf.toString()).to.eq(voteWeight.toString()); } @@ -234,10 +235,10 @@ describe("MaciState", function () { expect(r.ballots.length).to.eq(r.stateLeaves.length); - for (let i = 0; i < r.stateLeaves.length; i++) { - expect(r.stateLeaves[i].equals(poll.stateLeaves[i])).to.be.true; + for (let i = 0; i < r.stateLeaves.length; i += 1) { + expect(r.stateLeaves[i].equals(poll.stateLeaves[i])).to.eq(true); - expect(r.ballots[i].equals(poll.ballots[i])).to.be.true; + expect(r.ballots[i].equals(poll.ballots[i])).to.eq(true); } }); @@ -247,33 +248,35 @@ describe("MaciState", function () { expect(total.toString()).to.eq("0"); // Check that there are untallied results - expect(poll.hasUntalliedBallots()).to.be.true; + expect(poll.hasUntalliedBallots()).to.eq(true); // First batch tally poll.tallyVotes(); // Recall that each user `i` cast the same number of votes for // their option `i` - for (let i = 0; i < maciState.polls[pollId].tallyResult.length - 1; i++) { + for (let i = 0; i < maciState.polls[pollId].tallyResult.length - 1; i += 1) { expect(maciState.polls[pollId].tallyResult[i].toString()).to.eq(voteWeight.toString()); } - expect(poll.hasUntalliedBallots()).to.be.false; + expect(poll.hasUntalliedBallots()).to.eq(false); expect(() => { poll.tallyVotes(); - }).to.throw; + }).to.throw(); }); }); describe("Deep copy", () => { - let pollId; + let pollId: number; let m1: MaciState; const userKeypair = new Keypair(); const stateFile = "./state.json"; after(() => { - if (existsSync(stateFile)) unlinkSync(stateFile); + if (existsSync(stateFile)) { + unlinkSync(stateFile); + } }); before(() => { @@ -308,85 +311,86 @@ describe("MaciState", function () { const m2 = m1.copy(); // modify stateTreeDepth - m2.stateTreeDepth = m2.stateTreeDepth + 1; - expect(m1.equals(m2)).not.to.be.true; + m2.stateTreeDepth += 1; + expect(m1.equals(m2)).not.to.eq(true); // modify user.pubKey const m3 = m1.copy(); m3.stateLeaves[0].pubKey = new Keypair().pubKey; - expect(m1.equals(m3)).not.to.be.true; + expect(m1.equals(m3)).not.to.eq(true); // modify user.voiceCreditBalance const m4 = m1.copy(); m4.stateLeaves[0].voiceCreditBalance = BigInt(m4.stateLeaves[0].voiceCreditBalance) + BigInt(1); - expect(m1.equals(m4)).not.to.be.true; + expect(m1.equals(m4)).not.to.eq(true); // modify poll.coordinatorKeypair const m6 = m1.copy(); m6.polls[pollId].coordinatorKeypair = new Keypair(); - expect(m1.equals(m6)).not.to.be.true; + expect(m1.equals(m6)).not.to.eq(true); // modify poll.treeDepths.intStateTreeDepth const m9 = m1.copy(); - m9.polls[pollId].treeDepths.intStateTreeDepth = m9.polls[pollId].treeDepths.intStateTreeDepth + 1; - expect(m1.equals(m9)).not.to.be.true; + m9.polls[pollId].treeDepths.intStateTreeDepth += 1; + expect(m1.equals(m9)).not.to.eq(true); // modify poll.treeDepths.messageTreeDepth const m10 = m1.copy(); - m10.polls[pollId].treeDepths.messageTreeDepth = m10.polls[pollId].treeDepths.messageTreeDepth + 1; - expect(m1.equals(m10)).not.to.be.true; + m10.polls[pollId].treeDepths.messageTreeDepth += 1; + expect(m1.equals(m10)).not.to.eq(true); // modify poll.treeDepths.messageTreeSubDepth const m11 = m1.copy(); - m11.polls[pollId].treeDepths.messageTreeSubDepth = m11.polls[pollId].treeDepths.messageTreeSubDepth + 1; - expect(m1.equals(m11)).not.to.be.true; + m11.polls[pollId].treeDepths.messageTreeSubDepth += 1; + expect(m1.equals(m11)).not.to.eq(true); // modify poll.treeDepths.voteOptionTreeDepth const m12 = m1.copy(); - m12.polls[pollId].treeDepths.voteOptionTreeDepth = m12.polls[pollId].treeDepths.voteOptionTreeDepth + 1; - expect(m1.equals(m12)).not.to.be.true; + m12.polls[pollId].treeDepths.voteOptionTreeDepth += 1; + expect(m1.equals(m12)).not.to.eq(true); // modify poll.batchSizes.tallyBatchSize const m13 = m1.copy(); - m13.polls[pollId].batchSizes.tallyBatchSize = m13.polls[pollId].batchSizes.tallyBatchSize + 1; - expect(m1.equals(m13)).not.to.be.true; + m13.polls[pollId].batchSizes.tallyBatchSize += 1; + expect(m1.equals(m13)).not.to.eq(true); // modify poll.batchSizes.messageBatchSize const m14 = m1.copy(); - m14.polls[pollId].batchSizes.messageBatchSize = m14.polls[pollId].batchSizes.messageBatchSize + 1; - expect(m1.equals(m14)).not.to.be.true; + m14.polls[pollId].batchSizes.messageBatchSize += 1; + expect(m1.equals(m14)).not.to.eq(true); // modify poll.maxValues.maxMessages const m16 = m1.copy(); - m16.polls[pollId].maxValues.maxMessages = m16.polls[pollId].maxValues.maxMessages + 1; - expect(m1.equals(m16)).not.to.be.true; + m16.polls[pollId].maxValues.maxMessages += 1; + expect(m1.equals(m16)).not.to.eq(true); // modify poll.maxValues.maxVoteOptions const m17 = m1.copy(); - m17.polls[pollId].maxValues.maxVoteOptions = m17.polls[pollId].maxValues.maxVoteOptions + 1; - expect(m1.equals(m17)).not.to.be.true; + m17.polls[pollId].maxValues.maxVoteOptions += 1; + expect(m1.equals(m17)).not.to.eq(true); // modify poll.messages const m20 = m1.copy(); m20.polls[pollId].messages[0].data[0] = BigInt(m20.polls[pollId].messages[0].data[0]) + BigInt(1); - expect(m1.equals(m20)).not.to.be.true; + expect(m1.equals(m20)).not.to.eq(true); // modify poll.encPubKeys const m21 = m1.copy(); m21.polls[pollId].encPubKeys[0] = new Keypair().pubKey; - expect(m1.equals(m21)).not.to.be.true; + expect(m1.equals(m21)).not.to.eq(true); }); it("should create a JSON object from a MaciState object", () => { const json = m1.toJSON(); writeFileSync(stateFile, JSON.stringify(json, null, 4)); - const content = JSON.parse(readFileSync(stateFile).toString()); + const content = JSON.parse(readFileSync(stateFile).toString()) as IJsonMaciState; const state = MaciState.fromJSON(content); - for (const poll of state.polls) { + state.polls.forEach((poll) => { poll.setCoordinatorKeypair(coordinatorKeypair.privKey.serialize()); - expect(poll.coordinatorKeypair.equals(coordinatorKeypair)).to.be.true; - } - expect(state.equals(m1)).to.be.true; + expect(poll.coordinatorKeypair.equals(coordinatorKeypair)).to.eq(true); + }); + + expect(state.equals(m1)).to.eq(true); }); }); @@ -666,7 +670,7 @@ describe("MaciState", function () { it("should fill the batch with random messages", () => { const poll = maciState.polls[pollId]; - for (let i = 0; i < messageBatchSize - 1; i++) { + for (let i = 0; i < messageBatchSize - 1; i += 1) { const command = new PCommand( BigInt(1), user1Keypair.pubKey, @@ -818,7 +822,7 @@ describe("MaciState", function () { user1Keypair.pubKey, BigInt(0), // voice credits spent would be this value ** this value - BigInt(Math.sqrt(parseInt(voiceCreditBalance.toString())) + 1), + BigInt(Math.sqrt(Number.parseInt(voiceCreditBalance.toString(), 10)) + 1), BigInt(1), BigInt(pollId), ); @@ -1003,6 +1007,8 @@ describe("MaciState", function () { poll.processMessage(message, ecdhKeypair.pubKey); }).to.throw("invalid state leaf index"); + // keep this call to complete processing + // eslint-disable-next-line no-unused-expressions expect(() => poll.processMessages(pollId)).to.not.throw; }); @@ -1073,7 +1079,7 @@ describe("MaciState", function () { poll.processMessage(message, ecdhKeypair.pubKey); }).to.throw("invalid state leaf index"); - expect(() => poll.processAllMessages()).to.not.throw; + expect(() => poll.processAllMessages()).to.not.throw(); }); it("should return the correct state leaves and ballots", () => { diff --git a/core/ts/__tests__/ProcessMessage.test.ts b/core/ts/__tests__/ProcessMessage.test.ts deleted file mode 100644 index 074209dbc7..0000000000 --- a/core/ts/__tests__/ProcessMessage.test.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* eslint-disable */ -describe("Message processing", () => { - describe("Process a batch of messages", () => { - let maciState; - - before(async () => {}); - - it("TODO: processMessage() should process a valid message", async () => {}); - - it("TODO: processMessage() should not process a message with an incorrect nonce", async () => {}); - - it("TODO: processMessage() should not process a message with an incorrect vote weight", async () => {}); - - it("TODO: processMessage() should not process a message with an incorrect state tree index", async () => {}); - - it("TODO: processMessage() should not process a message with an incorrect signature", async () => {}); - - it("TODO: processMessage() should not process a message with an invalid maxVoteOptionIndex", async () => {}); - }); -}); diff --git a/core/ts/index.ts b/core/ts/index.ts index 9e5bfa1e0b..89a9290abf 100644 --- a/core/ts/index.ts +++ b/core/ts/index.ts @@ -11,7 +11,7 @@ export { packSubsidySmallVals, } from "./utils/utils"; -export { CircuitInputs, MaxValues, TreeDepths, BatchSizes } from "./utils/types"; +export type { CircuitInputs, MaxValues, TreeDepths, BatchSizes } from "./utils/types"; export { STATE_TREE_DEPTH, STATE_TREE_ARITY, diff --git a/core/ts/utils/types.ts b/core/ts/utils/types.ts index 2e8ac887a9..1718d99683 100644 --- a/core/ts/utils/types.ts +++ b/core/ts/utils/types.ts @@ -1,4 +1,6 @@ -import { +import type { MaciState } from "../MaciState"; +import type { Poll } from "../Poll"; +import type { Ballot, IJsonBallot, IJsonCommand, @@ -12,9 +14,7 @@ import { StateLeaf, TCommand, } from "maci-domainobjs"; -import { MaciState } from "../MaciState"; -import { Poll } from "../Poll"; -import { PathElements } from "optimisedmt"; +import type { PathElements } from "optimisedmt"; /** * A circuit inputs for the circom circuit diff --git a/core/ts/utils/utils.ts b/core/ts/utils/utils.ts index 8e3a59b00f..c509343638 100644 --- a/core/ts/utils/utils.ts +++ b/core/ts/utils/utils.ts @@ -1,28 +1,26 @@ +/* eslint-disable no-bitwise */ import assert from "assert"; /** * This function generates the signature of a ProcessMessage Verifying Key(VK). * This can be used to check if a ProcessMessages' circuit VK is registered * in a smart contract that holds several VKs. - * @param _stateTreeDepth - The depth of the state tree. + * @param stateTreeDepth - The depth of the state tree. * @param messageTreeDepth - The depth of the message tree. - * @param _voteOptionTreeDepth - The depth of the vote option tree. - * @param _batchSize - The size of the batch. + * @param voteOptionTreeDepth - The depth of the vote option tree. + * @param batchSize - The size of the batch. * @returns Returns a signature for querying if a verifying key with the given parameters is already registered in the contract. */ export const genProcessVkSig = ( - _stateTreeDepth: number, + stateTreeDepth: number, messageTreeDepth: number, - _voteOptionTreeDepth: number, - _batchSize: number, -): bigint => { - return ( - (BigInt(_batchSize) << BigInt(192)) + - (BigInt(_stateTreeDepth) << BigInt(128)) + - (BigInt(messageTreeDepth) << BigInt(64)) + - BigInt(_voteOptionTreeDepth) - ); -}; + voteOptionTreeDepth: number, + batchSize: number, +): bigint => + (BigInt(batchSize) << BigInt(192)) + + (BigInt(stateTreeDepth) << BigInt(128)) + + (BigInt(messageTreeDepth) << BigInt(64)) + + BigInt(voteOptionTreeDepth); /** * This function generates the signature of a Tally Verifying Key(VK). @@ -38,11 +36,8 @@ export const genTallyVkSig = ( _stateTreeDepth: number, _intStateTreeDepth: number, _voteOptionTreeDepth: number, -): bigint => { - return ( - (BigInt(_stateTreeDepth) << BigInt(128)) + (BigInt(_intStateTreeDepth) << BigInt(64)) + BigInt(_voteOptionTreeDepth) - ); -}; +): bigint => + (BigInt(_stateTreeDepth) << BigInt(128)) + (BigInt(_intStateTreeDepth) << BigInt(64)) + BigInt(_voteOptionTreeDepth); /** * This function generates the signature of a Subsidy Verifying Key(VK). @@ -58,11 +53,8 @@ export const genSubsidyVkSig = ( _stateTreeDepth: number, _intStateTreeDepth: number, _voteOptionTreeDepth: number, -): bigint => { - return ( - (BigInt(_stateTreeDepth) << BigInt(128)) + (BigInt(_intStateTreeDepth) << BigInt(64)) + BigInt(_voteOptionTreeDepth) - ); -}; +): bigint => + (BigInt(_stateTreeDepth) << BigInt(128)) + (BigInt(_intStateTreeDepth) << BigInt(64)) + BigInt(_voteOptionTreeDepth); /** * This function packs it's parameters into a single bigint. @@ -93,16 +85,23 @@ export const packProcessMessageSmallVals = ( * @param packedVals - The single bigint that contains the packed values. * @returns Returns an object that contains the unpacked values. */ -export const unpackProcessMessageSmallVals = (packedVals: bigint) => { +export const unpackProcessMessageSmallVals = ( + packedVals: bigint, +): { + maxVoteOptions: bigint; + numUsers: bigint; + batchStartIndex: bigint; + batchEndIndex: bigint; +} => { let asBin = packedVals.toString(2); assert(asBin.length <= 200); while (asBin.length < 200) { - asBin = "0" + asBin; + asBin = `0${asBin}`; } - const maxVoteOptions = BigInt("0b" + asBin.slice(150, 200)); - const numUsers = BigInt("0b" + asBin.slice(100, 150)); - const batchStartIndex = BigInt("0b" + asBin.slice(50, 100)); - const batchEndIndex = BigInt("0b" + asBin.slice(0, 50)); + const maxVoteOptions = BigInt(`0b${asBin.slice(150, 200)}`); + const numUsers = BigInt(`0b${asBin.slice(100, 150)}`); + const batchStartIndex = BigInt(`0b${asBin.slice(50, 100)}`); + const batchEndIndex = BigInt(`0b${asBin.slice(0, 50)}`); return { maxVoteOptions, @@ -131,14 +130,14 @@ export const packTallyVotesSmallVals = (batchStartIndex: number, batchSize: numb * @param packedVals - The single bigint that contains the packed values. * @returns Returns an object that contains the unpacked values. */ -export const unpackTallyVotesSmallVals = (packedVals: bigint) => { +export const unpackTallyVotesSmallVals = (packedVals: bigint): { numSignUps: bigint; batchStartIndex: bigint } => { let asBin = packedVals.toString(2); assert(asBin.length <= 100); while (asBin.length < 100) { - asBin = "0" + asBin; + asBin = `0${asBin}`; } - const numSignUps = BigInt("0b" + asBin.slice(0, 50)); - const batchStartIndex = BigInt("0b" + asBin.slice(50, 100)); + const numSignUps = BigInt(`0b${asBin.slice(0, 50)}`); + const batchStartIndex = BigInt(`0b${asBin.slice(50, 100)}`); return { numSignUps, batchStartIndex }; }; @@ -150,7 +149,7 @@ export const unpackTallyVotesSmallVals = (packedVals: bigint) => { * @param numSignUps - The number of signups. * @returns Returns a single bigint that contains the packed values. */ -export const packSubsidySmallVals = (row: number, col: number, numSignUps: number) => { +export const packSubsidySmallVals = (row: number, col: number, numSignUps: number): bigint => { // Note: the << operator has lower precedence than + const packedVals = (BigInt(numSignUps) << BigInt(100)) + (BigInt(row) << BigInt(50)) + BigInt(col); diff --git a/core/tsconfig.json b/core/tsconfig.json index 2c26af36c1..3e1726e913 100644 --- a/core/tsconfig.json +++ b/core/tsconfig.json @@ -1,7 +1,33 @@ { "extends": "../tsconfig.json", "compilerOptions": { - "outDir": "./build" + "outDir": "./build", + "declaration": true, + "allowJs": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "target": "ES2020", + "lib": ["es2020"], + "experimentalDecorators": true, + "strict": true, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "strictPropertyInitialization": true, + "strictNullChecks": true, + "module": "commonjs", + "moduleResolution": "node", + "resolveJsonModule": true, + "skipLibCheck": true, + "esModuleInterop": true, + "isolatedModules": true, + "forceConsistentCasingInFileNames": true, + "allowSyntheticDefaultImports": true, + "composite": true, + "incremental": true, + "declarationMap": true, + "sourceMap": true, + "stripInternal": true }, "include": ["./ts"], "exclude": ["./ts/__tests__.old"] From 35866fb0f086b18835b74e5ecdb55aaceb3ef8db Mon Sep 17 00:00:00 2001 From: 0xmad <0xmad@users.noreply.github.com> Date: Wed, 3 Jan 2024 08:22:35 -0600 Subject: [PATCH 15/37] chore(crypto): add type export for path elements --- core/package-lock.json | 13 +------------ core/package.json | 3 +-- core/ts/Poll.ts | 2 +- core/ts/utils/types.ts | 2 +- crypto/ts/index.ts | 2 +- 5 files changed, 5 insertions(+), 17 deletions(-) diff --git a/core/package-lock.json b/core/package-lock.json index e32c2a02f5..f860d5d94d 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -9,8 +9,7 @@ "version": "1.1.2", "dependencies": { "maci-crypto": "^1.1.2", - "maci-domainobjs": "^1.1.2", - "optimisedmt": "^0.0.9" + "maci-domainobjs": "^1.1.2" }, "devDependencies": { "@types/chai": "^4.3.11", @@ -5566,16 +5565,6 @@ "wrappy": "1" } }, - "node_modules/optimisedmt": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/optimisedmt/-/optimisedmt-0.0.9.tgz", - "integrity": "sha512-NgpgliUnd8hY8HG3i+mUJ8n+g4zuv/GrcMQDciOZC8OEOYSiBr2gUlM/trnh28YFKKm0VInMECEOA6nr1swoEg==", - "dependencies": { - "assert": "^2.0.0", - "circomlibjs": "0.0.8", - "ffjavascript": "^0.2.39" - } - }, "node_modules/p-cancelable": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", diff --git a/core/package.json b/core/package.json index a2183854c9..88de0df614 100644 --- a/core/package.json +++ b/core/package.json @@ -13,8 +13,7 @@ }, "dependencies": { "maci-crypto": "^1.1.2", - "maci-domainobjs": "^1.1.2", - "optimisedmt": "^0.0.9" + "maci-domainobjs": "^1.1.2" }, "devDependencies": { "@types/chai": "^4.3.11", diff --git a/core/ts/Poll.ts b/core/ts/Poll.ts index 74f9cd3dcd..99268dbfd2 100644 --- a/core/ts/Poll.ts +++ b/core/ts/Poll.ts @@ -30,7 +30,7 @@ import { import assert from "assert"; import type { MaciState } from "./MaciState"; -import type { PathElements } from "optimisedmt"; +import type { PathElements } from "maci-crypto"; import { STATE_TREE_ARITY, MESSAGE_TREE_ARITY, VOTE_OPTION_TREE_ARITY } from "./utils/constants"; import { ProcessMessageErrors, ProcessMessageError } from "./utils/errors"; diff --git a/core/ts/utils/types.ts b/core/ts/utils/types.ts index 1718d99683..9199c003c6 100644 --- a/core/ts/utils/types.ts +++ b/core/ts/utils/types.ts @@ -1,5 +1,6 @@ import type { MaciState } from "../MaciState"; import type { Poll } from "../Poll"; +import type { PathElements } from "maci-crypto"; import type { Ballot, IJsonBallot, @@ -14,7 +15,6 @@ import type { StateLeaf, TCommand, } from "maci-domainobjs"; -import type { PathElements } from "optimisedmt"; /** * A circuit inputs for the circom circuit diff --git a/crypto/ts/index.ts b/crypto/ts/index.ts index 75457d89c9..dabcf301a5 100644 --- a/crypto/ts/index.ts +++ b/crypto/ts/index.ts @@ -44,7 +44,7 @@ export { bigInt2Buffer, } from "./crypto"; -export { OptimisedMT as IncrementalQuinTree } from "optimisedmt"; +export { OptimisedMT as IncrementalQuinTree, type PathElements } from "optimisedmt"; export type { SnarkBigInt, From 0b2986fcaadbfce37ff9fc0007ddeae97573924e Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Sat, 30 Dec 2023 23:22:47 +0000 Subject: [PATCH 16/37] refactor(crypto): remove ffjavascript and implement utils functions locally Remove large dependency ffjavascript which was used only for a couple of util functions. Also ensure that we safely convert a bigint to a buffer and thus result in serialized maci private keys being the same length fix #458 --- .../scripts/ceremony-param-tests-c-witness.sh | 14 +- .../ts/__tests__/MessageValidator.test.ts | 22 +- circuits/ts/__tests__/Splicer.test.ts | 6 +- .../StateLeafAndBallotTransformer.test.ts | 10 +- cli/tests/constants.ts | 6 +- core/ts/Poll.ts | 17 +- crypto/package-lock.json | 1 - crypto/package.json | 4 +- crypto/ts/@types/ffjavascript.d.ts | 13 - crypto/ts/@types/main.d.ts | 1 - crypto/ts/AccQueue.ts | 9 +- crypto/ts/__tests__/Crypto.test.ts | 47 +--- crypto/ts/__tests__/Utils.test.ts | 227 ++++++++++++++++++ crypto/ts/bigIntUtils.ts | 142 +++++++++++ crypto/ts/crypto.ts | 15 +- crypto/ts/index.ts | 12 +- crypto/ts/types.ts | 19 ++ crypto/ts/utils.ts | 22 -- domainobjs/ts/__tests__/privateKey.test.ts | 8 + 19 files changed, 454 insertions(+), 141 deletions(-) delete mode 100644 crypto/ts/@types/ffjavascript.d.ts create mode 100644 crypto/ts/__tests__/Utils.test.ts create mode 100644 crypto/ts/bigIntUtils.ts diff --git a/.github/scripts/ceremony-param-tests-c-witness.sh b/.github/scripts/ceremony-param-tests-c-witness.sh index bb4cfcffbf..69db3b706c 100755 --- a/.github/scripts/ceremony-param-tests-c-witness.sh +++ b/.github/scripts/ceremony-param-tests-c-witness.sh @@ -17,7 +17,7 @@ HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js setVerifyingKeys -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js create -s 6 -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js deployPoll \ - -pk macipk.c974f4f168b79727ac98bfd53a65ea0b4e45dc2552fe73df9f8b51ebb0930330 \ + -pk macipk.bca7ac038ea1a6e4cb45a142ebe6485670bdb1c34b5ba45257c4c7faed8efc14 \ --duration 30 \ --max-messages 390625 \ --max-vote-options 125 \ @@ -27,11 +27,11 @@ HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js deployPoll \ --vote-option-tree-depth 3 \ -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js signup \ - --pubkey macipk.3e7bb2d7f0a1b7e980f1b6f363d1e3b7a12b9ae354c2cd60a9cfa9fd12917391 \ + --pubkey macipk.32c021243306d488fdc2aefa33c2093c1143e2baecb4b6fb04fba4c4abe972ae \ -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js publish \ - --pubkey macipk.3e7bb2d7f0a1b7e980f1b6f363d1e3b7a12b9ae354c2cd60a9cfa9fd12917391 \ - --privkey macisk.fd7aa614ec4a82716ffc219c24fd7e7b52a2b63b5afb17e81c22fe21515539c \ + --pubkey macipk.32c021243306d488fdc2aefa33c2093c1143e2baecb4b6fb04fba4c4abe972ae \ + --privkey macisk.209ed243578af94e720ef7ca90067ad9089f01195269926e511f3fac4f32841 \ --state-index 1 \ --vote-option-index 0 \ --new-vote-weight 9 \ @@ -39,8 +39,8 @@ HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js publish \ --poll-id 0 \ -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js publish \ - --pubkey macipk.d5788ea6ccf1ec295df99aaef859031fe7bd359e7e03acb80eb6e8a192f2ce19 \ - --privkey macisk.fd7aa614ec4a82716ffc219c24fd7e7b52a2b63b5afb17e81c22fe21515539c \ + --pubkey macipk.32c021243306d488fdc2aefa33c2093c1143e2baecb4b6fb04fba4c4abe972ae \ + --privkey macisk.209ed243578af94e720ef7ca90067ad9089f01195269926e511f3fac4f32841 \ --state-index 1 \ --vote-option-index 1 \ --new-vote-weight 9 \ @@ -51,7 +51,7 @@ HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js timeTravel -s 10 HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js mergeSignups --poll-id 0 -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js mergeMessages --poll-id 0 -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js genProofs \ - --privkey macisk.49953af3585856f539d194b46c82f4ed54ec508fb9b882940cbe68bbc57e59e \ + --privkey macisk.13035f1d0b35b0fe673c96586a4de84149c9539d8a03260a5fa333baaf45c11 \ --poll-id 0 \ --rapidsnark ~/rapidsnark/build/prover \ --process-zkey ./zkeys/processMessages_6-8-2-3.zkey \ diff --git a/circuits/ts/__tests__/MessageValidator.test.ts b/circuits/ts/__tests__/MessageValidator.test.ts index 978e08d213..771c439f4d 100644 --- a/circuits/ts/__tests__/MessageValidator.test.ts +++ b/circuits/ts/__tests__/MessageValidator.test.ts @@ -36,21 +36,21 @@ describe("MessageValidator circuit", function test() { const signature = command.sign(privKey); circuitInputs = stringifyBigInts({ - stateTreeIndex: 0, - numSignUps: 1, - voteOptionIndex: 0, - maxVoteOptions: 1, - originalNonce: 1, - nonce: 2, + stateTreeIndex: 0n, + numSignUps: 1n, + voteOptionIndex: 0n, + maxVoteOptions: 1n, + originalNonce: 1n, + nonce: 2n, cmd: command.asCircuitInputs(), pubKey: pubKey.asCircuitInputs(), sigR8: signature.R8, sigS: signature.S, - currentVoiceCreditBalance: 100, - currentVotesForOption: 0, - voteWeight: 9, - slTimestamp: 1, - pollEndTimestamp: 2, + currentVoiceCreditBalance: 100n, + currentVotesForOption: 0n, + voteWeight: 9n, + slTimestamp: 1n, + pollEndTimestamp: 2n, }) as CircuitInputs; }); diff --git a/circuits/ts/__tests__/Splicer.test.ts b/circuits/ts/__tests__/Splicer.test.ts index 9250cfc18d..299a54a6bd 100644 --- a/circuits/ts/__tests__/Splicer.test.ts +++ b/circuits/ts/__tests__/Splicer.test.ts @@ -15,9 +15,9 @@ describe("Splice circuit", () => { it("Should output the correct reconstructed level", async () => { for (let index = 0; index < 5; index += 1) { - const items = [0, 20, 30, 40]; - const leaf = 10; - const circuitInputs = stringifyBigInts({ in: items, leaf, index }); + const items = [0n, 20n, 30n, 40n]; + const leaf = 10n; + const circuitInputs = stringifyBigInts({ in: items, leaf, index: BigInt(index) }); // eslint-disable-next-line no-await-in-loop const witness = await circuit.calculateWitness(circuitInputs); diff --git a/circuits/ts/__tests__/StateLeafAndBallotTransformer.test.ts b/circuits/ts/__tests__/StateLeafAndBallotTransformer.test.ts index 59cfb61485..40776c6e62 100644 --- a/circuits/ts/__tests__/StateLeafAndBallotTransformer.test.ts +++ b/circuits/ts/__tests__/StateLeafAndBallotTransformer.test.ts @@ -19,8 +19,8 @@ describe("StateLeafAndBallotTransformer circuit", function test() { const nonce = BigInt(1); const pollId = BigInt(0); const salt = genRandomSalt(); - const numSignUps = 25; - const maxVoteOptions = 25; + const numSignUps = 25n; + const maxVoteOptions = 25n; const slKeypair = new Keypair(); const slPubKey = slKeypair.pubKey; @@ -28,8 +28,8 @@ describe("StateLeafAndBallotTransformer circuit", function test() { const slVoiceCreditBalance = BigInt(100); const ballotNonce = BigInt(0); const ballotCurrentVotesForOption = BigInt(0); - const slTimestamp = 1; - const pollEndTimestamp = 2; + const slTimestamp = 1n; + const pollEndTimestamp = 2n; const command: PCommand = new PCommand(stateIndex, newPubKey, voteOptionIndex, newVoteWeight, nonce, pollId, salt); @@ -91,7 +91,7 @@ describe("StateLeafAndBallotTransformer circuit", function test() { cmdNewPubKey: command.newPubKey.asCircuitInputs(), cmdVoteOptionIndex: command.voteOptionIndex, cmdNewVoteWeight: command.newVoteWeight, - cmdNonce: 2, // invalid + cmdNonce: 2n, // invalid cmdPollId: command.pollId, cmdSalt: command.salt, cmdSigR8: signature.R8, diff --git a/cli/tests/constants.ts b/cli/tests/constants.ts index 582cb843d8..f00aab3fb8 100644 --- a/cli/tests/constants.ts +++ b/cli/tests/constants.ts @@ -1,3 +1,4 @@ +import { Keypair } from "maci-domainobjs"; import { homedir } from "os"; export const STATE_TREE_DEPTH = 10; @@ -5,8 +6,9 @@ export const INT_STATE_TREE_DEPTH = 1; export const MSG_TREE_DEPTH = 2; export const VOTE_OPTION_TREE_DEPTH = 2; export const MSG_BATCH_DEPTH = 1; -export const coordinatorPubKey = "macipk.c974f4f168b79727ac98bfd53a65ea0b4e45dc2552fe73df9f8b51ebb0930330"; -export const coordinatorPrivKey = "macisk.49953af3585856f539d194b46c82f4ed54ec508fb9b882940cbe68bbc57e59e"; +const coordinatorKeypair = new Keypair(); +export const coordinatorPubKey = coordinatorKeypair.pubKey.serialize(); +export const coordinatorPrivKey = coordinatorKeypair.privKey.serialize(); export const processMessageTestZkeyPath = "./zkeys/ProcessMessages_10-2-1-2_test.0.zkey"; export const tallyVotesTestZkeyPath = "./zkeys/TallyVotes_10-1-2_test.0.zkey"; export const subsidyTestZkeyPath = "./zkeys/SubsidyPerBatch_10-1-2_test.0.zkey"; diff --git a/core/ts/Poll.ts b/core/ts/Poll.ts index 99268dbfd2..c7beade4d8 100644 --- a/core/ts/Poll.ts +++ b/core/ts/Poll.ts @@ -839,25 +839,21 @@ export class Poll implements IPoll { const circuitInputs = stringifyBigInts({ stateRoot, ballotRoot, - sbSalt, currentSubsidySalt, newSubsidySalt, - sbCommitment, currentSubsidyCommitment, newSubsidyCommitment, currentSubsidy, - packedVals, inputHash, - ballots1: ballots1.map((x) => x.asCircuitInputs()), ballots2: ballots2.map((x) => x.asCircuitInputs()), votes1: ballots1.map((x) => x.votes), votes2: ballots2.map((x) => x.votes), - ballotPathElements1: ballotSubrootProof1?.pathElements, - ballotPathElements2: ballotSubrootProof2?.pathElements, + ballotPathElements1: ballotSubrootProof1!.pathElements, + ballotPathElements2: ballotSubrootProof2!.pathElements, }); this.increaseSubsidyIndex(); @@ -1071,27 +1067,20 @@ export class Poll implements IPoll { stateRoot, ballotRoot, sbSalt, - sbCommitment, currentTallyCommitment, newTallyCommitment, - packedVals, // contains numSignUps and batchStartIndex inputHash, - ballots: ballots.map((x) => x.asCircuitInputs()), - ballotPathElements: ballotSubrootProof?.pathElements, + ballotPathElements: ballotSubrootProof!.pathElements, votes, - currentResults, currentResultsRootSalt, - currentSpentVoiceCreditSubtotal, currentSpentVoiceCreditSubtotalSalt, - currentPerVOSpentVoiceCredits, currentPerVOSpentVoiceCreditsRootSalt, - newResultsRootSalt, newPerVOSpentVoiceCreditsRootSalt, newSpentVoiceCreditSubtotalSalt, diff --git a/crypto/package-lock.json b/crypto/package-lock.json index d1a87de3dd..de33686a26 100644 --- a/crypto/package-lock.json +++ b/crypto/package-lock.json @@ -11,7 +11,6 @@ "blake-hash": "^1.1.0", "circomlib": "https://github.com/weijiekoh/circomlib.git#24ed08eee0bb613b8c0135d66c1013bd9f78d50a", "ethers": "^5.4.7", - "ffjavascript": "^0.2.62", "optimisedmt": "^0.0.9" }, "devDependencies": { diff --git a/crypto/package.json b/crypto/package.json index aec38fbed8..d3675418ab 100644 --- a/crypto/package.json +++ b/crypto/package.json @@ -8,13 +8,13 @@ "build": "tsc", "test": "nyc ts-mocha --exit ts/__tests__/*.test.ts", "test:crypto": "ts-mocha --exit ts/__tests__/Crypto.test.ts", - "test:accQueue": "ts-mocha --exit ts/__tests__/AccQueue.test.ts" + "test:accQueue": "ts-mocha --exit ts/__tests__/AccQueue.test.ts", + "test:utils": "ts-mocha --exit ts/__tests__/Utils.test.ts" }, "dependencies": { "blake-hash": "^1.1.0", "circomlib": "https://github.com/weijiekoh/circomlib.git#24ed08eee0bb613b8c0135d66c1013bd9f78d50a", "ethers": "^5.4.7", - "ffjavascript": "^0.2.62", "optimisedmt": "^0.0.9" }, "devDependencies": { diff --git a/crypto/ts/@types/ffjavascript.d.ts b/crypto/ts/@types/ffjavascript.d.ts deleted file mode 100644 index aaca2e4839..0000000000 --- a/crypto/ts/@types/ffjavascript.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -declare module "ffjavascript" { - export namespace Scalar { - function shr(value: bigint, shift: number): bigint[]; - } - - export namespace utils { - function leBuff2int(buffer: Buffer): bigint; - - function stringifyBigInts(bits: unknown): unknown; - - function unstringifyBigInts(bits: unknown): unknown; - } -} diff --git a/crypto/ts/@types/main.d.ts b/crypto/ts/@types/main.d.ts index cfeffe6ca0..ecdb3bc094 100644 --- a/crypto/ts/@types/main.d.ts +++ b/crypto/ts/@types/main.d.ts @@ -1,4 +1,3 @@ export * from "./blake-hash"; export * from "./circomlib"; -export * from "./ffjavascript"; export * from "./optimisedmt"; diff --git a/crypto/ts/AccQueue.ts b/crypto/ts/AccQueue.ts index 46516464c2..d5fce8b9aa 100644 --- a/crypto/ts/AccQueue.ts +++ b/crypto/ts/AccQueue.ts @@ -2,9 +2,10 @@ import { OptimisedMT as IncrementalQuinTree } from "optimisedmt"; import assert from "assert"; +import { deepCopyBigIntArray, stringifyBigInts, unstringifyBigInts } from "./bigIntUtils"; import { sha256Hash, hashLeftRight, hash5 } from "./crypto"; -import { Leaf, Queue } from "./types"; -import { calcDepthFromNumLeaves, deepCopyBigIntArray, stringifyBigInts, unstringifyBigInts } from "./utils"; +import { Leaf, Queue, StringifiedBigInts } from "./types"; +import { calcDepthFromNumLeaves } from "./utils"; /** * An Accumulator Queue which conforms to the implementation in AccQueue.sol. @@ -512,7 +513,7 @@ export class AccQueue { newAccQueue.currentSubtreeIndex = JSON.parse(JSON.stringify(this.currentSubtreeIndex)) as number; newAccQueue.numLeaves = JSON.parse(JSON.stringify(this.numLeaves)) as number; newAccQueue.leafQueue.levels = unstringifyBigInts( - JSON.parse(JSON.stringify(stringifyBigInts(this.leafQueue.levels))) as bigint[][], + JSON.parse(JSON.stringify(stringifyBigInts(this.leafQueue.levels))) as StringifiedBigInts, ) as bigint[][]; newAccQueue.leafQueue.indices = JSON.parse(JSON.stringify(this.leafQueue.indices)) as number[]; newAccQueue.subRoots = deepCopyBigIntArray(this.subRoots); @@ -523,7 +524,7 @@ export class AccQueue { newAccQueue.smallSRTroot = BigInt(this.smallSRTroot.toString()); newAccQueue.subRootQueue.indices = JSON.parse(JSON.stringify(this.subRootQueue.indices)) as number[]; newAccQueue.subRootQueue.levels = unstringifyBigInts( - JSON.parse(JSON.stringify(stringifyBigInts(this.subRootQueue.levels))) as bigint[][], + JSON.parse(JSON.stringify(stringifyBigInts(this.subRootQueue.levels))) as StringifiedBigInts, ) as bigint[][]; return newAccQueue; diff --git a/crypto/ts/__tests__/Crypto.test.ts b/crypto/ts/__tests__/Crypto.test.ts index 88932f90fe..e2d7511114 100644 --- a/crypto/ts/__tests__/Crypto.test.ts +++ b/crypto/ts/__tests__/Crypto.test.ts @@ -26,7 +26,6 @@ import { G1Point, G2Point, hashOne, - bigInt2Buffer, genRandomBabyJubValue, genPrivKey, packPubKey, @@ -34,7 +33,6 @@ import { bitToCurve, curveToBit, } from "../crypto"; -import { genTreeCommitment } from "../utils"; describe("Crypto", function test() { this.timeout(100000); @@ -481,41 +479,7 @@ describe("Crypto", function test() { expect(salt).to.not.eq(BigInt(0)); }); }); - describe("bigInt2Buffer", () => { - it("should convert a BigInt to a Buffer", () => { - const bigInt = BigInt(123456789); - const buffer = bigInt2Buffer(bigInt); - expect(buffer).to.be.instanceOf(Buffer); - }); - - it("should produce a Buffer with the correct value", () => { - const bigInt = BigInt(123456789); - const buffer = bigInt2Buffer(bigInt); - const expectedBuffer = Buffer.from(bigInt.toString(16), "hex"); - expect(buffer.equals(expectedBuffer)).to.eq(true); - }); - }); - describe("genTreeCommitment", () => { - const leaves = [BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5)]; - const salt = BigInt(6); - const depth = 3; - it("should generate a commitment to the tree root using the provided salt", () => { - const commitment = genTreeCommitment(leaves, salt, depth); - expect(commitment).to.satisfy((num: bigint) => num > 0); - expect(commitment).to.satisfy((num: bigint) => num < SNARK_FIELD_SIZE); - }); - - it("should always generate the same commitment for the same inputs", () => { - const commitment = genTreeCommitment(leaves, salt, depth); - expect(commitment).to.satisfy((num: bigint) => num > 0); - expect(commitment).to.satisfy((num: bigint) => num < SNARK_FIELD_SIZE); - const commitment2 = genTreeCommitment(leaves, salt, depth); - expect(commitment2).to.satisfy((num: bigint) => num > 0); - expect(commitment2).to.satisfy((num: bigint) => num < SNARK_FIELD_SIZE); - expect(commitment).to.eq(commitment2); - }); - }); describe("bitToCurve", () => { it("should map bit 0 to point [0, 1] on the curve", () => { const point = bitToCurve(BigInt(0)); @@ -684,6 +648,17 @@ describe("Crypto", function test() { expect(ciphertext).to.be.instanceOf(Array); expect(ciphertext.length).to.eq(4); }); + + it("should encrypt a ciphertext without passing a nonce (default to 0)", () => { + const { privKey } = genKeypair(); + const pubKey = genPubKey(genPrivKey()); + const sharedKey = genEcdhSharedKey(privKey, pubKey); + const plaintext = [BigInt(1), BigInt(2), BigInt(3)]; + const ciphertext = encrypt(plaintext, sharedKey); + expect(ciphertext).to.be.instanceOf(Array); + expect(ciphertext.length).to.eq(4); + }); + it("should produce a cihertext that is different from the plaintext", () => { const { privKey } = genKeypair(); const pubKey = genPubKey(genPrivKey()); diff --git a/crypto/ts/__tests__/Utils.test.ts b/crypto/ts/__tests__/Utils.test.ts new file mode 100644 index 0000000000..fec12fd52c --- /dev/null +++ b/crypto/ts/__tests__/Utils.test.ts @@ -0,0 +1,227 @@ +import { expect } from "chai"; + +import { bigInt2Buffer, fromRprLE, fromString, stringifyBigInts, unstringifyBigInts } from "../bigIntUtils"; +import { SNARK_FIELD_SIZE } from "../constants"; +import { genTreeCommitment, genTreeProof } from "../utils"; + +describe("Utils", () => { + describe("stringifyBigInts", () => { + it("Should work on a BigInt input", () => { + expect(stringifyBigInts(BigInt(1))).to.eq("1"); + }); + + it("Should work on a BigInt[] input", () => { + expect(stringifyBigInts([BigInt(1), BigInt(2)])).to.deep.eq(["1", "2"]); + }); + + it("Should work on a BigInt[][] input", () => { + expect( + stringifyBigInts([ + [BigInt(1), BigInt(2)], + [BigInt(3), BigInt(4)], + ]), + ).to.deep.eq([ + ["1", "2"], + ["3", "4"], + ]); + }); + + it("Should work on a BigInt[][][] input", () => { + expect( + stringifyBigInts([ + [ + [BigInt(1), BigInt(2)], + [BigInt(3), BigInt(4)], + ], + [ + [BigInt(5), BigInt(6)], + [BigInt(7), BigInt(8)], + ], + ]), + ).to.deep.eq([ + [ + ["1", "2"], + ["3", "4"], + ], + [ + ["5", "6"], + ["7", "8"], + ], + ]); + }); + + it("Should work on a { [key: string]: BigInt } input", () => { + expect(stringifyBigInts({ a: BigInt(1), b: BigInt(2) })).to.deep.eq({ a: "1", b: "2" }); + }); + + it("Should work on a null input", () => { + expect(stringifyBigInts(null)).to.eq(null); + }); + + it("Should return the input if it is not a valid value", () => { + expect(stringifyBigInts("A")).to.eq("A"); + }); + + it("should work on a Uint8Array input", () => { + const input = new Uint8Array([1, 2, 3, 4]); + expect(stringifyBigInts(input)).to.eq("67305985"); + }); + }); + + describe("unstringifyBigInts", () => { + it("Should work on a string input with decimal numbers", () => { + expect(unstringifyBigInts("1")).to.eq(BigInt(1)); + }); + + it("Should work on a string input with hex number", () => { + expect(unstringifyBigInts("0xA")).to.eq(BigInt(10)); + }); + + it("Should work on a string[] input", () => { + expect(unstringifyBigInts(["1", "2"])).to.deep.eq([BigInt(1), BigInt(2)]); + }); + + it("Should work on a string[][] input", () => { + expect( + unstringifyBigInts([ + ["1", "2"], + ["3", "4"], + ]), + ).to.deep.eq([ + [BigInt(1), BigInt(2)], + [BigInt(3), BigInt(4)], + ]); + }); + + it("Should work on a string[][][] input", () => { + expect( + unstringifyBigInts([ + [ + ["1", "2"], + ["3", "4"], + ], + [ + ["5", "6"], + ["7", "8"], + ], + ]), + ).to.deep.eq([ + [ + [BigInt(1), BigInt(2)], + [BigInt(3), BigInt(4)], + ], + [ + [BigInt(5), BigInt(6)], + [BigInt(7), BigInt(8)], + ], + ]); + }); + + it("Should work on a { [key: string]: string } input", () => { + expect(unstringifyBigInts({ a: "1", b: "2" })).to.deep.eq({ a: BigInt(1), b: BigInt(2) }); + }); + + it("Should work on a null input", () => { + expect(unstringifyBigInts(null)).to.eq(null); + }); + + it("Should return the input if it is not a valid value", () => { + expect(unstringifyBigInts("A")).to.eq("A"); + }); + }); + + describe("bigInt2Buffer", () => { + it("should convert a BigInt to a Buffer", () => { + const bigInt = BigInt(123456789); + const buffer = bigInt2Buffer(bigInt); + expect(buffer).to.be.instanceOf(Buffer); + }); + + it("should produce a Buffer with the correct value", () => { + const bigInt = BigInt(123456789); + const buffer = bigInt2Buffer(bigInt); + + let hex = bigInt.toString(16); + + // Ensure even length. + if (hex.length % 2 !== 0) { + hex = `0${hex}`; + } + const expectedBuffer = Buffer.from(hex, "hex"); + expect(buffer.equals(expectedBuffer)).to.eq(true); + }); + }); + + describe("genTreeCommitment", () => { + const leaves = [BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5)]; + const salt = BigInt(6); + const depth = 3; + + it("should generate a commitment to the tree root using the provided salt", () => { + const commitment = genTreeCommitment(leaves, salt, depth); + expect(commitment).to.satisfy((num: bigint) => num > 0); + expect(commitment).to.satisfy((num: bigint) => num < SNARK_FIELD_SIZE); + }); + + it("should always generate the same commitment for the same inputs", () => { + const commitment = genTreeCommitment(leaves, salt, depth); + expect(commitment).to.satisfy((num: bigint) => num > 0); + expect(commitment).to.satisfy((num: bigint) => num < SNARK_FIELD_SIZE); + + const commitment2 = genTreeCommitment(leaves, salt, depth); + expect(commitment2).to.satisfy((num: bigint) => num > 0); + expect(commitment2).to.satisfy((num: bigint) => num < SNARK_FIELD_SIZE); + expect(commitment).to.eq(commitment2); + }); + }); + + describe("fromString", () => { + it("should convert a string with radix 10 to a bigint", () => { + expect(fromString("123456789", 10)).to.eq(BigInt(123456789)); + }); + + it("should convert a string with radix 16 to a bigint", () => { + expect(fromString("123456789", 16)).to.eq(BigInt(0x123456789)); + }); + + it("should convert a string with radix 16 and starting with 0x to a bigint", () => { + expect(fromString("0x123456789", 16)).to.eq(BigInt(0x123456789)); + }); + + it("should convert a string with radix != 10 && != 16 to a bigint", () => { + expect(fromString("123456789", 2)).to.eq(BigInt(123456789)); + }); + }); + + describe("genTreeProof", () => { + it("should return the path elements for the given index", () => { + const leaves = [BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5)]; + const depth = 3; + const proof = genTreeProof(2, leaves, depth); + expect(proof.length).to.be.gt(0); + }); + }); + + describe("fromRprLE", () => { + it("should correctly parse a buffer with Little Endian Representation", () => { + const { buffer } = new Uint8Array([1, 2, 3, 4]); + const view = new DataView(buffer); + const expected = fromString("04030201", 16).toString(); + expect(fromRprLE(view)).to.eq(expected); + }); + + it("should correctly parse a buffer with Little Endian Representation with offset", () => { + const { buffer } = new Uint8Array([0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0]); + const view = new DataView(buffer); + const expected = fromString("04030201", 16).toString(); + expect(fromRprLE(view, 4, 4)).to.eq(expected); + }); + + it("should correctly parse a buffer with Little Endian Representation with byte length", () => { + const { buffer } = new Uint8Array([1, 2, 3, 4, 5, 6]); + const view = new DataView(buffer); + const expected = fromString("04030201", 16).toString(); + expect(fromRprLE(view, 0, 4)).to.eq(expected); + }); + }); +}); diff --git a/crypto/ts/bigIntUtils.ts b/crypto/ts/bigIntUtils.ts new file mode 100644 index 0000000000..75248b8f06 --- /dev/null +++ b/crypto/ts/bigIntUtils.ts @@ -0,0 +1,142 @@ +import { BigIntVariants, StringifiedBigInts } from "./types"; + +/** + * Given an input containing string values, convert them + * to bigint + * @param input - The input to convert + * @returns the input with string values converted to bigint + */ +export const unstringifyBigInts = (input: StringifiedBigInts): BigIntVariants => { + if (typeof input === "string" && /^[0-9]+$/.test(input)) { + return BigInt(input); + } + + if (typeof input === "string" && /^0x[0-9a-fA-F]+$/.test(input)) { + return BigInt(input); + } + + if (Array.isArray(input)) { + return input.map(unstringifyBigInts); + } + + if (input === null) { + return null; + } + + if (typeof input === "object") { + return Object.entries(input).reduce>((acc, [key, value]) => { + acc[key] = unstringifyBigInts(value) as bigint; + return acc; + }, {}); + } + + return input; +}; + +/** + * Converts a string to a bigint using the given radix + * @param str - The string to convert + * @param radix - The radix to use + * @returns The converted string as a bigint + */ +export const fromString = (str: string, radix: number): bigint => { + if (!radix || radix === 10) { + return BigInt(str); + } + + if (radix === 16) { + if (str.startsWith("0x")) { + return BigInt(str); + } + return BigInt(`0x${str}`); + } + + return BigInt(str); +}; + +/** + * Parses a buffer with Little Endian Representation + * @param buff - The buffer to parse + * @param o - The offset to start from + * @param n8 - The byte length + * @returns The parsed buffer as a string + */ +export const fromRprLE = (buff: ArrayBufferView, o = 0, n8: number = buff.byteLength): string => { + const v = new Uint32Array(buff.buffer, buff.byteOffset + o, n8 / 4); + const a: string[] = new Array(n8 / 4); + v.forEach((ch, i) => { + a[a.length - i - 1] = ch.toString(16).padStart(8, "0"); + }); + return fromString(a.join(""), 16).toString(); +}; + +/** + * Given an input of bigint values, convert them to their string representations + * @param input - The input to convert + * @returns The input with bigint values converted to string + */ +export const stringifyBigInts = (input: BigIntVariants): StringifiedBigInts => { + if (typeof input === "bigint") { + return input.toString(); + } + + if (input instanceof Uint8Array) { + return fromRprLE(input, 0); + } + + if (Array.isArray(input)) { + return input.map(stringifyBigInts); + } + + if (input === null) { + return null; + } + + if (typeof input === "object") { + return Object.entries(input).reduce>((acc, [key, value]) => { + acc[key] = stringifyBigInts(value); + return acc; + }, {}); + } + + return input; +}; + +/** + * Create a copy of a bigint array + * @param arr - the array of bigints to copy + * @returns a deep copy of the array + */ +export const deepCopyBigIntArray = (arr: bigint[]): bigint[] => arr.map((x) => BigInt(x.toString())); + +/** + * Convert a buffer to a bigint + * @param buffer - The buffer to convert + * @returns The buffer as a bigint + */ +export const leBufferToBigint = (buffer: Buffer): bigint => BigInt(`0x${buffer.reverse().toString("hex")}`); + +/** + * Sihft a left by n bits + * @param a - The first bigint + * @param n - The second bigint + * @returns The result of shifting a right by n + */ +export const shiftRight = (a: bigint, n: bigint): bigint => + // eslint-disable-next-line no-bitwise + a >> n; + +/** + * Convert a BigInt to a Buffer + * @param i - the bigint to convert + * @returns the buffer + */ +export const bigInt2Buffer = (i: bigint): Buffer => { + let hex = i.toString(16); + + // Ensure even length. + if (hex.length % 2 !== 0) { + hex = `0${hex}`; + } + return Buffer.from(hex, "hex"); +}; diff --git a/crypto/ts/crypto.ts b/crypto/ts/crypto.ts index d7328ece4a..fe969e34a1 100644 --- a/crypto/ts/crypto.ts +++ b/crypto/ts/crypto.ts @@ -1,7 +1,6 @@ import createBlakeHash from "blake-hash"; import { babyJub, poseidon, poseidonEncrypt, poseidonDecrypt, eddsa } from "circomlib"; import * as ethers from "ethers"; -import { utils, Scalar } from "ffjavascript"; import assert from "assert"; import { randomBytes } from "crypto"; @@ -18,6 +17,7 @@ import type { Signature, } from "./types"; +import { bigInt2Buffer, leBufferToBigint, shiftRight } from "./bigIntUtils"; import { SNARK_FIELD_SIZE } from "./constants"; /** @@ -241,13 +241,6 @@ export const hash13 = (elements: Plaintext): bigint => { */ export const hashOne = (preImage: bigint): bigint => poseidonT3([preImage, BigInt(0)]); -/** - * Convert a BigInt to a Buffer - * @param i - the bigint to convert - * @returns the buffer - */ -export const bigInt2Buffer = (i: bigint): Buffer => Buffer.from(i.toString(16), "hex"); - /** * Returns a BabyJub-compatible random value. We create it by first generating * a random value (initially 256 bits large) modulo the snark field size as @@ -295,11 +288,11 @@ export const genRandomSalt = (): bigint => genRandomBabyJubValue(); * @param privKey A private key generated using genPrivKey() * @returns A BabyJub-compatible private key. */ -export const formatPrivKeyForBabyJub = (privKey: PrivKey): bigint[] => { +export const formatPrivKeyForBabyJub = (privKey: PrivKey): bigint => { const sBuff = eddsa.pruneBuffer(createBlakeHash("blake512").update(bigInt2Buffer(privKey)).digest().subarray(0, 32)); - const s = utils.leBuff2int(sBuff); + const s = leBufferToBigint(sBuff); - return Scalar.shr(s, 3); + return shiftRight(s, BigInt(3)); }; /** diff --git a/crypto/ts/index.ts b/crypto/ts/index.ts index dabcf301a5..d023e1208a 100644 --- a/crypto/ts/index.ts +++ b/crypto/ts/index.ts @@ -2,14 +2,9 @@ import "./@types"; export { AccQueue } from "./AccQueue"; -export { - stringifyBigInts, - unstringifyBigInts, - deepCopyBigIntArray, - calcDepthFromNumLeaves, - genTreeCommitment, - genTreeProof, -} from "./utils"; +export { calcDepthFromNumLeaves, genTreeCommitment, genTreeProof } from "./utils"; + +export { bigInt2Buffer, stringifyBigInts, unstringifyBigInts, deepCopyBigIntArray } from "./bigIntUtils"; export { SNARK_FIELD_SIZE, NOTHING_UP_MY_SLEEVE, babyJubMaxValue } from "./constants"; @@ -41,7 +36,6 @@ export { curveToBit, babyJubAddPoint, bitToCurve, - bigInt2Buffer, } from "./crypto"; export { OptimisedMT as IncrementalQuinTree, type PathElements } from "optimisedmt"; diff --git a/crypto/ts/types.ts b/crypto/ts/types.ts index a739a61ea5..e5d8905162 100644 --- a/crypto/ts/types.ts +++ b/crypto/ts/types.ts @@ -44,3 +44,22 @@ export interface PoseidonFuncs { } export type Leaf = bigint; + +export type StringifiedBigInts = + | StringifiedBigInts[] + | string + | string[] + | string[][] + | string[][][] + | { [key: string]: StringifiedBigInts } + | null; +export type BigIntVariants = + | BigIntVariants[] + | StringifiedBigInts + | bigint + | bigint[] + | bigint[][] + | bigint[][][] + | { [key: string]: BigIntVariants } + | Uint8Array + | null; diff --git a/crypto/ts/utils.ts b/crypto/ts/utils.ts index 7f2b433ce1..397b5e5789 100644 --- a/crypto/ts/utils.ts +++ b/crypto/ts/utils.ts @@ -1,29 +1,7 @@ -import ff from "ffjavascript"; import { OptimisedMT as IncrementalQuinTree } from "optimisedmt"; import { hash5, hashLeftRight } from "./crypto"; -/** - * Convert a bigint to a string - * @param obj - the object to convert - * @returns the converted object - */ -export const stringifyBigInts = (obj: unknown): unknown => ff.utils.stringifyBigInts(obj); - -/** - * Convert a string to a bigint - * @param obj - the object to convert - * @returns the converted object - */ -export const unstringifyBigInts = (obj: unknown): unknown => ff.utils.unstringifyBigInts(obj); - -/** - * Create a copy of a bigint array - * @param arr - the array of bigints to copy - * @returns a deep copy of the array - */ -export const deepCopyBigIntArray = (arr: bigint[]): bigint[] => arr.map((x) => BigInt(x.toString())); - /** * Calculate the depth of a tree given the number of leaves * @param hashLength the hashing function param length diff --git a/domainobjs/ts/__tests__/privateKey.test.ts b/domainobjs/ts/__tests__/privateKey.test.ts index 5b951a39d3..68aff0fa37 100644 --- a/domainobjs/ts/__tests__/privateKey.test.ts +++ b/domainobjs/ts/__tests__/privateKey.test.ts @@ -24,6 +24,14 @@ describe("privateKey", () => { expect(PrivKey.isValidSerializedPrivKey(s.slice(1))).to.eq(false); }); + it("PrivKey.serialize() should always return a key with the same length", () => { + for (let i = 100; i < 100; i += 1) { + const k = new Keypair(); + const s = k.privKey.serialize(); + expect(s.length).to.eq(54); + } + }); + it("PrivKey.copy() should produce a deep copy", () => { const k = new Keypair(); const sk1 = k.privKey; From 32c348556e5bf7b0a586ed8925ef7037f6623af9 Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Tue, 19 Dec 2023 13:44:07 +0000 Subject: [PATCH 17/37] test(contracts): refactor and add unit tests to the current suite --- contracts/contracts/MACI.sol | 4 - contracts/contracts/Poll.sol | 2 +- contracts/contracts/PollFactory.sol | 3 - .../FreeForAllSignUpGatekeeper.sol | 4 - contracts/contracts/utilities/DomainObjs.sol | 2 - contracts/package.json | 30 ++- contracts/tests/AccQueue.test.ts | 13 +- contracts/tests/HasherBenchmarks.test.ts | 2 - contracts/tests/MACI.test.ts | 216 ++++++------------ contracts/tests/MaciOverflow.test.ts | 69 ------ contracts/tests/MessageProcessor.test.ts | 6 +- contracts/tests/Poll.test.ts | 161 +++++++++---- contracts/tests/PollFactory.test.ts | 63 +++++ contracts/tests/SignUpGatekeeper.test.ts | 38 ++- contracts/tests/Subsidy.test.ts | 190 +++++++++++++++ contracts/tests/Tally.test.ts | 8 +- contracts/tests/Utilities.test.ts | 33 +++ contracts/tests/Verifier.test.ts | 10 + contracts/tests/VkRegistry.test.ts | 189 +++++++++++++++ contracts/tests/utils.ts | 17 +- contracts/ts/deploy.ts | 35 ++- contracts/ts/types.ts | 2 + 22 files changed, 767 insertions(+), 330 deletions(-) delete mode 100644 contracts/tests/MaciOverflow.test.ts create mode 100644 contracts/tests/PollFactory.test.ts create mode 100644 contracts/tests/Subsidy.test.ts create mode 100644 contracts/tests/VkRegistry.test.ts diff --git a/contracts/contracts/MACI.sol b/contracts/contracts/MACI.sol index 5419d34e43..eead7b3500 100644 --- a/contracts/contracts/MACI.sol +++ b/contracts/contracts/MACI.sol @@ -79,9 +79,7 @@ contract MACI is IMACI, DomainObjs, Params, Utilities, Ownable { } error CallerMustBePoll(address _caller); - error AlreadyInitialized(); error PoseidonHashLibrariesNotLinked(); - error WrongPollOwner(); error TooManySignups(); error MaciPubKeyLargerThanSnarkFieldSize(); error PreviousPollNotCompleted(uint256 pollId); @@ -221,8 +219,6 @@ contract MACI is IMACI, DomainObjs, Params, Utilities, Ownable { /// @return root The calculated Merkle root function mergeStateAq(uint256 _pollId) public override onlyPoll(_pollId) returns (uint256 root) { root = stateAq.merge(stateTreeDepth); - - return root; } /// @notice Return the main root of the StateAq contract diff --git a/contracts/contracts/Poll.sol b/contracts/contracts/Poll.sol index 908650ac21..3f3132af80 100644 --- a/contracts/contracts/Poll.sol +++ b/contracts/contracts/Poll.sol @@ -47,7 +47,7 @@ contract Poll is Params, Utilities, SnarkCommon, Ownable, EmptyBallotRoots { // the case that none of the messages are valid. uint256 public currentSbCommitment; - uint256 internal numMessages; + uint256 public numMessages; /// @notice The number of messages which have been processed and the number of /// signups diff --git a/contracts/contracts/PollFactory.sol b/contracts/contracts/PollFactory.sol index 65cb795c5d..07e674427d 100644 --- a/contracts/contracts/PollFactory.sol +++ b/contracts/contracts/PollFactory.sol @@ -6,7 +6,6 @@ import { AccQueue, AccQueueQuinaryMaci } from "./trees/AccQueue.sol"; import { TopupCredit } from "./TopupCredit.sol"; import { Params } from "./utilities/Params.sol"; import { DomainObjs } from "./utilities/DomainObjs.sol"; -import { VkRegistry } from "./VkRegistry.sol"; import { Poll } from "./Poll.sol"; /// @title PollFactory @@ -69,7 +68,5 @@ contract PollFactory is Params, DomainObjs { poll.init(); poll.transferOwnership(_pollOwner); - - return poll; } } diff --git a/contracts/contracts/gatekeepers/FreeForAllSignUpGatekeeper.sol b/contracts/contracts/gatekeepers/FreeForAllSignUpGatekeeper.sol index 02b33d4805..5fb69efde0 100644 --- a/contracts/contracts/gatekeepers/FreeForAllSignUpGatekeeper.sol +++ b/contracts/contracts/gatekeepers/FreeForAllSignUpGatekeeper.sol @@ -7,10 +7,6 @@ import { MACI } from "../MACI.sol"; /// @title FreeForAllGatekeeper /// @notice A SignUpGatekeeper which allows anyone to sign up. contract FreeForAllGatekeeper is SignUpGatekeeper { - /// @notice setMaciInstance does nothing in this gatekeeper - /// @param _maci The MACI contract - function setMaciInstance(MACI _maci) public override {} - /// @notice Registers the user without any restrictions. /// @param _address The address of the user /// @param _data memory additional data diff --git a/contracts/contracts/utilities/DomainObjs.sol b/contracts/contracts/utilities/DomainObjs.sol index e5b66358c8..6b65a52afc 100644 --- a/contracts/contracts/utilities/DomainObjs.sol +++ b/contracts/contracts/utilities/DomainObjs.sol @@ -1,8 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import { Hasher } from "../crypto/Hasher.sol"; - /// @title DomainObjs /// @notice An utility contract that holds /// a number of domain objects and functions diff --git a/contracts/package.json b/contracts/package.json index a65a4c1da4..45dd3605a8 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -13,21 +13,20 @@ "postbuild": "cp -r ./artifacts ./build", "docs": "hardhat docgen", "test": "hardhat test", - "test-maci": "hardhat test ./tests/MACI.test.ts", - "test-poll": "hardhat test ./tests/Poll.test.ts", - "test-messageProcessor": "hardhat test ./tests/MessageProcessor.test.ts", - "test-tally": "hardhat test ./tests/Tally.test.ts", - "test-hasher": "hardhat test ./tests/Hasher.test.ts", - "test-utilities": "hardhat test ./tests/Utilities.test.ts", - "test-signupGatekeeper": "hardhat test ./tests/SignUpGatekeeper.test.ts", - "test-verifier": "hardhat test ./tests/Verifier.test.ts", - "test-accQueue": "hardhat test ./tests/AccQueue.test.ts", - "test-accQueueBenchmark": "hardhat test ./tests/AccQueueBenchmark.test.ts", - "test-maciOverflow": "hardhat test ./tests/MaciOverflow.test.ts", - "test-hasherBenchmarks": "hardhat test ./tests/HasherBenchmarks.test.ts" - }, - "_moduleAliases": { - "@maci-contracts": "." + "test:maci": "hardhat test ./tests/MACI.test.ts", + "test:poll": "hardhat test ./tests/Poll.test.ts", + "test:messageProcessor": "hardhat test ./tests/MessageProcessor.test.ts", + "test:tally": "hardhat test ./tests/Tally.test.ts", + "test:hasher": "hardhat test ./tests/Hasher.test.ts", + "test:utilities": "hardhat test ./tests/Utilities.test.ts", + "test:signupGatekeeper": "hardhat test ./tests/SignUpGatekeeper.test.ts", + "test:verifier": "hardhat test ./tests/Verifier.test.ts", + "test:accQueue": "hardhat test ./tests/AccQueue.test.ts", + "test:accQueueBenchmark": "hardhat test ./tests/AccQueueBenchmark.test.ts", + "test:hasherBenchmarks": "hardhat test ./tests/HasherBenchmarks.test.ts", + "test:vkRegistry": "hardhat test ./tests/VkRegistry.test.ts", + "test:pollFactory": "hardhat test ./tests/PollFactory.test.ts", + "test:subsidy": "hardhat test ./tests/Subsidy.test.ts" }, "dependencies": { "@nomicfoundation/hardhat-toolbox": "^4.0.0", @@ -40,7 +39,6 @@ "maci-core": "^1.1.2", "maci-crypto": "^1.1.2", "maci-domainobjs": "^1.1.2", - "module-alias": "^2.2.2", "solidity-docgen": "^0.6.0-beta.36" }, "devDependencies": { diff --git a/contracts/tests/AccQueue.test.ts b/contracts/tests/AccQueue.test.ts index ace5d86531..41e1d0a1ca 100644 --- a/contracts/tests/AccQueue.test.ts +++ b/contracts/tests/AccQueue.test.ts @@ -35,7 +35,7 @@ describe("AccQueues", () => { }); it("Should not be able to get a subroot that does not exist", async () => { - await expect(aqContract.getSubRoot(0)).to.be.revertedWithCustomError(aqContract, "InvalidIndex"); + await expect(aqContract.getSubRoot(5)).to.be.revertedWithCustomError(aqContract, "InvalidIndex"); }); it("Should enqueue leaves", async () => { @@ -59,7 +59,7 @@ describe("AccQueues", () => { }); it("Should not be able to get a subroot that does not exist", async () => { - await expect(aqContract.getSubRoot(0)).to.be.revertedWithCustomError(aqContract, "InvalidIndex"); + await expect(aqContract.getSubRoot(5)).to.be.revertedWithCustomError(aqContract, "InvalidIndex"); }); it("Should enqueue leaves", async () => { @@ -204,15 +204,6 @@ describe("AccQueues", () => { const HASH_LENGTH = 2; const ZERO = BigInt(0); - it("Should not be possible to merge if empty", async () => { - const r = await deployTestAccQueues("AccQueueBinary0", SUB_DEPTH, HASH_LENGTH, ZERO); - const aqContract = r.aqContract as AccQueueContract; - await expect(aqContract.mergeSubRoots(0, { gasLimit: 1000000 })).to.be.revertedWithCustomError( - aqContract, - "NothingToMerge", - ); - }); - it("Should not be possible to merge into a tree of depth 0", async () => { const r = await deployTestAccQueues("AccQueueBinary0", SUB_DEPTH, HASH_LENGTH, ZERO); diff --git a/contracts/tests/HasherBenchmarks.test.ts b/contracts/tests/HasherBenchmarks.test.ts index 4d8ac2e395..2b1a5b448d 100644 --- a/contracts/tests/HasherBenchmarks.test.ts +++ b/contracts/tests/HasherBenchmarks.test.ts @@ -6,8 +6,6 @@ import { deployPoseidonContracts, linkPoseidonLibraries } from "../ts/deploy"; import { getDefaultSigner } from "../ts/utils"; import { HasherBenchmarks } from "../typechain-types"; -require("module-alias/register"); - describe("Hasher", () => { let hasherContract: HasherBenchmarks; before(async () => { diff --git a/contracts/tests/MACI.test.ts b/contracts/tests/MACI.test.ts index 96fbc50b7e..b11fe4e016 100644 --- a/contracts/tests/MACI.test.ts +++ b/contracts/tests/MACI.test.ts @@ -1,33 +1,21 @@ /* eslint-disable no-underscore-dangle */ import { expect } from "chai"; -import { AbiCoder, BaseContract, BigNumberish, Signer } from "ethers"; +import { AbiCoder, BaseContract, BigNumberish, Contract, Signer } from "ethers"; import { EthereumProvider } from "hardhat/types"; -import { MaciState, genProcessVkSig, STATE_TREE_DEPTH } from "maci-core"; +import { MaciState, STATE_TREE_DEPTH } from "maci-core"; import { NOTHING_UP_MY_SLEEVE } from "maci-crypto"; -import { VerifyingKey, Keypair, PubKey, Message } from "maci-domainobjs"; - -import type { IVerifyingKeyStruct } from "../ts/types"; +import { Keypair, PubKey, Message } from "maci-domainobjs"; import { parseArtifact } from "../ts/abi"; -import { getDefaultSigner } from "../ts/utils"; -import { AccQueueQuinaryMaci, MACI, VkRegistry, Poll as PollContract } from "../typechain-types"; - -import { - duration, - initialVoiceCreditBalance, - maxValues, - messageBatchSize, - tallyBatchSize, - testProcessVk, - testTallyVk, - treeDepths, -} from "./constants"; -import { compareVks, timeTravel, deployTestContracts } from "./utils"; +import { getDefaultSigner, getSigners } from "../ts/utils"; +import { AccQueueQuinaryMaci, MACI, Poll as PollContract } from "../typechain-types"; + +import { duration, initialVoiceCreditBalance, maxValues, messageBatchSize, treeDepths } from "./constants"; +import { timeTravel, deployTestContracts } from "./utils"; describe("MACI", () => { let maciContract: MACI; let stateAqContract: AccQueueQuinaryMaci; - let vkRegistryContract: VkRegistry; let pollId: number; const coordinator = new Keypair(); @@ -37,7 +25,7 @@ describe("MACI", () => { let signer: Signer; const maciState = new MaciState(STATE_TREE_DEPTH); - const signUpTxOpts = { gasLimit: 300000 }; + const signUpTxOpts = { gasLimit: 400000 }; describe("Deployment", () => { before(async () => { @@ -46,23 +34,45 @@ describe("MACI", () => { maciContract = r.maciContract; stateAqContract = r.stateAqContract; - vkRegistryContract = r.vkRegistryContract; }); - it("MACI.stateTreeDepth should be correct", async () => { + it("should have set the correct stateTreeDepth", async () => { const std = await maciContract.stateTreeDepth(); expect(std.toString()).to.eq(STATE_TREE_DEPTH.toString()); }); + + it("should be the owner of the stateAqContract", async () => { + const stateAqAddr = await maciContract.stateAq(); + const stateAq = new Contract(stateAqAddr, parseArtifact("AccQueueQuinaryBlankSl")[0], signer); + + expect(await stateAq.owner()).to.eq(await maciContract.getAddress()); + }); + + it("should be possible to deploy Maci contracts with different state tree depth values", async () => { + const checkStateTreeDepth = async (stateTreeDepthTest: number): Promise => { + const { maciContract: testMaci } = await deployTestContracts( + initialVoiceCreditBalance, + stateTreeDepthTest, + signer, + true, + ); + expect(await testMaci.stateTreeDepth()).to.eq(stateTreeDepthTest); + }; + + await checkStateTreeDepth(1); + await checkStateTreeDepth(2); + await checkStateTreeDepth(3); + }); }); describe("Signups", () => { - it("should sign up users", async () => { + it("should sign up multiple users", async () => { const iface = maciContract.interface; await Promise.all( users.map(async (user, index) => { const tx = await maciContract.signUp( - user.pubKey.asContractParam() as { x: BigNumberish; y: BigNumberish }, + user.pubKey.asContractParam(), AbiCoder.defaultAbiCoder().encode(["uint256"], [1]), AbiCoder.defaultAbiCoder().encode(["uint256"], [0]), signUpTxOpts, @@ -91,7 +101,7 @@ describe("MACI", () => { ); }); - it("signUp() should fail when given an invalid pubkey", async () => { + it("should fail when given an invalid pubkey", async () => { await expect( maciContract.signUp( { @@ -134,76 +144,12 @@ describe("MACI", () => { describe("Deploy a Poll", () => { let deployTime: number | undefined; - it("should set VKs and deploy a poll", async () => { - const std = await maciContract.stateTreeDepth(); - - // Set VKs - let tx = await vkRegistryContract.setVerifyingKeys( - std.toString(), - treeDepths.intStateTreeDepth, - treeDepths.messageTreeDepth, - treeDepths.voteOptionTreeDepth, - messageBatchSize, - testProcessVk.asContractParam() as IVerifyingKeyStruct, - testTallyVk.asContractParam() as IVerifyingKeyStruct, - { gasLimit: 1000000 }, - ); - let receipt = await tx.wait(); - expect(receipt?.status).to.eq(1); - - const pSig = await vkRegistryContract.genProcessVkSig( - std.toString(), - treeDepths.messageTreeDepth, - treeDepths.voteOptionTreeDepth, - messageBatchSize, - ); - - expect(pSig.toString()).to.eq( - genProcessVkSig( - Number(std), - treeDepths.messageTreeDepth, - treeDepths.voteOptionTreeDepth, - messageBatchSize, - ).toString(), - ); - - const isPSigSet = await vkRegistryContract.isProcessVkSet(pSig); - expect(isPSigSet).to.eq(true); - - const tSig = await vkRegistryContract.genTallyVkSig( - std.toString(), - treeDepths.intStateTreeDepth, - treeDepths.voteOptionTreeDepth, - ); - const isTSigSet = await vkRegistryContract.isTallyVkSet(tSig); - expect(isTSigSet).to.eq(true); - - // Check that the VKs are set - const processVkOnChain = await vkRegistryContract.getProcessVk( - std, - treeDepths.messageTreeDepth, - treeDepths.voteOptionTreeDepth, - messageBatchSize, - ); - - const tallyVkOnChain = await vkRegistryContract.getTallyVk( - std.toString(), - treeDepths.intStateTreeDepth, - treeDepths.voteOptionTreeDepth, - ); - - compareVks(testProcessVk, processVkOnChain as unknown as VerifyingKey); - compareVks(testTallyVk, tallyVkOnChain as unknown as VerifyingKey); - + it("should deploy a poll", async () => { // Create the poll and get the poll ID from the tx event logs - tx = await maciContract.deployPoll( - duration, - maxValues, - treeDepths, - coordinator.pubKey.asContractParam() as { x: BigNumberish; y: BigNumberish }, - { gasLimit: 8000000 }, - ); - receipt = await tx.wait(); + const tx = await maciContract.deployPoll(duration, maxValues, treeDepths, coordinator.pubKey.asContractParam(), { + gasLimit: 8000000, + }); + const receipt = await tx.wait(); const block = await signer.provider!.getBlock(receipt!.blockHash); deployTime = block!.timestamp; @@ -226,8 +172,8 @@ describe("MACI", () => { expect(p.toString()).to.eq(pollId.toString()); // publish the NOTHING_UP_MY_SLEEVE message - const messageData = [NOTHING_UP_MY_SLEEVE, BigInt(0)]; - for (let i = 2; i < 10; i += 1) { + const messageData = [NOTHING_UP_MY_SLEEVE]; + for (let i = 1; i < 10; i += 1) { messageData.push(BigInt(0)); } const message = new Message(BigInt(1), messageData); @@ -238,52 +184,6 @@ describe("MACI", () => { maciState.polls[pollId].publishMessage(message, padKey); }); - it("should fail when attempting to init twice a Poll", async () => { - const pollContractAddress = await maciContract.getPoll(pollId); - const pollContract = new BaseContract(pollContractAddress, pollAbi, signer) as PollContract; - - await expect(pollContract.init()).to.be.reverted; - }); - - it("should set correct storage values", async () => { - // Retrieve the Poll state and check that each value is correct - const pollContractAddress = await maciContract.getPoll(pollId); - const pollContract = new BaseContract(pollContractAddress, pollAbi, signer) as PollContract; - - const dd = await pollContract.getDeployTimeAndDuration(); - - expect(Number(dd[0])).to.eq(deployTime); - expect(Number(dd[1])).to.eq(duration); - - expect(await pollContract.stateAqMerged()).to.eq(false); - - const sb = await pollContract.currentSbCommitment(); - expect(sb.toString()).to.eq("0"); - - const sm = await pollContract.numSignUpsAndMessages(); - // There are 3 signups via the MACI instance - expect(Number(sm[0])).to.eq(3); - - // There are 1 messages until a user publishes a message - // As we enqueue the NOTHING_UP_MY_SLEEVE hash - expect(Number(sm[1])).to.eq(1); - - const onChainMaxValues = await pollContract.maxValues(); - - expect(Number(onChainMaxValues.maxMessages)).to.eq(maxValues.maxMessages); - expect(Number(onChainMaxValues.maxVoteOptions)).to.eq(maxValues.maxVoteOptions); - - const onChainTreeDepths = await pollContract.treeDepths(); - expect(Number(onChainTreeDepths.intStateTreeDepth)).to.eq(treeDepths.intStateTreeDepth); - expect(Number(onChainTreeDepths.messageTreeDepth)).to.eq(treeDepths.messageTreeDepth); - expect(Number(onChainTreeDepths.messageTreeSubDepth)).to.eq(treeDepths.messageTreeSubDepth); - expect(Number(onChainTreeDepths.voteOptionTreeDepth)).to.eq(treeDepths.voteOptionTreeDepth); - - const onChainBatchSizes = await pollContract.batchSizes(); - expect(Number(onChainBatchSizes.messageBatchSize)).to.eq(messageBatchSize); - expect(Number(onChainBatchSizes.tallyBatchSize)).to.eq(tallyBatchSize); - }); - it("should prevent deploying a second poll before the first has finished", async () => { await expect( maciContract.deployPoll(duration, maxValues, treeDepths, coordinator.pubKey.asContractParam(), { @@ -303,7 +203,7 @@ describe("MACI", () => { pollContract = new BaseContract(pollContractAddress, pollAbi, signer) as PollContract; }); - it("coordinator should not be able to merge the signUp AccQueue", async () => { + it("should not allow the coordinator to merge the signUp AccQueue", async () => { await expect(maciContract.mergeStateAqSubRoots(0, 0, { gasLimit: 3000000 })).to.be.revertedWithCustomError( maciContract, "CallerMustBePoll", @@ -315,7 +215,14 @@ describe("MACI", () => { ); }); - it("The Poll should be able to merge the signUp AccQueue", async () => { + it("should not allow a user to merge the signUp AccQueue", async () => { + const nonAdminUser = (await getSigners())[1]; + await expect( + maciContract.connect(nonAdminUser).mergeStateAqSubRoots(0, 0, { gasLimit: 3000000 }), + ).to.be.revertedWithCustomError(maciContract, "CallerMustBePoll"); + }); + + it("should allow a Poll contract to merge the signUp AccQueue", async () => { await timeTravel(signer.provider as unknown as EthereumProvider, Number(duration) + 1); let tx = await pollContract.mergeMaciStateAqSubRoots(0, pollId, { gasLimit: 3000000, @@ -330,9 +237,26 @@ describe("MACI", () => { expect(receipt?.status).to.eq(1); }); - it("the state root must be correct", async () => { + it("should have the correct state root on chain after merging the acc queue", async () => { const onChainStateRoot = await stateAqContract.getMainRoot(STATE_TREE_DEPTH); expect(onChainStateRoot.toString()).to.eq(maciState.stateTree.root.toString()); }); }); + + describe("getStateAqRoot", () => { + it("should return the correct state root", async () => { + const onChainStateRoot = await maciContract.getStateAqRoot(); + expect(onChainStateRoot.toString()).to.eq(maciState.stateTree.root.toString()); + }); + }); + + describe("getPoll", () => { + it("should return an address for a valid id", async () => { + expect(await maciContract.getPoll(pollId)).to.not.eq(0); + }); + + it("should throw when given an invalid poll id", async () => { + await expect(maciContract.getPoll(5)).to.be.revertedWithCustomError(maciContract, "PollDoesNotExist").withArgs(5); + }); + }); }); diff --git a/contracts/tests/MaciOverflow.test.ts b/contracts/tests/MaciOverflow.test.ts deleted file mode 100644 index 9db5eecfe3..0000000000 --- a/contracts/tests/MaciOverflow.test.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { expect } from "chai"; -import { AbiCoder, BigNumberish } from "ethers"; -import { MaxValues, STATE_TREE_DEPTH, TreeDepths } from "maci-core"; -import { Keypair } from "maci-domainobjs"; - -import { getDefaultSigner } from "../ts/utils"; -import { MACI } from "../typechain-types"; - -import { duration, initialVoiceCreditBalance, maxValues, treeDepths } from "./constants"; -import { deployTestContracts } from "./utils"; - -describe("Overflow testing", () => { - let maciContract: MACI; - - const coordinator = new Keypair(); - const users = [new Keypair(), new Keypair(), new Keypair()]; - - beforeEach(async () => { - const r = await deployTestContracts(initialVoiceCreditBalance, STATE_TREE_DEPTH, await getDefaultSigner(), true); - maciContract = r.maciContract; - }); - - it("MACI.stateTreeDepth should be correct", async () => { - const std = await maciContract.stateTreeDepth(); - expect(std.toString()).to.eq(STATE_TREE_DEPTH.toString()); - }); - - it("SignUps - should not overflow", async () => { - await maciContract.signUp( - users[0].pubKey.asContractParam() as { x: BigNumberish; y: BigNumberish }, - AbiCoder.defaultAbiCoder().encode(["uint256"], [1]), - AbiCoder.defaultAbiCoder().encode(["uint256"], [0]), - ); - }); - - it("Deploy Poll - should not overflow", async () => { - await maciContract.deployPoll( - duration, - maxValues, - treeDepths, - coordinator.pubKey.asContractParam() as { x: BigNumberish; y: BigNumberish }, - ); - }); - - it("Deploy Poll - should not overflow with larger values for tree depths", async () => { - const depths: TreeDepths = { - intStateTreeDepth: 2, - messageTreeDepth: 5, - messageTreeSubDepth: 5, - voteOptionTreeDepth: 2, - }; - - const values: MaxValues = { - maxMessages: 3125, - maxVoteOptions: 25, - }; - - const tx = await maciContract.deployPoll( - duration, - values, - depths, - coordinator.pubKey.asContractParam() as { x: BigNumberish; y: BigNumberish }, - ); - const receipt = await tx.wait(); - - expect(receipt?.gasUsed.toString()).to.not.eq(""); - expect(receipt?.gasUsed.toString()).to.not.eq("0"); - }); -}); diff --git a/contracts/tests/MessageProcessor.test.ts b/contracts/tests/MessageProcessor.test.ts index efe9be6ccc..35c9b40d48 100644 --- a/contracts/tests/MessageProcessor.test.ts +++ b/contracts/tests/MessageProcessor.test.ts @@ -75,8 +75,8 @@ describe("MessageProcessor", () => { expect(p.toString()).to.eq(pollId.toString()); // publish the NOTHING_UP_MY_SLEEVE message - const messageData = [NOTHING_UP_MY_SLEEVE, BigInt(0)]; - for (let i = 2; i < 10; i += 1) { + const messageData = [NOTHING_UP_MY_SLEEVE]; + for (let i = 1; i < 10; i += 1) { messageData.push(BigInt(0)); } const message = new Message(BigInt(1), messageData); @@ -138,7 +138,7 @@ describe("MessageProcessor", () => { const onChainPackedVals = BigInt( await mpContract.genProcessMessagesPackedVals(await pollContract.getAddress(), 0, users.length), ); - expect(packedVals.toString(16)).to.eq(onChainPackedVals.toString(16)); + expect(packedVals.toString()).to.eq(onChainPackedVals.toString()); }); it("processMessages() should update the state and ballot root commitment", async () => { diff --git a/contracts/tests/Poll.test.ts b/contracts/tests/Poll.test.ts index e25970287a..87e90297dd 100644 --- a/contracts/tests/Poll.test.ts +++ b/contracts/tests/Poll.test.ts @@ -17,6 +17,7 @@ import { initialVoiceCreditBalance, maxValues, messageBatchSize, + tallyBatchSize, treeDepths, } from "./constants"; import { timeTravel, deployTestContracts } from "./utils"; @@ -33,52 +34,99 @@ describe("Poll", () => { const maciState = new MaciState(STATE_TREE_DEPTH); - before(async () => { - signer = await getDefaultSigner(); - const r = await deployTestContracts(initialVoiceCreditBalance, STATE_TREE_DEPTH, signer, true); - maciContract = r.maciContract; + describe("deployment", () => { + before(async () => { + signer = await getDefaultSigner(); + const r = await deployTestContracts(initialVoiceCreditBalance, STATE_TREE_DEPTH, signer, true); + maciContract = r.maciContract; - // deploy on chain poll - const tx = await maciContract.deployPoll(duration, maxValues, treeDepths, coordinator.pubKey.asContractParam(), { - gasLimit: 8000000, + // deploy on chain poll + const tx = await maciContract.deployPoll(duration, maxValues, treeDepths, coordinator.pubKey.asContractParam(), { + gasLimit: 8000000, + }); + const receipt = await tx.wait(); + + const block = await signer.provider!.getBlock(receipt!.blockHash); + deployTime = block!.timestamp; + + expect(receipt?.status).to.eq(1); + const iface = maciContract.interface; + const logs = receipt!.logs[receipt!.logs.length - 1]; + const event = iface.parseLog(logs as unknown as { topics: string[]; data: string }) as unknown as { + args: { _pollId: number }; + }; + pollId = event.args._pollId; + + const pollContractAddress = await maciContract.getPoll(pollId); + pollContract = new BaseContract(pollContractAddress, pollAbi, signer) as PollContract; + + // deploy local poll + const p = maciState.deployPoll( + BigInt(deployTime + duration), + maxValues, + treeDepths, + messageBatchSize, + coordinator, + ); + expect(p.toString()).to.eq(pollId.toString()); + // publish the NOTHING_UP_MY_SLEEVE message + const messageData = [NOTHING_UP_MY_SLEEVE]; + for (let i = 1; i < 10; i += 1) { + messageData.push(BigInt(0)); + } + const message = new Message(BigInt(1), messageData); + const padKey = new PubKey([ + BigInt("10457101036533406547632367118273992217979173478358440826365724437999023779287"), + BigInt("19824078218392094440610104313265183977899662750282163392862422243483260492317"), + ]); + maciState.polls[pollId].publishMessage(message, padKey); + }); + + it("should not be possible to init the Poll contract twice", async () => { + await expect(pollContract.init()).to.be.revertedWithCustomError(pollContract, "PollAlreadyInit"); + }); + + it("should have the correct coordinator public key set", async () => { + const coordinatorPubKey = await pollContract.coordinatorPubKey(); + expect(coordinatorPubKey[0].toString()).to.eq(coordinator.pubKey.rawPubKey[0].toString()); + expect(coordinatorPubKey[1].toString()).to.eq(coordinator.pubKey.rawPubKey[1].toString()); + + const coordinatorPubKeyHash = await pollContract.coordinatorPubKeyHash(); + expect(coordinatorPubKeyHash.toString()).to.eq(coordinator.pubKey.hash().toString()); + }); + + it("should have the correct duration set", async () => { + const dd = await pollContract.getDeployTimeAndDuration(); + expect(dd[1].toString()).to.eq(duration.toString()); + }); + + it("should have the correct max values set", async () => { + const mv = await pollContract.maxValues(); + expect(mv[0].toString()).to.eq(maxValues.maxMessages.toString()); + expect(mv[1].toString()).to.eq(maxValues.maxVoteOptions.toString()); + }); + + it("should have the correct tree depths set", async () => { + const td = await pollContract.treeDepths(); + expect(td[0].toString()).to.eq(treeDepths.intStateTreeDepth.toString()); + expect(td[1].toString()).to.eq(treeDepths.messageTreeSubDepth.toString()); + expect(td[2].toString()).to.eq(treeDepths.messageTreeDepth.toString()); + expect(td[3].toString()).to.eq(treeDepths.voteOptionTreeDepth.toString()); + }); + + it("should have the correct batch values set", async () => { + const batchSizes = await pollContract.batchSizes(); + expect(batchSizes[0].toString()).to.eq(messageBatchSize.toString()); + expect(batchSizes[1].toString()).to.eq(tallyBatchSize.toString()); }); - const receipt = await tx.wait(); - - const block = await signer.provider!.getBlock(receipt!.blockHash); - deployTime = block!.timestamp; - - expect(receipt?.status).to.eq(1); - const iface = maciContract.interface; - const logs = receipt!.logs[receipt!.logs.length - 1]; - const event = iface.parseLog(logs as unknown as { topics: string[]; data: string }) as unknown as { - args: { _pollId: number }; - }; - pollId = event.args._pollId; - - const pollContractAddress = await maciContract.getPoll(pollId); - pollContract = new BaseContract(pollContractAddress, pollAbi, signer) as PollContract; - - // deploy local poll - const p = maciState.deployPoll(BigInt(deployTime + duration), maxValues, treeDepths, messageBatchSize, coordinator); - expect(p.toString()).to.eq(pollId.toString()); - // publish the NOTHING_UP_MY_SLEEVE message - const messageData = [NOTHING_UP_MY_SLEEVE, BigInt(0)]; - for (let i = 2; i < 10; i += 1) { - messageData.push(BigInt(0)); - } - const message = new Message(BigInt(1), messageData); - const padKey = new PubKey([ - BigInt("10457101036533406547632367118273992217979173478358440826365724437999023779287"), - BigInt("19824078218392094440610104313265183977899662750282163392862422243483260492317"), - ]); - maciState.polls[pollId].publishMessage(message, padKey); - }); - it("should not be possible to init the Poll contract twice", async () => { - await expect(pollContract.init()).to.be.revertedWithCustomError(pollContract, "PollAlreadyInit"); + it("should have numMessages set to 1 (blank message)", async () => { + const numMessages = await pollContract.numMessages(); + expect(numMessages.toString()).to.eq("1"); + }); }); - describe("Publish messages (vote + key-change)", () => { + describe("publishMessage", () => { it("should publish a message to the Poll contract", async () => { const keypair = new Keypair(); @@ -102,7 +150,30 @@ describe("Poll", () => { maciState.polls[pollId].publishMessage(message, keypair.pubKey); }); - it("should not publish a message after the voting period", async () => { + it("should emit an event when publishing a message", async () => { + const keypair = new Keypair(); + + const command = new PCommand( + BigInt(1), + keypair.pubKey, + BigInt(0), + BigInt(9), + BigInt(1), + BigInt(pollId), + BigInt(0), + ); + + const signature = command.sign(keypair.privKey); + const sharedKey = Keypair.genEcdhSharedKey(keypair.privKey, coordinator.pubKey); + const message = command.encrypt(signature, sharedKey); + expect(await pollContract.publishMessage(message.asContractParam(), keypair.pubKey.asContractParam())) + .to.emit(pollContract, "PublishMessage") + .withArgs(message.asContractParam(), keypair.pubKey.asContractParam()); + + maciState.polls[pollId].publishMessage(message, keypair.pubKey); + }); + + it("shold not allow to publish a message after the voting period ends", async () => { const dd = await pollContract.getDeployTimeAndDuration(); await timeTravel(signer.provider as unknown as EthereumProvider, Number(dd[0]) + 1); @@ -137,14 +208,14 @@ describe("Poll", () => { messageAqContract = new BaseContract(messageAqAddress, accQueueQuinaryMaciAbi, signer) as AccQueue; }); - it("should revert if subtrees are not merged for StateAq", async () => { + it("should revert if the subtrees are not merged for StateAq", async () => { await expect(pollContract.mergeMaciStateAq(0, { gasLimit: 4000000 })).to.be.revertedWithCustomError( pollContract, "StateAqSubtreesNeedMerge", ); }); - it("coordinator should be able to merge the message AccQueue", async () => { + it("should allow the coordinator to merge the message AccQueue", async () => { let tx = await pollContract.mergeMessageAqSubRoots(0, { gasLimit: 3000000, }); @@ -156,7 +227,7 @@ describe("Poll", () => { expect(receipt?.status).to.eq(1); }); - it("the message root must be correct", async () => { + it("should have the correct message root set", async () => { const onChainMessageRoot = await messageAqContract.getMainRoot(MESSAGE_TREE_DEPTH); const offChainMessageRoot = maciState.polls[pollId].messageTree.root; diff --git a/contracts/tests/PollFactory.test.ts b/contracts/tests/PollFactory.test.ts new file mode 100644 index 0000000000..c930e04079 --- /dev/null +++ b/contracts/tests/PollFactory.test.ts @@ -0,0 +1,63 @@ +import { expect } from "chai"; +import { BaseContract, Signer, ZeroAddress } from "ethers"; +import { Keypair } from "maci-domainobjs"; + +import { deployPollFactory, getDefaultSigner } from "../ts"; +import { PollFactory } from "../typechain-types"; + +import { maxValues, messageBatchSize, tallyBatchSize, treeDepths } from "./constants"; + +describe("pollFactory", () => { + let pollFactory: PollFactory; + let signer: Signer; + + const { pubKey: coordinatorPubKey } = new Keypair(); + + before(async () => { + signer = await getDefaultSigner(); + pollFactory = (await deployPollFactory(signer, true)) as BaseContract as PollFactory; + }); + + describe("deployment", () => { + it("should allow anyone to deploy a new poll", async () => { + const tx = await pollFactory.deploy( + "100", + maxValues, + treeDepths, + { + messageBatchSize, + tallyBatchSize, + subsidyBatchSize: tallyBatchSize, + }, + coordinatorPubKey.asContractParam(), + ZeroAddress, + ZeroAddress, + await signer.getAddress(), + ); + const receipt = await tx.wait(); + expect(receipt?.status).to.eq(1); + }); + + it("should revert when called with an invalid param for max values", async () => { + await expect( + pollFactory.deploy( + "100", + { + maxMessages: maxValues.maxMessages * 10000, + maxVoteOptions: maxValues.maxVoteOptions, + }, + treeDepths, + { + messageBatchSize, + tallyBatchSize, + subsidyBatchSize: tallyBatchSize, + }, + coordinatorPubKey.asContractParam(), + ZeroAddress, + ZeroAddress, + await signer.getAddress(), + ), + ).to.be.revertedWithCustomError(pollFactory, "InvalidMaxValues"); + }); + }); +}); diff --git a/contracts/tests/SignUpGatekeeper.test.ts b/contracts/tests/SignUpGatekeeper.test.ts index 9ca7679f73..3693766b6c 100644 --- a/contracts/tests/SignUpGatekeeper.test.ts +++ b/contracts/tests/SignUpGatekeeper.test.ts @@ -1,5 +1,5 @@ import { expect } from "chai"; -import { AbiCoder, BigNumberish, Signer } from "ethers"; +import { AbiCoder, ZeroAddress, Signer } from "ethers"; import { STATE_TREE_DEPTH } from "maci-core"; import { Keypair } from "maci-domainobjs"; @@ -20,7 +20,7 @@ describe("SignUpGatekeeper", () => { signer = await getDefaultSigner(); freeForAllContract = await deployFreeForAllSignUpGatekeeper(signer, true); signUpToken = await deploySignupToken(signer, true); - signUpTokenGatekeeperContract = await deploySignupTokenGatekeeper(await signUpToken.getAddress()); + signUpTokenGatekeeperContract = await deploySignupTokenGatekeeper(await signUpToken.getAddress(), signer, true); }); describe("Deployment", () => { @@ -39,7 +39,6 @@ describe("SignUpGatekeeper", () => { let maciContract: MACI; beforeEach(async () => { - freeForAllContract = await deployFreeForAllSignUpGatekeeper(signer, true); signUpToken = await deploySignupToken(signer, true); signUpTokenGatekeeperContract = await deploySignupTokenGatekeeper(await signUpToken.getAddress(), signer, true); @@ -62,20 +61,43 @@ describe("SignUpGatekeeper", () => { expect(await signUpTokenGatekeeperContract.maci()).to.eq(maciAddress); }); - it("Reverts if address provided is not a MACI instance", async () => { + it("it should revert if the register function is called by a non registered maci instance", async () => { const user = new Keypair(); - const tx = await signUpToken.giveToken(await signer.getAddress(), 0); - await tx.wait(); + await signUpToken.giveToken(await signer.getAddress(), 0); await expect( maciContract.signUp( - user.pubKey.asContractParam() as { x: BigNumberish; y: BigNumberish }, + user.pubKey.asContractParam(), AbiCoder.defaultAbiCoder().encode(["uint256"], [1]), AbiCoder.defaultAbiCoder().encode(["uint256"], [0]), - { gasLimit: 300000 }, ), ).to.be.revertedWithCustomError(signUpTokenGatekeeperContract, "OnlyMACI"); }); + + it("should register a user if the register function is called by a registered maci instance", async () => { + const user = new Keypair(); + + await signUpToken.giveToken(await signer.getAddress(), 0); + + await signUpTokenGatekeeperContract.setMaciInstance(await maciContract.getAddress()); + + const tx = await maciContract.signUp( + user.pubKey.asContractParam(), + AbiCoder.defaultAbiCoder().encode(["uint256"], [0]), + AbiCoder.defaultAbiCoder().encode(["uint256"], [1]), + ); + const receipt = await tx.wait(); + + expect(receipt?.status).to.eq(1); + }); + }); + + describe("FreeForAllSignUpGatekeeper", () => { + it("should always complete successfully", async () => { + const tx = await freeForAllContract.register(ZeroAddress, AbiCoder.defaultAbiCoder().encode(["uint256"], [1])); + const receipt = await tx.wait(); + expect(receipt?.status).to.eq(1); + }); }); }); diff --git a/contracts/tests/Subsidy.test.ts b/contracts/tests/Subsidy.test.ts new file mode 100644 index 0000000000..34f8b1daf4 --- /dev/null +++ b/contracts/tests/Subsidy.test.ts @@ -0,0 +1,190 @@ +/* eslint-disable no-underscore-dangle */ +import { expect } from "chai"; +import { BaseContract, Signer } from "ethers"; +import { EthereumProvider } from "hardhat/types"; +import { MaciState, Poll, packSubsidySmallVals } from "maci-core"; +import { NOTHING_UP_MY_SLEEVE } from "maci-crypto"; +import { Keypair, Message, PubKey } from "maci-domainobjs"; + +import { parseArtifact } from "../ts/abi"; +import { IVerifyingKeyStruct } from "../ts/types"; +import { getDefaultSigner } from "../ts/utils"; +import { MACI, Poll as PollContract, MessageProcessor, Subsidy } from "../typechain-types"; + +import { + STATE_TREE_DEPTH, + duration, + maxValues, + messageBatchSize, + testProcessVk, + testTallyVk, + treeDepths, +} from "./constants"; +import { timeTravel, deployTestContracts } from "./utils"; + +describe("Subsidy", () => { + let signer: Signer; + let maciContract: MACI; + let pollContract: PollContract; + let subsidyContract: Subsidy; + let mpContract: MessageProcessor; + + const coordinator = new Keypair(); + const maciState = new MaciState(STATE_TREE_DEPTH); + + const [pollAbi] = parseArtifact("Poll"); + + let pollId: number; + let poll: Poll; + + let generatedInputs: { newSbCommitment: bigint }; + + before(async () => { + signer = await getDefaultSigner(); + + const r = await deployTestContracts(100, STATE_TREE_DEPTH, signer, true); + maciContract = r.maciContract; + mpContract = r.mpContract; + subsidyContract = r.subsidyContract!; + + // deploy a poll + // deploy on chain poll + const tx = await maciContract.deployPoll(duration, maxValues, treeDepths, coordinator.pubKey.asContractParam(), { + gasLimit: 8000000, + }); + const receipt = await tx.wait(); + + const block = await signer.provider!.getBlock(receipt!.blockHash); + const deployTime = block!.timestamp; + + expect(receipt?.status).to.eq(1); + const iface = maciContract.interface; + const logs = receipt!.logs[receipt!.logs.length - 1]; + const event = iface.parseLog(logs as unknown as { topics: string[]; data: string }) as unknown as { + args: { _pollId: number }; + }; + pollId = event.args._pollId; + + const pollContractAddress = await maciContract.getPoll(pollId); + pollContract = new BaseContract(pollContractAddress, pollAbi, signer) as PollContract; + + // deploy local poll + const p = maciState.deployPoll(BigInt(deployTime + duration), maxValues, treeDepths, messageBatchSize, coordinator); + expect(p.toString()).to.eq(pollId.toString()); + // publish the NOTHING_UP_MY_SLEEVE message + const messageData = [NOTHING_UP_MY_SLEEVE, BigInt(0)]; + for (let i = 2; i < 10; i += 1) { + messageData.push(BigInt(0)); + } + const message = new Message(BigInt(1), messageData); + const padKey = new PubKey([ + BigInt("10457101036533406547632367118273992217979173478358440826365724437999023779287"), + BigInt("19824078218392094440610104313265183977899662750282163392862422243483260492317"), + ]); + maciState.polls[pollId].publishMessage(message, padKey); + + // save the poll + poll = maciState.polls[pollId]; + + // process messages locally + generatedInputs = poll.processMessages(pollId) as typeof generatedInputs; + + // set the verification keys on the vk smart contract + const vkContract = r.vkRegistryContract; + await vkContract.setVerifyingKeys( + STATE_TREE_DEPTH, + treeDepths.intStateTreeDepth, + treeDepths.messageTreeDepth, + treeDepths.voteOptionTreeDepth, + messageBatchSize, + testProcessVk.asContractParam() as IVerifyingKeyStruct, + testTallyVk.asContractParam() as IVerifyingKeyStruct, + { gasLimit: 1000000 }, + ); + await vkContract.setSubsidyKeys( + STATE_TREE_DEPTH, + treeDepths.intStateTreeDepth, + treeDepths.voteOptionTreeDepth, + testProcessVk.asContractParam() as IVerifyingKeyStruct, + { gasLimit: 1000000 }, + ); + }); + + it("should not be possible to tally votes before the poll has ended", async () => { + await expect( + subsidyContract.updateSubsidy( + await pollContract.getAddress(), + await mpContract.getAddress(), + 0, + [0, 0, 0, 0, 0, 0, 0, 0], + ), + ).to.be.revertedWithCustomError(subsidyContract, "VOTING_PERIOD_NOT_PASSED"); + }); + + it("genSubsidyPackedVals() should generate the correct value", async () => { + const onChainPackedVals = BigInt(await subsidyContract.genSubsidyPackedVals(0)); + const packedVals = packSubsidySmallVals(0, 0, 0); + expect(onChainPackedVals.toString()).to.eq(packedVals.toString()); + }); + + it("updateSbCommitment() should revert when the messages have not been processed yet", async () => { + // go forward in time + await timeTravel(signer.provider! as unknown as EthereumProvider, duration + 1); + + await expect(subsidyContract.updateSbCommitment(await mpContract.getAddress())).to.be.revertedWithCustomError( + subsidyContract, + "ProcessingNotComplete", + ); + }); + + it("updateSubsidy() should fail as the messages have not been processed yet", async () => { + const pollContractAddress = await maciContract.getPoll(pollId); + await expect( + subsidyContract.updateSubsidy(pollContractAddress, await mpContract.getAddress(), 0, [0, 0, 0, 0, 0, 0, 0, 0]), + ).to.be.revertedWithCustomError(subsidyContract, "ProcessingNotComplete"); + }); + + describe("after merging acc queues", () => { + let subsidyGeneratedInputs: { newSubsidyCommitment: bigint }; + before(async () => { + await pollContract.mergeMaciStateAqSubRoots(0, pollId); + await pollContract.mergeMaciStateAq(0); + + await pollContract.mergeMessageAqSubRoots(0); + await pollContract.mergeMessageAq(); + subsidyGeneratedInputs = poll.subsidyPerBatch() as { newSubsidyCommitment: bigint }; + }); + it("updateSubsidy() should update the tally commitment", async () => { + // do the processing on the message processor contract + await mpContract.processMessages( + await pollContract.getAddress(), + generatedInputs.newSbCommitment, + [0, 0, 0, 0, 0, 0, 0, 0], + ); + + const tx = await subsidyContract.updateSubsidy( + await pollContract.getAddress(), + await mpContract.getAddress(), + subsidyGeneratedInputs.newSubsidyCommitment, + [0, 0, 0, 0, 0, 0, 0, 0], + ); + + const receipt = await tx.wait(); + expect(receipt?.status).to.eq(1); + + const onChainNewTallyCommitment = await subsidyContract.subsidyCommitment(); + + expect(subsidyGeneratedInputs.newSubsidyCommitment).to.eq(onChainNewTallyCommitment.toString()); + }); + it("updateSubsidy() should revert when votes have already been tallied", async () => { + await expect( + subsidyContract.updateSubsidy( + await pollContract.getAddress(), + await mpContract.getAddress(), + subsidyGeneratedInputs.newSubsidyCommitment, + [0, 0, 0, 0, 0, 0, 0, 0], + ), + ).to.be.revertedWithCustomError(subsidyContract, "AllSubsidyCalculated"); + }); + }); +}); diff --git a/contracts/tests/Tally.test.ts b/contracts/tests/Tally.test.ts index 20e21c5170..37b110b9f3 100644 --- a/contracts/tests/Tally.test.ts +++ b/contracts/tests/Tally.test.ts @@ -54,7 +54,7 @@ describe("TallyVotes", () => { const tx = await maciContract.deployPoll(duration, maxValues, treeDepths, coordinator.pubKey.asContractParam(), { gasLimit: 8000000, }); - let receipt = await tx.wait(); + const receipt = await tx.wait(); const block = await signer.provider!.getBlock(receipt!.blockHash); const deployTime = block!.timestamp; @@ -74,8 +74,8 @@ describe("TallyVotes", () => { const p = maciState.deployPoll(BigInt(deployTime + duration), maxValues, treeDepths, messageBatchSize, coordinator); expect(p.toString()).to.eq(pollId.toString()); // publish the NOTHING_UP_MY_SLEEVE message - const messageData = [NOTHING_UP_MY_SLEEVE, BigInt(0)]; - for (let i = 2; i < 10; i += 1) { + const messageData = [NOTHING_UP_MY_SLEEVE]; + for (let i = 1; i < 10; i += 1) { messageData.push(BigInt(0)); } const message = new Message(BigInt(1), messageData); @@ -103,8 +103,6 @@ describe("TallyVotes", () => { testTallyVk.asContractParam() as IVerifyingKeyStruct, { gasLimit: 1000000 }, ); - receipt = await tx.wait(); - expect(receipt?.status).to.eq(1); }); it("should not be possible to tally votes before the poll has ended", async () => { diff --git a/contracts/tests/Utilities.test.ts b/contracts/tests/Utilities.test.ts index ff91e2f87f..120e95d7cb 100644 --- a/contracts/tests/Utilities.test.ts +++ b/contracts/tests/Utilities.test.ts @@ -1,4 +1,5 @@ import { expect } from "chai"; +import { BigNumberish, ZeroAddress } from "ethers"; import { StateLeaf, Keypair } from "maci-domainobjs"; import { deployPoseidonContracts, linkPoseidonLibraries } from "../ts/deploy"; @@ -40,6 +41,13 @@ describe("Utilities", () => { await utilitiesContract.deploymentTransaction()?.wait(); }); + it("should have been deployed", async () => { + expect(utilitiesContract).to.not.eq(undefined); + expect(await utilitiesContract.getAddress()).to.not.eq(ZeroAddress); + }); + }); + + describe("hashStateLeaf", () => { it("should correctly hash a StateLeaf", async () => { const keypair = new Keypair(); const voiceCreditBalance = BigInt(1234); @@ -50,4 +58,29 @@ describe("Utilities", () => { expect(onChainHash.toString()).to.eq(expectedHash.toString()); }); }); + + describe("padAndHashMessage", () => { + it("should correctly pad and hash a message", async () => { + const dataToPad: [BigNumberish, BigNumberish] = [1234, 1234]; + const msgType = BigInt(2) as BigNumberish; + + // Call the padAndHashMessage function + const { message, padKey } = await utilitiesContract.padAndHashMessage(dataToPad, msgType); + + // Validate the returned message + expect(message.msgType.toString()).to.eq(msgType.toString()); + expect(message.data.slice(0, 2)).to.deep.eq(dataToPad); + for (let i = 2; i < 10; i += 1) { + expect(message.data[i]).to.eq(0); + } + + // Validate the returned padKey + expect(padKey.x.toString()).to.eq( + "10457101036533406547632367118273992217979173478358440826365724437999023779287", + ); + expect(padKey.y.toString()).to.eq( + "19824078218392094440610104313265183977899662750282163392862422243483260492317", + ); + }); + }); }); diff --git a/contracts/tests/Verifier.test.ts b/contracts/tests/Verifier.test.ts index 73044c62cc..d48d737c0f 100644 --- a/contracts/tests/Verifier.test.ts +++ b/contracts/tests/Verifier.test.ts @@ -92,5 +92,15 @@ describe("DomainObjs", () => { expect(isValid).to.eq(true); }); + it("should return false for a proof that is not valid", async () => { + const isValid = await verifierContract.verify( + proof, + vk.asContractParam() as IVerifyingKeyStruct, + BigInt(publicInputs[0]) + BigInt(1), + { gasLimit: 1000000 }, + ); + + expect(isValid).to.eq(false); + }); }); }); diff --git a/contracts/tests/VkRegistry.test.ts b/contracts/tests/VkRegistry.test.ts new file mode 100644 index 0000000000..b255874b39 --- /dev/null +++ b/contracts/tests/VkRegistry.test.ts @@ -0,0 +1,189 @@ +import { expect } from "chai"; +import { Signer } from "ethers"; + +import { IVerifyingKeyStruct, VkRegistry, deployVkRegistry, getDefaultSigner } from "../ts"; + +import { messageBatchSize, testProcessVk, testTallyVk, treeDepths } from "./constants"; +import { compareVks } from "./utils"; + +describe("VkRegistry", () => { + let signer: Signer; + let vkRegistryContract: VkRegistry; + + const stateTreeDepth = 10; + + describe("deployment", () => { + before(async () => { + signer = await getDefaultSigner(); + vkRegistryContract = await deployVkRegistry(signer, true); + }); + it("should have set the correct owner", async () => { + expect(await vkRegistryContract.owner()).to.eq(await signer.getAddress()); + }); + }); + + describe("setVerifyingKeys", () => { + it("should set the process and tally vks", async () => { + const tx = await vkRegistryContract.setVerifyingKeys( + stateTreeDepth, + treeDepths.intStateTreeDepth, + treeDepths.messageTreeDepth, + treeDepths.voteOptionTreeDepth, + messageBatchSize, + testProcessVk.asContractParam() as IVerifyingKeyStruct, + testTallyVk.asContractParam() as IVerifyingKeyStruct, + { gasLimit: 1000000 }, + ); + const receipt = await tx.wait(); + expect(receipt?.status).to.eq(1); + }); + + it("should throw when trying to set another vk for the same params", async () => { + await expect( + vkRegistryContract.setVerifyingKeys( + stateTreeDepth, + treeDepths.intStateTreeDepth, + treeDepths.messageTreeDepth, + treeDepths.voteOptionTreeDepth, + messageBatchSize, + testProcessVk.asContractParam() as IVerifyingKeyStruct, + testTallyVk.asContractParam() as IVerifyingKeyStruct, + { gasLimit: 1000000 }, + ), + ).to.be.revertedWithCustomError(vkRegistryContract, "ProcessVkAlreadySet"); + }); + + it("should allow to set vks for different params", async () => { + const tx = await vkRegistryContract.setVerifyingKeys( + stateTreeDepth + 1, + treeDepths.intStateTreeDepth, + treeDepths.messageTreeDepth, + treeDepths.voteOptionTreeDepth, + messageBatchSize, + testProcessVk.asContractParam() as IVerifyingKeyStruct, + testTallyVk.asContractParam() as IVerifyingKeyStruct, + { gasLimit: 1000000 }, + ); + const receipt = await tx.wait(); + expect(receipt?.status).to.eq(1); + }); + + it("should allow to set the subsidy vks", async () => { + const tx = await vkRegistryContract.setSubsidyKeys( + stateTreeDepth, + treeDepths.intStateTreeDepth, + treeDepths.voteOptionTreeDepth, + testProcessVk.asContractParam() as IVerifyingKeyStruct, + { gasLimit: 1000000 }, + ); + const receipt = await tx.wait(); + expect(receipt?.status).to.eq(1); + }); + }); + + describe("hasVks", () => { + describe("hasProcessVk", () => { + it("should return true for the process vk", async () => { + expect( + await vkRegistryContract.hasProcessVk( + stateTreeDepth, + treeDepths.messageTreeDepth, + treeDepths.voteOptionTreeDepth, + messageBatchSize, + ), + ).to.eq(true); + }); + it("should return false for a non-existing vk", async () => { + expect( + await vkRegistryContract.hasProcessVk( + stateTreeDepth + 2, + treeDepths.messageTreeDepth, + treeDepths.voteOptionTreeDepth, + messageBatchSize, + ), + ).to.eq(false); + }); + }); + + describe("hasTallyVk", () => { + it("should return true for the tally vk", async () => { + expect( + await vkRegistryContract.hasTallyVk( + stateTreeDepth, + treeDepths.intStateTreeDepth, + treeDepths.voteOptionTreeDepth, + ), + ).to.eq(true); + }); + it("should return false for a non-existing vk", async () => { + expect( + await vkRegistryContract.hasTallyVk( + stateTreeDepth + 2, + treeDepths.intStateTreeDepth, + treeDepths.voteOptionTreeDepth, + ), + ).to.eq(false); + }); + }); + + describe("hasSubsidyVk", () => { + it("should return true for the subsidy vk", async () => { + expect( + await vkRegistryContract.hasSubsidyVk( + stateTreeDepth, + treeDepths.intStateTreeDepth, + treeDepths.voteOptionTreeDepth, + ), + ).to.eq(true); + }); + it("should return false for a non-existing vk", async () => { + expect( + await vkRegistryContract.hasSubsidyVk( + stateTreeDepth + 2, + treeDepths.intStateTreeDepth, + treeDepths.voteOptionTreeDepth, + ), + ).to.eq(false); + }); + }); + }); + + describe("genSignatures", () => { + describe("genProcessVkSig", () => { + it("should generate a valid signature", async () => { + const sig = await vkRegistryContract.genProcessVkSig( + stateTreeDepth, + treeDepths.messageTreeDepth, + treeDepths.voteOptionTreeDepth, + messageBatchSize, + ); + const vk = await vkRegistryContract.getProcessVkBySig(sig); + compareVks(testProcessVk, vk); + }); + }); + + describe("genTallyVkSig", () => { + it("should generate a valid signature", async () => { + const sig = await vkRegistryContract.genTallyVkSig( + stateTreeDepth, + treeDepths.intStateTreeDepth, + treeDepths.voteOptionTreeDepth, + ); + const vk = await vkRegistryContract.getTallyVkBySig(sig); + compareVks(testTallyVk, vk); + }); + }); + + describe("genSubsidyVkSig", () => { + it("should generate a valid signature", async () => { + const sig = await vkRegistryContract.genSubsidyVkSig( + stateTreeDepth, + treeDepths.intStateTreeDepth, + treeDepths.voteOptionTreeDepth, + ); + const vk = await vkRegistryContract.getSubsidyVkBySig(sig); + compareVks(testProcessVk, vk); + }); + }); + }); +}); diff --git a/contracts/tests/utils.ts b/contracts/tests/utils.ts index be77a4ccbe..7e1fa4607c 100644 --- a/contracts/tests/utils.ts +++ b/contracts/tests/utils.ts @@ -2,7 +2,7 @@ import { expect } from "chai"; import { BaseContract, Signer } from "ethers"; import { IncrementalQuinTree, AccQueue, calcDepthFromNumLeaves, hash2, hash5 } from "maci-crypto"; -import { VerifyingKey } from "maci-domainobjs"; +import { IVkContractParams, VerifyingKey } from "maci-domainobjs"; import type { EthereumProvider } from "hardhat/types"; @@ -14,6 +14,7 @@ import { deployMessageProcessor, deployMockVerifier, deployPoseidonContracts, + deploySubsidy, deployTally, deployTopupCredit, deployVkRegistry, @@ -41,7 +42,7 @@ export async function timeTravel(provider: EthereumProvider, seconds: number): P * @param vk - the off chain vk * @param vkOnChain - the on chain vk */ -export const compareVks = (vk: VerifyingKey, vkOnChain: VerifyingKey): void => { +export const compareVks = (vk: VerifyingKey, vkOnChain: IVkContractParams): void => { expect(vk.ic.length).to.eq(vkOnChain.ic.length); for (let i = 0; i < vk.ic.length; i += 1) { expect(vk.ic[i].x.toString()).to.eq(vkOnChain.ic[i].x.toString()); @@ -548,6 +549,17 @@ export const deployTestContracts = async ( true, ); + const subsidyContract = await deploySubsidy( + mockVerifierContractAddress, + vkRegistryContractAddress, + poseidonAddrs[0], + poseidonAddrs[1], + poseidonAddrs[2], + poseidonAddrs[3], + signer, + true, + ); + return { mockVerifierContract, gatekeeperContract, @@ -557,5 +569,6 @@ export const deployTestContracts = async ( vkRegistryContract, mpContract, tallyContract, + subsidyContract, }; }; diff --git a/contracts/ts/deploy.ts b/contracts/ts/deploy.ts index 7951868e58..8c2fdc0711 100644 --- a/contracts/ts/deploy.ts +++ b/contracts/ts/deploy.ts @@ -187,15 +187,6 @@ export const deployPoseidonContracts = async (signer?: Signer, quiet = false): P }; }; -/** - * Deploy a PollFactory contract - * @param signer - the signer to use to deploy the contract - * @param quiet - whether to suppress console output - * @returns the deployed PollFactory contract - */ -export const deployPollFactory = async (signer?: Signer, quiet = false): Promise => - deployContract("PollFactory", signer, quiet); - /** * Deploy a contract with linked libraries * @param contractFactory - the contract factory to use @@ -219,6 +210,32 @@ export const deployContractWithLinkedLibraries = async ( return contract as T; }; +/** + * Deploy a Poll Factory contract + * @param signer - the signer object to use to deploy the contract + * @param quiet - whether to suppress console output + * @returns the deployed Poll Factory contract + */ +export const deployPollFactory = async (signer: Signer, quiet = false): Promise => { + const poseidonContracts = await deployPoseidonContracts(signer, quiet); + const [poseidonT3Contract, poseidonT4Contract, poseidonT5Contract, poseidonT6Contract] = await Promise.all([ + poseidonContracts.PoseidonT3Contract.getAddress(), + poseidonContracts.PoseidonT4Contract.getAddress(), + poseidonContracts.PoseidonT5Contract.getAddress(), + poseidonContracts.PoseidonT6Contract.getAddress(), + ]); + const contractFactory = await linkPoseidonLibraries( + "PollFactory", + poseidonT3Contract, + poseidonT4Contract, + poseidonT5Contract, + poseidonT6Contract, + signer, + quiet, + ); + return deployContractWithLinkedLibraries(contractFactory, "PollFactory", quiet); +}; + /** * Deploy a MessageProcessor contract * @param verifierAddress - the address of the Verifier contract diff --git a/contracts/ts/types.ts b/contracts/ts/types.ts index 5199358ea0..e12e8c8bcb 100644 --- a/contracts/ts/types.ts +++ b/contracts/ts/types.ts @@ -12,6 +12,7 @@ import type { PoseidonT4, PoseidonT5, PoseidonT6, + Subsidy, Tally, VkRegistry, } from "../typechain-types"; @@ -67,6 +68,7 @@ export interface IDeployedTestContracts { vkRegistryContract: VkRegistry; mpContract: MessageProcessor; tallyContract: Tally; + subsidyContract?: Subsidy; } /** From b1c8c9719da5d47b92408f1222399c9c4acf3df9 Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Wed, 3 Jan 2024 12:44:19 +0000 Subject: [PATCH 18/37] fix(signups): ensure we account for the blank state leaf currently the blank state leaf is not counted as one signup, and thus we could go over the supported amount of signups (based on the circuits parameters) by 1, potentially preventing one voters' votes from being tallied fix #947 --- cli/ts/commands/proveOnChain.ts | 11 +++++++---- contracts/contracts/MACI.sol | 6 ++++++ contracts/contracts/Subsidy.sol | 5 ++--- contracts/tests/MACI.test.ts | 3 ++- core/ts/MaciState.ts | 3 +++ 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/cli/ts/commands/proveOnChain.ts b/cli/ts/commands/proveOnChain.ts index 56849e62b9..80b86b0782 100644 --- a/cli/ts/commands/proveOnChain.ts +++ b/cli/ts/commands/proveOnChain.ts @@ -303,12 +303,11 @@ export const proveOnChain = async ( if (Object.keys(data.subsidyProofs).length !== 0) { let rbi = Number(await subsidyContract.rbi()); let cbi = Number(await subsidyContract.cbi()); - const numLeaves = numSignUps + 1; - const num1DBatches = Math.ceil(numLeaves / subsidyBatchSize); + const num1DBatches = Math.ceil(numSignUps / subsidyBatchSize); let subsidyBatchNum = rbi * num1DBatches + cbi; const totalBatchNum = (num1DBatches * (num1DBatches + 1)) / 2; - logYellow(quiet, info(`number of subsidy batch processed: ${subsidyBatchNum}, numleaf=${numLeaves}`)); + logYellow(quiet, info(`number of subsidy batch processed: ${subsidyBatchNum}, numleaf=${numSignUps}`)); // process all batches for (let i = subsidyBatchNum; i < totalBatchNum; i++) { @@ -373,7 +372,11 @@ export const proveOnChain = async ( } // vote tallying proofs - const totalTallyBatches = numSignUps < tallyBatchSize ? 1 : Math.floor(numSignUps / tallyBatchSize) + 1; + const totalTallyBatches = + numSignUps % tallyBatchSize === 0 + ? Math.floor(numSignUps / tallyBatchSize) + : Math.floor(numSignUps / tallyBatchSize) + 1; + let tallyBatchNum = Number(await tallyContract.tallyBatchNum()); if (tallyBatchNum < totalTallyBatches) logYellow(quiet, info("Submitting proofs of vote tallying...")); diff --git a/contracts/contracts/MACI.sol b/contracts/contracts/MACI.sol index eead7b3500..5071f20232 100644 --- a/contracts/contracts/MACI.sol +++ b/contracts/contracts/MACI.sol @@ -101,6 +101,12 @@ contract MACI is IMACI, DomainObjs, Params, Utilities, Ownable { stateAq = new AccQueueQuinaryBlankSl(STATE_TREE_SUBDEPTH); stateAq.enqueue(BLANK_STATE_LEAF_HASH); + // because we add a blank leaf we need to count one signup + // so we don't allow max + 1 + unchecked { + numSignUps++; + } + pollFactory = _pollFactory; topupCredit = _topupCredit; signUpGatekeeper = _signUpGatekeeper; diff --git a/contracts/contracts/Subsidy.sol b/contracts/contracts/Subsidy.sol index e5d1868550..60bcd94e16 100644 --- a/contracts/contracts/Subsidy.sol +++ b/contracts/contracts/Subsidy.sol @@ -103,10 +103,9 @@ contract Subsidy is Ownable, CommonUtilities, Hasher, SnarkCommon { uint256 subsidyBatchSize = uint256(treeArity) ** intStateTreeDepth; (uint256 numSignUps, ) = _poll.numSignUpsAndMessages(); - uint256 numLeaves = numSignUps + 1; // Require that there are unfinished ballots left - if (rbi * subsidyBatchSize > numLeaves) { + if (rbi * subsidyBatchSize > numSignUps) { revert AllSubsidyCalculated(); } @@ -115,7 +114,7 @@ contract Subsidy is Ownable, CommonUtilities, Hasher, SnarkCommon { revert InvalidSubsidyProof(); } subsidyCommitment = _newSubsidyCommitment; - increaseSubsidyIndex(subsidyBatchSize, numLeaves); + increaseSubsidyIndex(subsidyBatchSize, numSignUps); } /// @notice Increase the subsidy batch index (rbi, cbi) to next, diff --git a/contracts/tests/MACI.test.ts b/contracts/tests/MACI.test.ts index b11fe4e016..e806d183da 100644 --- a/contracts/tests/MACI.test.ts +++ b/contracts/tests/MACI.test.ts @@ -121,7 +121,8 @@ describe("MACI", () => { const maci = (await deployTestContracts(initialVoiceCreditBalance, stateTreeDepthTest, signer, true)) .maciContract; const keypair = new Keypair(); - for (let i = 0; i < maxUsers; i += 1) { + // start from one as we already have one signup (blank state leaf) + for (let i = 1; i < maxUsers; i += 1) { // eslint-disable-next-line no-await-in-loop await maci.signUp( keypair.pubKey.asContractParam(), diff --git a/core/ts/MaciState.ts b/core/ts/MaciState.ts index 38ae59652d..304da2e465 100644 --- a/core/ts/MaciState.ts +++ b/core/ts/MaciState.ts @@ -39,6 +39,9 @@ export class MaciState implements IMaciState { // we put a blank state leaf to prevent a DoS attack this.stateLeaves.push(blankStateLeaf); this.stateTree.insert(blankStateLeafHash); + // we need to increase the number of signups by one given + // that we already added the blank leaf + this.numSignUps += 1; } /** From 0340f7960a2214410d8885541ac542419a980a34 Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Sat, 30 Dec 2023 13:13:44 +0000 Subject: [PATCH 19/37] refactor(zk-kit-poseidon): remove old circomlib dependencies in crypto --- .../scripts/ceremony-param-tests-c-witness.sh | 14 +- contracts/package-lock.json | 40 +- contracts/package.json | 1 - contracts/ts/genMaciState.ts | 6 +- core/package-lock.json | 8026 ++++------------- crypto/package-lock.json | 935 +- crypto/package.json | 5 +- crypto/ts/@types/blake-hash.d.ts | 10 - crypto/ts/@types/circomlib.d.ts | 38 - crypto/ts/@types/main.d.ts | 2 - crypto/ts/__tests__/Crypto.test.ts | 160 +- crypto/ts/__tests__/Utils.test.ts | 16 +- crypto/ts/bigIntUtils.ts | 7 - crypto/ts/constants.ts | 12 +- crypto/ts/crypto.ts | 172 +- crypto/ts/index.ts | 18 +- crypto/ts/types.ts | 35 +- domainobjs/ts/__tests__/publicKey.test.ts | 6 +- domainobjs/ts/commands/PCommand.ts | 13 +- domainobjs/ts/privateKey.ts | 8 +- domainobjs/ts/publicKey.ts | 14 +- integrationTests/package-lock.json | 4 +- integrationTests/package.json | 10 +- .../ts/__tests__/maci-keys.test.ts | 125 + integrationTests/ts/__tests__/utils/utils.ts | 66 + 25 files changed, 2131 insertions(+), 7612 deletions(-) delete mode 100644 crypto/ts/@types/blake-hash.d.ts delete mode 100644 crypto/ts/@types/circomlib.d.ts create mode 100644 integrationTests/ts/__tests__/maci-keys.test.ts diff --git a/.github/scripts/ceremony-param-tests-c-witness.sh b/.github/scripts/ceremony-param-tests-c-witness.sh index 69db3b706c..1bb3277190 100755 --- a/.github/scripts/ceremony-param-tests-c-witness.sh +++ b/.github/scripts/ceremony-param-tests-c-witness.sh @@ -17,7 +17,7 @@ HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js setVerifyingKeys -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js create -s 6 -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js deployPoll \ - -pk macipk.bca7ac038ea1a6e4cb45a142ebe6485670bdb1c34b5ba45257c4c7faed8efc14 \ + -pk macipk.4d9929621583dd9b8cac251fdc7bf58050330f37e1f407b327e711d5e32ba3a9 \ --duration 30 \ --max-messages 390625 \ --max-vote-options 125 \ @@ -27,11 +27,11 @@ HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js deployPoll \ --vote-option-tree-depth 3 \ -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js signup \ - --pubkey macipk.32c021243306d488fdc2aefa33c2093c1143e2baecb4b6fb04fba4c4abe972ae \ + --pubkey macipk.5e304c40fbf7f84fe09b8a21b6d0454a9606fca1d34977e0b68b8e5fe1c9460a \ -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js publish \ - --pubkey macipk.32c021243306d488fdc2aefa33c2093c1143e2baecb4b6fb04fba4c4abe972ae \ - --privkey macisk.209ed243578af94e720ef7ca90067ad9089f01195269926e511f3fac4f32841 \ + --pubkey macipk.5e304c40fbf7f84fe09b8a21b6d0454a9606fca1d34977e0b68b8e5fe1c9460a \ + --privkey macisk.251a97d4d2ffde8673102572e530d0293afdc3394e2db8fd5b3029ec00c7c739 \ --state-index 1 \ --vote-option-index 0 \ --new-vote-weight 9 \ @@ -39,8 +39,8 @@ HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js publish \ --poll-id 0 \ -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js publish \ - --pubkey macipk.32c021243306d488fdc2aefa33c2093c1143e2baecb4b6fb04fba4c4abe972ae \ - --privkey macisk.209ed243578af94e720ef7ca90067ad9089f01195269926e511f3fac4f32841 \ + --pubkey macipk.5e304c40fbf7f84fe09b8a21b6d0454a9606fca1d34977e0b68b8e5fe1c9460a \ + --privkey macisk.251a97d4d2ffde8673102572e530d0293afdc3394e2db8fd5b3029ec00c7c739 \ --state-index 1 \ --vote-option-index 1 \ --new-vote-weight 9 \ @@ -51,7 +51,7 @@ HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js timeTravel -s 10 HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js mergeSignups --poll-id 0 -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js mergeMessages --poll-id 0 -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js genProofs \ - --privkey macisk.13035f1d0b35b0fe673c96586a4de84149c9539d8a03260a5fa333baaf45c11 \ + --privkey macisk.02115a4e210f81195aec6e6e9375bd1028f89dd873e6ee62bc5af298e13fd2e7 \ --poll-id 0 \ --rapidsnark ~/rapidsnark/build/prover \ --process-zkey ./zkeys/processMessages_6-8-2-3.zkey \ diff --git a/contracts/package-lock.json b/contracts/package-lock.json index d3025d833b..c6afa1eeff 100644 --- a/contracts/package-lock.json +++ b/contracts/package-lock.json @@ -10,11 +10,9 @@ "dependencies": { "@nomicfoundation/hardhat-toolbox": "^4.0.0", "@openzeppelin/contracts": "^4.8.0", - "circomlib": "^2.0.5", "circomlibjs": "^0.1.7", "ethers": "^6.9.0", "hardhat": "^2.19.1", - "module-alias": "^2.2.2", "solidity-docgen": "^0.6.0-beta.36" }, "devDependencies": { @@ -2421,6 +2419,20 @@ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" }, + "node_modules/bufferutil": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", + "hasInstallScript": true, + "optional": true, + "peer": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -2589,11 +2601,6 @@ "safe-buffer": "^5.0.1" } }, - "node_modules/circomlib": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/circomlib/-/circomlib-2.0.5.tgz", - "integrity": "sha512-O7NQ8OS+J4eshBuoy36z/TwQU0YHw8W3zxZcs4hVwpEll3e4hDm3mgkIPqItN8FDeLEKZFK3YeT/+k8TiLF3/A==" - }, "node_modules/circomlibjs": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/circomlibjs/-/circomlibjs-0.1.7.tgz", @@ -5455,11 +5462,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/module-alias": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.3.tgz", - "integrity": "sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q==" - }, "node_modules/module-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz", @@ -7399,6 +7401,20 @@ "punycode": "^2.1.0" } }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "hasInstallScript": true, + "optional": true, + "peer": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, "node_modules/utf8": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", diff --git a/contracts/package.json b/contracts/package.json index 45dd3605a8..b34fdb7118 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -31,7 +31,6 @@ "dependencies": { "@nomicfoundation/hardhat-toolbox": "^4.0.0", "@openzeppelin/contracts": "^4.8.0", - "circomlib": "^2.0.5", "circomlibjs": "^0.1.7", "ethers": "^6.9.0", "hardhat": "^2.19.1", diff --git a/contracts/ts/genMaciState.ts b/contracts/ts/genMaciState.ts index 0931772c27..68eac8a153 100644 --- a/contracts/ts/genMaciState.ts +++ b/contracts/ts/genMaciState.ts @@ -93,7 +93,7 @@ export const genMaciStateFromContract = async ( transactionIndex: log.transactionIndex, data: { stateIndex: Number(event.args._stateIndex), - pubKey: new PubKey(event.args._userPubKey.map((x) => BigInt(x))), + pubKey: new PubKey(event.args._userPubKey.map((x) => BigInt(x)) as [bigint, bigint]), voiceCreditBalance: Number(event.args._voiceCreditBalance), timestamp: Number(event.args._timestamp), }, @@ -111,7 +111,7 @@ export const genMaciStateFromContract = async ( args: { _pubKey: string[]; _pollAddr: string; _pollId: number }; }; - const pubKey = new PubKey(event.args._pubKey.map((x) => BigInt(x.toString()))); + const pubKey = new PubKey(event.args._pubKey.map((x) => BigInt(x.toString())) as [bigint, bigint]); const p = Number(event.args._pollId); assert(p === index); @@ -216,7 +216,7 @@ export const genMaciStateFromContract = async ( event.args._message[1].map((x) => BigInt(x)), ); - const encPubKey = new PubKey(event.args._encPubKey.map((x) => BigInt(x.toString()))); + const encPubKey = new PubKey(event.args._encPubKey.map((x) => BigInt(x.toString())) as [bigint, bigint]); actions.push({ type: "PublishMessage", diff --git a/core/package-lock.json b/core/package-lock.json index f860d5d94d..1a282e4090 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -7,10 +7,6 @@ "": { "name": "maci-core", "version": "1.1.2", - "dependencies": { - "maci-crypto": "^1.1.2", - "maci-domainobjs": "^1.1.2" - }, "devDependencies": { "@types/chai": "^4.3.11", "@types/mocha": "^10.0.6", @@ -482,5117 +478,742 @@ "node": ">=6.9.0" } }, - "node_modules/@ethereumjs/common": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.5.tgz", - "integrity": "sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==", + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, "dependencies": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.5" - } - }, - "node_modules/@ethereumjs/rlp": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", - "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", - "bin": { - "rlp": "bin/rlp" + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" }, "engines": { - "node": ">=14" + "node": ">=8" } }, - "node_modules/@ethereumjs/tx": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.2.tgz", - "integrity": "sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, "dependencies": { - "@ethereumjs/common": "^2.6.4", - "ethereumjs-util": "^7.1.5" + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" } }, - "node_modules/@ethereumjs/util": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", - "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, "dependencies": { - "@ethereumjs/rlp": "^4.0.1", - "ethereum-cryptography": "^2.0.0", - "micro-ftch": "^0.3.1" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=14" + "node": ">=8" } }, - "node_modules/@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, "dependencies": { - "@ethersproject/bytes": "^5.7.0" + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@ethersproject/basex": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", - "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/properties": "^5.7.0" + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" } }, - "node_modules/@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.7.0" + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0" + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@ethersproject/contracts": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", - "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0" - } - }, - "node_modules/@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "node_modules/@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dev": true, "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.0" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ] - }, - "node_modules/@ethersproject/networks": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", - "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" - } - }, - "node_modules/@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/providers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", - "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "node_modules/@ethersproject/random": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", - "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/sha2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", - "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/transactions": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", - "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0" - } - }, - "node_modules/@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@ethersproject/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@iden3/bigarray": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/@iden3/bigarray/-/bigarray-0.0.2.tgz", - "integrity": "sha512-Xzdyxqm1bOFF6pdIsiHLLl3HkSLjbhqJHVyqaTxXt3RqXBEnmsUmEW47H7VOi/ak7TdkRpNkxjyK5Zbkm+y52g==" - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", - "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@noble/curves": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", - "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", - "dependencies": { - "@noble/hashes": "1.3.1" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/hashes": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", - "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/base": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.5.tgz", - "integrity": "sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ==", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip32": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz", - "integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==", - "dependencies": { - "@noble/curves": "~1.1.0", - "@noble/hashes": "~1.3.1", - "@scure/base": "~1.1.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip39": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", - "integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==", - "dependencies": { - "@noble/hashes": "~1.3.0", - "@scure/base": "~1.1.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", - "dependencies": { - "defer-to-connect": "^2.0.1" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/@types/bn.js": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", - "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/cacheable-request": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", - "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", - "dependencies": { - "@types/http-cache-semantics": "*", - "@types/keyv": "^3.1.4", - "@types/node": "*", - "@types/responselike": "^1.0.0" - } - }, - "node_modules/@types/chai": { - "version": "4.3.11", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.11.tgz", - "integrity": "sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ==", - "dev": true - }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, - "optional": true - }, - "node_modules/@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/mocha": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.6.tgz", - "integrity": "sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==", - "dev": true - }, - "node_modules/@types/node": { - "version": "18.19.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.3.tgz", - "integrity": "sha512-k5fggr14DwAytoA/t8rPrIz++lXK7/DqckthCmoZOKNsEbJkId4Z//BqgApXBUGrGddrigYa1oqheo/7YmW4rg==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/responselike": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", - "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/secp256k1": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", - "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==" - }, - "node_modules/abortcontroller-polyfill": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz", - "integrity": "sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==" - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", - "dev": true, - "dependencies": { - "default-require-extensions": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", - "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", - "dependencies": { - "call-bind": "^1.0.2", - "is-nan": "^1.3.2", - "object-is": "^1.1.5", - "object.assign": "^4.1.4", - "util": "^0.12.5" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "engines": { - "node": "*" - } - }, - "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" - }, - "node_modules/async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" - }, - "node_modules/b4a": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", - "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/base64url": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", - "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, - "node_modules/big-integer": { - "version": "1.6.52", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", - "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/bignumber.js": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/blake-hash": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/blake-hash/-/blake-hash-1.1.1.tgz", - "integrity": "sha512-V93H+FEJuXXZi1eEsMtbcBFP9oL5Ept7SLw3cbXYlPC3nocm9Fr4m18ZhbhdJrZVS9J/Z0oNE4L3oDZvmorHNA==", - "hasInstallScript": true, - "dependencies": { - "bindings": "^1.2.1", - "inherits": "^2.0.3", - "nan": "^2.2.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/blake2b": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/blake2b/-/blake2b-2.1.4.tgz", - "integrity": "sha512-AyBuuJNI64gIvwx13qiICz6H6hpmjvYS5DGkG6jbXMOT8Z3WUJ3V1X0FlhIoT1b/5JtHE3ki+xjtMvu1nn+t9A==", - "dependencies": { - "blake2b-wasm": "^2.4.0", - "nanoassert": "^2.0.0" - } - }, - "node_modules/blake2b-wasm": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/blake2b-wasm/-/blake2b-wasm-2.4.0.tgz", - "integrity": "sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w==", - "dependencies": { - "b4a": "^1.0.1", - "nanoassert": "^2.0.0" - } - }, - "node_modules/blakejs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" - }, - "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserslist": { - "version": "4.22.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", - "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", - "dependencies": { - "base-x": "^3.0.2" - } - }, - "node_modules/bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "dependencies": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/buffer-to-arraybuffer": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==" - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" - }, - "node_modules/bufferutil": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", - "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", - "hasInstallScript": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacheable-lookup": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz", - "integrity": "sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==", - "engines": { - "node": ">=10.6.0" - } - }, - "node_modules/cacheable-request": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", - "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", - "dev": true, - "dependencies": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", - "dependencies": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001570", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", - "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" - }, - "node_modules/chai": { - "version": "4.3.10", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", - "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dependencies": { - "get-func-name": "^2.0.2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "node_modules/cids": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", - "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", - "deprecated": "This module has been superseded by the multiformats module", - "dependencies": { - "buffer": "^5.5.0", - "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" - }, - "engines": { - "node": ">=4.0.0", - "npm": ">=3.0.0" - } - }, - "node_modules/cids/node_modules/multicodec": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", - "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", - "deprecated": "This module has been superseded by the multiformats module", - "dependencies": { - "buffer": "^5.6.0", - "varint": "^5.0.0" - } - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/circom": { - "version": "0.5.45", - "resolved": "https://registry.npmjs.org/circom/-/circom-0.5.45.tgz", - "integrity": "sha512-5Ixp6UjwrhBWnnFBO/mTns+eeEDOpi5UoN4znAUWy5rklCUWYt2Ezl9QVUswBXjMP5kpfEtGUY2XSsYRAp6uMg==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dependencies": { - "chai": "^4.2.0", - "circom_runtime": "0.1.12", - "fastfile": "0.0.18", - "ffiasm": "0.1.1", - "ffjavascript": "0.2.22", - "ffwasm": "0.0.7", - "fnv-plus": "^1.3.1", - "r1csfile": "0.0.16", - "tmp-promise": "^2.0.2", - "wasmbuilder": "0.0.10" - }, - "bin": { - "circom": "cli.js" - } - }, - "node_modules/circom_runtime": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.1.12.tgz", - "integrity": "sha512-R+QT9HS9w71cmGmWIn+PSyD3aHyR5JZBiVvxOjCfn12wwnpuFwBjdMG7he+v8h/oQD1mDRAu2KrBeL4mAt5s4A==", - "dependencies": { - "ffjavascript": "0.2.34", - "fnv-plus": "^1.3.1" - }, - "bin": { - "calcwit": "calcwit.js" - } - }, - "node_modules/circom_runtime/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/circom_runtime/node_modules/chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.1" - } - }, - "node_modules/circom_runtime/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/circom_runtime/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/circom_runtime/node_modules/ffjavascript": { - "version": "0.2.34", - "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.34.tgz", - "integrity": "sha512-fq/qfJluC4spiOD1lp5jfckZVnS0o0kI5eKXVLw7UKwIwbNr+NBMBveBVcidSfMizF87T6wb7NBtLSdckQiAnQ==", - "dependencies": { - "big-integer": "^1.6.48", - "mocha": "^8.2.1", - "wasmcurves": "0.0.14", - "worker-threads": "^1.0.0" - } - }, - "node_modules/circom_runtime/node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/circom_runtime/node_modules/js-yaml": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", - "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/circom_runtime/node_modules/log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", - "dependencies": { - "chalk": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/circom_runtime/node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/circom_runtime/node_modules/mocha": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", - "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", - "dependencies": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.1", - "debug": "4.3.1", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.6", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.0.0", - "log-symbols": "4.0.0", - "minimatch": "3.0.4", - "ms": "2.1.3", - "nanoid": "3.1.20", - "serialize-javascript": "5.0.1", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.1.0", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 10.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/circom_runtime/node_modules/nanoid": { - "version": "3.1.20", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", - "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/circom_runtime/node_modules/readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/circom_runtime/node_modules/serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/circom_runtime/node_modules/wasmcurves": { - "version": "0.0.14", - "resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.0.14.tgz", - "integrity": "sha512-G1iMkxlRaQSdqQ1JrwHcU+awLmwyH6kFKfT8g9obd8MWe+u5oSdFXrODB0zmSI5aGGvJPG+4cAmqCGYv9R+7qg==", - "dependencies": { - "big-integer": "^1.6.42", - "blakejs": "^1.1.0" - } - }, - "node_modules/circom_runtime/node_modules/workerpool": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", - "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==" - }, - "node_modules/circom/node_modules/ffjavascript": { - "version": "0.2.22", - "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.22.tgz", - "integrity": "sha512-EsVqap2Txm17bKW0z/jXCX3M7rQ++nQUAJY8alWDpyhjRj90xjl6GLeVSKZQ8rOFDQ/SFFXcEB8w9X8Boxid+w==", - "dependencies": { - "big-integer": "^1.6.48", - "wasmcurves": "0.0.12", - "worker-threads": "^1.0.0" - } - }, - "node_modules/circom/node_modules/wasmcurves": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.0.12.tgz", - "integrity": "sha512-1Jl9mkatyHSNj80ILjf85SZUNuZQBCkTjJlhzqHnZQXUmIimCIWkugaVaYNjozLs1Gun4h/keZe1MBeBN0sRpg==", - "dependencies": { - "big-integer": "^1.6.42", - "blakejs": "^1.1.0" - } - }, - "node_modules/circomlib": { - "version": "0.5.2", - "resolved": "git+ssh://git@github.com/weijiekoh/circomlib.git#24ed08eee0bb613b8c0135d66c1013bd9f78d50a", - "integrity": "sha512-oWrlNshOYpXszPIaMlWA/Dq7kv18nhsYyBK8C9etCvec5i7huQC17yelbKZCayxbhhDulNbs+GMXw9IG1iARuw==", - "license": "GPL-3.0", - "dependencies": { - "blake-hash": "^1.1.0", - "blake2b": "^2.1.3", - "circom": "0.5.45", - "ffjavascript": "0.1.0", - "web3-utils": "^1.3.0" - } - }, - "node_modules/circomlib/node_modules/ffjavascript": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.1.0.tgz", - "integrity": "sha512-dmKlUasSfvUcxBm8nCSKl2x7EFJsXA7OVP8XLFA03T2+6mAc3IiVLC2ambEVOcMOhyhl0vJfVZjM9f9d38D1rw==", - "dependencies": { - "big-integer": "^1.6.48" - } - }, - "node_modules/circomlibjs": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/circomlibjs/-/circomlibjs-0.0.8.tgz", - "integrity": "sha512-oZFYapLO0mfiA+i2GU/V7bRNEEPjVcwV4M444nU5lNsdSJpqLwD57m9zxTD5m/KeY7WQ3lEAC9NNKEPQHu7s1w==", - "dependencies": { - "blake-hash": "^2.0.0", - "blake2b": "^2.1.3", - "ffjavascript": "^0.2.38", - "web3": "^1.6.0", - "web3-utils": "^1.6.0" - } - }, - "node_modules/circomlibjs/node_modules/blake-hash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/blake-hash/-/blake-hash-2.0.0.tgz", - "integrity": "sha512-Igj8YowDu1PRkRsxZA7NVkdFNxH5rKv5cpLxQ0CVXSIA77pVYwCPRQJ2sMew/oneUpfuYRyjG6r8SmmmnbZb1w==", - "hasInstallScript": true, - "dependencies": { - "node-addon-api": "^3.0.0", - "node-gyp-build": "^4.2.2", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/class-is": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", - "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==" - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "dependencies": { - "mimic-response": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-hash": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", - "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", - "dependencies": { - "cids": "^0.7.1", - "multicodec": "^0.5.5", - "multihashes": "^0.4.15" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "bin": { - "crc32": "bin/crc32.njs" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "node_modules/cross-fetch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", - "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", - "dependencies": { - "node-fetch": "^2.6.12" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/default-require-extensions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", - "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", - "dev": true, - "dependencies": { - "strip-bom": "^4.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-require-extensions/node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "engines": { - "node": ">=10" - } - }, - "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", - "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "node_modules/ejs": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", - "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.614", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.614.tgz", - "integrity": "sha512-X4ze/9Sc3QWs6h92yerwqv7aB/uU8vCjZcrMjA8N9R1pjMFRe44dLsck5FzLilOYvcXuDn93B+bpGYyufc70gQ==", - "dev": true - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "hasInstallScript": true, - "dependencies": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "node_modules/es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dependencies": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eth-ens-namehash": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", - "integrity": "sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==", - "dependencies": { - "idna-uts46-hx": "^2.3.1", - "js-sha3": "^0.5.7" - } - }, - "node_modules/eth-ens-namehash/node_modules/js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==" - }, - "node_modules/eth-lib": { - "version": "0.1.29", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", - "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" - } - }, - "node_modules/eth-lib/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/eth-lib/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/eth-lib/node_modules/ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dependencies": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - }, - "node_modules/ethereum-bloom-filters": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", - "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", - "dependencies": { - "js-sha3": "^0.8.0" - } - }, - "node_modules/ethereum-cryptography": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz", - "integrity": "sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==", - "dependencies": { - "@noble/curves": "1.1.0", - "@noble/hashes": "1.3.1", - "@scure/bip32": "1.3.1", - "@scure/bip39": "1.2.1" - } - }, - "node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/ethereumjs-util/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" - } - }, - "node_modules/ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", - "dependencies": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ethjs-unit/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" - }, - "node_modules/eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==" - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/express/node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dependencies": { - "type": "^2.7.2" - } - }, - "node_modules/ext/node_modules/type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fastfile": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.18.tgz", - "integrity": "sha512-q03PTKc+wptis4WmuFOwPNQx2p5myFUrl/dMgRlW9mymc1Egyc14JPHgiGnWK+sJ0+dBl2Vwtfh5GfSQltYOpw==" - }, - "node_modules/ffiasm": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ffiasm/-/ffiasm-0.1.1.tgz", - "integrity": "sha512-irMMHiR9JJ7BVBrAhtliUawxVdPYSdyl81taUYJ4C1mJ0iw2ueThE/qtr0J8B83tsIY8HJvh0lg5F+6ClK4xpA==", - "dependencies": { - "big-integer": "^1.6.48", - "ejs": "^3.0.1", - "yargs": "^15.3.1" - }, - "bin": { - "buildzqfield": "src/buildzqfield.js" - } - }, - "node_modules/ffiasm/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/ffiasm/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/ffiasm/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ffiasm/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ffiasm/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ffiasm/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ffiasm/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ffiasm/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ffiasm/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" - }, - "node_modules/ffiasm/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ffiasm/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ffjavascript": { - "version": "0.2.62", - "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.62.tgz", - "integrity": "sha512-uJ7MTrdzhX/3f+hxn0XhdXbJCqYZJSBB6y2/ui4t21vKYVjyTMlU80pPXu40ir6qpqbrdzUeKdlOdJ0aFG9UNA==", - "dependencies": { - "wasmbuilder": "0.0.16", - "wasmcurves": "0.2.2", - "web-worker": "^1.2.0" - } - }, - "node_modules/ffjavascript/node_modules/wasmbuilder": { - "version": "0.0.16", - "resolved": "https://registry.npmjs.org/wasmbuilder/-/wasmbuilder-0.0.16.tgz", - "integrity": "sha512-Qx3lEFqaVvp1cEYW7Bfi+ebRJrOiwz2Ieu7ZG2l7YyeSJIok/reEQCQCuicj/Y32ITIJuGIM9xZQppGx5LrQdA==" - }, - "node_modules/ffwasm": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ffwasm/-/ffwasm-0.0.7.tgz", - "integrity": "sha512-17cTLzv7HHAKqZbX8MvHxjSrR0yDdn1sh4TVsTbAvO9e6klhFicnyoVXc/sCuViV/M8g65sCmVrAmoPCZp1YkQ==", - "dependencies": { - "big-integer": "^1.6.48", - "wasmbuilder": "0.0.10" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "bin": { - "flat": "cli.js" - } - }, - "node_modules/fnv-plus": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/fnv-plus/-/fnv-plus-1.3.1.tgz", - "integrity": "sha512-Gz1EvfOneuFfk4yG458dJ3TLJ7gV19q3OM/vVvvHf7eT02Hm1DleB4edsia6ahbKgAYxO9gvyQ1ioWZR+a00Yw==" - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/form-data-encoder": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz", - "integrity": "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==" - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "node_modules/fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dependencies": { - "minipass": "^2.6.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "engines": { - "node": "*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", - "dependencies": { - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dependencies": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/got": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-12.1.0.tgz", - "integrity": "sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==", - "dependencies": { - "@sindresorhus/is": "^4.6.0", - "@szmarczak/http-timer": "^5.0.1", - "@types/cacheable-request": "^6.0.2", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^6.0.4", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "form-data-encoder": "1.7.1", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "engines": { - "node": ">=4.x" - } - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", - "dependencies": { - "get-intrinsic": "^1.2.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "dev": true, - "dependencies": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "bin": { - "he": "bin/he" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-https": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", - "integrity": "sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg==" - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/http2-wrapper": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/idna-uts46-hx": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", - "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", - "dependencies": { - "punycode": "2.1.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/idna-uts46-hx/node_modules/punycode": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" - }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", - "dependencies": { - "which-typed-array": "^1.1.11" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "dev": true, - "dependencies": { - "append-transform": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-processinfo": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", - "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", - "dev": true, - "dependencies": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.3", - "istanbul-lib-coverage": "^3.2.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^8.3.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-report/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-report/node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/istanbul-lib-report/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jake": { - "version": "10.8.7", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", - "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", - "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jake/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/jake/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" - }, - "node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "optional": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/keccak": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", - "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", - "hasInstallScript": true, - "dependencies": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/keccak/node_modules/node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", + "node_modules/@types/chai": { + "version": "4.3.11", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.11.tgz", + "integrity": "sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ==", "dev": true }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "dependencies": { - "get-func-name": "^2.0.1" - } + "optional": true }, - "node_modules/lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "node_modules/@types/mocha": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.6.tgz", + "integrity": "sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==", + "dev": true }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "node_modules/@types/node": { + "version": "18.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.3.tgz", + "integrity": "sha512-k5fggr14DwAytoA/t8rPrIz++lXK7/DqckthCmoZOKNsEbJkId4Z//BqgApXBUGrGddrigYa1oqheo/7YmW4rg==", "dev": true, "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/maci-crypto": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/maci-crypto/-/maci-crypto-1.1.2.tgz", - "integrity": "sha512-/eaWVItoLFl32OcANn/6UhTzhe0zyXEAvSsBxH8ZsuI1TpBad3uw4wLh4AMVfehKI2IflMmTLriSedS3vQiwQw==", - "deprecated": "1.1.2 is no longer supported. Please use 1.1.1 instead.", - "dependencies": { - "blake-hash": "^1.1.0", - "circomlib": "git+https://github.com/weijiekoh/circomlib.git#24ed08eee0bb613b8c0135d66c1013bd9f78d50a", - "ethers": "^5.0.32", - "ffjavascript": "^0.2.57", - "optimisedmt": "^0.0.7" - } - }, - "node_modules/maci-crypto/node_modules/optimisedmt": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/optimisedmt/-/optimisedmt-0.0.7.tgz", - "integrity": "sha512-yVlKMmP/egqiAtg12KFZxqKx35STm+RB5kSSvo9q0B0sIx/7HbWj7fJcFLUFtWzbYp2IvdOhx31s4IC7RmU5pQ==", - "dependencies": { - "assert": "^2.0.0", - "circomlibjs": "0.0.8", - "ffjavascript": "^0.2.39" - } - }, - "node_modules/maci-domainobjs": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/maci-domainobjs/-/maci-domainobjs-1.1.2.tgz", - "integrity": "sha512-4HIBMe173DFQ9TZh68Yuf/eYNHA2Uzt/Ucqf53R3BOZ3tcmuEGIgEiKyzQZPlNQshAOOHeBZqlPlsuDge7t51A==", - "deprecated": "1.1.2 is no longer supported. Please use 1.1.1 instead.", - "dependencies": { - "base64url": "^3.0.1" + "undici-types": "~5.26.4" } }, - "node_modules/make-dir": { + "node_modules/aggregate-error": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, "dependencies": { - "semver": "^6.0.0" + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" } }, - "node_modules/micro-ftch": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", - "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==" - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, "engines": { - "node": ">=4" + "node": ">=6" } }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { - "mime-db": "1.52.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", - "dependencies": { - "dom-walk": "^0.1.0" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" - }, - "node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", - "dependencies": { - "brace-expansion": "^2.0.1" + "node": ">=8" }, - "engines": { - "node": ">=10" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dependencies": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "node_modules/minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dependencies": { - "minipass": "^2.9.0" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/mkdirp-promise": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", - "integrity": "sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w==", - "deprecated": "This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that.", + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, "dependencies": { - "mkdirp": "*" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" }, "engines": { - "node": ">=4" + "node": ">= 8" } }, - "node_modules/mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", + "node_modules/append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", "dev": true, "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" + "default-require-extensions": "^3.0.0" }, "engines": { - "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" + "node": ">=8" } }, - "node_modules/mock-fs": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz", - "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==" + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", + "dev": true }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, - "node_modules/multibase": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", - "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", - "deprecated": "This module has been superseded by the multiformats module", - "dependencies": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/multicodec": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", - "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", - "deprecated": "This module has been superseded by the multiformats module", - "dependencies": { - "varint": "^5.0.0" + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" } }, - "node_modules/multihashes": { - "version": "0.4.21", - "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", - "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", - "dependencies": { - "buffer": "^5.5.0", - "multibase": "^0.7.0", - "varint": "^5.0.0" + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" } }, - "node_modules/multihashes/node_modules/multibase": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", - "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", - "deprecated": "This module has been superseded by the multiformats module", + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, "dependencies": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" + "balanced-match": "^1.0.0" } }, - "node_modules/nan": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", - "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==" - }, - "node_modules/nano-json-stream-parser": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==" - }, - "node_modules/nanoassert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-2.0.0.tgz", - "integrity": "sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==" - }, - "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" + "dependencies": { + "fill-range": "^7.0.1" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" - }, - "node_modules/node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "node_modules/browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" }, - "peerDependencies": { - "encoding": "^0.1.0" + "bin": { + "browserslist": "cli.js" }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/node-gyp-build": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.7.1.tgz", - "integrity": "sha512-wTSrZ+8lsRRa3I3H8Xr65dLWSgCvY2l4AOnaeKdPA9TB/WYMPaTcrzf3rXvFoVvjKNVnu0CcWSx54qq9GKRUYg==", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true }, - "node_modules/node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", "dev": true, "dependencies": { - "process-on-spawn": "^1.0.0" + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "node_modules/caniuse-lite": { + "version": "1.0.30001570", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", + "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chai": { + "version": "4.3.10", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", + "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "dependencies": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=6.5.0", - "npm": ">=3" + "node": ">=8" } }, - "node_modules/number-to-bn/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" - }, - "node_modules/nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, "dependencies": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" - }, - "bin": { - "nyc": "bin/nyc.js" + "get-func-name": "^2.0.2" }, "engines": { - "node": ">=8.9" + "node": "*" } }, - "node_modules/nyc/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true, "engines": { "node": ">=6" } }, - "node_modules/nyc/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" + "wrap-ansi": "^7.0.0" } }, - "node_modules/nyc/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, "engines": { - "node": ">=0.10.0" + "node": ">=7.0.0" } }, - "node_modules/nyc/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">=8" + "node": ">= 8" } }, - "node_modules/nyc/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { - "p-locate": "^4.1.0" + "ms": "2.1.2" }, "engines": { - "node": ">=8" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/nyc/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, "engines": { - "node": ">=6" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/nyc/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/deep-eql": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, "dependencies": { - "p-limit": "^2.2.0" + "type-detect": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/nyc/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "node_modules/default-require-extensions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", + "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "strip-bom": "^4.0.0" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/nyc/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/nyc/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "node_modules/default-require-extensions/node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, "engines": { "node": ">=8" } }, - "node_modules/nyc/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "engines": { - "node": "*" + "node": ">=0.3.1" } }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } + "node_modules/electron-to-chromium": { + "version": "1.4.614", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.614.tgz", + "integrity": "sha512-X4ze/9Sc3QWs6h92yerwqv7aB/uU8vCjZcrMjA8N9R1pjMFRe44dLsck5FzLilOYvcXuDn93B+bpGYyufc70gQ==", + "dev": true }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, - "node_modules/object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, "engines": { - "node": ">= 0.4" + "node": ">=6" } }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/oboe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", - "integrity": "sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA==", - "dependencies": { - "http-https": "^1.0.0" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" }, "engines": { - "node": ">= 0.8" + "node": ">=4" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, "dependencies": { - "wrappy": "1" - } - }, - "node_modules/p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "to-regex-range": "^5.0.1" + }, "engines": { - "node": ">=12.20" + "node": ">=8" } }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, "dependencies": { - "yocto-queue": "^0.1.0" + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" }, "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, - "node_modules/p-locate": { + "node_modules/find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, "dependencies": { - "p-limit": "^3.0.2" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { "node": ">=10" @@ -5601,278 +1222,330 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", "dev": true, "dependencies": { - "aggregate-error": "^3.0.0" + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" }, "engines": { - "node": ">=8" + "node": ">=8.0.0" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "node_modules/fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=6" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, - "dependencies": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - }, "engines": { - "node": ">=8" + "node": ">=6.9.0" } }, - "node_modules/parse-headers": { + "node_modules/get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", - "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==" - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, "engines": { - "node": ">= 0.8" + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8.0.0" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, "engines": { - "node": ">=8" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, "engines": { - "node": "*" + "node": ">= 6" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/pbkdf2": { + "node_modules/glob/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=0.12" + "node": "*" } }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "node": ">=8" } }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", "dev": true, "dependencies": { - "find-up": "^4.0.0" + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, "engines": { - "node": ">=8" + "node": ">=0.8.19" } }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, "engines": { "node": ">=8" } }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "dependencies": { - "p-limit": "^2.2.0" + "binary-extensions": "^2.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, "engines": { - "node": ">= 0.6.0" + "node": ">=0.10.0" } }, - "node_modules/process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "dependencies": { - "fromentries": "^1.2.0" - }, "engines": { "node": ">=8" } }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">= 0.10" + "node": ">=0.10.0" } }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" } }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, "engines": { - "node": ">=0.6" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "dependencies": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, "engines": { "node": ">=10" }, @@ -5880,1570 +1553,1241 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/r1csfile": { - "version": "0.0.16", - "resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.16.tgz", - "integrity": "sha512-A2jRVWzGgmXeG2lVAc0H4suJmzt50it5UvBnycJgBCpMXM3tH/M6RguP7nvs6suY/yYnkN6jX6iTScSiDUF3FA==", - "dependencies": { - "@iden3/bigarray": "0.0.2", - "fastfile": "0.0.18", - "ffjavascript": "0.2.22" - } - }, - "node_modules/r1csfile/node_modules/ffjavascript": { - "version": "0.2.22", - "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.22.tgz", - "integrity": "sha512-EsVqap2Txm17bKW0z/jXCX3M7rQ++nQUAJY8alWDpyhjRj90xjl6GLeVSKZQ8rOFDQ/SFFXcEB8w9X8Boxid+w==", - "dependencies": { - "big-integer": "^1.6.48", - "wasmcurves": "0.0.12", - "worker-threads": "^1.0.0" - } - }, - "node_modules/r1csfile/node_modules/wasmcurves": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.0.12.tgz", - "integrity": "sha512-1Jl9mkatyHSNj80ILjf85SZUNuZQBCkTjJlhzqHnZQXUmIimCIWkugaVaYNjozLs1Gun4h/keZe1MBeBN0sRpg==", - "dependencies": { - "big-integer": "^1.6.42", - "blakejs": "^1.1.0" + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "node_modules/istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "append-transform": "^2.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">=8" } }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" }, "engines": { - "node": ">= 6" + "node": ">=8" } }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", + "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", "dev": true, "dependencies": { - "picomatch": "^2.2.1" + "archy": "^1.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^8.3.2" }, "engines": { - "node": ">=8.10.0" + "node": ">=8" } }, - "node_modules/release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "dependencies": { - "es6-error": "^4.0.1" + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" } }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" + "node_modules/istanbul-lib-report/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" }, "engines": { - "node": ">= 6" + "node": ">=10" } }, - "node_modules/request/node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, "engines": { - "node": ">=0.6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "node_modules/istanbul-lib-report/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { - "uuid": "bin/uuid" + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" + "node_modules/istanbul-lib-report/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, "dependencies": { - "lowercase-keys": "^2.0.0" + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/responselike/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", "engines": { "node": ">=8" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "dependencies": { - "glob": "^7.1.3" + "argparse": "^2.0.1" }, "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" } }, - "node_modules/rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "optional": true, "dependencies": { - "bn.js": "^5.2.0" + "minimist": "^1.2.0" }, "bin": { - "rlp": "bin/rlp" + "json5": "lib/cli.js" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" - }, - "node_modules/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", - "hasInstallScript": true, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, "dependencies": { - "elliptic": "^6.5.4", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=10.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/secp256k1/node_modules/node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", + "dev": true }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, "dependencies": { - "ms": "2.0.0" + "get-func-name": "^2.0.1" } }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "dependencies": { - "randombytes": "^2.1.0" + "yallist": "^3.0.2" } }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" + "semver": "^6.0.0" }, "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/servify": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", - "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", - "dependencies": { - "body-parser": "^1.16.0", - "cors": "^2.8.1", - "express": "^4.14.0", - "request": "^2.79.0", - "xhr": "^2.3.3" + "node": ">=8" }, - "engines": { - "node": ">=6" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true }, - "node_modules/set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "node_modules/minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, "dependencies": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=10" } }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "minimist": "^1.2.6" }, "bin": { - "sha.js": "bin.js" + "mkdirp": "bin/cmd.js" } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "node_modules/mocha": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", "dev": true, "dependencies": { - "shebang-regex": "^3.0.0" + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" }, "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "node": ">= 14.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/mochajs" } }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true }, - "node_modules/simple-get": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", - "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", - "dependencies": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" + "node_modules/nanoid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/simple-get/node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "node_modules/node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, "dependencies": { - "mimic-response": "^1.0.0" + "process-on-spawn": "^1.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "node_modules/nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", "dev": true, "dependencies": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", "rimraf": "^3.0.0", "signal-exit": "^3.0.2", - "which": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/sshpk": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", - "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" }, "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" + "nyc": "bin/nyc.js" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" + "node": ">=8.9" } }, - "node_modules/strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", + "node_modules/nyc/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "node_modules/nyc/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, "dependencies": { - "safe-buffer": "~5.2.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" } }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, + "node_modules/nyc/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, "dependencies": { - "ansi-regex": "^5.0.1" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, - "optional": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", "dependencies": { - "is-hex-prefixed": "1.0.0" + "p-locate": "^4.1.0" }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/swarm-js": { - "version": "0.1.42", - "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.42.tgz", - "integrity": "sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ==", - "dependencies": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "eth-lib": "^0.1.26", - "fs-extra": "^4.0.2", - "got": "^11.8.5", - "mime-types": "^2.1.16", - "mkdirp-promise": "^5.0.1", - "mock-fs": "^4.1.0", - "setimmediate": "^1.0.5", - "tar": "^4.0.2", - "xhr-request": "^1.0.1" - } - }, - "node_modules/swarm-js/node_modules/@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dependencies": { - "defer-to-connect": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/swarm-js/node_modules/cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "engines": { - "node": ">=10.6.0" } }, - "node_modules/swarm-js/node_modules/got": { - "version": "11.8.6", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", - "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "node_modules/nyc/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, "dependencies": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" + "p-try": "^2.0.0" }, "engines": { - "node": ">=10.19.0" + "node": ">=6" }, "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/swarm-js/node_modules/http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" + "p-limit": "^2.2.0" }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/swarm-js/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/swarm-js/node_modules/p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", "engines": { "node": ">=8" } }, - "node_modules/tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "dependencies": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - }, - "engines": { - "node": ">=4.5" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "node_modules/nyc/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } + "node_modules/nyc/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true }, - "node_modules/test-exclude/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/nyc/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" }, "engines": { - "node": "*" - } - }, - "node_modules/timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", - "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/tmp": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz", - "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==", + "node_modules/nyc/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, "dependencies": { - "rimraf": "^2.6.3" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" }, "engines": { "node": ">=6" } }, - "node_modules/tmp-promise": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-2.1.1.tgz", - "integrity": "sha512-Z048AOz/w9b6lCbJUpevIJpRpUztENl8zdv1bmAKVHimfqRFl92ROkmT9rp7TVBnrEw2gtMTol/2Cp2S2kJa4Q==", + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, "dependencies": { - "tmp": "0.1.0" + "wrappy": "1" } }, - "node_modules/tmp/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, "dependencies": { - "glob": "^7.1.3" + "yocto-queue": "^0.1.0" }, - "bin": { - "rimraf": "bin.js" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, "dependencies": { - "is-number": "^7.0.0" + "aggregate-error": "^3.0.0" }, "engines": { - "node": ">=8.0" + "node": ">=8" } }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, "engines": { - "node": ">=0.6" + "node": ">=6" } }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "node_modules/package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" }, "engines": { - "node": ">=0.8" + "node": ">=8" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/ts-mocha": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/ts-mocha/-/ts-mocha-10.0.0.tgz", - "integrity": "sha512-VRfgDO+iiuJFlNB18tzOfypJ21xn2xbuZyDvJvqpTbWgkAgD17ONGr8t+Tl8rcBtOBdjXp5e/Rk+d39f7XBHRw==", + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, - "dependencies": { - "ts-node": "7.0.1" - }, - "bin": { - "ts-mocha": "bin/ts-mocha" - }, "engines": { - "node": ">= 6.X.X" - }, - "optionalDependencies": { - "tsconfig-paths": "^3.5.0" - }, - "peerDependencies": { - "mocha": "^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X" + "node": ">=8" } }, - "node_modules/ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, - "dependencies": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "bin": { - "ts-node": "dist/bin.js" - }, "engines": { - "node": ">=4.2.0" + "node": ">=0.10.0" } }, - "node_modules/ts-node/node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "engines": { - "node": ">=0.3.1" + "node": ">=8" } }, - "node_modules/tsconfig-paths": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", - "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true, - "optional": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dependencies": { - "safe-buffer": "^5.0.1" - }, "engines": { "node": "*" } }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" - }, - "node_modules/type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, "engines": { - "node": ">=4" + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, "engines": { "node": ">=8" } }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "p-locate": "^4.1.0" + }, "engines": { - "node": ">= 0.8" + "node": ">=8" } }, - "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "p-try": "^2.0.0" }, - "bin": { - "update-browserslist-db": "cli.js" + "engines": { + "node": ">=6" }, - "peerDependencies": { - "browserslist": ">= 4.21.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, "dependencies": { - "punycode": "^2.1.0" + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/url-set-query": { + "node_modules/process-on-spawn": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==" - }, - "node_modules/utf-8-validate": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", - "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", - "hasInstallScript": true, + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, "dependencies": { - "node-gyp-build": "^4.3.0" + "fromentries": "^1.2.0" }, "engines": { - "node": ">=6.14.2" + "node": ">=8" } }, - "node_modules/utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" - }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" + "safe-buffer": "^5.1.0" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, "engines": { - "node": ">= 0.4.0" + "node": ">=8.10.0" } }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "node_modules/release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", "dev": true, - "bin": { - "uuid": "dist/bin/uuid" + "dependencies": { + "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" } }, - "node_modules/varint": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", - "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==" - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, "engines": { - "node": ">= 0.8" + "node": ">=0.10.0" } }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true }, - "node_modules/wasmbuilder": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/wasmbuilder/-/wasmbuilder-0.0.10.tgz", - "integrity": "sha512-zQSvZ7d74d9OvN+mCN6ucNne4QS5/cBBYTHldX0Oe+u9gStY21orapvuX1ajisA7RVIpuFhYg+ZgdySsPfeh0A==", - "dependencies": { - "big-integer": "^1.6.48" + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" } }, - "node_modules/wasmcurves": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.2.2.tgz", - "integrity": "sha512-JRY908NkmKjFl4ytnTu5ED6AwPD+8VJ9oc94kdq7h5bIwbj0L4TDJ69mG+2aLs2SoCmGfqIesMWTEJjtYsoQXQ==", + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, "dependencies": { - "wasmbuilder": "0.0.16" + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/wasmcurves/node_modules/wasmbuilder": { - "version": "0.0.16", - "resolved": "https://registry.npmjs.org/wasmbuilder/-/wasmbuilder-0.0.16.tgz", - "integrity": "sha512-Qx3lEFqaVvp1cEYW7Bfi+ebRJrOiwz2Ieu7ZG2l7YyeSJIok/reEQCQCuicj/Y32ITIJuGIM9xZQppGx5LrQdA==" - }, - "node_modules/web-worker": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", - "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "node_modules/web3": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.10.3.tgz", - "integrity": "sha512-DgUdOOqC/gTqW+VQl1EdPxrVRPB66xVNtuZ5KD4adVBtko87hkgM8BTZ0lZ8IbUfnQk6DyjcDujMiH3oszllAw==", - "hasInstallScript": true, - "dependencies": { - "web3-bzz": "1.10.3", - "web3-core": "1.10.3", - "web3-eth": "1.10.3", - "web3-eth-personal": "1.10.3", - "web3-net": "1.10.3", - "web3-shh": "1.10.3", - "web3-utils": "1.10.3" - }, - "engines": { - "node": ">=8.0.0" + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/web3-bzz": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.10.3.tgz", - "integrity": "sha512-XDIRsTwekdBXtFytMpHBuun4cK4x0ZMIDXSoo1UVYp+oMyZj07c7gf7tNQY5qZ/sN+CJIas4ilhN25VJcjSijQ==", - "hasInstallScript": true, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, "dependencies": { - "@types/node": "^12.12.6", - "got": "12.1.0", - "swarm-js": "^0.1.40" - }, - "engines": { - "node": ">=8.0.0" + "randombytes": "^2.1.0" } }, - "node_modules/web3-bzz/node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true }, - "node_modules/web3-core": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.10.3.tgz", - "integrity": "sha512-Vbk0/vUNZxJlz3RFjAhNNt7qTpX8yE3dn3uFxfX5OHbuon5u65YEOd3civ/aQNW745N0vGUlHFNxxmn+sG9DIw==", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, "dependencies": { - "@types/bn.js": "^5.1.1", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.10.3", - "web3-core-method": "1.10.3", - "web3-core-requestmanager": "1.10.3", - "web3-utils": "1.10.3" + "shebang-regex": "^3.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=8" } }, - "node_modules/web3-core-helpers": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.3.tgz", - "integrity": "sha512-Yv7dQC3B9ipOc5sWm3VAz1ys70Izfzb8n9rSiQYIPjpqtJM+3V4EeK6ghzNR6CO2es0+Yu9CtCkw0h8gQhrTxA==", - "dependencies": { - "web3-eth-iban": "1.10.3", - "web3-utils": "1.10.3" - }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, "engines": { - "node": ">=8.0.0" + "node": ">=8" } }, - "node_modules/web3-core-method": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.10.3.tgz", - "integrity": "sha512-VZ/Dmml4NBmb0ep5PTSg9oqKoBtG0/YoMPei/bq/tUdlhB2dMB79sbeJPwx592uaV0Vpk7VltrrrBv5hTM1y4Q==", - "dependencies": { - "@ethersproject/transactions": "^5.6.2", - "web3-core-helpers": "1.10.3", - "web3-core-promievent": "1.10.3", - "web3-core-subscriptions": "1.10.3", - "web3-utils": "1.10.3" - }, - "engines": { - "node": ">=8.0.0" - } + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true }, - "node_modules/web3-core-promievent": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.10.3.tgz", - "integrity": "sha512-HgjY+TkuLm5uTwUtaAfkTgRx/NzMxvVradCi02gy17NxDVdg/p6svBHcp037vcNpkuGeFznFJgULP+s2hdVgUQ==", - "dependencies": { - "eventemitter3": "4.0.4" - }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, "engines": { - "node": ">=8.0.0" + "node": ">=0.10.0" } }, - "node_modules/web3-core-requestmanager": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.10.3.tgz", - "integrity": "sha512-VT9sKJfgM2yBOIxOXeXiDuFMP4pxzF6FT+y8KTLqhDFHkbG3XRe42Vm97mB/IvLQCJOmokEjl3ps8yP1kbggyw==", + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, "dependencies": { - "util": "^0.12.5", - "web3-core-helpers": "1.10.3", - "web3-providers-http": "1.10.3", - "web3-providers-ipc": "1.10.3", - "web3-providers-ws": "1.10.3" - }, - "engines": { - "node": ">=8.0.0" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "node_modules/web3-core-subscriptions": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.10.3.tgz", - "integrity": "sha512-KW0Mc8sgn70WadZu7RjQ4H5sNDJ5Lx8JMI3BWos+f2rW0foegOCyWhRu33W1s6ntXnqeBUw5rRCXZRlA3z+HNA==", + "node_modules/spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.10.3" + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" }, "engines": { - "node": ">=8.0.0" + "node": ">=8" } }, - "node_modules/web3-core/node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true }, - "node_modules/web3-eth": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.10.3.tgz", - "integrity": "sha512-Uk1U2qGiif2mIG8iKu23/EQJ2ksB1BQXy3wF3RvFuyxt8Ft9OEpmGlO7wOtAyJdoKzD5vcul19bJpPcWSAYZhA==", + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { - "web3-core": "1.10.3", - "web3-core-helpers": "1.10.3", - "web3-core-method": "1.10.3", - "web3-core-subscriptions": "1.10.3", - "web3-eth-abi": "1.10.3", - "web3-eth-accounts": "1.10.3", - "web3-eth-contract": "1.10.3", - "web3-eth-ens": "1.10.3", - "web3-eth-iban": "1.10.3", - "web3-eth-personal": "1.10.3", - "web3-net": "1.10.3", - "web3-utils": "1.10.3" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=8.0.0" + "node": ">=8" } }, - "node_modules/web3-eth-abi": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.10.3.tgz", - "integrity": "sha512-O8EvV67uhq0OiCMekqYsDtb6FzfYzMXT7VMHowF8HV6qLZXCGTdB/NH4nJrEh2mFtEwVdS6AmLFJAQd2kVyoMQ==", + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { - "@ethersproject/abi": "^5.6.3", - "web3-utils": "1.10.3" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=8.0.0" + "node": ">=8" } }, - "node_modules/web3-eth-accounts": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.10.3.tgz", - "integrity": "sha512-8MipGgwusDVgn7NwKOmpeo3gxzzd+SmwcWeBdpXknuyDiZSQy9tXe+E9LeFGrmys/8mLLYP79n3jSbiTyv+6pQ==", - "dependencies": { - "@ethereumjs/common": "2.6.5", - "@ethereumjs/tx": "3.5.2", - "@ethereumjs/util": "^8.1.0", - "eth-lib": "0.2.8", - "scrypt-js": "^3.0.1", - "uuid": "^9.0.0", - "web3-core": "1.10.3", - "web3-core-helpers": "1.10.3", - "web3-core-method": "1.10.3", - "web3-utils": "1.10.3" - }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "optional": true, "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-accounts/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/web3-eth-accounts/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" + "node": ">=4" } }, - "node_modules/web3-eth-accounts/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/bin/uuid" + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/web3-eth-contract": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.10.3.tgz", - "integrity": "sha512-Y2CW61dCCyY4IoUMD4JsEQWrILX4FJWDWC/Txx/pr3K/+fGsBGvS9kWQN5EsVXOp4g7HoFOfVh9Lf7BmVVSRmg==", + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, "dependencies": { - "@types/bn.js": "^5.1.1", - "web3-core": "1.10.3", - "web3-core-helpers": "1.10.3", - "web3-core-method": "1.10.3", - "web3-core-promievent": "1.10.3", - "web3-core-subscriptions": "1.10.3", - "web3-eth-abi": "1.10.3", - "web3-utils": "1.10.3" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/web3-eth-ens": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.10.3.tgz", - "integrity": "sha512-hR+odRDXGqKemw1GFniKBEXpjYwLgttTES+bc7BfTeoUyUZXbyDHe5ifC+h+vpzxh4oS0TnfcIoarK0Z9tFSiQ==", + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, "dependencies": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.10.3", - "web3-core-helpers": "1.10.3", - "web3-core-promievent": "1.10.3", - "web3-eth-abi": "1.10.3", - "web3-eth-contract": "1.10.3", - "web3-utils": "1.10.3" + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" }, "engines": { - "node": ">=8.0.0" + "node": ">=8" } }, - "node_modules/web3-eth-iban": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.3.tgz", - "integrity": "sha512-ZCfOjYKAjaX2TGI8uif5ah+J3BYFuo+47JOIV1RIz2l7kD9VfnxvRH5UiQDRyMALQC7KFd2hUqIEtHklapNyKA==", + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "dependencies": { - "bn.js": "^5.2.1", - "web3-utils": "1.10.3" - }, - "engines": { - "node": ">=8.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/web3-eth-personal": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.10.3.tgz", - "integrity": "sha512-avrQ6yWdADIvuNQcFZXmGLCEzulQa76hUOuVywN7O3cklB4nFc/Gp3yTvD3bOAaE7DhjLQfhUTCzXL7WMxVTsw==", + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "dependencies": { - "@types/node": "^12.12.6", - "web3-core": "1.10.3", - "web3-core-helpers": "1.10.3", - "web3-core-method": "1.10.3", - "web3-net": "1.10.3", - "web3-utils": "1.10.3" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=8.0.0" + "node": "*" } }, - "node_modules/web3-eth-personal/node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" - }, - "node_modules/web3-net": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.10.3.tgz", - "integrity": "sha512-IoSr33235qVoI1vtKssPUigJU9Fc/Ph0T9CgRi15sx+itysmvtlmXMNoyd6Xrgm9LuM4CIhxz7yDzH93B79IFg==", - "dependencies": { - "web3-core": "1.10.3", - "web3-core-method": "1.10.3", - "web3-utils": "1.10.3" - }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, "engines": { - "node": ">=8.0.0" + "node": ">=4" } }, - "node_modules/web3-providers-http": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.10.3.tgz", - "integrity": "sha512-6dAgsHR3MxJ0Qyu3QLFlQEelTapVfWNTu5F45FYh8t7Y03T1/o+YAkVxsbY5AdmD+y5bXG/XPJ4q8tjL6MgZHw==", + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "dependencies": { - "abortcontroller-polyfill": "^1.7.5", - "cross-fetch": "^4.0.0", - "es6-promise": "^4.2.8", - "web3-core-helpers": "1.10.3" + "is-number": "^7.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=8.0" } }, - "node_modules/web3-providers-ipc": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.10.3.tgz", - "integrity": "sha512-vP5WIGT8FLnGRfswTxNs9rMfS1vCbMezj/zHbBe/zB9GauBRTYVrUo2H/hVrhLg8Ut7AbsKZ+tCJ4mAwpKi2hA==", + "node_modules/ts-mocha": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/ts-mocha/-/ts-mocha-10.0.0.tgz", + "integrity": "sha512-VRfgDO+iiuJFlNB18tzOfypJ21xn2xbuZyDvJvqpTbWgkAgD17ONGr8t+Tl8rcBtOBdjXp5e/Rk+d39f7XBHRw==", + "dev": true, "dependencies": { - "oboe": "2.1.5", - "web3-core-helpers": "1.10.3" + "ts-node": "7.0.1" + }, + "bin": { + "ts-mocha": "bin/ts-mocha" }, "engines": { - "node": ">=8.0.0" + "node": ">= 6.X.X" + }, + "optionalDependencies": { + "tsconfig-paths": "^3.5.0" + }, + "peerDependencies": { + "mocha": "^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X" } }, - "node_modules/web3-providers-ws": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.10.3.tgz", - "integrity": "sha512-/filBXRl48INxsh6AuCcsy4v5ndnTZ/p6bl67kmO9aK1wffv7CT++DrtclDtVMeDGCgB3van+hEf9xTAVXur7Q==", + "node_modules/ts-node": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", + "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", + "dev": true, "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.10.3", - "websocket": "^1.0.32" + "arrify": "^1.0.0", + "buffer-from": "^1.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map-support": "^0.5.6", + "yn": "^2.0.0" + }, + "bin": { + "ts-node": "dist/bin.js" }, "engines": { - "node": ">=8.0.0" + "node": ">=4.2.0" } }, - "node_modules/web3-shh": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.10.3.tgz", - "integrity": "sha512-cAZ60CPvs9azdwMSQ/PSUdyV4PEtaW5edAZhu3rCXf6XxQRliBboic+AvwUvB6j3eswY50VGa5FygfVmJ1JVng==", - "hasInstallScript": true, - "dependencies": { - "web3-core": "1.10.3", - "web3-core-method": "1.10.3", - "web3-core-subscriptions": "1.10.3", - "web3-net": "1.10.3" - }, + "node_modules/ts-node/node_modules/diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true, "engines": { - "node": ">=8.0.0" + "node": ">=0.3.1" } }, - "node_modules/web3-utils": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.3.tgz", - "integrity": "sha512-OqcUrEE16fDBbGoQtZXWdavsPzbGIDc5v3VrRTZ0XrIpefC/viZ1ZU9bGEemazyS0catk/3rkOOxpzTfY+XsyQ==", + "node_modules/tsconfig-paths": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "dev": true, + "optional": true, "dependencies": { - "@ethereumjs/util": "^8.1.0", - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereum-cryptography": "^2.1.2", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" } }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "node_modules/websocket": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", - "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", - "dependencies": { - "bufferutil": "^4.0.1", - "debug": "^2.2.0", - "es5-ext": "^0.10.50", - "typedarray-to-buffer": "^3.1.5", - "utf-8-validate": "^5.0.2", - "yaeti": "^0.0.6" - }, + "node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, "engines": { - "node": ">=4.0.0" + "node": ">=8" } }, - "node_modules/websocket/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, "dependencies": { - "ms": "2.0.0" + "is-typedarray": "^1.0.0" } }, - "node_modules/websocket/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" } }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -7457,77 +2801,8 @@ "node_modules/which-module": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==" - }, - "node_modules/which-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", - "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.4", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, - "node_modules/wide-align/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/worker-threads": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/worker-threads/-/worker-threads-1.0.0.tgz", - "integrity": "sha512-vK6Hhvph8oLxocEJIlc3YfGAZhm210uGzjZsXSu+JYLAQ/s/w4Tqgl60JrdH58hW8NSGP4m3bp8a92qPXgX05w==" + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true }, "node_modules/workerpool": { "version": "6.2.1", @@ -7539,6 +2814,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -7554,7 +2830,8 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true }, "node_modules/write-file-atomic": { "version": "3.0.3", @@ -7568,92 +2845,26 @@ "typedarray-to-buffer": "^3.1.5" } }, - "node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "dependencies": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "node_modules/xhr-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", - "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", - "dependencies": { - "buffer-to-arraybuffer": "^0.0.5", - "object-assign": "^4.1.1", - "query-string": "^5.0.1", - "simple-get": "^2.7.0", - "timed-out": "^4.0.1", - "url-set-query": "^1.0.0", - "xhr": "^2.0.4" - } - }, - "node_modules/xhr-request-promise": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", - "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", - "dependencies": { - "xhr-request": "^1.1.0" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, "engines": { "node": ">=10" } }, - "node_modules/yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", - "engines": { - "node": ">=0.10.32" - } - }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true }, "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -7671,6 +2882,7 @@ "version": "20.2.4", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, "engines": { "node": ">=10" } @@ -7679,6 +2891,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", @@ -7702,6 +2915,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, "engines": { "node": ">=10" }, diff --git a/crypto/package-lock.json b/crypto/package-lock.json index de33686a26..bcb5b61196 100644 --- a/crypto/package-lock.json +++ b/crypto/package-lock.json @@ -8,8 +8,9 @@ "name": "maci-crypto", "version": "1.1.2", "dependencies": { - "blake-hash": "^1.1.0", - "circomlib": "https://github.com/weijiekoh/circomlib.git#24ed08eee0bb613b8c0135d66c1013bd9f78d50a", + "@zk-kit/baby-jubjub": "^0.1.1", + "@zk-kit/eddsa-poseidon": "^0.5.1", + "@zk-kit/poseidon-cipher": "^0.1.1", "ethers": "^5.4.7", "optimisedmt": "^0.0.9" }, @@ -1192,11 +1193,6 @@ "dev": true, "peer": true }, - "node_modules/@iden3/bigarray": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/@iden3/bigarray/-/bigarray-0.0.2.tgz", - "integrity": "sha512-Xzdyxqm1bOFF6pdIsiHLLl3HkSLjbhqJHVyqaTxXt3RqXBEnmsUmEW47H7VOi/ak7TdkRpNkxjyK5Zbkm+y52g==" - }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1569,11 +1565,6 @@ "@types/node": "*" } }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==" - }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", @@ -1581,6 +1572,44 @@ "dev": true, "peer": true }, + "node_modules/@zk-kit/baby-jubjub": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@zk-kit/baby-jubjub/-/baby-jubjub-0.1.1.tgz", + "integrity": "sha512-eWpUSpKKpllGZXE6mdS1IVuegRjY2Yu+3Qccyfg0+gMI8+p0ruioMM/MCK3tg2lRIUJTVd+16UghVcK0145yWg==", + "dependencies": { + "@zk-kit/utils": "0.1.0" + } + }, + "node_modules/@zk-kit/eddsa-poseidon": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@zk-kit/eddsa-poseidon/-/eddsa-poseidon-0.5.1.tgz", + "integrity": "sha512-sPyoyjwg9EZ+tHLGxOG+FDj9XJK1knVjm27nTMV4ZSiQIf0427QWnLhOk7b6zMvFmEpBWTG9gneJ5pr3jzJ4zg==", + "dependencies": { + "@zk-kit/baby-jubjub": "0.1.1", + "@zk-kit/utils": "0.1.0" + } + }, + "node_modules/@zk-kit/poseidon-cipher": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@zk-kit/poseidon-cipher/-/poseidon-cipher-0.1.1.tgz", + "integrity": "sha512-EPAuUrOCWBqSDPdUihaQ6bvFLulHsLDe4ViSHmnhLf1Ydyd7hQie8NDEdvNewpuv0ub9aLB+r1+Ev8Afv94RtA==", + "dependencies": { + "@zk-kit/baby-jubjub": "0.1.0" + } + }, + "node_modules/@zk-kit/poseidon-cipher/node_modules/@zk-kit/baby-jubjub": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@zk-kit/baby-jubjub/-/baby-jubjub-0.1.0.tgz", + "integrity": "sha512-oeTAT3gtam1qICNqb7aqCqZiFA9FP8zhFzwB51nhCfufIZvGGKDKWofRseZEpD8+fKoLTwU59aBNmAPTnvSdyg==", + "dependencies": { + "@zk-kit/utils": "0.1.0" + } + }, + "node_modules/@zk-kit/utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@zk-kit/utils/-/utils-0.1.0.tgz", + "integrity": "sha512-MZmuw2w2StB7XOSNg1TW4VwnBJ746UDmdXTvxwDO/U85UZfGfM3zb53gG35qz5sWpQo/DjfoKqaScmh6HUtQpA==" + }, "node_modules/abortcontroller-polyfill": { "version": "1.7.5", "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz", @@ -1658,6 +1687,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, "engines": { "node": ">=6" } @@ -1666,6 +1696,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "engines": { "node": ">=8" } @@ -1686,6 +1717,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1715,7 +1747,8 @@ "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "node_modules/array-flatten": { "version": "1.1.1", @@ -1763,15 +1796,11 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, "engines": { "node": "*" } }, - "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" - }, "node_modules/async-limiter": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", @@ -1814,7 +1843,8 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "node_modules/base-x": { "version": "3.0.9", @@ -1856,14 +1886,6 @@ "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" }, - "node_modules/big-integer": { - "version": "1.6.52", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", - "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", - "engines": { - "node": ">=0.6" - } - }, "node_modules/bignumber.js": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", @@ -1876,32 +1898,11 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, "engines": { "node": ">=8" } }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/blake-hash": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/blake-hash/-/blake-hash-1.1.1.tgz", - "integrity": "sha512-V93H+FEJuXXZi1eEsMtbcBFP9oL5Ept7SLw3cbXYlPC3nocm9Fr4m18ZhbhdJrZVS9J/Z0oNE4L3oDZvmorHNA==", - "hasInstallScript": true, - "dependencies": { - "bindings": "^1.2.1", - "inherits": "^2.0.3", - "nan": "^2.2.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/blake2b": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/blake2b/-/blake2b-2.1.4.tgz", @@ -1975,6 +1976,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1984,6 +1986,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -1999,7 +2002,8 @@ "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true }, "node_modules/browserify-aes": { "version": "1.2.0", @@ -2212,6 +2216,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, "engines": { "node": ">=10" }, @@ -2248,6 +2253,7 @@ "version": "4.3.10", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", + "dev": true, "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.3", @@ -2279,6 +2285,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, "dependencies": { "get-func-name": "^2.0.2" }, @@ -2338,447 +2345,32 @@ "dependencies": { "buffer": "^5.5.0", "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" - }, - "engines": { - "node": ">=4.0.0", - "npm": ">=3.0.0" - } - }, - "node_modules/cids/node_modules/multicodec": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", - "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", - "deprecated": "This module has been superseded by the multiformats module", - "dependencies": { - "buffer": "^5.6.0", - "varint": "^5.0.0" - } - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/circom": { - "version": "0.5.45", - "resolved": "https://registry.npmjs.org/circom/-/circom-0.5.45.tgz", - "integrity": "sha512-5Ixp6UjwrhBWnnFBO/mTns+eeEDOpi5UoN4znAUWy5rklCUWYt2Ezl9QVUswBXjMP5kpfEtGUY2XSsYRAp6uMg==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dependencies": { - "chai": "^4.2.0", - "circom_runtime": "0.1.12", - "fastfile": "0.0.18", - "ffiasm": "0.1.1", - "ffjavascript": "0.2.22", - "ffwasm": "0.0.7", - "fnv-plus": "^1.3.1", - "r1csfile": "0.0.16", - "tmp-promise": "^2.0.2", - "wasmbuilder": "0.0.10" - }, - "bin": { - "circom": "cli.js" - } - }, - "node_modules/circom_runtime": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.1.12.tgz", - "integrity": "sha512-R+QT9HS9w71cmGmWIn+PSyD3aHyR5JZBiVvxOjCfn12wwnpuFwBjdMG7he+v8h/oQD1mDRAu2KrBeL4mAt5s4A==", - "dependencies": { - "ffjavascript": "0.2.34", - "fnv-plus": "^1.3.1" - }, - "bin": { - "calcwit": "calcwit.js" - } - }, - "node_modules/circom_runtime/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/circom_runtime/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/circom_runtime/node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/circom_runtime/node_modules/chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.1" - } - }, - "node_modules/circom_runtime/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/circom_runtime/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/circom_runtime/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/circom_runtime/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/circom_runtime/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/circom_runtime/node_modules/ffjavascript": { - "version": "0.2.34", - "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.34.tgz", - "integrity": "sha512-fq/qfJluC4spiOD1lp5jfckZVnS0o0kI5eKXVLw7UKwIwbNr+NBMBveBVcidSfMizF87T6wb7NBtLSdckQiAnQ==", - "dependencies": { - "big-integer": "^1.6.48", - "mocha": "^8.2.1", - "wasmcurves": "0.0.14", - "worker-threads": "^1.0.0" - } - }, - "node_modules/circom_runtime/node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/circom_runtime/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/circom_runtime/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/circom_runtime/node_modules/js-yaml": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", - "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/circom_runtime/node_modules/log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", - "dependencies": { - "chalk": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/circom_runtime/node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/circom_runtime/node_modules/mocha": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", - "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", - "dependencies": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.1", - "debug": "4.3.1", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.6", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.0.0", - "log-symbols": "4.0.0", - "minimatch": "3.0.4", - "ms": "2.1.3", - "nanoid": "3.1.20", - "serialize-javascript": "5.0.1", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.1.0", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 10.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/circom_runtime/node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/circom_runtime/node_modules/nanoid": { - "version": "3.1.20", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", - "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/circom_runtime/node_modules/readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/circom_runtime/node_modules/serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/circom_runtime/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/circom_runtime/node_modules/wasmcurves": { - "version": "0.0.14", - "resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.0.14.tgz", - "integrity": "sha512-G1iMkxlRaQSdqQ1JrwHcU+awLmwyH6kFKfT8g9obd8MWe+u5oSdFXrODB0zmSI5aGGvJPG+4cAmqCGYv9R+7qg==", - "dependencies": { - "big-integer": "^1.6.42", - "blakejs": "^1.1.0" - } - }, - "node_modules/circom_runtime/node_modules/workerpool": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", - "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==" - }, - "node_modules/circom_runtime/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/circom_runtime/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/circom_runtime/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/circom/node_modules/ffjavascript": { - "version": "0.2.22", - "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.22.tgz", - "integrity": "sha512-EsVqap2Txm17bKW0z/jXCX3M7rQ++nQUAJY8alWDpyhjRj90xjl6GLeVSKZQ8rOFDQ/SFFXcEB8w9X8Boxid+w==", - "dependencies": { - "big-integer": "^1.6.48", - "wasmcurves": "0.0.12", - "worker-threads": "^1.0.0" - } - }, - "node_modules/circom/node_modules/wasmcurves": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.0.12.tgz", - "integrity": "sha512-1Jl9mkatyHSNj80ILjf85SZUNuZQBCkTjJlhzqHnZQXUmIimCIWkugaVaYNjozLs1Gun4h/keZe1MBeBN0sRpg==", - "dependencies": { - "big-integer": "^1.6.42", - "blakejs": "^1.1.0" + "multibase": "~0.6.0", + "multicodec": "^1.0.0", + "multihashes": "~0.4.15" + }, + "engines": { + "node": ">=4.0.0", + "npm": ">=3.0.0" } }, - "node_modules/circomlib": { - "version": "0.5.2", - "resolved": "git+ssh://git@github.com/weijiekoh/circomlib.git#24ed08eee0bb613b8c0135d66c1013bd9f78d50a", - "integrity": "sha512-oWrlNshOYpXszPIaMlWA/Dq7kv18nhsYyBK8C9etCvec5i7huQC17yelbKZCayxbhhDulNbs+GMXw9IG1iARuw==", - "license": "GPL-3.0", + "node_modules/cids/node_modules/multicodec": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", + "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", + "deprecated": "This module has been superseded by the multiformats module", "dependencies": { - "blake-hash": "^1.1.0", - "blake2b": "^2.1.3", - "circom": "0.5.45", - "ffjavascript": "0.1.0", - "web3-utils": "^1.3.0" + "buffer": "^5.6.0", + "varint": "^5.0.0" } }, - "node_modules/circomlib/node_modules/ffjavascript": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.1.0.tgz", - "integrity": "sha512-dmKlUasSfvUcxBm8nCSKl2x7EFJsXA7OVP8XLFA03T2+6mAc3IiVLC2ambEVOcMOhyhl0vJfVZjM9f9d38D1rw==", + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", "dependencies": { - "big-integer": "^1.6.48" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "node_modules/circomlibjs": { @@ -2825,6 +2417,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -2877,7 +2470,8 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true }, "node_modules/content-disposition": { "version": "0.5.4", @@ -3043,6 +2637,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -3084,6 +2679,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "dev": true, "dependencies": { "type-detect": "^4.0.0" }, @@ -3188,6 +2784,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, "engines": { "node": ">=0.3.1" } @@ -3224,20 +2821,6 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, - "node_modules/ejs": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", - "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/electron-to-chromium": { "version": "1.4.608", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.608.tgz", @@ -3266,7 +2849,8 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/encodeurl": { "version": "1.0.2", @@ -3332,6 +2916,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, "engines": { "node": ">=6" } @@ -4004,11 +3589,6 @@ "dev": true, "peer": true }, - "node_modules/fastfile": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.18.tgz", - "integrity": "sha512-q03PTKc+wptis4WmuFOwPNQx2p5myFUrl/dMgRlW9mymc1Egyc14JPHgiGnWK+sJ0+dBl2Vwtfh5GfSQltYOpw==" - }, "node_modules/fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -4019,19 +3599,6 @@ "reusify": "^1.0.4" } }, - "node_modules/ffiasm": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ffiasm/-/ffiasm-0.1.1.tgz", - "integrity": "sha512-irMMHiR9JJ7BVBrAhtliUawxVdPYSdyl81taUYJ4C1mJ0iw2ueThE/qtr0J8B83tsIY8HJvh0lg5F+6ClK4xpA==", - "dependencies": { - "big-integer": "^1.6.48", - "ejs": "^3.0.1", - "yargs": "^15.3.1" - }, - "bin": { - "buildzqfield": "src/buildzqfield.js" - } - }, "node_modules/ffjavascript": { "version": "0.2.62", "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.62.tgz", @@ -4047,15 +3614,6 @@ "resolved": "https://registry.npmjs.org/wasmbuilder/-/wasmbuilder-0.0.16.tgz", "integrity": "sha512-Qx3lEFqaVvp1cEYW7Bfi+ebRJrOiwz2Ieu7ZG2l7YyeSJIok/reEQCQCuicj/Y32ITIJuGIM9xZQppGx5LrQdA==" }, - "node_modules/ffwasm": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ffwasm/-/ffwasm-0.0.7.tgz", - "integrity": "sha512-17cTLzv7HHAKqZbX8MvHxjSrR0yDdn1sh4TVsTbAvO9e6klhFicnyoVXc/sCuViV/M8g65sCmVrAmoPCZp1YkQ==", - "dependencies": { - "big-integer": "^1.6.48", - "wasmbuilder": "0.0.10" - } - }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -4069,42 +3627,11 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -4163,6 +3690,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -4178,6 +3706,7 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, "bin": { "flat": "cli.js" } @@ -4204,11 +3733,6 @@ "dev": true, "peer": true }, - "node_modules/fnv-plus": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/fnv-plus/-/fnv-plus-1.3.1.tgz", - "integrity": "sha512-Gz1EvfOneuFfk4yG458dJ3TLJ7gV19q3OM/vVvvHf7eT02Hm1DleB4edsia6ahbKgAYxO9gvyQ1ioWZR+a00Yw==" - }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -4313,12 +3837,14 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -4349,6 +3875,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -4357,6 +3884,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, "engines": { "node": "*" } @@ -4407,6 +3935,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4502,14 +4031,6 @@ "dev": true, "peer": true }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "engines": { - "node": ">=4.x" - } - }, "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -4649,6 +4170,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, "bin": { "he": "bin/he" } @@ -4818,6 +4340,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -4855,6 +4378,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -4877,6 +4401,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -4885,6 +4410,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "engines": { "node": ">=8" } @@ -4912,6 +4438,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -4947,6 +4474,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, "engines": { "node": ">=0.12.0" } @@ -4965,6 +4493,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, "engines": { "node": ">=8" } @@ -5024,7 +4553,8 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "node_modules/isstream": { "version": "0.1.2", @@ -5203,87 +4733,6 @@ "node": ">=8" } }, - "node_modules/jake": { - "version": "10.8.7", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", - "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", - "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jake/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jake/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jake/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jake/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jake/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jake/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -5430,6 +4879,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -5543,6 +4993,7 @@ "version": "2.3.7", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, "dependencies": { "get-func-name": "^2.0.1" } @@ -5684,6 +5135,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -5938,7 +5390,8 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "node_modules/multibase": { "version": "0.6.1", @@ -5979,11 +5432,6 @@ "buffer": "^5.5.0" } }, - "node_modules/nan": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", - "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==" - }, "node_modules/nano-json-stream-parser": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", @@ -6082,6 +5530,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -6354,6 +5803,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, "dependencies": { "yocto-queue": "^0.1.0" }, @@ -6368,6 +5818,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -6394,6 +5845,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, "engines": { "node": ">=6" } @@ -6443,6 +5895,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, "engines": { "node": ">=8" } @@ -6451,6 +5904,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -6473,6 +5927,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, "engines": { "node": "*" } @@ -6507,6 +5962,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, "engines": { "node": ">=8.6" }, @@ -6701,35 +6157,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/r1csfile": { - "version": "0.0.16", - "resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.16.tgz", - "integrity": "sha512-A2jRVWzGgmXeG2lVAc0H4suJmzt50it5UvBnycJgBCpMXM3tH/M6RguP7nvs6suY/yYnkN6jX6iTScSiDUF3FA==", - "dependencies": { - "@iden3/bigarray": "0.0.2", - "fastfile": "0.0.18", - "ffjavascript": "0.2.22" - } - }, - "node_modules/r1csfile/node_modules/ffjavascript": { - "version": "0.2.22", - "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.22.tgz", - "integrity": "sha512-EsVqap2Txm17bKW0z/jXCX3M7rQ++nQUAJY8alWDpyhjRj90xjl6GLeVSKZQ8rOFDQ/SFFXcEB8w9X8Boxid+w==", - "dependencies": { - "big-integer": "^1.6.48", - "wasmcurves": "0.0.12", - "worker-threads": "^1.0.0" - } - }, - "node_modules/r1csfile/node_modules/wasmcurves": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.0.12.tgz", - "integrity": "sha512-1Jl9mkatyHSNj80ILjf85SZUNuZQBCkTjJlhzqHnZQXUmIimCIWkugaVaYNjozLs1Gun4h/keZe1MBeBN0sRpg==", - "dependencies": { - "big-integer": "^1.6.42", - "blakejs": "^1.1.0" - } - }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -6840,6 +6267,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -6847,7 +6275,8 @@ "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true }, "node_modules/resolve-alpn": { "version": "1.2.1", @@ -7092,7 +6521,8 @@ "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true }, "node_modules/set-function-length": { "version": "1.1.1", @@ -7304,6 +6734,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -7317,6 +6748,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -7350,6 +6782,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, "engines": { "node": ">=8" }, @@ -7504,36 +6937,6 @@ "node": ">=0.10.0" } }, - "node_modules/tmp": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz", - "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==", - "dependencies": { - "rimraf": "^2.6.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tmp-promise": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-2.1.1.tgz", - "integrity": "sha512-Z048AOz/w9b6lCbJUpevIJpRpUztENl8zdv1bmAKVHimfqRFl92ROkmT9rp7TVBnrEw2gtMTol/2Cp2S2kJa4Q==", - "dependencies": { - "tmp": "0.1.0" - } - }, - "node_modules/tmp/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -7547,6 +6950,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -7695,6 +7099,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, "engines": { "node": ">=4" } @@ -7891,14 +7296,6 @@ "extsprintf": "^1.2.0" } }, - "node_modules/wasmbuilder": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/wasmbuilder/-/wasmbuilder-0.0.10.tgz", - "integrity": "sha512-zQSvZ7d74d9OvN+mCN6ucNne4QS5/cBBYTHldX0Oe+u9gStY21orapvuX1ajisA7RVIpuFhYg+ZgdySsPfeh0A==", - "dependencies": { - "big-integer": "^1.6.48" - } - }, "node_modules/wasmcurves": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.2.2.tgz", @@ -8323,6 +7720,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -8336,7 +7734,8 @@ "node_modules/which-module": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==" + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true }, "node_modules/which-typed-array": { "version": "1.1.13", @@ -8356,58 +7755,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, - "node_modules/wide-align/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/worker-threads": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/worker-threads/-/worker-threads-1.0.0.tgz", - "integrity": "sha512-vK6Hhvph8oLxocEJIlc3YfGAZhm210uGzjZsXSu+JYLAQ/s/w4Tqgl60JrdH58hW8NSGP4m3bp8a92qPXgX05w==" - }, "node_modules/workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", @@ -8418,6 +7765,7 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -8431,6 +7779,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -8445,6 +7794,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -8455,7 +7805,8 @@ "node_modules/wrap-ansi/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/wrappy": { "version": "1.0.2", @@ -8538,7 +7889,8 @@ "node_modules/y18n": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true }, "node_modules/yaeti": { "version": "0.0.6", @@ -8557,6 +7909,7 @@ "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -8578,6 +7931,7 @@ "version": "20.2.4", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, "engines": { "node": ">=10" } @@ -8586,6 +7940,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", @@ -8600,6 +7955,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, "engines": { "node": ">=10" }, @@ -8611,6 +7967,7 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, "engines": { "node": ">=6" } @@ -8619,6 +7976,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -8631,6 +7989,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, "dependencies": { "p-locate": "^4.1.0" }, @@ -8642,6 +8001,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, "dependencies": { "p-try": "^2.0.0" }, @@ -8656,6 +8016,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, "dependencies": { "p-limit": "^2.2.0" }, @@ -8667,6 +8028,7 @@ "version": "18.1.3", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -8688,6 +8050,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, "engines": { "node": ">=10" }, diff --git a/crypto/package.json b/crypto/package.json index d3675418ab..36d8bb1a46 100644 --- a/crypto/package.json +++ b/crypto/package.json @@ -12,8 +12,9 @@ "test:utils": "ts-mocha --exit ts/__tests__/Utils.test.ts" }, "dependencies": { - "blake-hash": "^1.1.0", - "circomlib": "https://github.com/weijiekoh/circomlib.git#24ed08eee0bb613b8c0135d66c1013bd9f78d50a", + "@zk-kit/baby-jubjub": "^0.1.1", + "@zk-kit/eddsa-poseidon": "^0.5.1", + "@zk-kit/poseidon-cipher": "^0.1.1", "ethers": "^5.4.7", "optimisedmt": "^0.0.9" }, diff --git a/crypto/ts/@types/blake-hash.d.ts b/crypto/ts/@types/blake-hash.d.ts deleted file mode 100644 index 15b1dce657..0000000000 --- a/crypto/ts/@types/blake-hash.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -declare module "blake-hash" { - export interface BlakeHash { - update: (buffer: Buffer) => BlakeHash; - digest: () => Buffer; - } - - export function createBlakeHash(type: "blake512"): BlakeHash; - - export default createBlakeHash; -} diff --git a/crypto/ts/@types/circomlib.d.ts b/crypto/ts/@types/circomlib.d.ts deleted file mode 100644 index ccf4f11023..0000000000 --- a/crypto/ts/@types/circomlib.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -declare module "circomlib" { - interface Signature { - R8: bigint[]; - S: bigint; - } - - export function poseidon(inputs: bigint[]): bigint; - - export function poseidonEncrypt(plaintext: bigint[], sharedKey: bigint[], nonce?: bigint): bigint[]; - - export function poseidonDecrypt(ciphertext: bigint[], sharedKey: bigint[], nonce: bigint, length: number): bigint[]; - - export namespace eddsa { - function signPoseidon(buffer: Buffer, message: bigint): Signature; - - function verifyPoseidon(message: bigint, signature: Signature, pubKey: bigint[]): boolean; - - function pruneBuffer(buffer: Buffer): Buffer; - - function prv2pub(buffer: Buffer): bigint[]; - } - - export namespace babyJub { - type F = unknown; - - const p: string | bigint | number; - - const Base8: bigint[]; - - function addPoint(a: bigint, b: bigint): bigint; - - function packPoint(pubKey: bigint[]): Buffer; - - function unpackPoint(packed: Buffer): bigint[]; - - function mulPointEscalar(a: bigint | bigint[], b: bigint | bigint[]): bigint[]; - } -} diff --git a/crypto/ts/@types/main.d.ts b/crypto/ts/@types/main.d.ts index ecdb3bc094..3c4dd82c24 100644 --- a/crypto/ts/@types/main.d.ts +++ b/crypto/ts/@types/main.d.ts @@ -1,3 +1 @@ -export * from "./blake-hash"; -export * from "./circomlib"; export * from "./optimisedmt"; diff --git a/crypto/ts/__tests__/Crypto.test.ts b/crypto/ts/__tests__/Crypto.test.ts index e2d7511114..a3ad056403 100644 --- a/crypto/ts/__tests__/Crypto.test.ts +++ b/crypto/ts/__tests__/Crypto.test.ts @@ -1,14 +1,10 @@ import { expect } from "chai"; -import { babyJub } from "circomlib"; import { SNARK_FIELD_SIZE } from "../constants"; import { genPubKey, genKeypair, genEcdhSharedKey, - encrypt, - decrypt, - sign, sha256Hash, hash2, hash3, @@ -21,7 +17,6 @@ import { poseidonT4, poseidonT5, poseidonT6, - verifySignature, genRandomSalt, G1Point, G2Point, @@ -30,8 +25,6 @@ import { genPrivKey, packPubKey, unpackPubKey, - bitToCurve, - curveToBit, } from "../crypto"; describe("Crypto", function test() { @@ -462,7 +455,6 @@ describe("Crypto", function test() { }); }); }); - describe("utils", () => { describe("genRandomSalt", () => { it("should produce a random salt", () => { @@ -479,40 +471,7 @@ describe("Crypto", function test() { expect(salt).to.not.eq(BigInt(0)); }); }); - - describe("bitToCurve", () => { - it("should map bit 0 to point [0, 1] on the curve", () => { - const point = bitToCurve(BigInt(0)); - expect(point).to.deep.eq([BigInt(0), BigInt(1)]); - }); - - it("should map bit 1 to the base point of the curve", () => { - const point = bitToCurve(BigInt(1)); - expect(point).to.eq(babyJub.Base8); - }); - - it("should throw error for bit values other than 0 or 1", () => { - expect(() => bitToCurve(BigInt(2))).to.throw("Invalid bit value"); - expect(() => bitToCurve(BigInt(-1))).to.throw("Invalid bit value"); - }); - }); - describe("curveToBit", () => { - it("should map point [0, 1] on the curve to bit 0", () => { - const bit = curveToBit([BigInt(0), BigInt(1)]); - expect(bit).to.eq(BigInt(0)); - }); - - it("should map the base point of the curve to bit 1", () => { - const bit = curveToBit(babyJub.Base8); - expect(bit).to.eq(BigInt(1)); - }); - - it("should throw error for points not on the curve", () => { - expect(() => curveToBit([BigInt(1), BigInt(2)])).to.throw("Invalid point"); - }); - }); }); - describe("babyjub", () => { describe("genRandomBabyJubValue", () => { it("should generate a value what is < SNARK_FIELD_SIZE", () => { @@ -560,10 +519,10 @@ describe("Crypto", function test() { }); }); describe("packPubKey", () => { - it("should pack a public key into a Buffer", () => { + it("should pack a public key into a bigint", () => { const pk = genPubKey(genPrivKey()); const pkBuff = packPubKey(pk); - expect(pkBuff).to.be.instanceOf(Buffer); + expect(typeof pkBuff).to.eq("bigint"); }); }); describe("unpackPubKey", () => { @@ -599,7 +558,7 @@ describe("Crypto", function test() { }); it("should produce a private key which is < SNARK_FIELD_SIZE", () => { const { privKey } = genKeypair(); - expect(privKey < SNARK_FIELD_SIZE).to.eq(true); + expect(BigInt(privKey) < SNARK_FIELD_SIZE).to.eq(true); }); }); describe("genEcdhSharedKey", () => { @@ -635,117 +594,4 @@ describe("Crypto", function test() { }); }); }); - describe("encryption/decryption", () => { - const nonce = BigInt(123); - - describe("encrypt", () => { - it("should encrypt a plaintext", () => { - const { privKey } = genKeypair(); - const pubKey = genPubKey(genPrivKey()); - const sharedKey = genEcdhSharedKey(privKey, pubKey); - const plaintext = [BigInt(1), BigInt(2), BigInt(3)]; - const ciphertext = encrypt(plaintext, sharedKey, nonce); - expect(ciphertext).to.be.instanceOf(Array); - expect(ciphertext.length).to.eq(4); - }); - - it("should encrypt a ciphertext without passing a nonce (default to 0)", () => { - const { privKey } = genKeypair(); - const pubKey = genPubKey(genPrivKey()); - const sharedKey = genEcdhSharedKey(privKey, pubKey); - const plaintext = [BigInt(1), BigInt(2), BigInt(3)]; - const ciphertext = encrypt(plaintext, sharedKey); - expect(ciphertext).to.be.instanceOf(Array); - expect(ciphertext.length).to.eq(4); - }); - - it("should produce a cihertext that is different from the plaintext", () => { - const { privKey } = genKeypair(); - const pubKey = genPubKey(genPrivKey()); - const sharedKey = genEcdhSharedKey(privKey, pubKey); - const plaintext = [BigInt(1), BigInt(2), BigInt(3)]; - const ciphertext = encrypt(plaintext, sharedKey, nonce); - for (let i = 0; i < plaintext.length; i += 1) { - expect(plaintext[i] !== ciphertext[i + 1]).to.eq(true); - } - }); - it("should produce ciphertext that is < SNARK_FIELD_SIZE", () => { - const { privKey } = genKeypair(); - const pubKey = genPubKey(genPrivKey()); - const sharedKey = genEcdhSharedKey(privKey, pubKey); - const plaintext = [BigInt(1), BigInt(2), BigInt(3)]; - const ciphertext = encrypt(plaintext, sharedKey, nonce); - ciphertext.forEach((c) => { - expect(c < SNARK_FIELD_SIZE).to.eq(true); - }); - }); - }); - describe("decrypt", () => { - it("should decrypt a ciphertext", () => { - const { privKey } = genKeypair(); - const pubKey = genPubKey(genPrivKey()); - const sharedKey = genEcdhSharedKey(privKey, pubKey); - const plaintext = [BigInt(1), BigInt(2), BigInt(3)]; - const ciphertext = encrypt(plaintext, sharedKey, nonce); - const decryptedCiphertext = decrypt(ciphertext, sharedKey, nonce, plaintext.length); - expect(decryptedCiphertext).to.be.instanceOf(Array); - expect(decryptedCiphertext.length).to.eq(3); - expect(plaintext).to.deep.eq(decryptedCiphertext); - }); - it("should fail to decrypt if given the wrong key", () => { - const { privKey } = genKeypair(); - const pubKey = genPubKey(genPrivKey()); - const sharedKey = genEcdhSharedKey(privKey, pubKey); - const plaintext = [BigInt(1), BigInt(2), BigInt(3)]; - const ciphertext = encrypt(plaintext, sharedKey, nonce); - const differentKey = genEcdhSharedKey(BigInt(1), pubKey); - - expect(() => { - decrypt(ciphertext, differentKey, nonce, plaintext.length); - }).to.throw(); - }); - }); - }); - - describe("signatures", () => { - const { privKey, pubKey } = genKeypair(); - const message = BigInt(Math.floor(Math.random() * 1000000000)); - const signature = sign(privKey, message); - - it("should have the correct format and its constituent parts should be smaller than the snark field size", () => { - expect(signature).to.haveOwnProperty("R8"); - expect(signature).to.haveOwnProperty("S"); - expect(signature.R8[0] < SNARK_FIELD_SIZE).to.eq(true); - expect(signature.R8[1] < SNARK_FIELD_SIZE).to.eq(true); - expect(signature.S < SNARK_FIELD_SIZE).to.eq(true); - }); - - it("should be valid", () => { - const valid = verifySignature(message, signature, pubKey); - expect(valid).to.eq(true); - }); - - it("should be invalid for a different message", () => { - const valid = verifySignature(message + BigInt(1), signature, pubKey); - expect(valid).to.eq(false); - }); - - it("should be invalid if tampered with", () => { - const valid = verifySignature( - message, - { - R8: signature.R8, - S: BigInt(1), - }, - pubKey, - ); - expect(valid).to.eq(false); - }); - - it("should be invalid for a different public key", () => { - const pubKey1 = genPubKey(genPrivKey()); - const valid = verifySignature(message, signature, pubKey1); - expect(valid).to.eq(false); - }); - }); }); diff --git a/crypto/ts/__tests__/Utils.test.ts b/crypto/ts/__tests__/Utils.test.ts index fec12fd52c..095494aa47 100644 --- a/crypto/ts/__tests__/Utils.test.ts +++ b/crypto/ts/__tests__/Utils.test.ts @@ -1,6 +1,6 @@ import { expect } from "chai"; -import { bigInt2Buffer, fromRprLE, fromString, stringifyBigInts, unstringifyBigInts } from "../bigIntUtils"; +import { bigInt2Buffer, fromRprLE, fromString, shiftRight, stringifyBigInts, unstringifyBigInts } from "../bigIntUtils"; import { SNARK_FIELD_SIZE } from "../constants"; import { genTreeCommitment, genTreeProof } from "../utils"; @@ -150,6 +150,14 @@ describe("Utils", () => { const expectedBuffer = Buffer.from(hex, "hex"); expect(buffer.equals(expectedBuffer)).to.eq(true); }); + + it("should produce a Buffer with the correct value even if not even length", () => { + const bigInt = BigInt(15); + const buffer = bigInt2Buffer(bigInt); + + const expectedBuffer = Buffer.from("0f", "hex"); + expect(buffer.equals(expectedBuffer)).to.eq(true); + }); }); describe("genTreeCommitment", () => { @@ -224,4 +232,10 @@ describe("Utils", () => { expect(fromRprLE(view, 0, 4)).to.eq(expected); }); }); + + describe("shiftRight", () => { + it("should shift a bigint to the right by n bits", () => { + expect(shiftRight(16n, 2n)).to.eq(4n); + }); + }); }); diff --git a/crypto/ts/bigIntUtils.ts b/crypto/ts/bigIntUtils.ts index 75248b8f06..b5d1d26519 100644 --- a/crypto/ts/bigIntUtils.ts +++ b/crypto/ts/bigIntUtils.ts @@ -109,13 +109,6 @@ export const stringifyBigInts = (input: BigIntVariants): StringifiedBigInts => { */ export const deepCopyBigIntArray = (arr: bigint[]): bigint[] => arr.map((x) => BigInt(x.toString())); -/** - * Convert a buffer to a bigint - * @param buffer - The buffer to convert - * @returns The buffer as a bigint - */ -export const leBufferToBigint = (buffer: Buffer): bigint => BigInt(`0x${buffer.reverse().toString("hex")}`); - /** * Sihft a left by n bits * @param a - The first bigint diff --git a/crypto/ts/constants.ts b/crypto/ts/constants.ts index 1a99691d79..550e54cafd 100644 --- a/crypto/ts/constants.ts +++ b/crypto/ts/constants.ts @@ -1,16 +1,12 @@ -import { babyJub } from "circomlib"; -import * as ethers from "ethers"; +import { r } from "@zk-kit/baby-jubjub"; +import { utils } from "ethers"; import assert from "assert"; -// The BN254 group order p -export const SNARK_FIELD_SIZE = BigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); +export const SNARK_FIELD_SIZE = r; // A nothing-up-my-sleeve zero value // Should be equal to 8370432830353022751713833565135785980866757267633941821328460903436894336785 -export const NOTHING_UP_MY_SLEEVE = BigInt(ethers.utils.keccak256(ethers.utils.toUtf8Bytes("Maci"))) % SNARK_FIELD_SIZE; +export const NOTHING_UP_MY_SLEEVE = BigInt(utils.keccak256(utils.toUtf8Bytes("Maci"))) % SNARK_FIELD_SIZE; assert(NOTHING_UP_MY_SLEEVE === BigInt("8370432830353022751713833565135785980866757267633941821328460903436894336785")); - -// The largest value in the babyjub curve -export const babyJubMaxValue = BigInt(babyJub.p); diff --git a/crypto/ts/crypto.ts b/crypto/ts/crypto.ts index fe969e34a1..6222fc83b7 100644 --- a/crypto/ts/crypto.ts +++ b/crypto/ts/crypto.ts @@ -1,23 +1,13 @@ -import createBlakeHash from "blake-hash"; -import { babyJub, poseidon, poseidonEncrypt, poseidonDecrypt, eddsa } from "circomlib"; -import * as ethers from "ethers"; +import { mulPointEscalar, Point } from "@zk-kit/baby-jubjub"; +import { deriveSecretScalar, derivePublicKey, packPublicKey, unpackPublicKey } from "@zk-kit/eddsa-poseidon"; +import { poseidonPerm } from "@zk-kit/poseidon-cipher"; +import { utils } from "ethers"; import assert from "assert"; import { randomBytes } from "crypto"; -import type { - Ciphertext, - EcdhSharedKey, - Plaintext, - Point, - PrivKey, - PubKey, - PoseidonFuncs, - Keypair, - Signature, -} from "./types"; - -import { bigInt2Buffer, leBufferToBigint, shiftRight } from "./bigIntUtils"; +import type { EcdhSharedKey, PrivKey, PubKey, PoseidonFuncs, Keypair } from "./types"; + import { SNARK_FIELD_SIZE } from "./constants"; /** @@ -117,7 +107,7 @@ export const sha256Hash = (input: bigint[]): bigint => { return ( BigInt( - ethers.utils.soliditySha256( + utils.soliditySha256( types, input.map((x) => x.toString()), ), @@ -125,6 +115,13 @@ export const sha256Hash = (input: bigint[]): bigint => { ); }; +/** + * Generate the poseidon hash of the inputs provided + * @param inputs The inputs to hash + * @returns the hash of the inputs + */ +export const poseidon = (inputs: bigint[]): bigint => poseidonPerm([BigInt(0), ...inputs.map((x) => BigInt(x))])[0]; + /** * Hash up to 2 elements * @param inputs The elements to hash @@ -173,13 +170,20 @@ export const poseidonT6 = (inputs: bigint[]): bigint => { */ export const hashLeftRight = (left: bigint, right: bigint): bigint => poseidonT3([left, right]); +const funcs: PoseidonFuncs = { + 2: poseidonT3, + 3: poseidonT4, + 4: poseidonT5, + 5: poseidonT6, +}; + /** * Hash up to N elements * @param numElements The number of elements to hash * @param elements The elements to hash * @returns The hash of the elements */ -export const hashN = (numElements: number, elements: Plaintext): bigint => { +export const hashN = (numElements: number, elements: bigint[]): bigint => { const elementLength = elements.length; if (elements.length > numElements) { throw new TypeError(`the length of the elements array should be at most ${numElements}; got ${elements.length}`); @@ -191,21 +195,14 @@ export const hashN = (numElements: number, elements: Plaintext): bigint => { } } - const funcs: PoseidonFuncs = { - 2: poseidonT3, - 3: poseidonT4, - 4: poseidonT5, - 5: poseidonT6, - }; - return funcs[numElements](elementsPadded); }; // hash functions -export const hash2 = (elements: Plaintext): bigint => hashN(2, elements); -export const hash3 = (elements: Plaintext): bigint => hashN(3, elements); -export const hash4 = (elements: Plaintext): bigint => hashN(4, elements); -export const hash5 = (elements: Plaintext): bigint => hashN(5, elements); +export const hash2 = (elements: bigint[]): bigint => hashN(2, elements); +export const hash3 = (elements: bigint[]): bigint => hashN(3, elements); +export const hash4 = (elements: bigint[]): bigint => hashN(4, elements); +export const hash5 = (elements: bigint[]): bigint => hashN(5, elements); /** * A convenience function to use Poseidon to hash a Plaintext with @@ -213,7 +210,7 @@ export const hash5 = (elements: Plaintext): bigint => hashN(5, elements); * @param elements The elements to hash * @returns The hash of the elements */ -export const hash13 = (elements: Plaintext): bigint => { +export const hash13 = (elements: bigint[]): bigint => { const max = 13; const elementLength = elements.length; if (elementLength > max) { @@ -256,7 +253,7 @@ export const genRandomBabyJubValue = (): bigint => { // const min = (lim - SNARK_FIELD_SIZE) % SNARK_FIELD_SIZE const min = BigInt("6350874878119819312338956282401532410528162663560392320966563075034087161851"); - let privKey: PrivKey = SNARK_FIELD_SIZE; + let privKey = SNARK_FIELD_SIZE; do { const rand = BigInt(`0x${randomBytes(32).toString("hex")}`); @@ -288,26 +285,7 @@ export const genRandomSalt = (): bigint => genRandomBabyJubValue(); * @param privKey A private key generated using genPrivKey() * @returns A BabyJub-compatible private key. */ -export const formatPrivKeyForBabyJub = (privKey: PrivKey): bigint => { - const sBuff = eddsa.pruneBuffer(createBlakeHash("blake512").update(bigInt2Buffer(privKey)).digest().subarray(0, 32)); - const s = leBufferToBigint(sBuff); - - return shiftRight(s, BigInt(3)); -}; - -/** - * Losslessly reduces the size of the representation of a public key - * @param pubKey The public key to pack - * @returns A packed public key - */ -export const packPubKey = (pubKey: PubKey): Buffer => babyJub.packPoint(pubKey); - -/** - * Restores the original PubKey from its packed representation - * @param packed The value to unpack - * @returns The unpacked public key - */ -export const unpackPubKey = (packed: Buffer): PubKey => babyJub.unpackPoint(packed); +export const formatPrivKeyForBabyJub = (privKey: PrivKey): bigint => BigInt(deriveSecretScalar(privKey)); /** * @param privKey A private key generated using genPrivKey() @@ -315,9 +293,10 @@ export const unpackPubKey = (packed: Buffer): PubKey => babyJub.unpackPoint(pack */ export const genPubKey = (privKey: PrivKey): PubKey => { // Check whether privKey is a field element - assert(privKey < SNARK_FIELD_SIZE); + assert(BigInt(privKey) < SNARK_FIELD_SIZE); - return eddsa.prv2pub(bigInt2Buffer(privKey)); + const key = derivePublicKey(privKey); + return [BigInt(key[0]), BigInt(key[1])]; }; /** @@ -341,86 +320,21 @@ export const genKeypair = (): Keypair => { * @returns The ECDH shared key. */ export const genEcdhSharedKey = (privKey: PrivKey, pubKey: PubKey): EcdhSharedKey => - babyJub.mulPointEscalar(pubKey, formatPrivKeyForBabyJub(privKey)); - -/** - * Encrypts a plaintext using a given key. - * @param plaintext The plaintext to encrypt. - * @param sharedKey The shared key to use for encryption. - * @param nonce The nonce to use for encryption. - * @returns The ciphertext. - */ -export const encrypt = (plaintext: Plaintext, sharedKey: EcdhSharedKey, nonce = BigInt(0)): Ciphertext => { - const ciphertext = poseidonEncrypt(plaintext, sharedKey, nonce); - return ciphertext; -}; + mulPointEscalar(pubKey as Point, formatPrivKeyForBabyJub(privKey)); /** - * Decrypts a ciphertext using a given key. - * @param ciphertext The ciphertext to decrypt. - * @param sharedKey The shared key to use for decryption. - * @param nonce The nonce to use for decryption. - * @param length The length of the plaintext. - * @returns The plaintext. - */ -export const decrypt = (ciphertext: Ciphertext, sharedKey: EcdhSharedKey, nonce: bigint, length: number): Plaintext => - poseidonDecrypt(ciphertext, sharedKey, nonce, length); - -/** - * Generates a signature given a private key and plaintext. - * @param privKey A private key generated using genPrivKey() - * @param msg The plaintext to sign. - * @returns The signature. - */ -export const sign = (privKey: PrivKey, msg: bigint): Signature => eddsa.signPoseidon(bigInt2Buffer(privKey), msg); - -/** - * Checks whether the signature of the given plaintext was created using the - * private key associated with the given public key. - * @param msg The plaintext to verify. - * @param signature The signature to verify. - * @param pubKey The public key to use for verification. - * @returns True if the signature is valid, and false otherwise. + * Losslessly reduces the size of the representation of a public key + * @param pubKey The public key to pack + * @returns A packed public key */ -export const verifySignature = (msg: bigint, signature: Signature, pubKey: PubKey): boolean => - eddsa.verifyPoseidon(msg, signature, pubKey); +export const packPubKey = (pubKey: PubKey): bigint => BigInt(packPublicKey(pubKey)); /** - * Maps bit to a point on the curve - * @returns the point. - */ -export const bitToCurve = (bit: bigint): Point => { - switch (bit) { - case BigInt(0): - return [BigInt(0), BigInt(1)]; - case BigInt(1): - return babyJub.Base8; - default: - throw new Error("Invalid bit value"); - } -}; - -/** - * Maps curve point to bit - * @param p The point to map. - * @returns the bit value. + * Restores the original PubKey from its packed representation + * @param packed The value to unpack + * @returns The unpacked public key */ -export const curveToBit = (p: Point): bigint => { - if (p[0] === BigInt(0) && p[1] === BigInt(1)) { - return BigInt(0); - } - - if (p[0] === babyJub.Base8[0] && p[1] === babyJub.Base8[1]) { - return BigInt(1); - } - - throw new Error("Invalid point value"); +export const unpackPubKey = (packed: bigint): PubKey => { + const pubKey = unpackPublicKey(packed); + return pubKey.map((x: string) => BigInt(x)) as PubKey; }; - -/** - * Sums two points on the jubjub curve - * @param a The first point - * @param b The second point - * @returns the sum of the two points - */ -export const babyJubAddPoint = (a: bigint, b: bigint): bigint => babyJub.addPoint(a, b); diff --git a/crypto/ts/index.ts b/crypto/ts/index.ts index d023e1208a..2fc3cd9862 100644 --- a/crypto/ts/index.ts +++ b/crypto/ts/index.ts @@ -6,7 +6,7 @@ export { calcDepthFromNumLeaves, genTreeCommitment, genTreeProof } from "./utils export { bigInt2Buffer, stringifyBigInts, unstringifyBigInts, deepCopyBigIntArray } from "./bigIntUtils"; -export { SNARK_FIELD_SIZE, NOTHING_UP_MY_SLEEVE, babyJubMaxValue } from "./constants"; +export { NOTHING_UP_MY_SLEEVE, SNARK_FIELD_SIZE } from "./constants"; export { G1Point, @@ -24,24 +24,20 @@ export { genPrivKey, genRandomSalt, formatPrivKeyForBabyJub, - packPubKey, - unpackPubKey, genPubKey, genKeypair, genEcdhSharedKey, - encrypt, - decrypt, - sign, - verifySignature, - curveToBit, - babyJubAddPoint, - bitToCurve, + packPubKey, + unpackPubKey, } from "./crypto"; export { OptimisedMT as IncrementalQuinTree, type PathElements } from "optimisedmt"; +export { poseidonDecrypt, poseidonEncrypt } from "@zk-kit/poseidon-cipher"; + +export { verifySignature, signMessage as sign } from "@zk-kit/eddsa-poseidon"; + export type { - SnarkBigInt, PrivKey, PubKey, Point, diff --git a/crypto/ts/types.ts b/crypto/ts/types.ts index e5d8905162..9e37e6fd76 100644 --- a/crypto/ts/types.ts +++ b/crypto/ts/types.ts @@ -1,10 +1,24 @@ -export type SnarkBigInt = bigint; -export type PrivKey = bigint; -export type PubKey = bigint[]; -export type Point = bigint[]; -export type EcdhSharedKey = bigint[]; -export type Plaintext = bigint[]; -export type Ciphertext = bigint[]; +// we define a bignumber as either a bigint or a string +// which is what we use the most in MACI +export type SnarkBigNumber = bigint | string; + +// a private key is a single BigNumber +export type PrivKey = SnarkBigNumber; + +// a public key is a pair of BigNumbers +export type PubKey = [N, N]; + +// a shared key is a pair of BigNumbers +export type EcdhSharedKey = [N, N]; + +// a point is a pair of BigNumbers +export type Point = [N, N]; + +// a plaintext is an array of BigNumbers +export type Plaintext = N[]; + +// a ciphertext is an array of BigNumbers +export type Ciphertext = N[]; /** * A acc queue @@ -27,9 +41,9 @@ export interface Keypair { // field of order `l` where `l` is the large prime number dividing the order of // Baby Jubjub: see // https://iden3-docs.readthedocs.io/en/latest/_downloads/a04267077fb3fdbf2b608e014706e004/Ed-DSA.pdf -export interface Signature { - R8: bigint[]; - S: bigint; +export interface Signature { + R8: Point; + S: N; } /** @@ -43,6 +57,7 @@ export interface PoseidonFuncs { 5: (inputs: bigint[]) => bigint; } +// a leaf is a single BigNumber export type Leaf = bigint; export type StringifiedBigInts = diff --git a/domainobjs/ts/__tests__/publicKey.test.ts b/domainobjs/ts/__tests__/publicKey.test.ts index c036fce2d6..4e63e7d902 100644 --- a/domainobjs/ts/__tests__/publicKey.test.ts +++ b/domainobjs/ts/__tests__/publicKey.test.ts @@ -21,7 +21,7 @@ describe("public key", () => { expect(s.startsWith("macipk.")).to.eq(true); const d = s.slice(7); - const unpacked = unpackPubKey(Buffer.from(d, "hex")); + const unpacked = unpackPubKey(BigInt(`0x${d.toString()}`)); expect(unpacked[0].toString()).to.eq(pk1.rawPubKey[0].toString()); expect(unpacked[1].toString()).to.eq(pk1.rawPubKey[1].toString()); @@ -35,7 +35,7 @@ describe("public key", () => { const pk2 = pk1; expect(pk1.rawPubKey.toString()).to.eq(pk2.rawPubKey.toString()); - pk1.rawPubKey = [BigInt(0)]; + pk1.rawPubKey = [BigInt(0), BigInt(0)]; expect(pk1.rawPubKey.toString()).to.eq(pk2.rawPubKey.toString()); // deep copy @@ -43,7 +43,7 @@ describe("public key", () => { const pk3 = k1.pubKey; const pk4 = pk3.copy(); expect(pk3.rawPubKey.toString()).to.eq(pk4.rawPubKey.toString()); - pk4.rawPubKey = [BigInt(0)]; + pk4.rawPubKey = [BigInt(0), BigInt(0)]; expect(pk3.rawPubKey.toString()).not.to.eq(pk4.rawPubKey.toString()); }); }); diff --git a/domainobjs/ts/commands/PCommand.ts b/domainobjs/ts/commands/PCommand.ts index 2046a0102d..176639ca82 100644 --- a/domainobjs/ts/commands/PCommand.ts +++ b/domainobjs/ts/commands/PCommand.ts @@ -1,6 +1,6 @@ import { - decrypt, - encrypt, + poseidonDecrypt, + poseidonEncrypt, genRandomSalt, hash4, sign, @@ -8,6 +8,7 @@ import { Signature, Ciphertext, EcdhSharedKey, + Point, } from "maci-crypto"; import assert from "assert"; @@ -158,11 +159,11 @@ export class PCommand implements ICommand { * 6. poll ID */ encrypt = (signature: Signature, sharedKey: EcdhSharedKey): Message => { - const plaintext = [...this.asArray(), signature.R8[0], signature.R8[1], signature.S]; + const plaintext = [...this.asArray(), BigInt(signature.R8[0]), BigInt(signature.R8[1]), BigInt(signature.S)]; assert(plaintext.length === 7); - const ciphertext: Ciphertext = encrypt(plaintext, sharedKey, BigInt(0)); + const ciphertext: Ciphertext = poseidonEncrypt(plaintext, sharedKey, BigInt(0)); const message = new Message(BigInt(1), ciphertext as bigint[]); @@ -175,7 +176,7 @@ export class PCommand implements ICommand { * @param {EcdhSharedKey} sharedKey - the shared key to use for decryption */ static decrypt = (message: Message, sharedKey: EcdhSharedKey): IDecryptMessage => { - const decrypted = decrypt(message.data, sharedKey, BigInt(0), 7); + const decrypted = poseidonDecrypt(message.data, sharedKey, BigInt(0), 7); const p = BigInt(decrypted[0].toString()); @@ -206,7 +207,7 @@ export class PCommand implements ICommand { const command = new PCommand(stateIndex, newPubKey, voteOptionIndex, newVoteWeight, nonce, pollId, salt); const signature = { - R8: [decrypted[4], decrypted[5]], + R8: [decrypted[4], decrypted[5]] as Point, S: decrypted[6], }; diff --git a/domainobjs/ts/privateKey.ts b/domainobjs/ts/privateKey.ts index d191b0b0b0..ba18ea6409 100644 --- a/domainobjs/ts/privateKey.ts +++ b/domainobjs/ts/privateKey.ts @@ -38,7 +38,13 @@ export class PrivKey { * Serialize the private key * @returns the serialized private key */ - serialize = (): string => SERIALIZED_PRIV_KEY_PREFIX + this.rawPrivKey.toString(16); + serialize = (): string => { + const x = this.rawPrivKey.toString(16); + if (x.length % 2 !== 0) { + return `${SERIALIZED_PRIV_KEY_PREFIX}0${x}`; + } + return `${SERIALIZED_PRIV_KEY_PREFIX}${x}`; + }; /** * Deserialize the private key diff --git a/domainobjs/ts/publicKey.ts b/domainobjs/ts/publicKey.ts index 9a46846943..43c6c59a45 100644 --- a/domainobjs/ts/publicKey.ts +++ b/domainobjs/ts/publicKey.ts @@ -21,7 +21,6 @@ export class PubKey { * @param rawPubKey the raw public key */ constructor(rawPubKey: RawPubKey) { - assert(rawPubKey.length === 2); assert(rawPubKey[0] < SNARK_FIELD_SIZE); assert(rawPubKey[1] < SNARK_FIELD_SIZE); this.rawPubKey = rawPubKey; @@ -68,8 +67,14 @@ export class PubKey { if (BigInt(x) === BigInt(0) && BigInt(y) === BigInt(0)) { return `${SERIALIZED_PUB_KEY_PREFIX}z`; } - const packed = packPubKey(this.rawPubKey).toString("hex"); - return SERIALIZED_PUB_KEY_PREFIX + packed.toString(); + + const packed = packPubKey(this.rawPubKey).toString(16); + + if (packed.length % 2 !== 0) { + return `${SERIALIZED_PUB_KEY_PREFIX}0${packed}`; + } + + return `${SERIALIZED_PUB_KEY_PREFIX}${packed}`; }; /** @@ -97,8 +102,7 @@ export class PubKey { } const len = SERIALIZED_PUB_KEY_PREFIX.length; - const packed = Buffer.from(s.slice(len), "hex"); - return new PubKey(unpackPubKey(packed)); + return new PubKey(unpackPubKey(BigInt(`0x${s.slice(len).toString()}`))); }; /** diff --git a/integrationTests/package-lock.json b/integrationTests/package-lock.json index 9debc18978..b264515ba2 100644 --- a/integrationTests/package-lock.json +++ b/integrationTests/package-lock.json @@ -8,7 +8,8 @@ "name": "maci-integrationtests", "version": "1.1.2", "dependencies": { - "@nomicfoundation/hardhat-toolbox": "^4.0.0" + "@nomicfoundation/hardhat-toolbox": "^4.0.0", + "ethers": "^6.9.0" }, "devDependencies": { "@fastify/busboy": "^2.0.0", @@ -18,7 +19,6 @@ "@types/node": "^18.11.9", "chai": "^4.3.10", "chai-as-promised": "^7.1.1", - "ethers": "^6.9.0", "hardhat": "^2.19.2", "hardhat-artifactor": "^0.2.0", "hardhat-contract-sizer": "^2.0.3", diff --git a/integrationTests/package.json b/integrationTests/package.json index e970ac8d4e..1f8e76d556 100644 --- a/integrationTests/package.json +++ b/integrationTests/package.json @@ -7,10 +7,10 @@ "watch": "tsc --watch", "build": "tsc", "test": "ts-mocha --exit ./ts/__tests__/**.test.ts", - "test-cli-genMaciKeypair": "ts-mocha --exit ./ts/__tests__/cli-genMaciKeypair.test.ts", - "test-cli-genMaciPubkey": "ts-mocha --exit ./ts/__tests__/cli-genMaciPubkey.test.ts", - "test-suites": "NODE_OPTIONS=--max-old-space-size=4096 ts-mocha --exit ./ts/__tests__/suites.test.ts", - "test-deployPoll": "NODE_OPTIONS=--max-old-space-size=4096 ts-mocha --exit ./ts/__tests__/deployPollWithRandomSigner.test.ts", + "test:genMaciKeypair": "ts-mocha --exit ./ts/__tests__/cli-genMaciKeypair.test.ts", + "test:genMaciPubkey": "ts-mocha --exit ./ts/__tests__/cli-genMaciPubkey.test.ts", + "test:suites": "NODE_OPTIONS=--max-old-space-size=4096 ts-mocha --exit ./ts/__tests__/suites.test.ts", + "test:maciKeys": "ts-mocha --exit ./ts/__tests__/maci-keys.test.ts", "download-zkeys": "./scripts/download_zkeys.sh" }, "devDependencies": { @@ -21,7 +21,6 @@ "@types/node": "^18.11.9", "chai": "^4.3.10", "chai-as-promised": "^7.1.1", - "ethers": "^6.9.0", "hardhat": "^2.19.2", "hardhat-artifactor": "^0.2.0", "hardhat-contract-sizer": "^2.0.3", @@ -31,6 +30,7 @@ }, "dependencies": { "@nomicfoundation/hardhat-toolbox": "^4.0.0", + "ethers": "^6.9.0", "maci-circuits": "^1.1.2", "maci-cli": "^1.1.2", "maci-contracts": "^1.1.2", diff --git a/integrationTests/ts/__tests__/maci-keys.test.ts b/integrationTests/ts/__tests__/maci-keys.test.ts new file mode 100644 index 0000000000..e89295a5ea --- /dev/null +++ b/integrationTests/ts/__tests__/maci-keys.test.ts @@ -0,0 +1,125 @@ +import { expect } from "chai"; +import { BaseContract, Signer } from "ethers"; +import { MACI, Poll, getDefaultSigner, parseArtifact } from "maci-contracts"; +import { genPrivKey, genPubKey } from "maci-crypto"; +import { Keypair, PrivKey, PubKey } from "maci-domainobjs"; + +import { + INT_STATE_TREE_DEPTH, + STATE_TREE_DEPTH, + VOTE_OPTION_TREE_DEPTH, + duration, + initialVoiceCredits, + maxMessages, + maxVoteOptions, + messageBatchDepth, + messageTreeDepth, +} from "./utils/constants"; +import { deployTestContracts } from "./utils/utils"; + +describe("integration tests private/public/keypair", () => { + describe("crypto/domainobjs", () => { + it("should serialize and deserialize a private key correctly", () => { + const privateKeyCrypto = genPrivKey(); + + const privKeyDomainobjs = new PrivKey(privateKeyCrypto); + const privKeyDomainobjsSerialized = privKeyDomainobjs.serialize(); + + const privKeyDomainobjsDeserialized = PrivKey.deserialize(privKeyDomainobjsSerialized); + + expect(privKeyDomainobjsDeserialized.rawPrivKey.toString()).to.eq(privateKeyCrypto.toString()); + }); + + it("should serialize and deserialize a public key correctly", () => { + const privateKeyCrypto = genPrivKey(); + + const publicKeyCrypto = genPubKey(privateKeyCrypto); + + const pubKeyDomainobjs = new PubKey(publicKeyCrypto); + + const pubKeyDomainobjsSerialized = pubKeyDomainobjs.serialize(); + const pubKeyDomainobjsDeserialized = PubKey.deserialize(pubKeyDomainobjsSerialized); + + expect(pubKeyDomainobjsDeserialized.rawPubKey[0].toString()).to.eq(publicKeyCrypto[0].toString()); + expect(pubKeyDomainobjsDeserialized.rawPubKey[1].toString()).to.eq(publicKeyCrypto[1].toString()); + }); + + it("should serialize and deserialize a private key correct after serializing as contract params", () => { + const privateKeyCrypto = genPrivKey(); + + const privKeyDomainobjs = new PrivKey(privateKeyCrypto); + const keypairDomainobjs = new Keypair(privKeyDomainobjs); + + const pubKeyDomainobjsAsContractParam = keypairDomainobjs.pubKey.asContractParam(); + + const privKeyDomainobjsSerialized = privKeyDomainobjs.serialize(); + + const privKeyDomainobjsDeserialized = PrivKey.deserialize(privKeyDomainobjsSerialized); + const keypairDomainobjsDeserialized = new Keypair(privKeyDomainobjsDeserialized); + + expect(keypairDomainobjsDeserialized.pubKey.rawPubKey[0].toString()).to.eq( + pubKeyDomainobjsAsContractParam.x.toString(), + ); + expect(keypairDomainobjsDeserialized.pubKey.rawPubKey[1].toString()).to.eq( + pubKeyDomainobjsAsContractParam.y.toString(), + ); + }); + }); + + describe("crypto/domainobjs/contracts", () => { + // deploy maci + let maciContract: MACI; + let pollContract: Poll; + + let signer: Signer; + const coordinatorKeypair = new Keypair(); + + before(async () => { + signer = await getDefaultSigner(); + maciContract = await deployTestContracts(initialVoiceCredits, STATE_TREE_DEPTH, signer, true); + + // deploy a poll + await maciContract.deployPoll( + BigInt(duration), + { + maxMessages, + maxVoteOptions, + }, + { + intStateTreeDepth: INT_STATE_TREE_DEPTH, + messageTreeDepth, + messageTreeSubDepth: messageBatchDepth, + voteOptionTreeDepth: VOTE_OPTION_TREE_DEPTH, + }, + coordinatorKeypair.pubKey.asContractParam(), + ); + + // we know it's the first poll so id is 0 + pollContract = new BaseContract(await maciContract.polls(0), parseArtifact("Poll")[0], signer) as Poll; + }); + + it("should have the correct coordinator pub key set on chain", async () => { + const onChainKey = await pollContract.coordinatorPubKey(); + expect(onChainKey.x.toString()).to.eq(coordinatorKeypair.pubKey.rawPubKey[0].toString()); + expect(onChainKey.y.toString()).to.eq(coordinatorKeypair.pubKey.rawPubKey[1].toString()); + }); + + it("should serialize and deserialize the coordinator private key to match the on chain key", async () => { + const onChainKey = await pollContract.coordinatorPubKey(); + + const coordinatorPrivKeySerialized = coordinatorKeypair.privKey.serialize(); + const coordinatorPrivKeyDeserialized = PrivKey.deserialize(coordinatorPrivKeySerialized); + const coordinatorKeypairDeserialized = new Keypair(coordinatorPrivKeyDeserialized); + + expect(coordinatorKeypairDeserialized.pubKey.rawPubKey[0].toString()).to.eq(onChainKey.x.toString()); + expect(coordinatorKeypairDeserialized.pubKey.rawPubKey[1].toString()).to.eq(onChainKey.y.toString()); + }); + + it("should have a matching coordinator public key hash", async () => { + const onChainKeyHash = await pollContract.coordinatorPubKeyHash(); + const coordinatorPubKeyHash = coordinatorKeypair.pubKey.hash(); + + expect(onChainKeyHash.toString()).to.eq(coordinatorPubKeyHash.toString()); + }); + }); +}); diff --git a/integrationTests/ts/__tests__/utils/utils.ts b/integrationTests/ts/__tests__/utils/utils.ts index 6cc43ff723..e2365c5123 100644 --- a/integrationTests/ts/__tests__/utils/utils.ts +++ b/integrationTests/ts/__tests__/utils/utils.ts @@ -1,5 +1,15 @@ // eslint-disable-next-line import/no-extraneous-dependencies import { expect } from "chai"; +import { Signer } from "ethers"; +import { + FreeForAllGatekeeper, + MACI, + deployConstantInitialVoiceCreditProxy, + deployFreeForAllSignUpGatekeeper, + deployMaci, + deployMockVerifier, + deployTopupCredit, +} from "maci-contracts"; import { Keypair } from "maci-domainobjs"; import { arch } from "os"; @@ -169,3 +179,59 @@ export const sleep = async (ms: number): Promise => * @returns whether we are running on an arm chip */ export const isArm = (): boolean => arch().includes("arm"); + +/** + * Deploy a set of smart contracts that can be used for testing. + * @param initialVoiceCreditBalance - the initial voice credit balance for each user + * @param stateTreeDepth - the depth of the state tree + * @param signer - the signer to use + * @param quiet - whether to suppress console output + * @param gatekeeper - the gatekeeper contract to use + * @returns the deployed contracts + */ +export const deployTestContracts = async ( + initialVoiceCreditBalance: number, + stateTreeDepth: number, + signer?: Signer, + quiet = false, + gatekeeper: FreeForAllGatekeeper | undefined = undefined, +): Promise => { + const mockVerifierContract = await deployMockVerifier(signer, true); + + let gatekeeperContract = gatekeeper; + if (!gatekeeperContract) { + gatekeeperContract = await deployFreeForAllSignUpGatekeeper(signer, true); + } + + const constantIntialVoiceCreditProxyContract = await deployConstantInitialVoiceCreditProxy( + initialVoiceCreditBalance, + signer, + true, + ); + + // VkRegistry + const topupCreditContract = await deployTopupCredit(signer, true); + const [ + gatekeeperContractAddress, + mockVerifierContractAddress, + constantIntialVoiceCreditProxyContractAddress, + topupCreditContractAddress, + ] = await Promise.all([ + gatekeeperContract.getAddress(), + mockVerifierContract.getAddress(), + constantIntialVoiceCreditProxyContract.getAddress(), + topupCreditContract.getAddress(), + ]); + + const { maciContract } = await deployMaci( + gatekeeperContractAddress, + constantIntialVoiceCreditProxyContractAddress, + mockVerifierContractAddress, + topupCreditContractAddress, + signer, + stateTreeDepth, + quiet, + ); + + return maciContract; +}; From 2b95044921cd0bed72694d069e2f9ed8fa44e72e Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Fri, 15 Dec 2023 17:31:17 +0000 Subject: [PATCH 20/37] feat(proofs): make preferred witness type in circuit's genProof function Remove isArm check in circuits and instead accept a parameter to decide which witness type to use. Made appropriate changes in tests and cli --- circuits/ts/index.ts | 2 +- circuits/ts/proofs.ts | 21 ++++++++++++++++++--- circuits/ts/types.ts | 1 + cli/tests/e2e.subsidy.test.ts | 3 +-- cli/tests/e2e.test.ts | 3 +-- cli/tests/keyChange.test.ts | 3 +-- cli/tests/utils.ts | 14 ++++++++++++-- cli/ts/commands/genProofs.ts | 3 +++ 8 files changed, 38 insertions(+), 12 deletions(-) diff --git a/circuits/ts/index.ts b/circuits/ts/index.ts index add0ed5816..90ba1ac8db 100644 --- a/circuits/ts/index.ts +++ b/circuits/ts/index.ts @@ -1,2 +1,2 @@ export { genProof, verifyProof, extractVk } from "./proofs"; -export { isArm, cleanThreads } from "./utils"; +export { cleanThreads } from "./utils"; diff --git a/circuits/ts/proofs.ts b/circuits/ts/proofs.ts index 55acb8a929..39f4b306c1 100644 --- a/circuits/ts/proofs.ts +++ b/circuits/ts/proofs.ts @@ -16,6 +16,7 @@ import { cleanThreads, isArm } from "./utils"; * snark and a WASM witness * @param inputs - the inputs to the circuit * @param zkeyPath - the path to the zkey + * @param useWasm - whether we want to use the wasm witness or not * @param rapidsnarkExePath - the path to the rapidnsark binary * @param witnessExePath - the path to the compiled witness binary * @param wasmPath - the path to the wasm witness @@ -25,16 +26,30 @@ import { cleanThreads, isArm } from "./utils"; export const genProof = async ({ inputs, zkeyPath, + useWasm, rapidsnarkExePath, witnessExePath, wasmPath, silent = false, }: IGenProofOptions): Promise => { - // if we are running on an arm chip we can use snarkjs directly - if (isArm()) { - const { proof, publicSignals } = await groth16.fullProve(inputs, wasmPath!, zkeyPath); + // if we want to use a wasm witness we use snarkjs + if (useWasm) { + if (!wasmPath) { + throw new Error("wasmPath must be specified"); + } + + if (!fs.existsSync(wasmPath)) { + throw new Error(`wasmPath ${wasmPath} does not exist`); + } + + const { proof, publicSignals } = await groth16.fullProve(inputs, wasmPath, zkeyPath); return { proof, publicSignals }; } + + if (isArm()) { + throw new Error("To use rapidnsnark you currently need to be running on an intel chip"); + } + // intel chip flow (use rapidnsark) // Create tmp directory const tmpPath = path.resolve(tmpdir(), `tmp-${Date.now()}`); diff --git a/circuits/ts/types.ts b/circuits/ts/types.ts index ae1c2f863e..620e58be77 100644 --- a/circuits/ts/types.ts +++ b/circuits/ts/types.ts @@ -6,6 +6,7 @@ import type { CircuitInputs } from "maci-core"; export interface IGenProofOptions { inputs: CircuitInputs; zkeyPath: string; + useWasm?: boolean; rapidsnarkExePath?: string; witnessExePath?: string; wasmPath?: string; diff --git a/cli/tests/e2e.subsidy.test.ts b/cli/tests/e2e.subsidy.test.ts index 1041e0359e..6681af87fa 100644 --- a/cli/tests/e2e.subsidy.test.ts +++ b/cli/tests/e2e.subsidy.test.ts @@ -39,8 +39,7 @@ import { testTallyVotesWasmPath, testTallyVotesWitnessPath, } from "./constants"; -import { cleanSubsidy } from "./utils"; -import { isArm } from "maci-circuits"; +import { cleanSubsidy, isArm } from "./utils"; import { genRandomSalt } from "maci-crypto"; import { DeployedContracts, PollContracts } from "../ts/utils"; diff --git a/cli/tests/e2e.test.ts b/cli/tests/e2e.test.ts index 46bb441a7b..e0357e6ab6 100644 --- a/cli/tests/e2e.test.ts +++ b/cli/tests/e2e.test.ts @@ -36,8 +36,7 @@ import { testTallyVotesWasmPath, testTallyVotesWitnessPath, } from "./constants"; -import { cleanVanilla } from "./utils"; -import { isArm } from "maci-circuits"; +import { cleanVanilla, isArm } from "./utils"; import { DeployedContracts, PollContracts } from "../ts/utils"; import { Keypair } from "maci-domainobjs"; import { genRandomSalt } from "maci-crypto"; diff --git a/cli/tests/keyChange.test.ts b/cli/tests/keyChange.test.ts index 5af2e45ab8..9f7cc2578d 100644 --- a/cli/tests/keyChange.test.ts +++ b/cli/tests/keyChange.test.ts @@ -1,4 +1,3 @@ -import { isArm } from "maci-circuits"; import { deploy, deployPoll, @@ -32,7 +31,7 @@ import { testTallyVotesWitnessPath, } from "./constants"; import { Keypair } from "maci-domainobjs"; -import { cleanVanilla } from "./utils"; +import { cleanVanilla, isArm } from "./utils"; import { readFileSync } from "fs"; import { expect } from "chai"; import { genRandomSalt } from "maci-crypto"; diff --git a/cli/tests/utils.ts b/cli/tests/utils.ts index bcb0a40e3b..61e7e5d60f 100644 --- a/cli/tests/utils.ts +++ b/cli/tests/utils.ts @@ -1,5 +1,7 @@ import { existsSync, readdirSync, rmSync } from "fs"; -import { join } from "path"; +import { arch } from "os"; + +import path from "path"; /** * Test utility to clean up the proofs directory @@ -8,7 +10,7 @@ import { join } from "path"; export const cleanVanilla = () => { const files = readdirSync("./proofs"); for (const file of files) { - rmSync(join("./proofs", file)); + rmSync(path.join("./proofs", file)); } if (existsSync("./tally.json")) rmSync("./tally.json"); }; @@ -21,3 +23,11 @@ export const cleanSubsidy = () => { cleanVanilla(); if (existsSync("./subsidy.json")) rmSync("./subsidy.json"); }; + +/** + * Check if we are running on an arm chip + * @returns whether we are running on an arm chip + */ +export const isArm = (): boolean => { + return arch().includes("arm"); +}; diff --git a/cli/ts/commands/genProofs.ts b/cli/ts/commands/genProofs.ts index ae30092135..138de5856b 100644 --- a/cli/ts/commands/genProofs.ts +++ b/cli/ts/commands/genProofs.ts @@ -228,6 +228,7 @@ export const genProofs = async ( const r = await genProof({ inputs: circuitInputs, zkeyPath: processZkey, + useWasm, rapidsnarkExePath: rapidsnark, witnessExePath: processWitgen, wasmPath: processWasm, @@ -287,6 +288,7 @@ export const genProofs = async ( const r = await genProof({ inputs: subsidyCircuitInputs, zkeyPath: subsidyZkey, + useWasm, rapidsnarkExePath: rapidsnark, witnessExePath: subsidyWitgen, wasmPath: subsidyWasm, @@ -350,6 +352,7 @@ export const genProofs = async ( const r = await genProof({ inputs: tallyCircuitInputs, zkeyPath: tallyZkey, + useWasm, rapidsnarkExePath: rapidsnark, witnessExePath: tallyWitgen, wasmPath: tallyWasm, From c19d1d3b6652d306e5ae7f4083eb20c4832c1233 Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Sat, 16 Dec 2023 18:30:22 +0000 Subject: [PATCH 21/37] test(domainobjs): implement unit tests for the domainobjs package --- .../scripts/ceremony-param-tests-c-witness.sh | 14 +- domainobjs/package.json | 3 +- domainobjs/ts/__tests__/ballot.test.ts | 121 +++++++++- domainobjs/ts/__tests__/commands.test.ts | 228 ++++++++++-------- domainobjs/ts/__tests__/keypair.test.ts | 145 +++++++---- domainobjs/ts/__tests__/message.test.ts | 120 +++++++++ domainobjs/ts/__tests__/privateKey.test.ts | 148 +++++++++--- domainobjs/ts/__tests__/publicKey.test.ts | 203 +++++++++++++--- domainobjs/ts/__tests__/stateLeaf.test.ts | 145 ++++++++--- domainobjs/ts/__tests__/verifyingKey.test.ts | 157 +++++++++--- domainobjs/ts/privateKey.ts | 7 +- 11 files changed, 993 insertions(+), 298 deletions(-) create mode 100644 domainobjs/ts/__tests__/message.test.ts diff --git a/.github/scripts/ceremony-param-tests-c-witness.sh b/.github/scripts/ceremony-param-tests-c-witness.sh index 1bb3277190..33fb5cc3b6 100755 --- a/.github/scripts/ceremony-param-tests-c-witness.sh +++ b/.github/scripts/ceremony-param-tests-c-witness.sh @@ -17,7 +17,7 @@ HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js setVerifyingKeys -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js create -s 6 -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js deployPoll \ - -pk macipk.4d9929621583dd9b8cac251fdc7bf58050330f37e1f407b327e711d5e32ba3a9 \ + -pk macipk.ea638a3366ed91f2e955110888573861f7c0fc0bb5fb8b8dca9cd7a08d7d6b93 \ --duration 30 \ --max-messages 390625 \ --max-vote-options 125 \ @@ -27,11 +27,11 @@ HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js deployPoll \ --vote-option-tree-depth 3 \ -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js signup \ - --pubkey macipk.5e304c40fbf7f84fe09b8a21b6d0454a9606fca1d34977e0b68b8e5fe1c9460a \ + --pubkey macipk.e743ffb5298ef0f5c1f63b6464a48fea19ea7ee5a885c67ae1b24a1d04f03f07 \ -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js publish \ - --pubkey macipk.5e304c40fbf7f84fe09b8a21b6d0454a9606fca1d34977e0b68b8e5fe1c9460a \ - --privkey macisk.251a97d4d2ffde8673102572e530d0293afdc3394e2db8fd5b3029ec00c7c739 \ + --pubkey macipk.e743ffb5298ef0f5c1f63b6464a48fea19ea7ee5a885c67ae1b24a1d04f03f07 \ + --privkey macisk.0ab0281365e01cff60afc62310daec765e590487bf989a7c4986ebc3fd49895e \ --state-index 1 \ --vote-option-index 0 \ --new-vote-weight 9 \ @@ -39,8 +39,8 @@ HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js publish \ --poll-id 0 \ -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js publish \ - --pubkey macipk.5e304c40fbf7f84fe09b8a21b6d0454a9606fca1d34977e0b68b8e5fe1c9460a \ - --privkey macisk.251a97d4d2ffde8673102572e530d0293afdc3394e2db8fd5b3029ec00c7c739 \ + --pubkey macipk.e743ffb5298ef0f5c1f63b6464a48fea19ea7ee5a885c67ae1b24a1d04f03f07 \ + --privkey macisk.0ab0281365e01cff60afc62310daec765e590487bf989a7c4986ebc3fd49895e \ --state-index 1 \ --vote-option-index 1 \ --new-vote-weight 9 \ @@ -51,7 +51,7 @@ HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js timeTravel -s 10 HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js mergeSignups --poll-id 0 -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js mergeMessages --poll-id 0 -q true HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js genProofs \ - --privkey macisk.02115a4e210f81195aec6e6e9375bd1028f89dd873e6ee62bc5af298e13fd2e7 \ + --privkey macisk.1751146b59d32e3c0d7426de411218172428263f93b2fc4d981c036047a4d8c0 \ --poll-id 0 \ --rapidsnark ~/rapidsnark/build/prover \ --process-zkey ./zkeys/processMessages_6-8-2-3.zkey \ diff --git a/domainobjs/package.json b/domainobjs/package.json index dc90d30f69..9085697b2e 100644 --- a/domainobjs/package.json +++ b/domainobjs/package.json @@ -33,7 +33,8 @@ "exclude": [ "**/__tests__/*.ts", "**/*.js", - "**/*.d.ts" + "**/*.d.ts", + "ts/index.ts" ], "branches": ">50%", "lines": ">50%", diff --git a/domainobjs/ts/__tests__/ballot.test.ts b/domainobjs/ts/__tests__/ballot.test.ts index 9483d9a3bf..d7afcb64d0 100644 --- a/domainobjs/ts/__tests__/ballot.test.ts +++ b/domainobjs/ts/__tests__/ballot.test.ts @@ -3,22 +3,117 @@ import { expect } from "chai"; import { Ballot } from ".."; describe("Ballot", () => { - it("should create a new ballot and hash it", () => { - const b = new Ballot(0, 2); - const h = b.hash(); - expect(h).to.not.eq(null); + describe("constructor", () => { + it("should create an empty ballot", () => { + const b = new Ballot(0, 2); + expect(b.votes.length).to.eq(0); + }); + + it("should create a ballot with 1 vote", () => { + const b = new Ballot(1, 2); + expect(b.votes.length).to.eq(1); + expect(b.votes[0]).to.eq(BigInt(0)); + }); + }); + + describe("hash", () => { + it("should produce an hash of the ballot", () => { + const b = new Ballot(0, 2); + const h = b.hash(); + expect(h).to.not.eq(null); + }); + }); + + describe("copy", () => { + it("should produce a deep copy", () => { + const b1 = Ballot.genRandomBallot(2, 2); + const b2 = b1.copy(); + + expect(b1.voteOptionTreeDepth).to.eq(b2.voteOptionTreeDepth); + expect(b1.nonce).to.eq(b2.nonce); + expect(b1.votes.length).to.eq(b2.votes.length); + expect(b1.votes).to.deep.eq(b2.votes); + + expect(b1.equals(b2)).to.eq(true); + }); + }); + + describe("asCircuitInputs", () => { + it("should produce an array", () => { + const len = 2; + const b1 = Ballot.genRandomBallot(len, 2); + const arr = b1.asCircuitInputs(); + expect(arr).to.be.instanceOf(Array); + expect(arr.length).to.eq(len); + }); + }); + + describe("isEqual", () => { + it("should return false for ballots that are not equal (different votes length)", () => { + const b1 = Ballot.genRandomBallot(2, 2); + const b2 = Ballot.genRandomBallot(2, 3); + expect(b1.equals(b2)).to.eq(false); + }); + it("should return true for ballots that are equal", () => { + const b1 = new Ballot(0, 2); + const b2 = new Ballot(0, 2); + expect(b1.equals(b2)).to.eq(true); + }); + it("should return false for ballots that are not equal (different nonce)", () => { + const b1 = Ballot.genRandomBallot(3, 2); + const b2 = Ballot.genRandomBallot(2, 2); + b2.nonce = BigInt(1); + expect(b1.equals(b2)).to.eq(false); + }); + }); + + describe("asArray", () => { + it("should produce a valid result", () => { + const b1 = Ballot.genRandomBallot(2, 2); + b1.votes[0] = BigInt(1); + b1.votes[1] = BigInt(2); + b1.votes[2] = BigInt(3); + const arr = b1.asArray(); + expect(arr[0]).to.eq(b1.nonce); + }); + }); + + describe("genRandomBallot", () => { + it("should generate a ballot with a random nonce", () => { + const b1 = Ballot.genRandomBallot(2, 2); + const b2 = Ballot.genRandomBallot(2, 2); + expect(b1.nonce).to.not.eq(b2.nonce); + }); }); - it("copy should produce a deep copy", () => { - const b1 = Ballot.genRandomBallot(2, 2); - const b2 = b1.copy(); - expect(b1.equals(b2)).to.eq(true); + describe("genBlankBallot", () => { + it("should generate a ballot with all votes set to 0", () => { + const b1 = Ballot.genBlankBallot(2, 2); + expect(b1.votes.every((v) => v === BigInt(0))).to.eq(true); + }); }); - it("asCircuitInputs should produce an array", () => { - const b1 = Ballot.genRandomBallot(2, 2); - const arr = b1.asCircuitInputs(); - expect(arr).to.be.instanceOf(Array); - expect(arr.length).to.eq(2); + describe("serialization/deserialization", () => { + describe("toJSON", () => { + it("toJSON should produce a JSON object representing the ballot", () => { + const b1 = Ballot.genBlankBallot(2, 2); + const json = b1.toJSON(); + expect(json).to.have.property("votes"); + expect(json).to.have.property("nonce"); + expect(json).to.have.property("voteOptionTreeDepth"); + expect(json.votes.length).to.eq(b1.votes.length); + expect(json.nonce).to.eq(b1.nonce.toString()); + expect(json.voteOptionTreeDepth).to.eq(b1.voteOptionTreeDepth.toString()); + }); + }); + + describe("fromJSON", () => { + it("should create a ballot from a JSON object", () => { + const b1 = Ballot.genBlankBallot(2, 2); + const json = b1.toJSON(); + const b2 = Ballot.fromJSON(json); + expect(b1.equals(b2)).to.eq(true); + }); + }); }); }); diff --git a/domainobjs/ts/__tests__/commands.test.ts b/domainobjs/ts/__tests__/commands.test.ts index 531a57b457..1c2e03bad1 100644 --- a/domainobjs/ts/__tests__/commands.test.ts +++ b/domainobjs/ts/__tests__/commands.test.ts @@ -1,120 +1,158 @@ import { expect } from "chai"; import { genRandomSalt } from "maci-crypto"; -import { Keypair, Message, PCommand, TCommand } from ".."; +import { PCommand, Keypair, TCommand } from ".."; -describe("Commands & Messages", () => { +describe("Commands", () => { const { privKey, pubKey } = new Keypair(); - const k = new Keypair(); - const pubKey1 = k.pubKey; - - const newPubKey = k.pubKey; - - const ecdhSharedKey = Keypair.genEcdhSharedKey(privKey, pubKey1); + const ecdhSharedKey = Keypair.genEcdhSharedKey(privKey, pubKey); // eslint-disable-next-line no-bitwise const random50bitBigInt = (): bigint => ((BigInt(1) << BigInt(50)) - BigInt(1)) & BigInt(genRandomSalt().toString()); - const command: PCommand = new PCommand( - random50bitBigInt(), - newPubKey, - random50bitBigInt(), - random50bitBigInt(), - random50bitBigInt(), - random50bitBigInt(), - genRandomSalt(), - ); - const signature = command.sign(privKey); - const message = command.encrypt(signature, ecdhSharedKey); - const decrypted = PCommand.decrypt(message, ecdhSharedKey); - - it("command.sign() should produce a valid signature", () => { - expect(command.verifySignature(signature, pubKey)).to.eq(true); + + describe("constructor", () => { + it("should create a PCommand", () => { + const command: PCommand = new PCommand( + random50bitBigInt(), + pubKey, + random50bitBigInt(), + random50bitBigInt(), + random50bitBigInt(), + random50bitBigInt(), + genRandomSalt(), + ); + expect(command).to.not.eq(null); + }); + it("should create a TCommand", () => { + const command: TCommand = new TCommand(random50bitBigInt(), random50bitBigInt(), random50bitBigInt()); + expect(command).to.not.eq(null); + }); }); - it("decrypted message should match the original command", () => { - expect(decrypted.command.equals(command)).to.eq(true); - expect(decrypted.signature.R8[0].toString()).to.eq(signature.R8[0].toString()); - expect(decrypted.signature.R8[1].toString()).to.eq(signature.R8[1].toString()); - expect(decrypted.signature.S.toString()).to.eq(signature.S.toString()); + describe("signature", () => { + const command: PCommand = new PCommand( + random50bitBigInt(), + pubKey, + random50bitBigInt(), + random50bitBigInt(), + random50bitBigInt(), + random50bitBigInt(), + genRandomSalt(), + ); + it("should produce a valid signature", () => { + const signature = command.sign(privKey); + expect(command.verifySignature(signature, pubKey)).to.eq(true); + }); }); - it("decrypted message should have a valid signature", () => { - const isValid = decrypted.command.verifySignature(decrypted.signature, pubKey); - expect(isValid).to.eq(true); + describe("encryption", () => { + const command: PCommand = new PCommand( + random50bitBigInt(), + pubKey, + random50bitBigInt(), + random50bitBigInt(), + random50bitBigInt(), + random50bitBigInt(), + genRandomSalt(), + ); + + const signature = command.sign(privKey); + + describe("encrypt", () => { + it("should encrypt a command", () => { + const message = command.encrypt(signature, ecdhSharedKey); + expect(message).to.not.eq(null); + }); + }); + + describe("decrypt", () => { + const message = command.encrypt(signature, ecdhSharedKey); + + const decrypted = PCommand.decrypt(message, ecdhSharedKey); + + it("should decrypt a message and keep the correct values", () => { + expect(decrypted).to.not.eq(null); + expect(decrypted.command.equals(command)).to.eq(true); + expect(decrypted.signature.R8[0].toString()).to.eq(signature.R8[0].toString()); + expect(decrypted.signature.R8[1].toString()).to.eq(signature.R8[1].toString()); + expect(decrypted.signature.S.toString()).to.eq(signature.S.toString()); + }); + it("should have a valid signature after decryption", () => { + const isValid = decrypted.command.verifySignature(decrypted.signature, pubKey); + expect(isValid).to.eq(true); + }); + }); }); - it("Command.copy() should produce a deep copy", () => { - const c1: PCommand = new PCommand(BigInt(10), newPubKey, BigInt(0), BigInt(9), BigInt(1), BigInt(123)); + describe("copy", () => { + it("should produce a deep copy for PCommand", () => { + const c1: PCommand = new PCommand(BigInt(10), pubKey, BigInt(0), BigInt(9), BigInt(1), BigInt(123)); - // shallow copy - const c2 = c1; - c1.nonce = BigInt(9999); - expect(c1.nonce.toString()).to.eq(c2.nonce.toString()); + // shallow copy + const c2 = c1; + c1.nonce = BigInt(9999); + expect(c1.nonce.toString()).to.eq(c2.nonce.toString()); - // deep copy - const c3 = c1.copy(); - c1.nonce = BigInt(8888); + // deep copy + const c3 = c1.copy(); + c1.nonce = BigInt(8888); - expect(c1.nonce.toString()).not.to.eq(c3.nonce.toString()); - }); + expect(c1.nonce.toString()).not.to.eq(c3.nonce.toString()); + }); - it("message.copy() should produce a deep copy", () => { - const m1 = new Message(BigInt(1), [ - BigInt(2), - BigInt(3), - BigInt(4), - BigInt(5), - BigInt(6), - BigInt(7), - BigInt(8), - BigInt(9), - BigInt(10), - BigInt(11), - ]); - - const m2 = m1.copy(); - expect(m2.equals(m1)).to.eq(true); - }); + it("should produce a deep copy for TCommand", () => { + const c1: TCommand = new TCommand(BigInt(10), BigInt(0), BigInt(9)); - it("message.asCircuitInputs() should return a array", () => { - const m1 = new Message(BigInt(1), [ - BigInt(2), - BigInt(3), - BigInt(4), - BigInt(5), - BigInt(6), - BigInt(7), - BigInt(8), - BigInt(9), - BigInt(10), - BigInt(11), - ]); - - const arr = m1.asCircuitInputs(); - expect(arr.length).to.eq(11); - expect(arr[0]).to.eq(BigInt(1)); - expect(arr[1]).to.eq(BigInt(2)); - expect(arr[2]).to.eq(BigInt(3)); - expect(arr[3]).to.eq(BigInt(4)); - expect(arr[4]).to.eq(BigInt(5)); - expect(arr[5]).to.eq(BigInt(6)); - expect(arr[6]).to.eq(BigInt(7)); - expect(arr[7]).to.eq(BigInt(8)); - expect(arr[8]).to.eq(BigInt(9)); - expect(arr[9]).to.eq(BigInt(10)); - expect(arr[10]).to.eq(BigInt(11)); - expect(arr).to.be.instanceOf(Array); + // shallow copy + const c2 = c1; + c1.amount = BigInt(9999); + expect(c1.amount.toString()).to.eq(c2.amount.toString()); + + // deep copy + const c3 = c1.copy(); + c1.amount = BigInt(8888); + + expect(c1.amount.toString()).not.to.eq(c3.amount.toString()); + }); }); - describe("TCommand", () => { - const stateIndex = BigInt(0); - const amount = BigInt(100); - const pollId = BigInt(1); - const tCommand = new TCommand(stateIndex, amount, pollId); + describe("deserialization/serialization", () => { + describe("toJSON", () => { + it("should produce a JSON object with valid values", () => { + const c1: TCommand = new TCommand(BigInt(10), BigInt(0), BigInt(9)); + const json = c1.toJSON(); + expect(json).to.not.eq(null); + expect(json.cmdType).to.eq("2"); + expect(json.stateIndex).to.eq("10"); + expect(json.amount).to.eq("0"); + expect(json.pollId).to.eq("9"); + }); + it("should produce a JSON object with valid values", () => { + const c1: PCommand = new PCommand(BigInt(10), pubKey, BigInt(0), BigInt(9), BigInt(1), BigInt(123)); + const json = c1.toJSON(); + expect(json).to.not.eq(null); + expect(json.stateIndex).to.eq("10"); + expect(json.voteOptionIndex).to.eq("0"); + expect(json.newVoteWeight).to.eq("9"); + expect(json.nonce).to.eq("1"); + expect(json.pollId).to.eq("123"); + expect(json.cmdType).to.eq("1"); + }); + }); - it("copy should produce a deep copy", () => { - const c = tCommand.copy(); - expect(c.equals(tCommand)).to.eq(true); + describe("fromJSON", () => { + it("should produce a TCommand from a JSON object", () => { + const c1: TCommand = new TCommand(BigInt(10), BigInt(0), BigInt(9)); + const json = c1.toJSON(); + const c2 = TCommand.fromJSON(json); + expect(c2.equals(c1)).to.eq(true); + }); + it("should produce a PCommand from a JSON object", () => { + const c1: PCommand = new PCommand(BigInt(10), pubKey, BigInt(0), BigInt(9), BigInt(1), BigInt(123)); + const json = c1.toJSON(); + const c2 = PCommand.fromJSON(json); + expect(c2.equals(c1)).to.eq(true); + }); }); }); }); diff --git a/domainobjs/ts/__tests__/keypair.test.ts b/domainobjs/ts/__tests__/keypair.test.ts index 458d7617f5..ce68864bed 100644 --- a/domainobjs/ts/__tests__/keypair.test.ts +++ b/domainobjs/ts/__tests__/keypair.test.ts @@ -1,66 +1,119 @@ import { expect } from "chai"; -import { genKeypair } from "maci-crypto"; +import { genKeypair, genPrivKey } from "maci-crypto"; import { Keypair, PrivKey } from ".."; describe("keypair", () => { - it("the Keypair constructor should generate a random keypair if not provided a private key", () => { - const k1 = new Keypair(); - const k2 = new Keypair(); + describe("constructor", () => { + it("should generate a random keypair if not provided a private key", () => { + const k1 = new Keypair(); + const k2 = new Keypair(); - expect(k1.equals(k2)).to.eq(false); + expect(k1.equals(k2)).to.eq(false); - expect(k1.privKey.rawPrivKey).not.to.eq(k2.privKey.rawPrivKey); - }); + expect(k1.privKey.rawPrivKey).not.to.eq(k2.privKey.rawPrivKey); + }); - it("the Keypair constructor should generate the correct public key given a private key", () => { - const rawKeyPair = genKeypair(); - const k = new Keypair(new PrivKey(rawKeyPair.privKey)); - expect(rawKeyPair.pubKey[0]).to.eq(k.pubKey.rawPubKey[0]); - expect(rawKeyPair.pubKey[1]).to.eq(k.pubKey.rawPubKey[1]); + it("should generate the correct public key given a private key", () => { + const rawKeyPair = genKeypair(); + const k = new Keypair(new PrivKey(rawKeyPair.privKey)); + expect(rawKeyPair.pubKey[0]).to.eq(k.pubKey.rawPubKey[0]); + expect(rawKeyPair.pubKey[1]).to.eq(k.pubKey.rawPubKey[1]); + }); }); - it("should return false for two completely different keypairs", () => { - const k1 = new Keypair(); - const k2 = new Keypair(); - expect(k1.equals(k2)).to.eq(false); - }); + describe("equals", () => { + it("should return false for two completely different keypairs", () => { + const k1 = new Keypair(); + const k2 = new Keypair(); + expect(k1.equals(k2)).to.eq(false); + }); - it("should return false for two keypairs with different private keys", () => { - const k1 = new Keypair(); - const k2 = new Keypair(); - k2.privKey.rawPrivKey = BigInt(0); - expect(k1.equals(k2)).to.eq(false); - }); - it("should return false for two keypairs with different public keys", () => { - const k1 = new Keypair(); - const k2 = new Keypair(); - k2.pubKey.rawPubKey[0] = BigInt(0); - expect(k1.equals(k2)).to.eq(false); + it("should return false for two keypairs with different private keys", () => { + const privateKey = new PrivKey(genPrivKey()); + const privateKey2 = new PrivKey(genPrivKey()); + const k1 = new Keypair(privateKey); + const k2 = new Keypair(privateKey2); + expect(k1.equals(k2)).to.eq(false); + }); + it("should throw when the private keys are equal but the public keys are not", () => { + const privateKey = new PrivKey(genPrivKey()); + const k1 = new Keypair(privateKey); + const k2 = new Keypair(privateKey); + k2.pubKey.rawPubKey[0] = BigInt(9); + expect(() => k1.equals(k2)).to.throw(); + }); + it("should return true for two identical keypairs", () => { + const k1 = new Keypair(); + const k2 = k1.copy(); + expect(k1.equals(k2)).to.eq(true); + }); }); - it("should return true for two identical keypairs", () => { - const k1 = new Keypair(); - const k2 = k1.copy(); - expect(k1.equals(k2)).to.eq(true); - }); + describe("copy", () => { + it("should produce a deep copy", () => { + const k1 = new Keypair(); + + // shallow copy + const k2 = k1; - it("copy should produce a deep copy", () => { - const k1 = new Keypair(); + expect(k1.privKey.rawPrivKey.toString()).to.eq(k2.privKey.rawPrivKey.toString()); + k1.privKey.rawPrivKey = BigInt(0); + expect(k1.privKey.rawPrivKey.toString()).to.eq(k2.privKey.rawPrivKey.toString()); - // shallow copy - const k2 = k1; + // deep copy + const k3 = new Keypair(); + const k4 = k3.copy(); + expect(k3.privKey.rawPrivKey.toString()).to.eq(k4.privKey.rawPrivKey.toString()); + + k3.privKey.rawPrivKey = BigInt(0); + expect(k3.privKey.rawPrivKey.toString()).not.to.eq(k4.privKey.rawPrivKey.toString()); + }); + }); + + describe("genEcdhSharedKey", () => { + it("should produce a shared key", () => { + const k1 = new Keypair(); + const k2 = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(k1.privKey, k2.pubKey); + expect(sharedKey).to.not.eq(null); + }); + }); - expect(k1.privKey.rawPrivKey.toString()).to.eq(k2.privKey.rawPrivKey.toString()); - k1.privKey.rawPrivKey = BigInt(0); - expect(k1.privKey.rawPrivKey.toString()).to.eq(k2.privKey.rawPrivKey.toString()); + describe("serialization/deserialization", () => { + describe("toJSON", () => { + it("should produce a JSON object", () => { + const k1 = new Keypair(); + const json = k1.toJSON(); + expect(json).to.not.eq(null); + }); + it("should produce a JSON object with the correct keys", () => { + const k1 = new Keypair(); + const json = k1.toJSON(); + expect(Object.keys(json)).to.deep.eq(["privKey", "pubKey"]); + }); + it("should preserve the data correctly", () => { + const k1 = new Keypair(); + const json = k1.toJSON(); - // deep copy - const k3 = new Keypair(); - const k4 = k3.copy(); - expect(k3.privKey.rawPrivKey.toString()).to.eq(k4.privKey.rawPrivKey.toString()); + expect(k1.privKey.serialize()).to.eq(json.privKey); + expect(k1.pubKey.serialize()).to.eq(json.pubKey); + }); + }); - k3.privKey.rawPrivKey = BigInt(0); - expect(k3.privKey.rawPrivKey.toString()).not.to.eq(k4.privKey.rawPrivKey.toString()); + describe("fromJSON", () => { + it("should produce a Keypair instance", () => { + const k1 = new Keypair(); + const json = k1.toJSON(); + const k2 = Keypair.fromJSON(json); + expect(k2).to.be.instanceOf(Keypair); + }); + it("should preserve the data correctly", () => { + const k1 = new Keypair(); + const json = k1.toJSON(); + const k2 = Keypair.fromJSON(json); + expect(k1.equals(k2)).to.eq(true); + }); + }); }); }); diff --git a/domainobjs/ts/__tests__/message.test.ts b/domainobjs/ts/__tests__/message.test.ts new file mode 100644 index 0000000000..5491e98074 --- /dev/null +++ b/domainobjs/ts/__tests__/message.test.ts @@ -0,0 +1,120 @@ +import { expect } from "chai"; + +import { Message, Keypair } from ".."; + +describe("message", () => { + describe("constructor", () => { + it("should create a new message", () => { + const msg = new Message(BigInt(0), Array(10).fill(BigInt(0))); + expect(msg).to.not.eq(null); + }); + it("should throw an error if the data length is not 10", () => { + expect(() => new Message(BigInt(0), Array(9).fill(BigInt(0)))).to.throw(); + }); + }); + + describe("asCircuitInputs", () => { + it("should produce an array", () => { + const msg = new Message(BigInt(0), Array(10).fill(BigInt(0))); + const arr = msg.asCircuitInputs(); + expect(arr).to.be.instanceOf(Array); + expect(arr.length).to.eq(11); + expect(arr).to.deep.eq([BigInt(0), ...Array(10).fill(BigInt(0))]); + }); + }); + + describe("asContractParam", () => { + it("should produce an object", () => { + const msg = new Message(BigInt(0), Array(10).fill(BigInt(0))); + const obj = msg.asContractParam(); + expect(obj).to.be.instanceOf(Object); + expect(Object.keys(obj)).to.deep.eq(["msgType", "data"]); + }); + it("should produce an object with the correct values", () => { + const msg = new Message(BigInt(0), Array(10).fill(BigInt(0))); + const obj = msg.asContractParam(); + expect(obj.msgType).to.eq("0"); + expect(obj.data).to.deep.eq(Array(10).fill("0")); + }); + }); + + describe("hash", () => { + const keypair = new Keypair(); + it("should produce a hash", () => { + const msg = new Message(BigInt(0), Array(10).fill(BigInt(0))); + const h = msg.hash(keypair.pubKey); + expect(h).to.not.eq(null); + }); + it("should produce the same hash for the same ballot", () => { + const msg1 = new Message(BigInt(0), Array(10).fill(BigInt(0))); + const msg2 = new Message(BigInt(0), Array(10).fill(BigInt(0))); + const h1 = msg1.hash(keypair.pubKey); + const h2 = msg2.hash(keypair.pubKey); + expect(h1).to.eq(h2); + }); + }); + describe("copy", () => { + it("should produce a deep copy", () => { + const msg1 = new Message(BigInt(0), Array(10).fill(BigInt(0))); + const msg2 = msg1.copy(); + expect(msg1.equals(msg2)).to.eq(true); + expect(msg1.data).to.deep.eq(msg2.data); + expect(msg1.msgType).to.eq(msg2.msgType); + }); + }); + describe("equals", () => { + it("should return false for messages that are not equal (different length)", () => { + const msg1 = new Message(BigInt(0), Array(10).fill(BigInt(0))); + const msg2 = new Message(BigInt(0), Array(10).fill(BigInt(0))); + msg1.data[10] = BigInt(1); + expect(msg1.equals(msg2)).to.eq(false); + }); + it("should return true for messages that are equal", () => { + const msg1 = new Message(BigInt(0), Array(10).fill(BigInt(0))); + const msg2 = new Message(BigInt(0), Array(10).fill(BigInt(0))); + expect(msg1.equals(msg2)).to.eq(true); + }); + it("should return false when the message type is not equal", () => { + const msg1 = new Message(BigInt(0), Array(10).fill(BigInt(0))); + const msg2 = new Message(BigInt(1), Array(10).fill(BigInt(0))); + expect(msg1.equals(msg2)).to.eq(false); + }); + }); + + describe("serialization/deserialization", () => { + describe("toJSON", () => { + it("should produce a JSON object", () => { + const msg = new Message(BigInt(0), Array(10).fill(BigInt(0))); + const json = msg.toJSON(); + expect(json).to.not.eq(null); + }); + it("should produce a JSON object with the correct keys", () => { + const msg = new Message(BigInt(0), Array(10).fill(BigInt(0))); + const json = msg.toJSON(); + expect(Object.keys(json)).to.deep.eq(["msgType", "data"]); + }); + it("should preserve the data correctly", () => { + const msg = new Message(BigInt(0), Array(10).fill(BigInt(0))); + const json = msg.toJSON(); + + expect(msg.msgType.toString()).to.eq(json.msgType); + expect(msg.data.map((x: bigint) => x.toString())).to.deep.eq(json.data); + }); + }); + + describe("fromJSON", () => { + it("should produce a Message instance", () => { + const msg = new Message(BigInt(0), Array(10).fill(BigInt(0))); + const json = msg.toJSON(); + const msg2 = Message.fromJSON(json); + expect(msg2).to.be.instanceOf(Message); + }); + it("should preserve the data correctly", () => { + const msg = new Message(BigInt(0), Array(10).fill(BigInt(0))); + const json = msg.toJSON(); + const msg2 = Message.fromJSON(json); + expect(msg.equals(msg2)).to.eq(true); + }); + }); + }); +}); diff --git a/domainobjs/ts/__tests__/privateKey.test.ts b/domainobjs/ts/__tests__/privateKey.test.ts index 68aff0fa37..5f905a1075 100644 --- a/domainobjs/ts/__tests__/privateKey.test.ts +++ b/domainobjs/ts/__tests__/privateKey.test.ts @@ -1,54 +1,128 @@ import { expect } from "chai"; +import { SNARK_FIELD_SIZE, genRandomBabyJubValue } from "maci-crypto"; import { Keypair, PrivKey } from ".."; -describe("privateKey", () => { - it("PrivKey.serialize() and deserialize() should work correctly", () => { - const k = new Keypair(); - const sk1 = k.privKey; +describe("privateKey", function test() { + this.timeout(90000); - const s = sk1.serialize(); - expect(s.startsWith("macisk.")).to.eq(true); - const d = `0x${s.slice(7)}`; - expect(sk1.rawPrivKey.toString()).to.eq(BigInt(d).toString()); - - const c = PrivKey.deserialize(s); - expect(sk1.rawPrivKey.toString()).to.eq(BigInt(`${c.rawPrivKey}`).toString()); + describe("constructor", () => { + it("should create a private key", () => { + const priv = genRandomBabyJubValue(); + const k = new PrivKey(priv); + expect(k).to.not.eq(null); + }); + it("should create the same private key object for the same raw key", () => { + const priv = genRandomBabyJubValue(); + const k1 = new PrivKey(priv); + const k2 = new PrivKey(priv); + expect(k1.rawPrivKey.toString()).to.eq(k2.rawPrivKey.toString()); + }); }); - it("PrivKey.isValidSerializedPrivKey() should work correctly", () => { - const k = new Keypair(); - const s = k.privKey.serialize(); + describe("serialization", () => { + describe("serialize", () => { + it("should serialize the private key", () => { + const priv = genRandomBabyJubValue(); + const k = new PrivKey(priv); + const s = k.serialize(); + expect(s.startsWith("macisk.")).to.eq(true); + const d = `0x${s.slice(7)}`; + expect(priv.toString()).to.eq(BigInt(d).toString()); + }); + + it("should always return a key with the same length", () => { + for (let i = 0; i < 100; i += 1) { + const k = new Keypair(); + const s = k.privKey.serialize(); + expect(s.length).to.eq(71); + } + }); + }); + + describe("deserialize", () => { + it("should deserialize the private key", () => { + const priv = genRandomBabyJubValue(); + const k = new PrivKey(priv); + const s = k.serialize(); + const k2 = PrivKey.deserialize(s); + expect(k.rawPrivKey.toString()).to.eq(k2.rawPrivKey.toString()); + }); + }); + + describe("isValidSerializedPrivKey", () => { + it("should return true for a valid serialized private key", () => { + const priv = genRandomBabyJubValue(); + const k = new PrivKey(priv); + const s = k.serialize(); + expect(PrivKey.isValidSerializedPrivKey(s)).to.eq(true); + }); + it("should return false for an invalid serialized private key", () => { + const s = "macisk.0x1234567890"; + expect(PrivKey.isValidSerializedPrivKey(s)).to.eq(false); + }); + }); - expect(PrivKey.isValidSerializedPrivKey(s)).to.eq(true); - expect(PrivKey.isValidSerializedPrivKey(s.slice(1))).to.eq(false); + describe("toJSON", () => { + it("should produce a JSON object", () => { + const priv = genRandomBabyJubValue(); + const k = new PrivKey(priv); + const json = k.toJSON(); + expect(json).to.not.eq(null); + }); + it("should produce a JSON object with the correct keys", () => { + const priv = genRandomBabyJubValue(); + const k = new PrivKey(priv); + const json = k.toJSON(); + expect(Object.keys(json)).to.deep.eq(["privKey"]); + }); + it("should preserve the data correctly", () => { + const priv = genRandomBabyJubValue(); + const k = new PrivKey(priv); + const json = k.toJSON(); + expect(k.serialize()).to.eq(json.privKey); + }); + }); + + describe("fromJSON", () => { + it("should produce a PrivKey instance", () => { + const priv = genRandomBabyJubValue(); + const k = new PrivKey(priv); + const json = k.toJSON(); + const k2 = PrivKey.fromJSON(json); + expect(k2).to.be.instanceOf(PrivKey); + }); + }); }); - it("PrivKey.serialize() should always return a key with the same length", () => { - for (let i = 100; i < 100; i += 1) { + describe("copy", () => { + it("should produce a deep copy", () => { const k = new Keypair(); - const s = k.privKey.serialize(); - expect(s.length).to.eq(54); - } - }); + const sk1 = k.privKey; - it("PrivKey.copy() should produce a deep copy", () => { - const k = new Keypair(); - const sk1 = k.privKey; + // shallow copy + const sk2 = sk1; - // shallow copy - const sk2 = sk1; + expect(sk1.rawPrivKey.toString()).to.eq(sk2.rawPrivKey.toString()); + sk1.rawPrivKey = BigInt(0); + expect(sk1.rawPrivKey.toString()).to.eq(sk2.rawPrivKey.toString()); - expect(sk1.rawPrivKey.toString()).to.eq(sk2.rawPrivKey.toString()); - sk1.rawPrivKey = BigInt(0); - expect(sk1.rawPrivKey.toString()).to.eq(sk2.rawPrivKey.toString()); + // deep copy + const k1 = new Keypair(); + const sk3 = k1.privKey; + const sk4 = sk3.copy(); + expect(sk3.rawPrivKey.toString()).to.eq(sk4.rawPrivKey.toString()); + sk4.rawPrivKey = BigInt(0); + expect(sk3.rawPrivKey.toString()).not.to.eq(sk4.rawPrivKey.toString()); + }); + }); - // deep copy - const k1 = new Keypair(); - const sk3 = k1.privKey; - const sk4 = sk3.copy(); - expect(sk3.rawPrivKey.toString()).to.eq(sk4.rawPrivKey.toString()); - sk4.rawPrivKey = BigInt(0); - expect(sk3.rawPrivKey.toString()).not.to.eq(sk4.rawPrivKey.toString()); + describe("asCircuitInputs", () => { + it("should generate a value that is < SNARK_FIELD_SIZE", () => { + const k = new Keypair(); + const sk = k.privKey; + const circuitInputs = sk.asCircuitInputs(); + expect(BigInt(circuitInputs) < SNARK_FIELD_SIZE).to.eq(true); + }); }); }); diff --git a/domainobjs/ts/__tests__/publicKey.test.ts b/domainobjs/ts/__tests__/publicKey.test.ts index 4e63e7d902..21f2288607 100644 --- a/domainobjs/ts/__tests__/publicKey.test.ts +++ b/domainobjs/ts/__tests__/publicKey.test.ts @@ -1,49 +1,190 @@ import { expect } from "chai"; -import { unpackPubKey } from "maci-crypto"; +import { SNARK_FIELD_SIZE, unpackPubKey } from "maci-crypto"; import { Keypair, PubKey } from ".."; describe("public key", () => { - it("isValidSerializedPubKey() should work correctly", () => { - const k = new Keypair(); - const s = k.pubKey.serialize(); + describe("constructor", () => { + it("should create a public key", () => { + const k = new Keypair(); + const pk = new PubKey(k.pubKey.rawPubKey); + expect(pk).to.not.eq(null); + }); + it("should create the same public key object for the same raw key", () => { + const k = new Keypair(); + const pk1 = new PubKey(k.pubKey.rawPubKey); + const pk2 = new PubKey(k.pubKey.rawPubKey); + expect(pk1.rawPubKey.toString()).to.eq(pk2.rawPubKey.toString()); + }); + it("should fail to create a public key if the raw key is invalid", () => { + expect(() => new PubKey([BigInt(0), BigInt(SNARK_FIELD_SIZE)])).to.throw(); + expect(() => new PubKey([BigInt(SNARK_FIELD_SIZE), BigInt(0)])).to.throw(); + expect(() => new PubKey([BigInt(SNARK_FIELD_SIZE), BigInt(SNARK_FIELD_SIZE)])).to.throw(); + }); + }); + + describe("copy", () => { + it("should produce a deep copy", () => { + const k = new Keypair(); + const pk1 = k.pubKey; + + // shallow copy + const pk2 = pk1; + + expect(pk1.rawPubKey.toString()).to.eq(pk2.rawPubKey.toString()); + pk1.rawPubKey = [BigInt(0), BigInt(0)]; + expect(pk1.rawPubKey.toString()).to.eq(pk2.rawPubKey.toString()); - expect(PubKey.isValidSerializedPubKey(s)).to.eq(true); - expect(PubKey.isValidSerializedPubKey(`${s}ffffffffffffffffffffffffffffff`)).to.eq(false); - expect(PubKey.isValidSerializedPubKey(s.slice(1))).to.eq(false); + // deep copy + const k1 = new Keypair(); + const pk3 = k1.pubKey; + const pk4 = pk3.copy(); + expect(pk3.rawPubKey.toString()).to.eq(pk4.rawPubKey.toString()); + pk4.rawPubKey = [BigInt(0), BigInt(0)]; + expect(pk3.rawPubKey.toString()).not.to.eq(pk4.rawPubKey.toString()); + }); }); - it("serialize() and deserialize() should work correctly", () => { - const k = new Keypair(); - const pk1 = k.pubKey; + describe("serialization", () => { + describe("serialize", () => { + it("should serialize into a string", () => { + const k = new Keypair(); + const pk1 = k.pubKey; + + const s = pk1.serialize(); + expect(s.startsWith("macipk.")).to.eq(true); + + const unpacked = unpackPubKey(BigInt(`0x${s.slice(7).toString()}`)); + + expect(unpacked[0].toString()).to.eq(pk1.rawPubKey[0].toString()); + expect(unpacked[1].toString()).to.eq(pk1.rawPubKey[1].toString()); + }); + it("should serialize into an invalid serialized key when the key is [bigint(0), bigint(0)]", () => { + const pk1 = new PubKey([BigInt(0), BigInt(0)]); + const s = pk1.serialize(); + expect(s).to.eq("macipk.z"); + }); + }); - const s = pk1.serialize(); - expect(s.startsWith("macipk.")).to.eq(true); + describe("deserialize", () => { + it("should deserialize the public key", () => { + const k = new Keypair(); + const pk1 = k.pubKey; + const s = pk1.serialize(); + const pk2 = PubKey.deserialize(s); + expect(pk1.rawPubKey.toString()).to.eq(pk2.rawPubKey.toString()); + }); + it("should deserialize into an invalid serialized key when the key is equal to macipk.z", () => { + const pk1 = PubKey.deserialize("macipk.z"); + expect(pk1.rawPubKey.toString()).to.eq([BigInt(0), BigInt(0)].toString()); + }); + }); - const d = s.slice(7); - const unpacked = unpackPubKey(BigInt(`0x${d.toString()}`)); + describe("isValidSerializedPubKey", () => { + const k = new Keypair(); + const s = k.pubKey.serialize(); + it("should return true for keys that are serialized in the correct format", () => { + expect(PubKey.isValidSerializedPubKey(s)).to.eq(true); + }); - expect(unpacked[0].toString()).to.eq(pk1.rawPubKey[0].toString()); - expect(unpacked[1].toString()).to.eq(pk1.rawPubKey[1].toString()); + it("should return false for keys that are not serialized in the correct format", () => { + expect(PubKey.isValidSerializedPubKey(`${s}ffffffffffffffffffffffffffffff`)).to.eq(false); + expect(PubKey.isValidSerializedPubKey(s.slice(1))).to.eq(false); + }); + }); + + describe("toJSON", () => { + it("should produce a JSON object", () => { + const k = new Keypair(); + const pk1 = k.pubKey; + const json = pk1.toJSON(); + expect(json).to.not.eq(null); + }); + it("should produce a JSON object with the correct keys", () => { + const k = new Keypair(); + const pk1 = k.pubKey; + const json = pk1.toJSON(); + expect(Object.keys(json)).to.deep.eq(["pubKey"]); + }); + it("should preserve the data correctly", () => { + const k = new Keypair(); + const pk1 = k.pubKey; + const json = pk1.toJSON(); + + expect(pk1.serialize()).to.eq(json.pubKey); + }); + }); + describe("fromJSON", () => { + it("should produce a public key", () => { + const k = new Keypair(); + const pk1 = k.pubKey; + const json = pk1.toJSON(); + const pk2 = PubKey.fromJSON(json); + expect(pk2).to.not.eq(null); + }); + it("should produce the same public key object for the same raw key", () => { + const k = new Keypair(); + const pk1 = k.pubKey; + const json = pk1.toJSON(); + const pk2 = PubKey.fromJSON(json); + expect(pk1.rawPubKey.toString()).to.eq(pk2.rawPubKey.toString()); + }); + }); }); - it("copy() should produce a deep copy", () => { - const k = new Keypair(); - const pk1 = k.pubKey; + describe("asContractParam", () => { + it("should produce an object with the correct values", () => { + const k = new Keypair(); + const pk1 = k.pubKey; + const obj = pk1.asContractParam(); + expect(obj.x).to.eq(pk1.rawPubKey[0].toString()); + expect(obj.y).to.eq(pk1.rawPubKey[1].toString()); + }); + }); - // shallow copy - const pk2 = pk1; + describe("asCircuitInputs", () => { + it("should produce an array with the two points of the public key", () => { + const k = new Keypair(); + const pk1 = k.pubKey; + const arr = pk1.asCircuitInputs(); + expect(arr).to.be.instanceOf(Array); + expect(arr.length).to.eq(2); + }); + }); - expect(pk1.rawPubKey.toString()).to.eq(pk2.rawPubKey.toString()); - pk1.rawPubKey = [BigInt(0), BigInt(0)]; - expect(pk1.rawPubKey.toString()).to.eq(pk2.rawPubKey.toString()); + describe("asArray", () => { + it("should produce an array with the two points of the public key", () => { + const k = new Keypair(); + const pk1 = k.pubKey; + const arr = pk1.asArray(); + expect(arr).to.be.instanceOf(Array); + expect(arr.length).to.eq(2); + expect(arr).to.deep.eq(pk1.rawPubKey); + }); + }); + + describe("hash", () => { + it("should produce a hash", () => { + const k = new Keypair(); + const pk1 = k.pubKey; + const h = pk1.hash(); + expect(h).to.not.eq(null); + }); + }); - // deep copy - const k1 = new Keypair(); - const pk3 = k1.pubKey; - const pk4 = pk3.copy(); - expect(pk3.rawPubKey.toString()).to.eq(pk4.rawPubKey.toString()); - pk4.rawPubKey = [BigInt(0), BigInt(0)]; - expect(pk3.rawPubKey.toString()).not.to.eq(pk4.rawPubKey.toString()); + describe("equals", () => { + it("should return false for public keys that are not equal", () => { + const k1 = new Keypair(); + const pk1 = k1.pubKey; + const k2 = new Keypair(); + const pk2 = k2.pubKey; + expect(pk1.equals(pk2)).to.eq(false); + }); + it("should return true for public keys that are equal", () => { + const k1 = new Keypair(); + const pk1 = k1.pubKey; + const pk2 = pk1.copy(); + expect(pk1.equals(pk2)).to.eq(true); + }); }); }); diff --git a/domainobjs/ts/__tests__/stateLeaf.test.ts b/domainobjs/ts/__tests__/stateLeaf.test.ts index 6482695103..826b6e8250 100644 --- a/domainobjs/ts/__tests__/stateLeaf.test.ts +++ b/domainobjs/ts/__tests__/stateLeaf.test.ts @@ -2,54 +2,139 @@ import { expect } from "chai"; import { Keypair, StateLeaf } from ".."; -describe("State leaves", () => { +describe("stateLeaf", () => { const { pubKey } = new Keypair(); - it("serialize() and deserialize() functions should work correctly", () => { - const stateLeaf = new StateLeaf(pubKey, BigInt(123), BigInt(1231267)); - - const serialized = stateLeaf.serialize(); - const deserialized = StateLeaf.deserialize(serialized); - - expect(deserialized.voiceCreditBalance.toString()).to.eq(stateLeaf.voiceCreditBalance.toString()); + describe("constructor", () => { + it("should create a state leaf", () => { + const stateLeaf = new StateLeaf(pubKey, BigInt(123), BigInt(1231267)); + expect(stateLeaf).to.not.eq(null); + expect(stateLeaf.pubKey.equals(pubKey)).to.eq(true); + expect(stateLeaf.voiceCreditBalance).to.eq(BigInt(123)); + expect(stateLeaf.timestamp).to.eq(BigInt(1231267)); + }); }); - it("copy should create an exact copy of the state leaf", () => { - const stateLeaf = new StateLeaf(pubKey, BigInt(123), BigInt(1231267)); + describe("copy", () => { + it("should create an exact copy of the state leaf", () => { + const stateLeaf = new StateLeaf(pubKey, BigInt(123), BigInt(1231267)); - const copy = stateLeaf.copy(); + const copy = stateLeaf.copy(); - expect(stateLeaf.equals(copy)).to.eq(true); + expect(stateLeaf.equals(copy)).to.eq(true); + }); }); - it("genRandomLeaf should return a random leaf", () => { - const randomLeaf = StateLeaf.genRandomLeaf(); - const randomLeaf2 = StateLeaf.genRandomLeaf(); - expect(randomLeaf.equals(randomLeaf2)).to.eq(false); + describe("genBlankLeaf", () => { + it("should return a blank leaf", () => { + const blankLeaf = StateLeaf.genBlankLeaf(); + expect(blankLeaf.pubKey.rawPubKey[0]).to.eq( + BigInt("10457101036533406547632367118273992217979173478358440826365724437999023779287"), + ); + expect(blankLeaf.pubKey.rawPubKey[1]).to.eq( + BigInt("19824078218392094440610104313265183977899662750282163392862422243483260492317"), + ); + expect(blankLeaf.voiceCreditBalance).to.eq(BigInt(0)); + expect(blankLeaf.timestamp).to.eq(BigInt(0)); + }); }); - it("asCircuitInputs should return an array", () => { - const stateLeaf = new StateLeaf(pubKey, BigInt(123), BigInt(1231267)); + describe("genRandomLeaf", () => { + it("should return a random leaf", () => { + const randomLeaf = StateLeaf.genRandomLeaf(); + const randomLeaf2 = StateLeaf.genRandomLeaf(); + expect(randomLeaf.equals(randomLeaf2)).to.eq(false); + }); + }); + + describe("equals", () => { + it("should return true when comparing two equal state leaves", () => { + const stateLeaf = new StateLeaf(pubKey, BigInt(123), BigInt(1231267)); + + const stateLeaf2 = new StateLeaf(pubKey, BigInt(123), BigInt(1231267)); - const arr = stateLeaf.asCircuitInputs(); - expect(arr).to.be.instanceOf(Array); - expect(arr.length).to.be.gt(0); - expect(arr.length).to.eq(4); + expect(stateLeaf.equals(stateLeaf2)).to.eq(true); + }); + + it("should return false when comparing two different state leaves", () => { + const stateLeaf = new StateLeaf(pubKey, BigInt(123), BigInt(1231267)); + + const stateLeaf2 = new StateLeaf(pubKey, BigInt(123), BigInt(1231268)); + + expect(stateLeaf.equals(stateLeaf2)).to.eq(false); + }); }); - it("equals should return true when comparing two equal state leaves", () => { - const stateLeaf = new StateLeaf(pubKey, BigInt(123), BigInt(1231267)); + describe("serialization", () => { + describe("serialize", () => { + it("should work correctly", () => { + const stateLeaf = new StateLeaf(pubKey, BigInt(123), BigInt(1231267)); + + const serialized = stateLeaf.serialize(); + expect(serialized).to.not.eq(null); + }); + }); + + describe("deserialize", () => { + it("should work correctly", () => { + const stateLeaf = new StateLeaf(pubKey, BigInt(123), BigInt(1231267)); + + const serialized = stateLeaf.serialize(); + const deserialized = StateLeaf.deserialize(serialized); + expect(deserialized.equals(stateLeaf)).to.eq(true); + }); + }); + + describe("toJSON", () => { + it("should produce an object with the correct properities", () => { + const stateLeaf = new StateLeaf(pubKey, BigInt(123), BigInt(1231267)); + + const json = stateLeaf.toJSON(); + expect(json).to.not.eq(null); + + expect(Object.keys(json)).to.deep.eq(["pubKey", "voiceCreditBalance", "timestamp"]); + }); + }); + + describe("fromJSON", () => { + it("should produce a state leaf from a JSON object", () => { + const stateLeaf = new StateLeaf(pubKey, BigInt(123), BigInt(1231267)); + + const json = stateLeaf.toJSON(); + const deserialized = StateLeaf.fromJSON(json); + expect(deserialized.equals(stateLeaf)).to.eq(true); + }); + }); + }); - const stateLeaf2 = new StateLeaf(pubKey, BigInt(123), BigInt(1231267)); + describe("asCircuitInputs", () => { + it("should return an array", () => { + const stateLeaf = new StateLeaf(pubKey, BigInt(123), BigInt(1231267)); - expect(stateLeaf.equals(stateLeaf2)).to.eq(true); + const arr = stateLeaf.asCircuitInputs(); + expect(arr).to.be.instanceOf(Array); + expect(arr.length).to.eq(4); + }); }); - it("equals should return false when comparing two different state leaves", () => { - const stateLeaf = new StateLeaf(pubKey, BigInt(123), BigInt(1231267)); + describe("asContractParam", () => { + it("should return an object with the correct properties and values", () => { + const stateLeaf = new StateLeaf(pubKey, BigInt(123), BigInt(1231267)); + const obj = stateLeaf.asContractParam(); + expect(obj).to.not.eq(null); + expect(Object.keys(obj)).to.deep.eq(["pubKey", "voiceCreditBalance", "timestamp"]); + expect(obj.pubKey).to.deep.eq(pubKey.asContractParam()); + expect(obj.voiceCreditBalance).to.eq("123"); + expect(obj.timestamp).to.eq("1231267"); + }); + }); - const stateLeaf2 = new StateLeaf(pubKey, BigInt(123), BigInt(1231268)); + describe("hash", () => { + it("should hash into a single bigint value which is not null", () => { + const stateLeaf = new StateLeaf(pubKey, BigInt(123), BigInt(1231267)); - expect(stateLeaf.equals(stateLeaf2)).to.eq(false); + const hash = stateLeaf.hash(); + expect(hash).to.not.eq(null); + }); }); }); diff --git a/domainobjs/ts/__tests__/verifyingKey.test.ts b/domainobjs/ts/__tests__/verifyingKey.test.ts index 237f724e98..4672b41196 100644 --- a/domainobjs/ts/__tests__/verifyingKey.test.ts +++ b/domainobjs/ts/__tests__/verifyingKey.test.ts @@ -1,4 +1,5 @@ import { expect } from "chai"; +import { G1Point } from "maci-crypto"; import fs from "fs"; import path from "path"; @@ -6,43 +7,129 @@ import path from "path"; import { IVkObjectParams, VerifyingKey } from ".."; describe("verifyingKey", () => { - it("Should convert a JSON file from snarkjs to a VerifyingKey", () => { - const file = path.join(__dirname, "./artifacts/test_vk.json"); - const j = fs.readFileSync(file).toString(); - const d = JSON.parse(j) as IVkObjectParams; - const vk = VerifyingKey.fromJSON(j); - - expect(d.vk_alpha_1[0]).to.eq(vk.alpha1.x.toString()); - expect(d.vk_alpha_1[1]).to.eq(vk.alpha1.y.toString()); - - expect(d.vk_beta_2[0][0]).to.eq(vk.beta2.x[1].toString()); - expect(d.vk_beta_2[0][1]).to.eq(vk.beta2.x[0].toString()); - expect(d.vk_beta_2[1][0]).to.eq(vk.beta2.y[1].toString()); - expect(d.vk_beta_2[1][1]).to.eq(vk.beta2.y[0].toString()); - - expect(d.vk_gamma_2[0][0]).to.eq(vk.gamma2.x[1].toString()); - expect(d.vk_gamma_2[0][1]).to.eq(vk.gamma2.x[0].toString()); - expect(d.vk_gamma_2[1][0]).to.eq(vk.gamma2.y[1].toString()); - expect(d.vk_gamma_2[1][1]).to.eq(vk.gamma2.y[0].toString()); - - expect(d.vk_delta_2[0][0]).to.eq(vk.delta2.x[1].toString()); - expect(d.vk_delta_2[0][1]).to.eq(vk.delta2.x[0].toString()); - expect(d.vk_delta_2[1][0]).to.eq(vk.delta2.y[1].toString()); - expect(d.vk_delta_2[1][1]).to.eq(vk.delta2.y[0].toString()); - - expect(d.IC.length).to.eq(vk.ic.length); - for (let i = 0; i < d.IC.length; i += 1) { - expect(d.IC[i][0]).to.eq(vk.ic[i].x.toString()); - expect(d.IC[i][1]).to.eq(vk.ic[i].y.toString()); - } + describe("fromJSON", () => { + it("should convert a JSON file from snarkjs to a VerifyingKey", () => { + const file = path.join(__dirname, "./artifacts/test_vk.json"); + const j = fs.readFileSync(file).toString(); + const d = JSON.parse(j) as IVkObjectParams; + const vk = VerifyingKey.fromJSON(j); + + expect(d.vk_alpha_1[0]).to.eq(vk.alpha1.x.toString()); + expect(d.vk_alpha_1[1]).to.eq(vk.alpha1.y.toString()); + + expect(d.vk_beta_2[0][0]).to.eq(vk.beta2.x[1].toString()); + expect(d.vk_beta_2[0][1]).to.eq(vk.beta2.x[0].toString()); + expect(d.vk_beta_2[1][0]).to.eq(vk.beta2.y[1].toString()); + expect(d.vk_beta_2[1][1]).to.eq(vk.beta2.y[0].toString()); + + expect(d.vk_gamma_2[0][0]).to.eq(vk.gamma2.x[1].toString()); + expect(d.vk_gamma_2[0][1]).to.eq(vk.gamma2.x[0].toString()); + expect(d.vk_gamma_2[1][0]).to.eq(vk.gamma2.y[1].toString()); + expect(d.vk_gamma_2[1][1]).to.eq(vk.gamma2.y[0].toString()); + + expect(d.vk_delta_2[0][0]).to.eq(vk.delta2.x[1].toString()); + expect(d.vk_delta_2[0][1]).to.eq(vk.delta2.x[0].toString()); + expect(d.vk_delta_2[1][0]).to.eq(vk.delta2.y[1].toString()); + expect(d.vk_delta_2[1][1]).to.eq(vk.delta2.y[0].toString()); + + expect(d.IC.length).to.eq(vk.ic.length); + for (let i = 0; i < d.IC.length; i += 1) { + expect(d.IC[i][0]).to.eq(vk.ic[i].x.toString()); + expect(d.IC[i][1]).to.eq(vk.ic[i].y.toString()); + } + }); + }); + + describe("copy", () => { + it("Copy should generate a deep copy", () => { + const file = path.join(__dirname, "./artifacts/test_vk.json"); + const j = fs.readFileSync(file).toString(); + const vk = VerifyingKey.fromJSON(j); + + const vk2 = vk.copy(); + expect(vk.equals(vk2)).to.eq(true); + }); + }); + + describe("equals", () => { + it("Should return true for equal verifying keys", () => { + const file = path.join(__dirname, "./artifacts/test_vk.json"); + const j = fs.readFileSync(file).toString(); + const vk = VerifyingKey.fromJSON(j); + const vk2 = vk.copy(); + expect(vk.equals(vk2)).to.eq(true); + }); + it("Should return false for unequal verifying keys", () => { + const file = path.join(__dirname, "./artifacts/test_vk.json"); + const j = fs.readFileSync(file).toString(); + const vk = VerifyingKey.fromJSON(j); + const vk2 = vk.copy(); + vk2.alpha1.x = BigInt(123); + expect(vk.equals(vk2)).to.eq(false); + }); + it("should return false for unequal verifying keys (different ic)", () => { + const file = path.join(__dirname, "./artifacts/test_vk.json"); + const j = fs.readFileSync(file).toString(); + const vk = VerifyingKey.fromJSON(j); + const vk2 = vk.copy(); + vk2.ic[15] = {} as unknown as G1Point; + expect(vk.equals(vk2)).to.eq(false); + }); + }); + + describe("fromObj", () => { + it("Should convert an object to a VerifyingKey", () => { + const file = path.join(__dirname, "./artifacts/test_vk.json"); + const j = fs.readFileSync(file).toString(); + const d = JSON.parse(j) as IVkObjectParams; + const vk = VerifyingKey.fromObj(d); + + expect(d.vk_alpha_1[0]).to.eq(vk.alpha1.x.toString()); + expect(d.vk_alpha_1[1]).to.eq(vk.alpha1.y.toString()); + + expect(d.vk_beta_2[0][0]).to.eq(vk.beta2.x[1].toString()); + expect(d.vk_beta_2[0][1]).to.eq(vk.beta2.x[0].toString()); + expect(d.vk_beta_2[1][0]).to.eq(vk.beta2.y[1].toString()); + expect(d.vk_beta_2[1][1]).to.eq(vk.beta2.y[0].toString()); + + expect(d.vk_gamma_2[0][0]).to.eq(vk.gamma2.x[1].toString()); + expect(d.vk_gamma_2[0][1]).to.eq(vk.gamma2.x[0].toString()); + expect(d.vk_gamma_2[1][0]).to.eq(vk.gamma2.y[1].toString()); + expect(d.vk_gamma_2[1][1]).to.eq(vk.gamma2.y[0].toString()); + + expect(d.vk_delta_2[0][0]).to.eq(vk.delta2.x[1].toString()); + expect(d.vk_delta_2[0][1]).to.eq(vk.delta2.x[0].toString()); + expect(d.vk_delta_2[1][0]).to.eq(vk.delta2.y[1].toString()); + expect(d.vk_delta_2[1][1]).to.eq(vk.delta2.y[0].toString()); + + expect(d.IC.length).to.eq(vk.ic.length); + for (let i = 0; i < d.IC.length; i += 1) { + expect(d.IC[i][0]).to.eq(vk.ic[i].x.toString()); + expect(d.IC[i][1]).to.eq(vk.ic[i].y.toString()); + } + }); + }); + + describe("asContractParam", () => { + it("Should produce an object with the correct properties", () => { + const file = path.join(__dirname, "./artifacts/test_vk.json"); + const j = fs.readFileSync(file).toString(); + const vk = VerifyingKey.fromJSON(j); + const obj = vk.asContractParam(); + + expect(Object.keys(obj)).to.deep.eq(["alpha1", "beta2", "gamma2", "delta2", "ic"]); + }); }); - it("Copy should generate a deep copy", () => { - const file = path.resolve(__dirname, "artifacts/test_vk.json"); - const j = fs.readFileSync(file).toString(); - const vk = VerifyingKey.fromJSON(j); + describe("fromContract", () => { + it("Should produce a VerifyingKey from a contract object", () => { + const file = path.join(__dirname, "./artifacts/test_vk.json"); + const j = fs.readFileSync(file).toString(); + const vk = VerifyingKey.fromJSON(j); + const obj = vk.asContractParam(); + const vk2 = VerifyingKey.fromContract(obj); - const vk2 = vk.copy(); - expect(vk.equals(vk2)).to.eq(true); + expect(vk.equals(vk2)).to.eq(true); + }); }); }); diff --git a/domainobjs/ts/privateKey.ts b/domainobjs/ts/privateKey.ts index ba18ea6409..bfc8f88130 100644 --- a/domainobjs/ts/privateKey.ts +++ b/domainobjs/ts/privateKey.ts @@ -39,11 +39,12 @@ export class PrivKey { * @returns the serialized private key */ serialize = (): string => { - const x = this.rawPrivKey.toString(16); + let x = this.rawPrivKey.toString(16); if (x.length % 2 !== 0) { - return `${SERIALIZED_PRIV_KEY_PREFIX}0${x}`; + x = `0${x}`; } - return `${SERIALIZED_PRIV_KEY_PREFIX}${x}`; + + return `${SERIALIZED_PRIV_KEY_PREFIX}${x.padStart(64, "0")}`; }; /** From b10ff70a9f90e9e8d97497b7442d1416b06a09b9 Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Fri, 15 Dec 2023 10:30:41 +0000 Subject: [PATCH 22/37] refactor(contracts): smart contracts optimizations Unify usage of TREE_ARITY Use calldata vs memory for function params which are immutable Ensure we do not accept max messages + 1 in top up Use payable for constructors to reduce deployment costs --- contracts/contracts/MACI.sol | 20 +++++++------ contracts/contracts/MessageProcessor.sol | 2 +- contracts/contracts/Poll.sol | 30 +++++++++++-------- contracts/contracts/PollFactory.sol | 14 +++++---- contracts/contracts/SignUpToken.sol | 2 +- contracts/contracts/Subsidy.sol | 17 ++++++----- contracts/contracts/Tally.sol | 24 +++++++-------- contracts/contracts/TopupCredit.sol | 2 +- contracts/contracts/VkRegistry.sol | 9 ++++-- .../FreeForAllSignUpGatekeeper.sol | 7 +++++ .../gatekeepers/SignUpTokenGatekeeper.sol | 2 +- .../ConstantInitialVoiceCreditProxy.sol | 2 +- contracts/contracts/trees/AccQueue.sol | 2 +- contracts/contracts/utilities/Utilities.sol | 4 +-- contracts/tests/Subsidy.test.ts | 2 +- contracts/tests/Tally.test.ts | 2 +- 16 files changed, 82 insertions(+), 59 deletions(-) diff --git a/contracts/contracts/MACI.sol b/contracts/contracts/MACI.sol index 5071f20232..67ef936bed 100644 --- a/contracts/contracts/MACI.sol +++ b/contracts/contracts/MACI.sol @@ -18,7 +18,7 @@ import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; /// @title MACI - Minimum Anti-Collusion Infrastructure Version 1 /// @notice A contract which allows users to sign up, and deploy new polls -contract MACI is IMACI, DomainObjs, Params, Utilities, Ownable { +contract MACI is IMACI, Params, Utilities, Ownable { /// @notice The state tree depth is fixed. As such it should be as large as feasible /// so that there can be as many users as possible. i.e. 5 ** 10 = 9765625 /// this should also match the parameter of the circom circuits. @@ -28,8 +28,7 @@ contract MACI is IMACI, DomainObjs, Params, Utilities, Ownable { /// in contracts/ts/genEmptyBallotRootsContract.ts file /// if we change the state tree depth! uint8 internal constant STATE_TREE_SUBDEPTH = 2; - uint8 internal constant STATE_TREE_ARITY = 5; - uint8 internal constant MESSAGE_TREE_ARITY = 5; + uint8 internal constant TREE_ARITY = 5; /// @notice The hash of a blank state leaf uint256 internal constant BLANK_STATE_LEAF_HASH = @@ -78,6 +77,7 @@ contract MACI is IMACI, DomainObjs, Params, Utilities, Ownable { _; } + /// @notice custom errors error CallerMustBePoll(address _caller); error PoseidonHashLibrariesNotLinked(); error TooManySignups(); @@ -96,7 +96,7 @@ contract MACI is IMACI, DomainObjs, Params, Utilities, Ownable { InitialVoiceCreditProxy _initialVoiceCreditProxy, TopupCredit _topupCredit, uint8 _stateTreeDepth - ) { + ) payable { // Deploy the state AccQueue stateAq = new AccQueueQuinaryBlankSl(STATE_TREE_SUBDEPTH); stateAq.enqueue(BLANK_STATE_LEAF_HASH); @@ -137,14 +137,15 @@ contract MACI is IMACI, DomainObjs, Params, Utilities, Ownable { bytes memory _initialVoiceCreditProxyData ) public { // ensure we do not have more signups than what the circuits support - if (numSignUps == uint256(STATE_TREE_ARITY) ** uint256(stateTreeDepth)) revert TooManySignups(); + if (numSignUps == uint256(TREE_ARITY) ** uint256(stateTreeDepth)) revert TooManySignups(); if (_pubKey.x >= SNARK_SCALAR_FIELD || _pubKey.y >= SNARK_SCALAR_FIELD) { revert MaciPubKeyLargerThanSnarkFieldSize(); } // Increment the number of signups - // cannot overflow as numSignUps < 5 ** 10 -1 + // cannot overflow with realistic stateTreeDepth + // values as numSignUps < 5 ** stateTreeDepth -1 unchecked { numSignUps++; } @@ -176,6 +177,7 @@ contract MACI is IMACI, DomainObjs, Params, Utilities, Ownable { TreeDepths memory _treeDepths, PubKey memory _coordinatorPubKey ) public onlyOwner returns (address pollAddr) { + // cache the poll to a local variable so we can increment it uint256 pollId = nextPollId; // Increment the poll ID for the next poll @@ -190,9 +192,9 @@ contract MACI is IMACI, DomainObjs, Params, Utilities, Ownable { // The message batch size and the tally batch size BatchSizes memory batchSizes = BatchSizes( - uint24(MESSAGE_TREE_ARITY) ** _treeDepths.messageTreeSubDepth, - uint24(STATE_TREE_ARITY) ** _treeDepths.intStateTreeDepth, - uint24(STATE_TREE_ARITY) ** _treeDepths.intStateTreeDepth + uint24(TREE_ARITY) ** _treeDepths.messageTreeSubDepth, + uint24(TREE_ARITY) ** _treeDepths.intStateTreeDepth, + uint24(TREE_ARITY) ** _treeDepths.intStateTreeDepth ); Poll p = pollFactory.deploy( diff --git a/contracts/contracts/MessageProcessor.sol b/contracts/contracts/MessageProcessor.sol index 5c34af370a..1cf6d3b049 100644 --- a/contracts/contracts/MessageProcessor.sol +++ b/contracts/contracts/MessageProcessor.sol @@ -44,7 +44,7 @@ contract MessageProcessor is Ownable, SnarkCommon, CommonUtilities, Hasher { /// @notice Create a new instance /// @param _verifier The Verifier contract address /// @param _vkRegistry The VkRegistry contract address - constructor(Verifier _verifier, VkRegistry _vkRegistry) { + constructor(Verifier _verifier, VkRegistry _vkRegistry) payable { verifier = _verifier; vkRegistry = _vkRegistry; } diff --git a/contracts/contracts/Poll.sol b/contracts/contracts/Poll.sol index 3f3132af80..e9b5df31b6 100644 --- a/contracts/contracts/Poll.sol +++ b/contracts/contracts/Poll.sol @@ -49,20 +49,11 @@ contract Poll is Params, Utilities, SnarkCommon, Ownable, EmptyBallotRoots { uint256 public numMessages; - /// @notice The number of messages which have been processed and the number of - /// signups - /// @return numSignups The number of signups - /// @return numMsgs The number of messages sent by voters - function numSignUpsAndMessages() public view returns (uint256 numSignups, uint256 numMsgs) { - numSignups = extContracts.maci.numSignUps(); - numMsgs = numMessages; - } - MaxValues public maxValues; TreeDepths public treeDepths; BatchSizes public batchSizes; - // errors + /// @notice custom errors error VotingPeriodOver(); error VotingPeriodNotOver(); error PollAlreadyInit(); @@ -95,7 +86,7 @@ contract Poll is Params, Utilities, SnarkCommon, Ownable, EmptyBallotRoots { BatchSizes memory _batchSizes, PubKey memory _coordinatorPubKey, ExtContracts memory _extContracts - ) { + ) payable { extContracts = _extContracts; coordinatorPubKey = _coordinatorPubKey; @@ -151,7 +142,8 @@ contract Poll is Params, Utilities, SnarkCommon, Ownable, EmptyBallotRoots { /// @param stateIndex The index of user in the state queue /// @param amount The amount of credits to topup function topup(uint256 stateIndex, uint256 amount) public isWithinVotingDeadline { - if (numMessages > maxValues.maxMessages) revert TooManyMessages(); + // we check that we do not exceed the max number of messages + if (numMessages == maxValues.maxMessages) revert TooManyMessages(); unchecked { numMessages++; @@ -173,9 +165,11 @@ contract Poll is Params, Utilities, SnarkCommon, Ownable, EmptyBallotRoots { /// @param _encPubKey An epheremal public key which can be combined with the /// coordinator's private key to generate an ECDH shared key with which /// to encrypt the message. - function publishMessage(Message memory _message, PubKey memory _encPubKey) public isWithinVotingDeadline { + function publishMessage(Message memory _message, PubKey calldata _encPubKey) public isWithinVotingDeadline { + // we check that we do not exceed the max number of messages if (numMessages == maxValues.maxMessages) revert TooManyMessages(); + // validate that the public key is valid if (_encPubKey.x >= SNARK_SCALAR_FIELD || _encPubKey.y >= SNARK_SCALAR_FIELD) { revert MaciPubKeyLargerThanSnarkFieldSize(); } @@ -184,6 +178,7 @@ contract Poll is Params, Utilities, SnarkCommon, Ownable, EmptyBallotRoots { numMessages++; } + // force the message to have type 1 _message.msgType = 1; uint256 messageLeaf = hashMessageAndEncPubKey(_message, _encPubKey); extContracts.messageAq.enqueue(messageLeaf); @@ -252,4 +247,13 @@ contract Poll is Params, Utilities, SnarkCommon, Ownable, EmptyBallotRoots { _deployTime = deployTime; _duration = duration; } + + /// @notice The number of messages which have been processed and the number of + /// signups + /// @return numSignups The number of signups + /// @return numMsgs The number of messages sent by voters + function numSignUpsAndMessages() public view returns (uint256 numSignups, uint256 numMsgs) { + numSignups = extContracts.maci.numSignUps(); + numMsgs = numMessages; + } } diff --git a/contracts/contracts/PollFactory.sol b/contracts/contracts/PollFactory.sol index 07e674427d..86604e3076 100644 --- a/contracts/contracts/PollFactory.sol +++ b/contracts/contracts/PollFactory.sol @@ -13,10 +13,14 @@ import { Poll } from "./Poll.sol"; /// size to stay within the limit set by EIP-170. contract PollFactory is Params, DomainObjs { // The number of children each node in the message tree has - uint256 public constant TREE_ARITY = 5; + uint256 internal constant TREE_ARITY = 5; + // custom error error InvalidMaxValues(); + /// @notice The PollFactory constructor + constructor() payable {} + /// @notice Deploy a new Poll contract and AccQueue contract for messages. /// @param _duration The duration of the poll /// @param _maxValues The max values for the poll @@ -29,10 +33,10 @@ contract PollFactory is Params, DomainObjs { /// @return poll The deployed Poll contract function deploy( uint256 _duration, - MaxValues memory _maxValues, - TreeDepths memory _treeDepths, - BatchSizes memory _batchSizes, - PubKey memory _coordinatorPubKey, + MaxValues calldata _maxValues, + TreeDepths calldata _treeDepths, + BatchSizes calldata _batchSizes, + PubKey calldata _coordinatorPubKey, IMACI _maci, TopupCredit _topupCredit, address _pollOwner diff --git a/contracts/contracts/SignUpToken.sol b/contracts/contracts/SignUpToken.sol index 48b0fad8c4..702f525572 100644 --- a/contracts/contracts/SignUpToken.sol +++ b/contracts/contracts/SignUpToken.sol @@ -9,7 +9,7 @@ import "@openzeppelin/contracts/access/Ownable.sol"; /// can be used to allow users to sign up for a poll. contract SignUpToken is ERC721, Ownable { /// @notice The constructor which calls the ERC721 constructor - constructor() ERC721("SignUpToken", "SignUpToken") {} + constructor() payable ERC721("SignUpToken", "SignUpToken") {} /// @notice Gives an ERC721 token to an address /// @param to The address to give the token to diff --git a/contracts/contracts/Subsidy.sol b/contracts/contracts/Subsidy.sol index 60bcd94e16..714774e37b 100644 --- a/contracts/contracts/Subsidy.sol +++ b/contracts/contracts/Subsidy.sol @@ -16,13 +16,16 @@ import { VkRegistry } from "./VkRegistry.sol"; /// are correct. It is also used to update the subsidy commitment if the /// proof is valid. contract Subsidy is Ownable, CommonUtilities, Hasher, SnarkCommon { - uint256 public rbi; // row batch index - uint256 public cbi; // column batch index + // row batch index + uint256 public rbi; + // column batch index + uint256 public cbi; + // The final commitment to the state and ballot roots uint256 public sbCommitment; uint256 public subsidyCommitment; - uint8 public constant treeArity = 5; + uint8 internal constant TREE_ARITY = 5; // Error codes error ProcessingNotComplete(); @@ -39,7 +42,7 @@ contract Subsidy is Ownable, CommonUtilities, Hasher, SnarkCommon { /// @notice Create a new Subsidy contract /// @param _verifier The Verifier contract /// @param _vkRegistry The VkRegistry contract - constructor(Verifier _verifier, VkRegistry _vkRegistry) { + constructor(Verifier _verifier, VkRegistry _vkRegistry) payable { verifier = _verifier; vkRegistry = _vkRegistry; } @@ -93,14 +96,14 @@ contract Subsidy is Ownable, CommonUtilities, Hasher, SnarkCommon { Poll _poll, MessageProcessor _mp, uint256 _newSubsidyCommitment, - uint256[8] memory _proof + uint256[8] calldata _proof ) external onlyOwner { _votingPeriodOver(_poll); updateSbCommitment(_mp); (uint8 intStateTreeDepth, , , ) = _poll.treeDepths(); - uint256 subsidyBatchSize = uint256(treeArity) ** intStateTreeDepth; + uint256 subsidyBatchSize = uint256(TREE_ARITY) ** intStateTreeDepth; (uint256 numSignUps, ) = _poll.numSignUpsAndMessages(); @@ -140,7 +143,7 @@ contract Subsidy is Ownable, CommonUtilities, Hasher, SnarkCommon { /// @return isValid True if the proof is valid function verifySubsidyProof( Poll _poll, - uint256[8] memory _proof, + uint256[8] calldata _proof, uint256 _numSignUps, uint256 _newSubsidyCommitment ) public view returns (bool isValid) { diff --git a/contracts/contracts/Tally.sol b/contracts/contracts/Tally.sol index d541974e01..8f5686922f 100644 --- a/contracts/contracts/Tally.sol +++ b/contracts/contracts/Tally.sol @@ -24,7 +24,7 @@ contract Tally is Ownable, SnarkCommon, CommonUtilities, Hasher { error BatchStartIndexTooLarge(); error TallyBatchSizeTooLarge(); - uint8 private constant LEAVES_PER_NODE = 5; + uint8 private constant TREE_ARITY = 5; /// @notice The commitment to the tally results. Its initial value is 0, but after /// the tally of each batch is proven on-chain via a zk-SNARK, it should be @@ -51,7 +51,7 @@ contract Tally is Ownable, SnarkCommon, CommonUtilities, Hasher { /// @notice Create a new Tally contract /// @param _verifier The Verifier contract /// @param _vkRegistry The VkRegistry contract - constructor(Verifier _verifier, VkRegistry _vkRegistry) { + constructor(Verifier _verifier, VkRegistry _vkRegistry) payable { verifier = _verifier; vkRegistry = _vkRegistry; } @@ -115,7 +115,7 @@ contract Tally is Ownable, SnarkCommon, CommonUtilities, Hasher { Poll _poll, MessageProcessor _mp, uint256 _newTallyCommitment, - uint256[8] memory _proof + uint256[8] calldata _proof ) public onlyOwner { _votingPeriodOver(_poll); updateSbCommitment(_mp); @@ -149,7 +149,7 @@ contract Tally is Ownable, SnarkCommon, CommonUtilities, Hasher { /// @return isValid whether the proof is valid function verifyTallyProof( Poll _poll, - uint256[8] memory _proof, + uint256[8] calldata _proof, uint256 _numSignUps, uint256 _batchStartIndex, uint256 _tallyBatchSize, @@ -185,16 +185,16 @@ contract Tally is Ownable, SnarkCommon, CommonUtilities, Hasher { uint8 _depth, uint256 _index, uint256 _leaf, - uint256[][] memory _pathElements + uint256[][] calldata _pathElements ) internal pure returns (uint256 current) { - uint256 pos = _index % LEAVES_PER_NODE; + uint256 pos = _index % TREE_ARITY; current = _leaf; uint8 k; - uint256[LEAVES_PER_NODE] memory level; + uint256[TREE_ARITY] memory level; for (uint8 i = 0; i < _depth; ++i) { - for (uint8 j = 0; j < LEAVES_PER_NODE; ++j) { + for (uint8 j = 0; j < TREE_ARITY; ++j) { if (j == pos) { level[j] = current; } else { @@ -207,8 +207,8 @@ contract Tally is Ownable, SnarkCommon, CommonUtilities, Hasher { } } - _index /= LEAVES_PER_NODE; - pos = _index % LEAVES_PER_NODE; + _index /= TREE_ARITY; + pos = _index % TREE_ARITY; current = hash5(level); } } @@ -246,7 +246,7 @@ contract Tally is Ownable, SnarkCommon, CommonUtilities, Hasher { function verifyPerVOSpentVoiceCredits( uint256 _voteOptionIndex, uint256 _spent, - uint256[][] memory _spentProof, + uint256[][] calldata _spentProof, uint256 _spentSalt, uint8 _voteOptionTreeDepth, uint256 _spentVoiceCreditsHash, @@ -275,7 +275,7 @@ contract Tally is Ownable, SnarkCommon, CommonUtilities, Hasher { function verifyTallyResult( uint256 _voteOptionIndex, uint256 _tallyResult, - uint256[][] memory _tallyResultProof, + uint256[][] calldata _tallyResultProof, uint256 _tallyResultSalt, uint8 _voteOptionTreeDepth, uint256 _spentVoiceCreditsHash, diff --git a/contracts/contracts/TopupCredit.sol b/contracts/contracts/TopupCredit.sol index b2a40577a3..db0d4d08af 100644 --- a/contracts/contracts/TopupCredit.sol +++ b/contracts/contracts/TopupCredit.sol @@ -12,7 +12,7 @@ contract TopupCredit is ERC20, Ownable { uint256 public constant MAXIMUM_AIRDROP_AMOUNT = 100000 * 10 ** _decimals; /// @notice create a new TopupCredit token - constructor() ERC20("TopupCredit", "TopupCredit") {} + constructor() payable ERC20("TopupCredit", "TopupCredit") {} /// @notice mint tokens to an account /// @param account the account to mint tokens to diff --git a/contracts/contracts/VkRegistry.sol b/contracts/contracts/VkRegistry.sol index 1ab6176415..5b9ff7a9d8 100644 --- a/contracts/contracts/VkRegistry.sol +++ b/contracts/contracts/VkRegistry.sol @@ -30,6 +30,9 @@ contract VkRegistry is Ownable, SnarkCommon { error TallyVkNotSet(); error SubsidyVkNotSet(); + /// @notice Create a new instance of the VkRegistry contract + constructor() payable {} + /// @notice Check if the process verifying key is set /// @param _sig The signature /// @return isSet whether the verifying key is set @@ -106,8 +109,8 @@ contract VkRegistry is Ownable, SnarkCommon { uint256 _messageTreeDepth, uint256 _voteOptionTreeDepth, uint256 _messageBatchSize, - VerifyingKey memory _processVk, - VerifyingKey memory _tallyVk + VerifyingKey calldata _processVk, + VerifyingKey calldata _tallyVk ) public onlyOwner { uint256 processVkSig = genProcessVkSig(_stateTreeDepth, _messageTreeDepth, _voteOptionTreeDepth, _messageBatchSize); @@ -152,7 +155,7 @@ contract VkRegistry is Ownable, SnarkCommon { uint256 _stateTreeDepth, uint256 _intStateTreeDepth, uint256 _voteOptionTreeDepth, - VerifyingKey memory _subsidyVk + VerifyingKey calldata _subsidyVk ) public onlyOwner { uint256 subsidyVkSig = genSubsidyVkSig(_stateTreeDepth, _intStateTreeDepth, _voteOptionTreeDepth); diff --git a/contracts/contracts/gatekeepers/FreeForAllSignUpGatekeeper.sol b/contracts/contracts/gatekeepers/FreeForAllSignUpGatekeeper.sol index 5fb69efde0..2a94417a38 100644 --- a/contracts/contracts/gatekeepers/FreeForAllSignUpGatekeeper.sol +++ b/contracts/contracts/gatekeepers/FreeForAllSignUpGatekeeper.sol @@ -7,6 +7,13 @@ import { MACI } from "../MACI.sol"; /// @title FreeForAllGatekeeper /// @notice A SignUpGatekeeper which allows anyone to sign up. contract FreeForAllGatekeeper is SignUpGatekeeper { + /// @notice Create a new instance of FreeForAllGatekeeper + constructor() payable {} + + /// @notice setMaciInstance does nothing in this gatekeeper + /// @param _maci The MACI contract + function setMaciInstance(MACI _maci) public override {} + /// @notice Registers the user without any restrictions. /// @param _address The address of the user /// @param _data memory additional data diff --git a/contracts/contracts/gatekeepers/SignUpTokenGatekeeper.sol b/contracts/contracts/gatekeepers/SignUpTokenGatekeeper.sol index 1b92c007cd..19a017e79d 100644 --- a/contracts/contracts/gatekeepers/SignUpTokenGatekeeper.sol +++ b/contracts/contracts/gatekeepers/SignUpTokenGatekeeper.sol @@ -27,7 +27,7 @@ contract SignUpTokenGatekeeper is SignUpGatekeeper, Ownable { /// @notice creates a new SignUpTokenGatekeeper /// @param _token the address of the SignUpToken contract - constructor(SignUpToken _token) Ownable() { + constructor(SignUpToken _token) payable Ownable() { token = _token; } diff --git a/contracts/contracts/initialVoiceCreditProxy/ConstantInitialVoiceCreditProxy.sol b/contracts/contracts/initialVoiceCreditProxy/ConstantInitialVoiceCreditProxy.sol index e167c8b600..c9c326ded7 100644 --- a/contracts/contracts/initialVoiceCreditProxy/ConstantInitialVoiceCreditProxy.sol +++ b/contracts/contracts/initialVoiceCreditProxy/ConstantInitialVoiceCreditProxy.sol @@ -12,7 +12,7 @@ contract ConstantInitialVoiceCreditProxy is InitialVoiceCreditProxy { /// @notice creates a new ConstantInitialVoiceCreditProxy /// @param _balance the balance to be returned by getVoiceCredits - constructor(uint256 _balance) { + constructor(uint256 _balance) payable { balance = _balance; } diff --git a/contracts/contracts/trees/AccQueue.sol b/contracts/contracts/trees/AccQueue.sol index 21bab55fb4..76b9fc95b2 100644 --- a/contracts/contracts/trees/AccQueue.sol +++ b/contracts/contracts/trees/AccQueue.sol @@ -93,7 +93,7 @@ abstract contract AccQueue is Ownable, Hasher { /// @notice Create a new AccQueue /// @param _subDepth The depth of each subtree. /// @param _hashLength The number of leaves per node (2 or 5). - constructor(uint256 _subDepth, uint256 _hashLength) { + constructor(uint256 _subDepth, uint256 _hashLength) payable { /// validation if (_subDepth == 0) revert SubDepthCannotBeZero(); if (_subDepth > MAX_DEPTH) revert SubdepthTooLarge(_subDepth, MAX_DEPTH); diff --git a/contracts/contracts/utilities/Utilities.sol b/contracts/contracts/utilities/Utilities.sol index 6239c9542f..b58e133c96 100644 --- a/contracts/contracts/utilities/Utilities.sol +++ b/contracts/contracts/utilities/Utilities.sol @@ -10,7 +10,7 @@ import { Poll } from "../Poll.sol"; /// which are to be used by multiple contracts /// namely Subsidy, Tally and MessageProcessor contract CommonUtilities { - error VOTING_PERIOD_NOT_PASSED(); + error VotingPeriodNotPassed(); /// @notice common function for MessageProcessor, Tally and Subsidy /// @param _poll the poll to be checked @@ -19,7 +19,7 @@ contract CommonUtilities { // Require that the voting period is over uint256 secondsPassed = block.timestamp - deployTime; if (secondsPassed <= duration) { - revert VOTING_PERIOD_NOT_PASSED(); + revert VotingPeriodNotPassed(); } } } diff --git a/contracts/tests/Subsidy.test.ts b/contracts/tests/Subsidy.test.ts index 34f8b1daf4..95f43a0d0a 100644 --- a/contracts/tests/Subsidy.test.ts +++ b/contracts/tests/Subsidy.test.ts @@ -118,7 +118,7 @@ describe("Subsidy", () => { 0, [0, 0, 0, 0, 0, 0, 0, 0], ), - ).to.be.revertedWithCustomError(subsidyContract, "VOTING_PERIOD_NOT_PASSED"); + ).to.be.revertedWithCustomError(subsidyContract, "VotingPeriodNotPassed"); }); it("genSubsidyPackedVals() should generate the correct value", async () => { diff --git a/contracts/tests/Tally.test.ts b/contracts/tests/Tally.test.ts index 37b110b9f3..3f1ef77b50 100644 --- a/contracts/tests/Tally.test.ts +++ b/contracts/tests/Tally.test.ts @@ -113,7 +113,7 @@ describe("TallyVotes", () => { 0, [0, 0, 0, 0, 0, 0, 0, 0], ), - ).to.be.revertedWithCustomError(tallyContract, "VOTING_PERIOD_NOT_PASSED"); + ).to.be.revertedWithCustomError(tallyContract, "VotingPeriodNotPassed"); }); it("genTallyVotesPackedVals() should generate the correct value", async () => { From ed85bc513336ac8e9d3dacbe98fd58fbaed31151 Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Sat, 16 Dec 2023 17:12:08 +0000 Subject: [PATCH 23/37] refactor(crypto): improve discoverability of the package by further separating classes and functions --- crypto/ts/AccQueue.ts | 5 +- crypto/ts/__tests__/Crypto.test.ts | 16 +- crypto/ts/babyjub.ts | 131 +++++++++++ crypto/ts/crypto.ts | 340 ----------------------------- crypto/ts/hashing.ts | 160 ++++++++++++++ crypto/ts/index.ts | 18 +- crypto/ts/keys.ts | 81 +++++++ crypto/ts/utils.ts | 2 +- 8 files changed, 385 insertions(+), 368 deletions(-) create mode 100644 crypto/ts/babyjub.ts delete mode 100644 crypto/ts/crypto.ts create mode 100644 crypto/ts/hashing.ts create mode 100644 crypto/ts/keys.ts diff --git a/crypto/ts/AccQueue.ts b/crypto/ts/AccQueue.ts index d5fce8b9aa..a32cc83ca6 100644 --- a/crypto/ts/AccQueue.ts +++ b/crypto/ts/AccQueue.ts @@ -2,9 +2,10 @@ import { OptimisedMT as IncrementalQuinTree } from "optimisedmt"; import assert from "assert"; +import type { Leaf, Queue, StringifiedBigInts } from "./types"; + import { deepCopyBigIntArray, stringifyBigInts, unstringifyBigInts } from "./bigIntUtils"; -import { sha256Hash, hashLeftRight, hash5 } from "./crypto"; -import { Leaf, Queue, StringifiedBigInts } from "./types"; +import { sha256Hash, hashLeftRight, hash5 } from "./hashing"; import { calcDepthFromNumLeaves } from "./utils"; /** diff --git a/crypto/ts/__tests__/Crypto.test.ts b/crypto/ts/__tests__/Crypto.test.ts index a3ad056403..efaaee2d4c 100644 --- a/crypto/ts/__tests__/Crypto.test.ts +++ b/crypto/ts/__tests__/Crypto.test.ts @@ -1,10 +1,8 @@ import { expect } from "chai"; +import { G1Point, G2Point, genRandomBabyJubValue } from "../babyjub"; import { SNARK_FIELD_SIZE } from "../constants"; import { - genPubKey, - genKeypair, - genEcdhSharedKey, sha256Hash, hash2, hash3, @@ -13,19 +11,13 @@ import { hash13, hashLeftRight, hashN, + hashOne, poseidonT3, poseidonT4, poseidonT5, poseidonT6, - genRandomSalt, - G1Point, - G2Point, - hashOne, - genRandomBabyJubValue, - genPrivKey, - packPubKey, - unpackPubKey, -} from "../crypto"; +} from "../hashing"; +import { genPubKey, genKeypair, genEcdhSharedKey, genRandomSalt, genPrivKey, packPubKey, unpackPubKey } from "../keys"; describe("Crypto", function test() { this.timeout(100000); diff --git a/crypto/ts/babyjub.ts b/crypto/ts/babyjub.ts new file mode 100644 index 0000000000..30a3dca500 --- /dev/null +++ b/crypto/ts/babyjub.ts @@ -0,0 +1,131 @@ +import assert from "assert"; +import { randomBytes } from "crypto"; + +import { SNARK_FIELD_SIZE } from "./constants"; +import { PrivKey } from "./types"; + +/** + * @notice A class representing a point on the first group (G1) + * of the Jubjub curve + */ +export class G1Point { + x: bigint; + + y: bigint; + + /** + * Create a new instance of G1Point + * @param x the x coordinate + * @param y the y coordinate + */ + constructor(x: bigint, y: bigint) { + assert(x < SNARK_FIELD_SIZE && x >= 0, "G1Point x out of range"); + assert(y < SNARK_FIELD_SIZE && y >= 0, "G1Point y out of range"); + this.x = x; + this.y = y; + } + + /** + * Check whether two points are equal + * @param pt the point to compare with + * @returns whether they are equal or not + */ + equals(pt: G1Point): boolean { + return this.x === pt.x && this.y === pt.y; + } + + /** + * Return the point as a contract param in the form of an object + * @returns the point as a contract param + */ + asContractParam(): { x: string; y: string } { + return { + x: this.x.toString(), + y: this.y.toString(), + }; + } +} + +/** + * @notice A class representing a point on the second group (G2) + * of the Jubjub curve. This is usually an extension field of the + * base field of the curve. + */ +export class G2Point { + x: bigint[]; + + y: bigint[]; + + /** + * Create a new instance of G2Point + * @param x the x coordinate + * @param y the y coordinate + */ + constructor(x: bigint[], y: bigint[]) { + this.checkPointsRange(x, "x"); + this.checkPointsRange(y, "y"); + + this.x = x; + this.y = y; + } + + /** + * Check whether two points are equal + * @param pt the point to compare with + * @returns whether they are equal or not + */ + equals(pt: G2Point): boolean { + return this.x[0] === pt.x[0] && this.x[1] === pt.x[1] && this.y[0] === pt.y[0] && this.y[1] === pt.y[1]; + } + + /** + * Return the point as a contract param in the form of an object + * @returns the point as a contract param + */ + asContractParam(): { x: string[]; y: string[] } { + return { + x: this.x.map((n) => n.toString()), + y: this.y.map((n) => n.toString()), + }; + } + + /** + * Check whether the points are in range + * @param x the x coordinate + * @param type the type of the coordinate + */ + private checkPointsRange(x: bigint[], type: "x" | "y") { + assert( + x.every((n) => n < SNARK_FIELD_SIZE && n >= 0), + `G2Point ${type} out of range`, + ); + } +} + +/** + * Returns a BabyJub-compatible random value. We create it by first generating + * a random value (initially 256 bits large) modulo the snark field size as + * described in EIP197. This results in a key size of roughly 253 bits and no + * more than 254 bits. To prevent modulo bias, we then use this efficient + * algorithm: + * http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/lib/libc/crypt/arc4random_uniform.c + * @returns A BabyJub-compatible random value. + */ +export const genRandomBabyJubValue = (): bigint => { + // Prevent modulo bias + // const lim = BigInt('0x10000000000000000000000000000000000000000000000000000000000000000') + // const min = (lim - SNARK_FIELD_SIZE) % SNARK_FIELD_SIZE + const min = BigInt("6350874878119819312338956282401532410528162663560392320966563075034087161851"); + + let privKey: PrivKey = SNARK_FIELD_SIZE; + + do { + const rand = BigInt(`0x${randomBytes(32).toString("hex")}`); + + if (rand >= min) { + privKey = rand % SNARK_FIELD_SIZE; + } + } while (privKey >= SNARK_FIELD_SIZE); + + return privKey; +}; diff --git a/crypto/ts/crypto.ts b/crypto/ts/crypto.ts deleted file mode 100644 index 6222fc83b7..0000000000 --- a/crypto/ts/crypto.ts +++ /dev/null @@ -1,340 +0,0 @@ -import { mulPointEscalar, Point } from "@zk-kit/baby-jubjub"; -import { deriveSecretScalar, derivePublicKey, packPublicKey, unpackPublicKey } from "@zk-kit/eddsa-poseidon"; -import { poseidonPerm } from "@zk-kit/poseidon-cipher"; -import { utils } from "ethers"; - -import assert from "assert"; -import { randomBytes } from "crypto"; - -import type { EcdhSharedKey, PrivKey, PubKey, PoseidonFuncs, Keypair } from "./types"; - -import { SNARK_FIELD_SIZE } from "./constants"; - -/** - * @notice A class representing a point on the first group (G1) - * of the Jubjub curve - */ -export class G1Point { - x: bigint; - - y: bigint; - - constructor(x: bigint, y: bigint) { - assert(x < SNARK_FIELD_SIZE && x >= 0, "G1Point x out of range"); - assert(y < SNARK_FIELD_SIZE && y >= 0, "G1Point y out of range"); - this.x = x; - this.y = y; - } - - /** - * Check whether two points are equal - * @param pt the point to compare with - * @returns whether they are equal or not - */ - equals(pt: G1Point): boolean { - return this.x === pt.x && this.y === pt.y; - } - - /** - * Return the point as a contract param in the form of an object - * @returns the point as a contract param - */ - asContractParam(): { x: string; y: string } { - return { - x: this.x.toString(), - y: this.y.toString(), - }; - } -} - -/** - * @notice A class representing a point on the second group (G2) - * of the Jubjub curve. This is usually an extension field of the - * base field of the curve. - */ -export class G2Point { - x: bigint[]; - - y: bigint[]; - - constructor(x: bigint[], y: bigint[]) { - this.checkPointsRange(x, "x"); - this.checkPointsRange(y, "y"); - - this.x = x; - this.y = y; - } - - /** - * Check whether two points are equal - * @param pt the point to compare with - * @returns whether they are equal or not - */ - equals(pt: G2Point): boolean { - return this.x[0] === pt.x[0] && this.x[1] === pt.x[1] && this.y[0] === pt.y[0] && this.y[1] === pt.y[1]; - } - - /** - * Return the point as a contract param in the form of an object - * @returns the point as a contract param - */ - asContractParam(): { x: string[]; y: string[] } { - return { - x: this.x.map((n) => n.toString()), - y: this.y.map((n) => n.toString()), - }; - } - - private checkPointsRange(x: bigint[], type: "x" | "y") { - assert( - x.every((n) => n < SNARK_FIELD_SIZE && n >= 0), - `G2Point ${type} out of range`, - ); - } -} - -/** - * Hash an array of uint256 values the same way that the EVM does. - * @param input - the array of values to hash - * @returns a EVM compatible sha256 hash - */ -export const sha256Hash = (input: bigint[]): bigint => { - const types: string[] = []; - - input.forEach(() => { - types.push("uint256"); - }); - - return ( - BigInt( - utils.soliditySha256( - types, - input.map((x) => x.toString()), - ), - ) % SNARK_FIELD_SIZE - ); -}; - -/** - * Generate the poseidon hash of the inputs provided - * @param inputs The inputs to hash - * @returns the hash of the inputs - */ -export const poseidon = (inputs: bigint[]): bigint => poseidonPerm([BigInt(0), ...inputs.map((x) => BigInt(x))])[0]; - -/** - * Hash up to 2 elements - * @param inputs The elements to hash - * @returns the hash of the elements - */ -export const poseidonT3 = (inputs: bigint[]): bigint => { - assert(inputs.length === 2); - return poseidon(inputs); -}; - -/** - * Hash up to 3 elements - * @param inputs The elements to hash - * @returns the hash of the elements - */ -export const poseidonT4 = (inputs: bigint[]): bigint => { - assert(inputs.length === 3); - return poseidon(inputs); -}; - -/** - * Hash up to 4 elements - * @param inputs The elements to hash - * @retuns the hash of the elements - */ -export const poseidonT5 = (inputs: bigint[]): bigint => { - assert(inputs.length === 4); - return poseidon(inputs); -}; - -/** - * Hash up to 5 elements - * @param inputs The elements to hash - * @returns the hash of the elements - */ -export const poseidonT6 = (inputs: bigint[]): bigint => { - assert(inputs.length === 5); - return poseidon(inputs); -}; - -/** - * Hash two BigInts with the Poseidon hash function - * @param left The left-hand element to hash - * @param right The right-hand element to hash - * @returns The hash of the two elements - */ -export const hashLeftRight = (left: bigint, right: bigint): bigint => poseidonT3([left, right]); - -const funcs: PoseidonFuncs = { - 2: poseidonT3, - 3: poseidonT4, - 4: poseidonT5, - 5: poseidonT6, -}; - -/** - * Hash up to N elements - * @param numElements The number of elements to hash - * @param elements The elements to hash - * @returns The hash of the elements - */ -export const hashN = (numElements: number, elements: bigint[]): bigint => { - const elementLength = elements.length; - if (elements.length > numElements) { - throw new TypeError(`the length of the elements array should be at most ${numElements}; got ${elements.length}`); - } - const elementsPadded = elements.slice(); - if (elementLength < numElements) { - for (let i = elementLength; i < numElements; i += 1) { - elementsPadded.push(BigInt(0)); - } - } - - return funcs[numElements](elementsPadded); -}; - -// hash functions -export const hash2 = (elements: bigint[]): bigint => hashN(2, elements); -export const hash3 = (elements: bigint[]): bigint => hashN(3, elements); -export const hash4 = (elements: bigint[]): bigint => hashN(4, elements); -export const hash5 = (elements: bigint[]): bigint => hashN(5, elements); - -/** - * A convenience function to use Poseidon to hash a Plaintext with - * no more than 13 elements - * @param elements The elements to hash - * @returns The hash of the elements - */ -export const hash13 = (elements: bigint[]): bigint => { - const max = 13; - const elementLength = elements.length; - if (elementLength > max) { - throw new TypeError(`the length of the elements array should be at most ${max}; got ${elements.length}`); - } - const elementsPadded = elements.slice(); - if (elementLength < max) { - for (let i = elementLength; i < max; i += 1) { - elementsPadded.push(BigInt(0)); - } - } - return poseidonT6([ - elementsPadded[0], - poseidonT6(elementsPadded.slice(1, 6)), - poseidonT6(elementsPadded.slice(6, 11)), - elementsPadded[11], - elementsPadded[12], - ]); -}; - -/** - * Hash a single BigInt with the Poseidon hash function - * @param preImage The element to hash - * @returns The hash of the element - */ -export const hashOne = (preImage: bigint): bigint => poseidonT3([preImage, BigInt(0)]); - -/** - * Returns a BabyJub-compatible random value. We create it by first generating - * a random value (initially 256 bits large) modulo the snark field size as - * described in EIP197. This results in a key size of roughly 253 bits and no - * more than 254 bits. To prevent modulo bias, we then use this efficient - * algorithm: - * http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/lib/libc/crypt/arc4random_uniform.c - * @returns A BabyJub-compatible random value. - */ -export const genRandomBabyJubValue = (): bigint => { - // Prevent modulo bias - // const lim = BigInt('0x10000000000000000000000000000000000000000000000000000000000000000') - // const min = (lim - SNARK_FIELD_SIZE) % SNARK_FIELD_SIZE - const min = BigInt("6350874878119819312338956282401532410528162663560392320966563075034087161851"); - - let privKey = SNARK_FIELD_SIZE; - - do { - const rand = BigInt(`0x${randomBytes(32).toString("hex")}`); - - if (rand >= min) { - privKey = rand % SNARK_FIELD_SIZE; - } - } while (privKey >= SNARK_FIELD_SIZE); - - return privKey; -}; - -/** - * Generate a private key - * @returns A BabyJub-compatible private key. - */ -export const genPrivKey = (): bigint => genRandomBabyJubValue(); - -/** - * Generate a random value - * @returns A BabyJub-compatible salt. - */ -export const genRandomSalt = (): bigint => genRandomBabyJubValue(); - -/** - * An internal function which formats a random private key to be compatible - * with the BabyJub curve. This is the format which should be passed into the - * PubKey and other circuits. - * @param privKey A private key generated using genPrivKey() - * @returns A BabyJub-compatible private key. - */ -export const formatPrivKeyForBabyJub = (privKey: PrivKey): bigint => BigInt(deriveSecretScalar(privKey)); - -/** - * @param privKey A private key generated using genPrivKey() - * @returns A public key associated with the private key - */ -export const genPubKey = (privKey: PrivKey): PubKey => { - // Check whether privKey is a field element - assert(BigInt(privKey) < SNARK_FIELD_SIZE); - - const key = derivePublicKey(privKey); - return [BigInt(key[0]), BigInt(key[1])]; -}; - -/** - * Generates a keypair. - * @returns a keypair - */ -export const genKeypair = (): Keypair => { - const privKey = genPrivKey(); - const pubKey = genPubKey(privKey); - - const keypair: Keypair = { privKey, pubKey }; - - return keypair; -}; - -/** - * Generates an Elliptic-Curve Diffie–Hellman (ECDH) shared key given a private - * key and a public key. - * @param privKey A private key generated using genPrivKey() - * @param pubKey A public key generated using genPubKey() - * @returns The ECDH shared key. - */ -export const genEcdhSharedKey = (privKey: PrivKey, pubKey: PubKey): EcdhSharedKey => - mulPointEscalar(pubKey as Point, formatPrivKeyForBabyJub(privKey)); - -/** - * Losslessly reduces the size of the representation of a public key - * @param pubKey The public key to pack - * @returns A packed public key - */ -export const packPubKey = (pubKey: PubKey): bigint => BigInt(packPublicKey(pubKey)); - -/** - * Restores the original PubKey from its packed representation - * @param packed The value to unpack - * @returns The unpacked public key - */ -export const unpackPubKey = (packed: bigint): PubKey => { - const pubKey = unpackPublicKey(packed); - return pubKey.map((x: string) => BigInt(x)) as PubKey; -}; diff --git a/crypto/ts/hashing.ts b/crypto/ts/hashing.ts new file mode 100644 index 0000000000..c2f3e7badf --- /dev/null +++ b/crypto/ts/hashing.ts @@ -0,0 +1,160 @@ +import { poseidonPerm } from "@zk-kit/poseidon-cipher"; +import { utils } from "ethers"; + +import assert from "assert"; + +import type { Plaintext, PoseidonFuncs } from "./types"; + +import { SNARK_FIELD_SIZE } from "./constants"; + +/** + * Hash an array of uint256 values the same way that the EVM does. + * @param input - the array of values to hash + * @returns a EVM compatible sha256 hash + */ +export const sha256Hash = (input: bigint[]): bigint => { + const types: string[] = []; + + input.forEach(() => { + types.push("uint256"); + }); + + return ( + BigInt( + utils.soliditySha256( + types, + input.map((x) => x.toString()), + ), + ) % SNARK_FIELD_SIZE + ); +}; + +/** + * Generate the poseidon hash of the inputs provided + * @param inputs The inputs to hash + * @returns the hash of the inputs + */ +export const poseidon = (inputs: bigint[]): bigint => poseidonPerm([BigInt(0), ...inputs.map((x) => BigInt(x))])[0]; + +/** + * Hash up to 2 elements + * @param inputs The elements to hash + * @returns the hash of the elements + */ +export const poseidonT3 = (inputs: bigint[]): bigint => { + assert(inputs.length === 2); + return poseidon(inputs); +}; + +/** + * Hash up to 3 elements + * @param inputs The elements to hash + * @returns the hash of the elements + */ +export const poseidonT4 = (inputs: bigint[]): bigint => { + assert(inputs.length === 3); + return poseidon(inputs); +}; + +/** + * Hash up to 4 elements + * @param inputs The elements to hash + * @retuns the hash of the elements + */ +export const poseidonT5 = (inputs: bigint[]): bigint => { + assert(inputs.length === 4); + return poseidon(inputs); +}; + +/** + * Hash up to 5 elements + * @param inputs The elements to hash + * @returns the hash of the elements + */ +export const poseidonT6 = (inputs: bigint[]): bigint => { + assert(inputs.length === 5); + return poseidon(inputs); +}; + +/** + * Hash two BigInts with the Poseidon hash function + * @param left The left-hand element to hash + * @param right The right-hand element to hash + * @returns The hash of the two elements + */ +export const hashLeftRight = (left: bigint, right: bigint): bigint => poseidonT3([left, right]); + +// hash functions +const funcs: PoseidonFuncs = { + 2: poseidonT3, + 3: poseidonT4, + 4: poseidonT5, + 5: poseidonT6, +}; + +/** + * Hash up to N elements + * @param numElements The number of elements to hash + * @param elements The elements to hash + * @returns The hash of the elements + */ +export const hashN = (numElements: number, elements: Plaintext): bigint => { + const elementLength = elements.length; + + if (elements.length > numElements) { + throw new TypeError(`the length of the elements array should be at most ${numElements}; got ${elements.length}`); + } + const elementsPadded = elements.slice(); + + if (elementLength < numElements) { + for (let i = elementLength; i < numElements; i += 1) { + elementsPadded.push(BigInt(0)); + } + } + + return funcs[numElements](elementsPadded); +}; + +// hash functions +export const hash2 = (elements: Plaintext): bigint => hashN(2, elements); +export const hash3 = (elements: Plaintext): bigint => hashN(3, elements); +export const hash4 = (elements: Plaintext): bigint => hashN(4, elements); +export const hash5 = (elements: Plaintext): bigint => hashN(5, elements); + +/** + * A convenience function to use Poseidon to hash a Plaintext with + * no more than 13 elements + * @param elements The elements to hash + * @returns The hash of the elements + */ +export const hash13 = (elements: Plaintext): bigint => { + const max = 13; + const elementLength = elements.length; + + if (elementLength > max) { + throw new TypeError(`the length of the elements array should be at most ${max}; got ${elements.length}`); + } + + const elementsPadded = elements.slice(); + + if (elementLength < max) { + for (let i = elementLength; i < max; i += 1) { + elementsPadded.push(BigInt(0)); + } + } + + return poseidonT6([ + elementsPadded[0], + poseidonT6(elementsPadded.slice(1, 6)), + poseidonT6(elementsPadded.slice(6, 11)), + elementsPadded[11], + elementsPadded[12], + ]); +}; + +/** + * Hash a single BigInt with the Poseidon hash function + * @param preImage The element to hash + * @returns The hash of the element + */ +export const hashOne = (preImage: bigint): bigint => poseidonT3([preImage, BigInt(0)]); diff --git a/crypto/ts/index.ts b/crypto/ts/index.ts index 2fc3cd9862..5d28ddf198 100644 --- a/crypto/ts/index.ts +++ b/crypto/ts/index.ts @@ -9,18 +9,6 @@ export { bigInt2Buffer, stringifyBigInts, unstringifyBigInts, deepCopyBigIntArra export { NOTHING_UP_MY_SLEEVE, SNARK_FIELD_SIZE } from "./constants"; export { - G1Point, - G2Point, - sha256Hash, - hashLeftRight, - hashN, - hash2, - hash3, - hash4, - hash5, - hash13, - hashOne, - genRandomBabyJubValue, genPrivKey, genRandomSalt, formatPrivKeyForBabyJub, @@ -29,7 +17,11 @@ export { genEcdhSharedKey, packPubKey, unpackPubKey, -} from "./crypto"; +} from "./keys"; + +export { G1Point, G2Point, genRandomBabyJubValue } from "./babyjub"; + +export { sha256Hash, hashLeftRight, hashN, hash2, hash3, hash4, hash5, hash13, hashOne } from "./hashing"; export { OptimisedMT as IncrementalQuinTree, type PathElements } from "optimisedmt"; diff --git a/crypto/ts/keys.ts b/crypto/ts/keys.ts new file mode 100644 index 0000000000..6b7ffba220 --- /dev/null +++ b/crypto/ts/keys.ts @@ -0,0 +1,81 @@ +import { mulPointEscalar } from "@zk-kit/baby-jubjub"; +import { derivePublicKey, deriveSecretScalar, packPublicKey, unpackPublicKey } from "@zk-kit/eddsa-poseidon"; + +import assert from "assert"; + +import { genRandomBabyJubValue } from "./babyjub"; +import { SNARK_FIELD_SIZE } from "./constants"; +import { EcdhSharedKey, Keypair, Point, PrivKey, PubKey } from "./types"; + +/** + * Generate a private key + * @returns A BabyJub-compatible private key. + */ +export const genPrivKey = (): bigint => genRandomBabyJubValue(); + +/** + * Generate a random value + * @returns A BabyJub-compatible salt. + */ +export const genRandomSalt = (): bigint => genRandomBabyJubValue(); + +/** + * An internal function which formats a random private key to be compatible + * with the BabyJub curve. This is the format which should be passed into the + * PubKey and other circuits. + * @param privKey A private key generated using genPrivKey() + * @returns A BabyJub-compatible private key. + */ +export const formatPrivKeyForBabyJub = (privKey: PrivKey): bigint => BigInt(deriveSecretScalar(privKey)); + +/** + * Losslessly reduces the size of the representation of a public key + * @param pubKey The public key to pack + * @returns A packed public key + */ +export const packPubKey = (pubKey: PubKey): bigint => BigInt(packPublicKey(pubKey)); + +/** + * Restores the original PubKey from its packed representation + * @param packed The value to unpack + * @returns The unpacked public key + */ +export const unpackPubKey = (packed: bigint): PubKey => { + const pubKey = unpackPublicKey(packed); + return pubKey.map((x: string) => BigInt(x)) as PubKey; +}; + +/** + * @param privKey A private key generated using genPrivKey() + * @returns A public key associated with the private key + */ +export const genPubKey = (privKey: PrivKey): PubKey => { + // Check whether privKey is a field element + assert(BigInt(privKey) < SNARK_FIELD_SIZE); + + const key = derivePublicKey(privKey); + return [BigInt(key[0]), BigInt(key[1])]; +}; + +/** + * Generates a keypair. + * @returns a keypair + */ +export const genKeypair = (): Keypair => { + const privKey = genPrivKey(); + const pubKey = genPubKey(privKey); + + const keypair: Keypair = { privKey, pubKey }; + + return keypair; +}; + +/** + * Generates an Elliptic-Curve Diffie–Hellman (ECDH) shared key given a private + * key and a public key. + * @param privKey A private key generated using genPrivKey() + * @param pubKey A public key generated using genPubKey() + * @returns The ECDH shared key. + */ +export const genEcdhSharedKey = (privKey: PrivKey, pubKey: PubKey): EcdhSharedKey => + mulPointEscalar(pubKey as Point, formatPrivKeyForBabyJub(privKey)); diff --git a/crypto/ts/utils.ts b/crypto/ts/utils.ts index 397b5e5789..5a01f7566c 100644 --- a/crypto/ts/utils.ts +++ b/crypto/ts/utils.ts @@ -1,6 +1,6 @@ import { OptimisedMT as IncrementalQuinTree } from "optimisedmt"; -import { hash5, hashLeftRight } from "./crypto"; +import { hash5, hashLeftRight } from "./hashing"; /** * Calculate the depth of a tree given the number of leaves From 7775a8b3295f29b098446d3e78a4200c03c847dd Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Fri, 5 Jan 2024 14:49:54 +0000 Subject: [PATCH 24/37] test(topup): implement test cases for the topup feature --- circuits/package.json | 26 +- circuits/ts/__tests__/ProcessMessages.test.ts | 70 ++ cli/testScript.sh | 53 ++ cli/tests/e2e.test.ts | 82 +++ cli/ts/commands/airdrop.ts | 7 +- contracts/tests/Poll.test.ts | 46 +- contracts/tests/utils.ts | 1 + contracts/ts/types.ts | 2 + core/package.json | 4 +- core/ts/__tests__/MaciState.test.ts | 653 ++---------------- core/ts/__tests__/e2e.test.ts | 597 ++++++++++++++++ 11 files changed, 916 insertions(+), 625 deletions(-) create mode 100644 cli/testScript.sh create mode 100644 core/ts/__tests__/e2e.test.ts diff --git a/circuits/package.json b/circuits/package.json index 32e67f2185..8afc86fddf 100644 --- a/circuits/package.json +++ b/circuits/package.json @@ -9,19 +9,19 @@ "watch": "tsc --watch", "build": "tsc", "test": "ts-mocha --exit ts/__tests__/*.test.ts", - "test-hasher": "ts-mocha --exit ts/__tests__/Hasher.test.ts", - "test-unpackElement": "ts-mocha --exit ts/__tests__/UnpackElement.test.ts", - "test-slAndBallotTransformer": "ts-mocha --exit ts/__tests__/StateLeafAndBallotTransformer.test.ts", - "test-messageToCommand": "ts-mocha --exit ts/__tests__/MessageToCommand.test.ts", - "test-messageValidator": "ts-mocha --exit ts/__tests__/MessageValidator.test.ts", - "test-verifySignature": "ts-mocha --exit ts/__tests__/VerifySignature.test.ts", - "test-splicer": "ts-mocha --exit ts/__tests__/Splicer.test.ts", - "test-ecdh": "ts-mocha --exit ts/__tests__/Ecdh.test.ts", - "test-privToPubKey": "ts-mocha --exit ts/__tests__/PrivToPubKey.test.ts", - "test-calculateTotal": "ts-mocha --exit ts/__tests__/CalculateTotal.test.ts", - "test-processMessages": "NODE_OPTIONS=--max-old-space-size=4096 ts-mocha --exit ts/__tests__/ProcessMessages.test.ts", - "test-tallyVotes": "NODE_OPTIONS=--max-old-space-size=4096 ts-mocha --exit ts/__tests__/TallyVotes.test.ts", - "test-ceremonyParams": "ts-mocha --exit ts/__tests__/CeremonyParams.test.ts" + "test:hasher": "ts-mocha --exit ts/__tests__/Hasher.test.ts", + "test:unpackElement": "ts-mocha --exit ts/__tests__/UnpackElement.test.ts", + "test:slAndBallotTransformer": "ts-mocha --exit ts/__tests__/StateLeafAndBallotTransformer.test.ts", + "test:messageToCommand": "ts-mocha --exit ts/__tests__/MessageToCommand.test.ts", + "test:messageValidator": "ts-mocha --exit ts/__tests__/MessageValidator.test.ts", + "test:verifySignature": "ts-mocha --exit ts/__tests__/VerifySignature.test.ts", + "test:splicer": "ts-mocha --exit ts/__tests__/Splicer.test.ts", + "test:ecdh": "ts-mocha --exit ts/__tests__/Ecdh.test.ts", + "test:privToPubKey": "ts-mocha --exit ts/__tests__/PrivToPubKey.test.ts", + "test:calculateTotal": "ts-mocha --exit ts/__tests__/CalculateTotal.test.ts", + "test:processMessages": "NODE_OPTIONS=--max-old-space-size=4096 ts-mocha --exit ts/__tests__/ProcessMessages.test.ts", + "test:tallyVotes": "NODE_OPTIONS=--max-old-space-size=4096 ts-mocha --exit ts/__tests__/TallyVotes.test.ts", + "test:ceremonyParams": "ts-mocha --exit ts/__tests__/CeremonyParams.test.ts" }, "dependencies": { "circomlib": "https://github.com/weijiekoh/circomlib#ac85e82c1914d47789e2032fb11ceb2cfdd38a2b", diff --git a/circuits/ts/__tests__/ProcessMessages.test.ts b/circuits/ts/__tests__/ProcessMessages.test.ts index e76cd69a53..5a88417c0a 100644 --- a/circuits/ts/__tests__/ProcessMessages.test.ts +++ b/circuits/ts/__tests__/ProcessMessages.test.ts @@ -427,4 +427,74 @@ describe("ProcessMessage circuit", function test() { }); }); }); + + describe("1 user, 1 topup, 2 messages", () => { + const maciState = new MaciState(STATE_TREE_DEPTH); + const voteOptionIndex = BigInt(0); + let stateIndex: bigint; + let pollId: number; + let poll: Poll; + const userKeypair = new Keypair(); + + before(() => { + // Sign up and publish + stateIndex = BigInt( + maciState.signUp(userKeypair.pubKey, voiceCreditBalance, BigInt(Math.floor(Date.now() / 1000))), + ); + + pollId = maciState.deployPoll( + BigInt(Math.floor(Date.now() / 1000) + duration), + maxValues, + treeDepths, + messageBatchSize, + coordinatorKeypair, + ); + + poll = maciState.polls[pollId]; + }); + + it("should work when publishing 2 vote messages and a topup (the second vote uses more than initial voice credit balance)", async () => { + // First command (valid) + const command1 = new PCommand( + stateIndex, // BigInt(1), + userKeypair.pubKey, + voteOptionIndex + 1n, // voteOptionIndex, + 5n, // vote weight + BigInt(2), // nonce + BigInt(pollId), + ); + + const signature1 = command1.sign(userKeypair.privKey); + + const ecdhKeypair1 = new Keypair(); + const sharedKey1 = Keypair.genEcdhSharedKey(ecdhKeypair1.privKey, coordinatorKeypair.pubKey); + const message1 = command1.encrypt(signature1, sharedKey1); + + poll.publishMessage(message1, ecdhKeypair1.pubKey); + + poll.topupMessage(new Message(2n, [BigInt(stateIndex), 50n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n])); + + // First command (valid) + const command = new PCommand( + stateIndex, // BigInt(1), + userKeypair.pubKey, + voteOptionIndex, // voteOptionIndex, + 10n, // vote weight + BigInt(1), // nonce + BigInt(pollId), + ); + + const signature = command.sign(userKeypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + const message = command.encrypt(signature, sharedKey); + + poll.publishMessage(message, ecdhKeypair.pubKey); + + const inputs = poll.processMessages(pollId); + const witness = await circuit.calculateWitness(inputs, true); + await circuit.checkConstraints(witness); + }); + }); }); diff --git a/cli/testScript.sh b/cli/testScript.sh new file mode 100644 index 0000000000..7c64431381 --- /dev/null +++ b/cli/testScript.sh @@ -0,0 +1,53 @@ +#! /bin/bash +# rm -r ./proofs +# rm tally.json +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js deployVkRegistry +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js setVerifyingKeys \ + --state-tree-depth 10 \ + --int-state-tree-depth 1 \ + --msg-tree-depth 2 \ + --vote-option-tree-depth 2 \ + --msg-batch-depth 1 \ + --process-messages-zkey ./zkeys/ProcessMessages_10-2-1-2_test.0.zkey \ + --tally-votes-zkey ./zkeys/TallyVotes_10-1-2_test.0.zkey +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js create -s 10 +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js deployPoll \ + --pubkey macipk.ea638a3366ed91f2e955110888573861f7c0fc0bb5fb8b8dca9cd7a08d7d6b93 \ + -t 30 -g 25 -mv 25 -i 1 -m 2 -b 1 -v 2 +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js signup \ + --pubkey macipk.e743ffb5298ef0f5c1f63b6464a48fea19ea7ee5a885c67ae1b24a1d04f03f07 +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js publish \ + --pubkey macipk.e743ffb5298ef0f5c1f63b6464a48fea19ea7ee5a885c67ae1b24a1d04f03f07 \ + --privkey macisk.0ab0281365e01cff60afc62310daec765e590487bf989a7c4986ebc3fd49895e \ + --state-index 1 \ + --vote-option-index 0 \ + --new-vote-weight 9 \ + --nonce 1 \ + --poll-id 0 +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js publish \ + --pubkey macipk.e743ffb5298ef0f5c1f63b6464a48fea19ea7ee5a885c67ae1b24a1d04f03f07 \ + --privkey macisk.0ab0281365e01cff60afc62310daec765e590487bf989a7c4986ebc3fd49895e \ + --state-index 1 \ + --vote-option-index 1 \ + --new-vote-weight 9 \ + --nonce 2 \ + --poll-id 0 +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js timeTravel -s 100 +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js mergeSignups --poll-id 0 +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js mergeMessages --poll-id 0 +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js genProofs \ + --privkey macisk.1751146b59d32e3c0d7426de411218172428263f93b2fc4d981c036047a4d8c0 \ + --poll-id 0 \ + --process-zkey ./zkeys/ProcessMessages_10-2-1-2_test.0.zkey \ + --tally-zkey ./zkeys/TallyVotes_10-1-2_test.0.zkey \ + --tally-file tally.json \ + --output proofs/ \ + -tw ./zkeys/TallyVotes_10-1-2_test_js/TallyVotes_10-1-2_test.wasm \ + -pw ./zkeys/ProcessMessages_10-2-1-2_test_js/ProcessMessages_10-2-1-2_test.wasm \ + -w true +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js proveOnChain \ + --poll-id 0 \ + --proof-dir proofs/ +HARDHAT_CONFIG=./build/hardhat.config.js node build/ts/index.js verify \ + --poll-id 0 \ + --tally-file tally.json diff --git a/cli/tests/e2e.test.ts b/cli/tests/e2e.test.ts index e0357e6ab6..3016bbaf9c 100644 --- a/cli/tests/e2e.test.ts +++ b/cli/tests/e2e.test.ts @@ -1,5 +1,6 @@ import { existsSync, unlinkSync } from "fs"; import { + airdrop, checkVerifyingKeys, deploy, deployPoll, @@ -13,6 +14,7 @@ import { setVerifyingKeys, signup, timeTravel, + topup, verify, } from "../ts/commands"; import { @@ -1236,4 +1238,84 @@ describe("e2e tests", function () { await verify("0", testTallyFilePath); }); }); + + describe("topup message", () => { + const user = new Keypair(); + const tokenAmount = 100; + let stateIndex: number | undefined; + + after(() => { + cleanVanilla(); + }); + + before(async () => { + // deploy the smart contracts + maciAddresses = await deploy(STATE_TREE_DEPTH); + // deploy a poll contract + pollAddresses = await deployPoll( + pollDuration, + maxMessages, + maxVoteOptions, + INT_STATE_TREE_DEPTH, + MSG_BATCH_DEPTH, + MSG_TREE_DEPTH, + VOTE_OPTION_TREE_DEPTH, + coordinatorPubKey, + ); + }); + + it("should signup one user", async () => { + stateIndex = Number.parseInt(await signup(user.pubKey.serialize()), 10); + }); + + it("should airdrop topup tokens to the coordinator user", async () => { + await airdrop(tokenAmount, maciAddresses.topupCreditAddress, 0, maciAddresses.maciAddress, true); + }); + + it("should publish one topup message", async () => { + await topup(tokenAmount, stateIndex!, 0, maciAddresses.maciAddress, true); + }); + + it("should publish one vote message", async () => { + await publish( + user.pubKey.serialize(), + 1, + 0, + 1, + 0, + 9, + maciAddresses.maciAddress, + genRandomSalt().toString(), + user.privKey.serialize(), + ); + }); + + it("should generate proofs and verify them", async () => { + await timeTravel(pollDuration, true); + await mergeMessages(0); + await mergeSignups(0); + await genProofs( + testProofsDirPath, + testTallyFilePath, + tallyVotesTestZkeyPath, + processMessageTestZkeyPath, + 0, + undefined, + undefined, + testRapidsnarkPath, + testProcessMessagesWitnessPath, + testTallyVotesWitnessPath, + undefined, + coordinatorPrivKey, + undefined, + undefined, + testProcessMessagesWasmPath, + testTallyVotesWasmPath, + undefined, + useWasm, + ); + await proveOnChain("0", testProofsDirPath); + await verify("0", testTallyFilePath); + }); + }); }); diff --git a/cli/ts/commands/airdrop.ts b/cli/ts/commands/airdrop.ts index 34ade30232..350c10b487 100644 --- a/cli/ts/commands/airdrop.ts +++ b/cli/ts/commands/airdrop.ts @@ -1,5 +1,5 @@ import { readContractAddress } from "../utils/storage"; -import { Contract, MaxUint256 } from "ethers"; +import { Contract } from "ethers"; import { contractExists } from "../utils/contracts"; import { getDefaultSigner, parseArtifact } from "maci-contracts"; import { logError, logGreen, success } from "../utils/theme"; @@ -63,7 +63,7 @@ export const airdrop = async ( // if there is a poll id provided, we can pre-approve all of the tokens // so there is no need to do it afterwards - if (pollId) { + if (pollId !== undefined) { maciAddress = readContractAddress("MACI") ? readContractAddress("MACI") : maciAddress; if (!maciAddress) logError("Please provide a MACI contract address"); @@ -73,7 +73,8 @@ export const airdrop = async ( const pollAddr = await maciContract.getPoll(pollId); try { - const tx = await tokenContract.approve(pollAddr, MaxUint256, { gasLimit: 1000000 }); + const tx = await tokenContract.approve(pollAddr, amount, { gasLimit: 1000000 }); + await tx.wait(); logGreen(quiet, success(`Approved ${pollAddr} to spend ${amount} credits`)); diff --git a/contracts/tests/Poll.test.ts b/contracts/tests/Poll.test.ts index 87e90297dd..2a1f903a0c 100644 --- a/contracts/tests/Poll.test.ts +++ b/contracts/tests/Poll.test.ts @@ -7,8 +7,8 @@ import { NOTHING_UP_MY_SLEEVE } from "maci-crypto"; import { Keypair, Message, PCommand, PubKey } from "maci-domainobjs"; import { parseArtifact } from "../ts/abi"; -import { getDefaultSigner } from "../ts/utils"; -import { AccQueue, MACI, Poll as PollContract } from "../typechain-types"; +import { getDefaultSigner, getSigners } from "../ts/utils"; +import { AccQueue, MACI, Poll as PollContract, TopupCredit } from "../typechain-types"; import { MESSAGE_TREE_DEPTH, @@ -26,6 +26,7 @@ describe("Poll", () => { let maciContract: MACI; let pollId: number; let pollContract: PollContract; + let topupCreditContract: TopupCredit; let signer: Signer; let deployTime: number; const coordinator = new Keypair(); @@ -39,6 +40,7 @@ describe("Poll", () => { signer = await getDefaultSigner(); const r = await deployTestContracts(initialVoiceCreditBalance, STATE_TREE_DEPTH, signer, true); maciContract = r.maciContract; + topupCreditContract = r.topupCreditContract; // deploy on chain poll const tx = await maciContract.deployPoll(duration, maxValues, treeDepths, coordinator.pubKey.asContractParam(), { @@ -126,6 +128,46 @@ describe("Poll", () => { }); }); + describe("topup", () => { + let voter: Signer; + + before(async () => { + // transfer tokens to a user and pre-approve + [, voter] = await getSigners(); + await topupCreditContract.airdropTo(voter.getAddress(), 200n); + await topupCreditContract.connect(voter).approve(await pollContract.getAddress(), 1000n); + }); + + it("should allow to publish a topup message when the caller has enough topup tokens", async () => { + const tx = await pollContract.connect(voter).topup(1n, 50n); + const receipt = await tx.wait(); + expect(receipt?.status).to.eq(1); + + // publish on local maci state + maciState.polls[pollId].topupMessage(new Message(2n, [1n, 50n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n])); + }); + + it("should throw when the user does not have enough tokens", async () => { + await expect(pollContract.connect(signer).topup(1n, 50n)).to.be.revertedWith("ERC20: insufficient allowance"); + }); + + it("should emit an event when publishing a topup message", async () => { + expect(await pollContract.connect(voter).topup(1n, 50n)).to.emit(pollContract, "TopupMessage"); + // publish on local maci state + maciState.polls[pollId].topupMessage(new Message(2n, [1n, 50n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n])); + }); + + it("should successfully increase the number of messages", async () => { + const numMessages = await pollContract.numMessages(); + await pollContract.connect(voter).topup(1n, 50n); + const newNumMessages = await pollContract.numMessages(); + expect(newNumMessages.toString()).to.eq((numMessages + 1n).toString()); + + // publish on local maci state + maciState.polls[pollId].topupMessage(new Message(2n, [1n, 50n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n])); + }); + }); + describe("publishMessage", () => { it("should publish a message to the Poll contract", async () => { const keypair = new Keypair(); diff --git a/contracts/tests/utils.ts b/contracts/tests/utils.ts index 7e1fa4607c..0a6fc19f90 100644 --- a/contracts/tests/utils.ts +++ b/contracts/tests/utils.ts @@ -570,5 +570,6 @@ export const deployTestContracts = async ( mpContract, tallyContract, subsidyContract, + topupCreditContract, }; }; diff --git a/contracts/ts/types.ts b/contracts/ts/types.ts index e12e8c8bcb..10209b1cd1 100644 --- a/contracts/ts/types.ts +++ b/contracts/ts/types.ts @@ -14,6 +14,7 @@ import type { PoseidonT6, Subsidy, Tally, + TopupCredit, VkRegistry, } from "../typechain-types"; import type { BigNumberish, Fragment, JsonFragment } from "ethers"; @@ -68,6 +69,7 @@ export interface IDeployedTestContracts { vkRegistryContract: VkRegistry; mpContract: MessageProcessor; tallyContract: Tally; + topupCreditContract: TopupCredit; subsidyContract?: Subsidy; } diff --git a/core/package.json b/core/package.json index 88de0df614..9b2a184691 100644 --- a/core/package.json +++ b/core/package.json @@ -7,8 +7,8 @@ "scripts": { "watch": "tsc --watch", "build": "tsc", - "test-processMessage": "ts-mocha --exit ts/__tests__/ProcessMessage.test.ts", - "test-maciState": "ts-mocha --exit ts/__tests__/MaciState.test.ts", + "test:e2e": "ts-mocha --exit ts/__tests__/e2e.test.ts", + "test:unit": "ts-mocha --exit ts/__tests__/MaciState.test.ts", "test": "nyc ts-mocha --exit ts/__tests__/*.test.ts" }, "dependencies": { diff --git a/core/ts/__tests__/MaciState.test.ts b/core/ts/__tests__/MaciState.test.ts index f2d023f730..2d7adb337b 100644 --- a/core/ts/__tests__/MaciState.test.ts +++ b/core/ts/__tests__/MaciState.test.ts @@ -1,272 +1,17 @@ import { expect } from "chai"; -import { hash5, NOTHING_UP_MY_SLEEVE, IncrementalQuinTree, AccQueue } from "maci-crypto"; -import { PCommand, Message, Keypair, StateLeaf, blankStateLeafHash, PrivKey, Ballot } from "maci-domainobjs"; +import { PCommand, Message, Keypair, StateLeaf, PrivKey, Ballot } from "maci-domainobjs"; import { existsSync, readFileSync, unlinkSync, writeFileSync } from "fs"; import { MaciState } from "../MaciState"; -import { Poll } from "../Poll"; -import { STATE_TREE_DEPTH, STATE_TREE_ARITY, STATE_TREE_SUBDEPTH } from "../utils/constants"; +import { STATE_TREE_DEPTH } from "../utils/constants"; import { IJsonMaciState } from "../utils/types"; -import { packProcessMessageSmallVals, unpackProcessMessageSmallVals } from "../utils/utils"; import { coordinatorKeypair, duration, maxValues, messageBatchSize, treeDepths, voiceCreditBalance } from "./constants"; -import { calculateTotal } from "./utils"; describe("MaciState", function test() { this.timeout(100000); - describe("Process and tally 1 message from 1 user", () => { - let maciState: MaciState; - let pollId: number; - let poll: Poll; - let msgTree: IncrementalQuinTree; - const voteWeight = BigInt(9); - const voteOptionIndex = BigInt(0); - let stateIndex: number; - const userKeypair = new Keypair(); - - before(() => { - maciState = new MaciState(STATE_TREE_DEPTH); - msgTree = new IncrementalQuinTree(treeDepths.messageTreeDepth, NOTHING_UP_MY_SLEEVE, 5, hash5); - }); - - // The end result should be that option 0 gets 3 votes - // because the user spends 9 voice credits on it - it("the state root should be correct", () => { - const accumulatorQueue: AccQueue = new AccQueue(STATE_TREE_SUBDEPTH, STATE_TREE_ARITY, blankStateLeafHash); - const timestamp = BigInt(Math.floor(Date.now() / 1000)); - const stateLeaf = new StateLeaf(userKeypair.pubKey, voiceCreditBalance, timestamp); - - accumulatorQueue.enqueue(blankStateLeafHash); - accumulatorQueue.enqueue(stateLeaf.hash()); - accumulatorQueue.mergeSubRoots(0); - accumulatorQueue.merge(STATE_TREE_DEPTH); - - stateIndex = maciState.signUp(userKeypair.pubKey, voiceCreditBalance, timestamp); - expect(stateIndex.toString()).to.eq("1"); - - expect(accumulatorQueue.getRoot(STATE_TREE_DEPTH)?.toString()).to.eq(maciState.stateTree.root.toString()); - }); - - it("the message root should be correct", () => { - pollId = maciState.deployPoll( - BigInt(Math.floor(Date.now() / 1000) + duration), - maxValues, - treeDepths, - messageBatchSize, - coordinatorKeypair, - ); - - poll = maciState.polls[pollId]; - - const command = new PCommand( - BigInt(stateIndex), - userKeypair.pubKey, - voteOptionIndex, - voteWeight, - BigInt(1), - BigInt(pollId), - ); - - const signature = command.sign(userKeypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); - const message = command.encrypt(signature, sharedKey); - - poll.publishMessage(message, ecdhKeypair.pubKey); - msgTree.insert(message.hash(ecdhKeypair.pubKey)); - - // Use the accumulator queue to compare the root of the message tree - const accumulatorQueue: AccQueue = new AccQueue( - treeDepths.messageTreeSubDepth, - STATE_TREE_ARITY, - NOTHING_UP_MY_SLEEVE, - ); - accumulatorQueue.enqueue(message.hash(ecdhKeypair.pubKey)); - accumulatorQueue.mergeSubRoots(0); - accumulatorQueue.merge(treeDepths.messageTreeDepth); - - expect(accumulatorQueue.getRoot(treeDepths.messageTreeDepth)?.toString()).to.eq(msgTree.root.toString()); - }); - - it("packProcessMessageSmallVals and unpackProcessMessageSmallVals", () => { - const maxVoteOptions = BigInt(1); - const numUsers = BigInt(2); - const batchStartIndex = 5; - const batchEndIndex = 10; - const packedVals = packProcessMessageSmallVals(maxVoteOptions, numUsers, batchStartIndex, batchEndIndex); - - const unpacked = unpackProcessMessageSmallVals(packedVals); - expect(unpacked.maxVoteOptions.toString()).to.eq(maxVoteOptions.toString()); - expect(unpacked.numUsers.toString()).to.eq(numUsers.toString()); - expect(unpacked.batchStartIndex.toString()).to.eq(batchStartIndex.toString()); - expect(unpacked.batchEndIndex.toString()).to.eq(batchEndIndex.toString()); - }); - - it("Process a batch of messages (though only 1 message is in the batch)", () => { - poll.processMessages(pollId); - - // Check the ballot - expect(poll.ballots[1].votes[Number(voteOptionIndex)].toString()).to.eq(voteWeight.toString()); - // Check the state leaf in the poll - expect(poll.stateLeaves[1].voiceCreditBalance.toString()).to.eq( - (voiceCreditBalance - voteWeight * voteWeight).toString(), - ); - }); - - it("Tally ballots", () => { - const initialTotal = calculateTotal(maciState.polls[pollId].tallyResult); - expect(initialTotal.toString()).to.eq("0"); - - expect(poll.hasUntalliedBallots()).to.eq(true); - - poll.tallyVotes(); - - const finalTotal = calculateTotal(maciState.polls[pollId].tallyResult); - expect(finalTotal.toString()).to.eq(voteWeight.toString()); - }); - }); - - describe(`Process and tally ${messageBatchSize * 2} messages from ${messageBatchSize} users`, () => { - let maciState: MaciState; - let pollId: number; - let poll: Poll; - const voteWeight = BigInt(9); - - const users: Keypair[] = []; - - before(() => { - maciState = new MaciState(STATE_TREE_DEPTH); - // Sign up and vote - for (let i = 0; i < messageBatchSize - 1; i += 1) { - const userKeypair = new Keypair(); - users.push(userKeypair); - - maciState.signUp(userKeypair.pubKey, voiceCreditBalance, BigInt(Math.floor(Date.now() / 1000))); - } - - pollId = maciState.deployPoll( - BigInt(Math.floor(Date.now() / 1000) + duration), - maxValues, - treeDepths, - messageBatchSize, - coordinatorKeypair, - ); - poll = maciState.polls[pollId]; - }); - - it("should process votes correctly", () => { - // 24 valid votes - for (let i = 0; i < messageBatchSize - 1; i += 1) { - const userKeypair = users[i]; - - const command = new PCommand( - BigInt(i + 1), - userKeypair.pubKey, - BigInt(i), // vote option index - voteWeight, - BigInt(1), - BigInt(pollId), - ); - - const signature = command.sign(userKeypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); - const message = command.encrypt(signature, sharedKey); - poll.publishMessage(message, ecdhKeypair.pubKey); - } - - expect(poll.messages.length).to.eq(messageBatchSize - 1); - - // 24 invalid votes - for (let i = 0; i < messageBatchSize - 1; i += 1) { - const userKeypair = users[i]; - const command = new PCommand( - BigInt(i + 1), - userKeypair.pubKey, - BigInt(i), // vote option index - voiceCreditBalance * BigInt(2), // invalid vote weight - BigInt(1), - BigInt(pollId), - ); - - const signature = command.sign(userKeypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); - const message = command.encrypt(signature, sharedKey); - poll.publishMessage(message, ecdhKeypair.pubKey); - } - - // 48 messages in total - expect(poll.messages.length).to.eq(2 * (messageBatchSize - 1)); - - expect(poll.currentMessageBatchIndex).to.eq(undefined); - expect(poll.numBatchesProcessed).to.eq(0); - - // Process messages - poll.processMessages(pollId); - - // currentMessageBatchIndex is 0 because the current batch starts - // with index 0. - expect(poll.currentMessageBatchIndex).to.eq(0); - expect(poll.numBatchesProcessed).to.eq(1); - - // Process messages - poll.processMessages(pollId); - - expect(poll.currentMessageBatchIndex).to.eq(0); - expect(poll.numBatchesProcessed).to.eq(2); - - for (let i = 1; i < messageBatchSize; i += 1) { - const leaf = poll.ballots[i].votes[i - 1]; - expect(leaf.toString()).to.eq(voteWeight.toString()); - } - - // Test processAllMessages - const r = poll.processAllMessages(); - - expect(r.stateLeaves.length).to.eq(poll.stateLeaves.length); - - expect(r.ballots.length).to.eq(poll.ballots.length); - - expect(r.ballots.length).to.eq(r.stateLeaves.length); - - for (let i = 0; i < r.stateLeaves.length; i += 1) { - expect(r.stateLeaves[i].equals(poll.stateLeaves[i])).to.eq(true); - - expect(r.ballots[i].equals(poll.ballots[i])).to.eq(true); - } - }); - - it("should tally ballots correctly", () => { - // Start with tallyResult = [0...0] - const total = calculateTotal(maciState.polls[pollId].tallyResult); - expect(total.toString()).to.eq("0"); - - // Check that there are untallied results - expect(poll.hasUntalliedBallots()).to.eq(true); - - // First batch tally - poll.tallyVotes(); - - // Recall that each user `i` cast the same number of votes for - // their option `i` - for (let i = 0; i < maciState.polls[pollId].tallyResult.length - 1; i += 1) { - expect(maciState.polls[pollId].tallyResult[i].toString()).to.eq(voteWeight.toString()); - } - - expect(poll.hasUntalliedBallots()).to.eq(false); - - expect(() => { - poll.tallyVotes(); - }).to.throw(); - }); - }); - describe("Deep copy", () => { let pollId: number; let m1: MaciState; @@ -394,337 +139,6 @@ describe("MaciState", function test() { }); }); - describe("key changes", () => { - const user1Keypair = new Keypair(); - const user2Keypair = new Keypair(); - const user1SecondKeypair = new Keypair(); - const user2SecondKeypair = new Keypair(); - let pollId: number; - let user1StateIndex: number; - let user2StateIndex: number; - const user1VoteOptionIndex = BigInt(0); - const user2VoteOptionIndex = BigInt(1); - const user1VoteWeight = BigInt(9); - const user2VoteWeight = BigInt(3); - const user1NewVoteWeight = BigInt(5); - const user2NewVoteWeight = BigInt(7); - - describe("only user 1 changes key", () => { - const maciState: MaciState = new MaciState(STATE_TREE_DEPTH); - - before(() => { - // Sign up - user1StateIndex = maciState.signUp( - user1Keypair.pubKey, - voiceCreditBalance, - BigInt(Math.floor(Date.now() / 1000)), - ); - user2StateIndex = maciState.signUp( - user2Keypair.pubKey, - voiceCreditBalance, - BigInt(Math.floor(Date.now() / 1000)), - ); - - // deploy a poll - pollId = maciState.deployPoll( - BigInt(Math.floor(Date.now() / 1000) + duration), - maxValues, - treeDepths, - messageBatchSize, - coordinatorKeypair, - ); - }); - it("should submit a vote for each user", () => { - const poll = maciState.polls[pollId]; - const command1 = new PCommand( - BigInt(user1StateIndex), - user1Keypair.pubKey, - user1VoteOptionIndex, - user1VoteWeight, - BigInt(1), - BigInt(pollId), - ); - - const signature1 = command1.sign(user1Keypair.privKey); - - const ecdhKeypair1 = new Keypair(); - const sharedKey1 = Keypair.genEcdhSharedKey(ecdhKeypair1.privKey, coordinatorKeypair.pubKey); - - const message1 = command1.encrypt(signature1, sharedKey1); - poll.publishMessage(message1, ecdhKeypair1.pubKey); - - const command2 = new PCommand( - BigInt(user2StateIndex), - user2Keypair.pubKey, - user2VoteOptionIndex, - user2VoteWeight, - BigInt(1), - BigInt(pollId), - ); - - const signature2 = command2.sign(user2Keypair.privKey); - - const ecdhKeypair2 = new Keypair(); - const sharedKey2 = Keypair.genEcdhSharedKey(ecdhKeypair2.privKey, coordinatorKeypair.pubKey); - - const message2 = command2.encrypt(signature2, sharedKey2); - poll.publishMessage(message2, ecdhKeypair2.pubKey); - }); - - it("user1 sends a keychange message with a new vote", () => { - const poll = maciState.polls[pollId]; - const command = new PCommand( - BigInt(user1StateIndex), - user1SecondKeypair.pubKey, - user1VoteOptionIndex, - user1NewVoteWeight, - BigInt(1), - BigInt(pollId), - ); - - const signature = command.sign(user1Keypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); - - const message = command.encrypt(signature, sharedKey); - poll.publishMessage(message, ecdhKeypair.pubKey); - }); - - it("should perform the processing and tallying correctly", () => { - const poll = maciState.polls[pollId]; - poll.processMessages(pollId); - poll.tallyVotes(); - expect(poll.perVOSpentVoiceCredits[0].toString()).to.eq((user1NewVoteWeight * user1NewVoteWeight).toString()); - expect(poll.perVOSpentVoiceCredits[1].toString()).to.eq((user2VoteWeight * user2VoteWeight).toString()); - }); - - it("should confirm that the user key pair was changed (user's 2 one has not)", () => { - const poll = maciState.polls[pollId]; - const stateLeaf1 = poll.stateLeaves[user1StateIndex]; - const stateLeaf2 = poll.stateLeaves[user2StateIndex]; - expect(stateLeaf1.pubKey.equals(user1SecondKeypair.pubKey)).to.eq(true); - expect(stateLeaf2.pubKey.equals(user2Keypair.pubKey)).to.eq(true); - }); - }); - - describe("both users change key", () => { - const maciState: MaciState = new MaciState(STATE_TREE_DEPTH); - - before(() => { - // Sign up - user1StateIndex = maciState.signUp( - user1Keypair.pubKey, - voiceCreditBalance, - BigInt(Math.floor(Date.now() / 1000)), - ); - user2StateIndex = maciState.signUp( - user2Keypair.pubKey, - voiceCreditBalance, - BigInt(Math.floor(Date.now() / 1000)), - ); - - // deploy a poll - pollId = maciState.deployPoll( - BigInt(Math.floor(Date.now() / 1000) + duration), - maxValues, - treeDepths, - messageBatchSize, - coordinatorKeypair, - ); - }); - it("should submit a vote for each user", () => { - const poll = maciState.polls[pollId]; - const command1 = new PCommand( - BigInt(user1StateIndex), - user1Keypair.pubKey, - user1VoteOptionIndex, - user1VoteWeight, - BigInt(1), - BigInt(pollId), - ); - - const signature1 = command1.sign(user1Keypair.privKey); - - const ecdhKeypair1 = new Keypair(); - const sharedKey1 = Keypair.genEcdhSharedKey(ecdhKeypair1.privKey, coordinatorKeypair.pubKey); - - const message1 = command1.encrypt(signature1, sharedKey1); - poll.publishMessage(message1, ecdhKeypair1.pubKey); - - const command2 = new PCommand( - BigInt(user2StateIndex), - user2Keypair.pubKey, - user2VoteOptionIndex, - user2VoteWeight, - BigInt(1), - BigInt(pollId), - ); - - const signature2 = command2.sign(user2Keypair.privKey); - - const ecdhKeypair2 = new Keypair(); - const sharedKey2 = Keypair.genEcdhSharedKey(ecdhKeypair2.privKey, coordinatorKeypair.pubKey); - - const message2 = command2.encrypt(signature2, sharedKey2); - poll.publishMessage(message2, ecdhKeypair2.pubKey); - }); - - it("user1 sends a keychange message with a new vote", () => { - const poll = maciState.polls[pollId]; - const command = new PCommand( - BigInt(user1StateIndex), - user1SecondKeypair.pubKey, - user1VoteOptionIndex, - user1NewVoteWeight, - BigInt(1), - BigInt(pollId), - ); - - const signature = command.sign(user1Keypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); - - const message = command.encrypt(signature, sharedKey); - poll.publishMessage(message, ecdhKeypair.pubKey); - }); - - it("user2 sends a keychange message with a new vote", () => { - const poll = maciState.polls[pollId]; - const command = new PCommand( - BigInt(user2StateIndex), - user2SecondKeypair.pubKey, - user2VoteOptionIndex, - user2NewVoteWeight, - BigInt(1), - BigInt(pollId), - ); - - const signature = command.sign(user2Keypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); - - const message = command.encrypt(signature, sharedKey); - poll.publishMessage(message, ecdhKeypair.pubKey); - }); - - it("should perform the processing and tallying correctly", () => { - const poll = maciState.polls[pollId]; - poll.processMessages(pollId); - poll.tallyVotes(); - expect(poll.perVOSpentVoiceCredits[0].toString()).to.eq((user1NewVoteWeight * user1NewVoteWeight).toString()); - expect(poll.perVOSpentVoiceCredits[1].toString()).to.eq((user2NewVoteWeight * user2NewVoteWeight).toString()); - }); - - it("should confirm that the users key pairs were changed", () => { - const poll = maciState.polls[pollId]; - const stateLeaf1 = poll.stateLeaves[user1StateIndex]; - const stateLeaf2 = poll.stateLeaves[user2StateIndex]; - expect(stateLeaf1.pubKey.equals(user1SecondKeypair.pubKey)).to.eq(true); - expect(stateLeaf2.pubKey.equals(user2SecondKeypair.pubKey)).to.eq(true); - }); - }); - - describe("user1 changes key, but messages are in different batches", () => { - const maciState = new MaciState(STATE_TREE_DEPTH); - - before(() => { - // Sign up - user1StateIndex = maciState.signUp( - user1Keypair.pubKey, - voiceCreditBalance, - BigInt(Math.floor(Date.now() / 1000)), - ); - - // deploy a poll - pollId = maciState.deployPoll( - BigInt(Math.floor(Date.now() / 1000) + duration), - maxValues, - treeDepths, - messageBatchSize, - coordinatorKeypair, - ); - }); - - it("should submit a vote for one user in one batch", () => { - const poll = maciState.polls[pollId]; - const command1 = new PCommand( - BigInt(user1StateIndex), - user1Keypair.pubKey, - user1VoteOptionIndex, - user1VoteWeight, - BigInt(1), - BigInt(pollId), - ); - - const signature1 = command1.sign(user1Keypair.privKey); - - const ecdhKeypair1 = new Keypair(); - const sharedKey1 = Keypair.genEcdhSharedKey(ecdhKeypair1.privKey, coordinatorKeypair.pubKey); - - const message1 = command1.encrypt(signature1, sharedKey1); - poll.publishMessage(message1, ecdhKeypair1.pubKey); - }); - - it("should fill the batch with random messages", () => { - const poll = maciState.polls[pollId]; - for (let i = 0; i < messageBatchSize - 1; i += 1) { - const command = new PCommand( - BigInt(1), - user1Keypair.pubKey, - user1VoteOptionIndex, - user1VoteWeight, - BigInt(2), - BigInt(pollId), - ); - - const signature = command.sign(user1Keypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); - - const message = command.encrypt(signature, sharedKey); - poll.publishMessage(message, ecdhKeypair.pubKey); - } - }); - - it("should submit a new message in a new batch", () => { - const poll = maciState.polls[pollId]; - const command1 = new PCommand( - BigInt(user1StateIndex), - user1SecondKeypair.pubKey, - user1VoteOptionIndex, - user1NewVoteWeight, - BigInt(1), - BigInt(pollId), - ); - - const signature1 = command1.sign(user1Keypair.privKey); - - const ecdhKeypair1 = new Keypair(); - const sharedKey1 = Keypair.genEcdhSharedKey(ecdhKeypair1.privKey, coordinatorKeypair.pubKey); - - const message1 = command1.encrypt(signature1, sharedKey1); - poll.publishMessage(message1, ecdhKeypair1.pubKey); - }); - - it("should perform the processing and tallying correctly", () => { - const poll = maciState.polls[pollId]; - poll.processAllMessages(); - poll.tallyVotes(); - expect(poll.perVOSpentVoiceCredits[0].toString()).to.eq((user1NewVoteWeight * user1NewVoteWeight).toString()); - }); - - it("should confirm that the user key pair was changed", () => { - const poll = maciState.polls[pollId]; - const stateLeaf1 = poll.stateLeaves[user1StateIndex]; - expect(stateLeaf1.pubKey.equals(user1SecondKeypair.pubKey)).to.eq(true); - }); - }); - }); - describe("processMessage", () => { const maciState = new MaciState(STATE_TREE_DEPTH); const pollId = maciState.deployPoll( @@ -1001,6 +415,7 @@ describe("MaciState", function test() { const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); poll.publishMessage(message, ecdhKeypair.pubKey); poll.copyStateFromMaci(); expect(() => { @@ -1012,27 +427,19 @@ describe("MaciState", function test() { expect(() => poll.processMessages(pollId)).to.not.throw; }); - it("should throw when called after all messages have been processed", () => { - const command = new PCommand( - BigInt(user1StateIndex), - user1Keypair.pubKey, - BigInt(0), - BigInt(1), - BigInt(0), - BigInt(pollId), - ); - - const signature = command.sign(user1Keypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); - - const message = command.encrypt(signature, sharedKey); + it("should correctly process a topup message and increase an user's voice credit balance", () => { + const topupMessage = new Message(2n, [BigInt(user1StateIndex), 50n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n]); - poll.publishMessage(message, ecdhKeypair.pubKey); + poll.topupMessage(topupMessage); + const balanceBefore = poll.stateLeaves[user1StateIndex].voiceCreditBalance; poll.processMessages(pollId); + // check balance + expect(poll.stateLeaves[user1StateIndex].voiceCreditBalance.toString()).to.eq((balanceBefore + 50n).toString()); + }); + + it("should throw when called after all messages have been processed", () => { expect(() => poll.processMessages(pollId)).to.throw("No more messages to process"); }); }); @@ -1136,4 +543,40 @@ describe("MaciState", function test() { expect(poll.hasUnprocessedMessages()).to.eq(false); }); }); + + describe("topup", () => { + const maciState = new MaciState(STATE_TREE_DEPTH); + const pollId = maciState.deployPoll( + BigInt(Math.floor(Date.now() / 1000) + duration), + maxValues, + treeDepths, + messageBatchSize, + coordinatorKeypair, + ); + const poll = maciState.polls[pollId]; + + it("should allow to publish a topup message", () => { + const user1Keypair = new Keypair(); + // signup the user + const user1StateIndex = maciState.signUp( + user1Keypair.pubKey, + voiceCreditBalance, + BigInt(Math.floor(Date.now() / 1000)), + ); + + const message = new Message(2n, [BigInt(user1StateIndex), 50n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n]); + + poll.topupMessage(message); + + expect(poll.messages.length).to.eq(1); + }); + + it("should throw if the message has an invalid message type", () => { + const message = new Message(1n, [1n, 50n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n]); + + expect(() => { + poll.topupMessage(message); + }).to.throw("A Topup message must have msgType 2"); + }); + }); }); diff --git a/core/ts/__tests__/e2e.test.ts b/core/ts/__tests__/e2e.test.ts new file mode 100644 index 0000000000..350a8aba44 --- /dev/null +++ b/core/ts/__tests__/e2e.test.ts @@ -0,0 +1,597 @@ +import { expect } from "chai"; +import { hash5, NOTHING_UP_MY_SLEEVE, IncrementalQuinTree, AccQueue } from "maci-crypto"; +import { PCommand, Keypair, StateLeaf, blankStateLeafHash } from "maci-domainobjs"; + +import { MaciState } from "../MaciState"; +import { Poll } from "../Poll"; +import { STATE_TREE_DEPTH, STATE_TREE_ARITY, STATE_TREE_SUBDEPTH } from "../utils/constants"; +import { packProcessMessageSmallVals, unpackProcessMessageSmallVals } from "../utils/utils"; + +import { coordinatorKeypair, duration, maxValues, messageBatchSize, treeDepths, voiceCreditBalance } from "./constants"; +import { calculateTotal } from "./utils"; + +describe("MaciState e2e", function test() { + this.timeout(300000); + + describe("key changes", () => { + const user1Keypair = new Keypair(); + const user2Keypair = new Keypair(); + const user1SecondKeypair = new Keypair(); + const user2SecondKeypair = new Keypair(); + let pollId: number; + let user1StateIndex: number; + let user2StateIndex: number; + const user1VoteOptionIndex = BigInt(0); + const user2VoteOptionIndex = BigInt(1); + const user1VoteWeight = BigInt(9); + const user2VoteWeight = BigInt(3); + const user1NewVoteWeight = BigInt(5); + const user2NewVoteWeight = BigInt(7); + + describe("only user 1 changes key", () => { + const maciState: MaciState = new MaciState(STATE_TREE_DEPTH); + + before(() => { + // Sign up + user1StateIndex = maciState.signUp( + user1Keypair.pubKey, + voiceCreditBalance, + BigInt(Math.floor(Date.now() / 1000)), + ); + user2StateIndex = maciState.signUp( + user2Keypair.pubKey, + voiceCreditBalance, + BigInt(Math.floor(Date.now() / 1000)), + ); + + // deploy a poll + pollId = maciState.deployPoll( + BigInt(Math.floor(Date.now() / 1000) + duration), + maxValues, + treeDepths, + messageBatchSize, + coordinatorKeypair, + ); + }); + it("should submit a vote for each user", () => { + const poll = maciState.polls[pollId]; + const command1 = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + user1VoteOptionIndex, + user1VoteWeight, + BigInt(1), + BigInt(pollId), + ); + + const signature1 = command1.sign(user1Keypair.privKey); + + const ecdhKeypair1 = new Keypair(); + const sharedKey1 = Keypair.genEcdhSharedKey(ecdhKeypair1.privKey, coordinatorKeypair.pubKey); + + const message1 = command1.encrypt(signature1, sharedKey1); + poll.publishMessage(message1, ecdhKeypair1.pubKey); + + const command2 = new PCommand( + BigInt(user2StateIndex), + user2Keypair.pubKey, + user2VoteOptionIndex, + user2VoteWeight, + BigInt(1), + BigInt(pollId), + ); + + const signature2 = command2.sign(user2Keypair.privKey); + + const ecdhKeypair2 = new Keypair(); + const sharedKey2 = Keypair.genEcdhSharedKey(ecdhKeypair2.privKey, coordinatorKeypair.pubKey); + + const message2 = command2.encrypt(signature2, sharedKey2); + poll.publishMessage(message2, ecdhKeypair2.pubKey); + }); + + it("user1 sends a keychange message with a new vote", () => { + const poll = maciState.polls[pollId]; + const command = new PCommand( + BigInt(user1StateIndex), + user1SecondKeypair.pubKey, + user1VoteOptionIndex, + user1NewVoteWeight, + BigInt(1), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + }); + + it("should perform the processing and tallying correctly", () => { + const poll = maciState.polls[pollId]; + poll.processMessages(pollId); + poll.tallyVotes(); + expect(poll.perVOSpentVoiceCredits[0].toString()).to.eq((user1NewVoteWeight * user1NewVoteWeight).toString()); + expect(poll.perVOSpentVoiceCredits[1].toString()).to.eq((user2VoteWeight * user2VoteWeight).toString()); + }); + + it("should confirm that the user key pair was changed (user's 2 one has not)", () => { + const poll = maciState.polls[pollId]; + const stateLeaf1 = poll.stateLeaves[user1StateIndex]; + const stateLeaf2 = poll.stateLeaves[user2StateIndex]; + expect(stateLeaf1.pubKey.equals(user1SecondKeypair.pubKey)).to.eq(true); + expect(stateLeaf2.pubKey.equals(user2Keypair.pubKey)).to.eq(true); + }); + }); + + describe("both users change key", () => { + const maciState: MaciState = new MaciState(STATE_TREE_DEPTH); + + before(() => { + // Sign up + user1StateIndex = maciState.signUp( + user1Keypair.pubKey, + voiceCreditBalance, + BigInt(Math.floor(Date.now() / 1000)), + ); + user2StateIndex = maciState.signUp( + user2Keypair.pubKey, + voiceCreditBalance, + BigInt(Math.floor(Date.now() / 1000)), + ); + + // deploy a poll + pollId = maciState.deployPoll( + BigInt(Math.floor(Date.now() / 1000) + duration), + maxValues, + treeDepths, + messageBatchSize, + coordinatorKeypair, + ); + }); + it("should submit a vote for each user", () => { + const poll = maciState.polls[pollId]; + const command1 = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + user1VoteOptionIndex, + user1VoteWeight, + BigInt(1), + BigInt(pollId), + ); + + const signature1 = command1.sign(user1Keypair.privKey); + + const ecdhKeypair1 = new Keypair(); + const sharedKey1 = Keypair.genEcdhSharedKey(ecdhKeypair1.privKey, coordinatorKeypair.pubKey); + + const message1 = command1.encrypt(signature1, sharedKey1); + poll.publishMessage(message1, ecdhKeypair1.pubKey); + + const command2 = new PCommand( + BigInt(user2StateIndex), + user2Keypair.pubKey, + user2VoteOptionIndex, + user2VoteWeight, + BigInt(1), + BigInt(pollId), + ); + + const signature2 = command2.sign(user2Keypair.privKey); + + const ecdhKeypair2 = new Keypair(); + const sharedKey2 = Keypair.genEcdhSharedKey(ecdhKeypair2.privKey, coordinatorKeypair.pubKey); + + const message2 = command2.encrypt(signature2, sharedKey2); + poll.publishMessage(message2, ecdhKeypair2.pubKey); + }); + + it("user1 sends a keychange message with a new vote", () => { + const poll = maciState.polls[pollId]; + const command = new PCommand( + BigInt(user1StateIndex), + user1SecondKeypair.pubKey, + user1VoteOptionIndex, + user1NewVoteWeight, + BigInt(1), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + }); + + it("user2 sends a keychange message with a new vote", () => { + const poll = maciState.polls[pollId]; + const command = new PCommand( + BigInt(user2StateIndex), + user2SecondKeypair.pubKey, + user2VoteOptionIndex, + user2NewVoteWeight, + BigInt(1), + BigInt(pollId), + ); + + const signature = command.sign(user2Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + }); + + it("should perform the processing and tallying correctly", () => { + const poll = maciState.polls[pollId]; + poll.processMessages(pollId); + poll.tallyVotes(); + expect(poll.perVOSpentVoiceCredits[0].toString()).to.eq((user1NewVoteWeight * user1NewVoteWeight).toString()); + expect(poll.perVOSpentVoiceCredits[1].toString()).to.eq((user2NewVoteWeight * user2NewVoteWeight).toString()); + }); + + it("should confirm that the users key pairs were changed", () => { + const poll = maciState.polls[pollId]; + const stateLeaf1 = poll.stateLeaves[user1StateIndex]; + const stateLeaf2 = poll.stateLeaves[user2StateIndex]; + expect(stateLeaf1.pubKey.equals(user1SecondKeypair.pubKey)).to.eq(true); + expect(stateLeaf2.pubKey.equals(user2SecondKeypair.pubKey)).to.eq(true); + }); + }); + + describe("user1 changes key, but messages are in different batches", () => { + const maciState = new MaciState(STATE_TREE_DEPTH); + + before(() => { + // Sign up + user1StateIndex = maciState.signUp( + user1Keypair.pubKey, + voiceCreditBalance, + BigInt(Math.floor(Date.now() / 1000)), + ); + + // deploy a poll + pollId = maciState.deployPoll( + BigInt(Math.floor(Date.now() / 1000) + duration), + maxValues, + treeDepths, + messageBatchSize, + coordinatorKeypair, + ); + }); + + it("should submit a vote for one user in one batch", () => { + const poll = maciState.polls[pollId]; + const command1 = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + user1VoteOptionIndex, + user1VoteWeight, + BigInt(1), + BigInt(pollId), + ); + + const signature1 = command1.sign(user1Keypair.privKey); + + const ecdhKeypair1 = new Keypair(); + const sharedKey1 = Keypair.genEcdhSharedKey(ecdhKeypair1.privKey, coordinatorKeypair.pubKey); + + const message1 = command1.encrypt(signature1, sharedKey1); + poll.publishMessage(message1, ecdhKeypair1.pubKey); + }); + + it("should fill the batch with random messages", () => { + const poll = maciState.polls[pollId]; + for (let i = 0; i < messageBatchSize - 1; i += 1) { + const command = new PCommand( + BigInt(1), + user1Keypair.pubKey, + user1VoteOptionIndex, + user1VoteWeight, + BigInt(2), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + } + }); + + it("should submit a new message in a new batch", () => { + const poll = maciState.polls[pollId]; + const command1 = new PCommand( + BigInt(user1StateIndex), + user1SecondKeypair.pubKey, + user1VoteOptionIndex, + user1NewVoteWeight, + BigInt(1), + BigInt(pollId), + ); + + const signature1 = command1.sign(user1Keypair.privKey); + + const ecdhKeypair1 = new Keypair(); + const sharedKey1 = Keypair.genEcdhSharedKey(ecdhKeypair1.privKey, coordinatorKeypair.pubKey); + + const message1 = command1.encrypt(signature1, sharedKey1); + poll.publishMessage(message1, ecdhKeypair1.pubKey); + }); + + it("should perform the processing and tallying correctly", () => { + const poll = maciState.polls[pollId]; + poll.processAllMessages(); + poll.tallyVotes(); + expect(poll.perVOSpentVoiceCredits[0].toString()).to.eq((user1NewVoteWeight * user1NewVoteWeight).toString()); + }); + + it("should confirm that the user key pair was changed", () => { + const poll = maciState.polls[pollId]; + const stateLeaf1 = poll.stateLeaves[user1StateIndex]; + expect(stateLeaf1.pubKey.equals(user1SecondKeypair.pubKey)).to.eq(true); + }); + }); + }); + + describe("Process and tally 1 message from 1 user", () => { + let maciState: MaciState; + let pollId: number; + let poll: Poll; + let msgTree: IncrementalQuinTree; + const voteWeight = BigInt(9); + const voteOptionIndex = BigInt(0); + let stateIndex: number; + const userKeypair = new Keypair(); + + before(() => { + maciState = new MaciState(STATE_TREE_DEPTH); + msgTree = new IncrementalQuinTree(treeDepths.messageTreeDepth, NOTHING_UP_MY_SLEEVE, 5, hash5); + }); + + // The end result should be that option 0 gets 3 votes + // because the user spends 9 voice credits on it + it("the state root should be correct", () => { + const accumulatorQueue: AccQueue = new AccQueue(STATE_TREE_SUBDEPTH, STATE_TREE_ARITY, blankStateLeafHash); + const timestamp = BigInt(Math.floor(Date.now() / 1000)); + const stateLeaf = new StateLeaf(userKeypair.pubKey, voiceCreditBalance, timestamp); + + accumulatorQueue.enqueue(blankStateLeafHash); + accumulatorQueue.enqueue(stateLeaf.hash()); + accumulatorQueue.mergeSubRoots(0); + accumulatorQueue.merge(STATE_TREE_DEPTH); + + stateIndex = maciState.signUp(userKeypair.pubKey, voiceCreditBalance, timestamp); + expect(stateIndex.toString()).to.eq("1"); + + expect(accumulatorQueue.getRoot(STATE_TREE_DEPTH)?.toString()).to.eq(maciState.stateTree.root.toString()); + }); + + it("the message root should be correct", () => { + pollId = maciState.deployPoll( + BigInt(Math.floor(Date.now() / 1000) + duration), + maxValues, + treeDepths, + messageBatchSize, + coordinatorKeypair, + ); + + poll = maciState.polls[pollId]; + + const command = new PCommand( + BigInt(stateIndex), + userKeypair.pubKey, + voteOptionIndex, + voteWeight, + BigInt(1), + BigInt(pollId), + ); + + const signature = command.sign(userKeypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + const message = command.encrypt(signature, sharedKey); + + poll.publishMessage(message, ecdhKeypair.pubKey); + msgTree.insert(message.hash(ecdhKeypair.pubKey)); + + // Use the accumulator queue to compare the root of the message tree + const accumulatorQueue: AccQueue = new AccQueue( + treeDepths.messageTreeSubDepth, + STATE_TREE_ARITY, + NOTHING_UP_MY_SLEEVE, + ); + accumulatorQueue.enqueue(message.hash(ecdhKeypair.pubKey)); + accumulatorQueue.mergeSubRoots(0); + accumulatorQueue.merge(treeDepths.messageTreeDepth); + + expect(accumulatorQueue.getRoot(treeDepths.messageTreeDepth)?.toString()).to.eq(msgTree.root.toString()); + }); + + it("packProcessMessageSmallVals and unpackProcessMessageSmallVals", () => { + const maxVoteOptions = BigInt(1); + const numUsers = BigInt(2); + const batchStartIndex = 5; + const batchEndIndex = 10; + const packedVals = packProcessMessageSmallVals(maxVoteOptions, numUsers, batchStartIndex, batchEndIndex); + + const unpacked = unpackProcessMessageSmallVals(packedVals); + expect(unpacked.maxVoteOptions.toString()).to.eq(maxVoteOptions.toString()); + expect(unpacked.numUsers.toString()).to.eq(numUsers.toString()); + expect(unpacked.batchStartIndex.toString()).to.eq(batchStartIndex.toString()); + expect(unpacked.batchEndIndex.toString()).to.eq(batchEndIndex.toString()); + }); + + it("Process a batch of messages (though only 1 message is in the batch)", () => { + poll.processMessages(pollId); + + // Check the ballot + expect(poll.ballots[1].votes[Number(voteOptionIndex)].toString()).to.eq(voteWeight.toString()); + // Check the state leaf in the poll + expect(poll.stateLeaves[1].voiceCreditBalance.toString()).to.eq( + (voiceCreditBalance - voteWeight * voteWeight).toString(), + ); + }); + + it("Tally ballots", () => { + const initialTotal = calculateTotal(maciState.polls[pollId].tallyResult); + expect(initialTotal.toString()).to.eq("0"); + + expect(poll.hasUntalliedBallots()).to.eq(true); + + poll.tallyVotes(); + + const finalTotal = calculateTotal(maciState.polls[pollId].tallyResult); + expect(finalTotal.toString()).to.eq(voteWeight.toString()); + }); + }); + + describe(`Process and tally ${messageBatchSize * 2} messages from ${messageBatchSize} users`, () => { + let maciState: MaciState; + let pollId: number; + let poll: Poll; + const voteWeight = BigInt(9); + + const users: Keypair[] = []; + + before(() => { + maciState = new MaciState(STATE_TREE_DEPTH); + // Sign up and vote + for (let i = 0; i < messageBatchSize - 1; i += 1) { + const userKeypair = new Keypair(); + users.push(userKeypair); + + maciState.signUp(userKeypair.pubKey, voiceCreditBalance, BigInt(Math.floor(Date.now() / 1000))); + } + + pollId = maciState.deployPoll( + BigInt(Math.floor(Date.now() / 1000) + duration), + maxValues, + treeDepths, + messageBatchSize, + coordinatorKeypair, + ); + poll = maciState.polls[pollId]; + }); + + it("should process votes correctly", () => { + // 24 valid votes + for (let i = 0; i < messageBatchSize - 1; i += 1) { + const userKeypair = users[i]; + + const command = new PCommand( + BigInt(i + 1), + userKeypair.pubKey, + BigInt(i), // vote option index + voteWeight, + BigInt(1), + BigInt(pollId), + ); + + const signature = command.sign(userKeypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + } + + expect(poll.messages.length).to.eq(messageBatchSize - 1); + + // 24 invalid votes + for (let i = 0; i < messageBatchSize - 1; i += 1) { + const userKeypair = users[i]; + const command = new PCommand( + BigInt(i + 1), + userKeypair.pubKey, + BigInt(i), // vote option index + voiceCreditBalance * BigInt(2), // invalid vote weight + BigInt(1), + BigInt(pollId), + ); + + const signature = command.sign(userKeypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + } + + // 48 messages in total + expect(poll.messages.length).to.eq(2 * (messageBatchSize - 1)); + + expect(poll.currentMessageBatchIndex).to.eq(undefined); + expect(poll.numBatchesProcessed).to.eq(0); + + // Process messages + poll.processMessages(pollId); + + // currentMessageBatchIndex is 0 because the current batch starts + // with index 0. + expect(poll.currentMessageBatchIndex).to.eq(0); + expect(poll.numBatchesProcessed).to.eq(1); + + // Process messages + poll.processMessages(pollId); + + expect(poll.currentMessageBatchIndex).to.eq(0); + expect(poll.numBatchesProcessed).to.eq(2); + + for (let i = 1; i < messageBatchSize; i += 1) { + const leaf = poll.ballots[i].votes[i - 1]; + expect(leaf.toString()).to.eq(voteWeight.toString()); + } + + // Test processAllMessages + const r = poll.processAllMessages(); + + expect(r.stateLeaves.length).to.eq(poll.stateLeaves.length); + + expect(r.ballots.length).to.eq(poll.ballots.length); + + expect(r.ballots.length).to.eq(r.stateLeaves.length); + + for (let i = 0; i < r.stateLeaves.length; i += 1) { + expect(r.stateLeaves[i].equals(poll.stateLeaves[i])).to.eq(true); + + expect(r.ballots[i].equals(poll.ballots[i])).to.eq(true); + } + }); + + it("should tally ballots correctly", () => { + // Start with tallyResult = [0...0] + const total = calculateTotal(maciState.polls[pollId].tallyResult); + expect(total.toString()).to.eq("0"); + + // Check that there are untallied results + expect(poll.hasUntalliedBallots()).to.eq(true); + + // First batch tally + poll.tallyVotes(); + + // Recall that each user `i` cast the same number of votes for + // their option `i` + for (let i = 0; i < maciState.polls[pollId].tallyResult.length - 1; i += 1) { + expect(maciState.polls[pollId].tallyResult[i].toString()).to.eq(voteWeight.toString()); + } + + expect(poll.hasUntalliedBallots()).to.eq(false); + + expect(() => { + poll.tallyVotes(); + }).to.throw(); + }); + }); +}); From 49571a1199a8a027c64a7c39bd21f46a3a268f43 Mon Sep 17 00:00:00 2001 From: 0xmad <0xmad@users.noreply.github.com> Date: Fri, 5 Jan 2024 15:00:08 -0600 Subject: [PATCH 25/37] chore(cli): integrate linter - [x] Lint and type fixes - [x] Dependency management --- .github/workflows/reusable-e2e.yml | 1 + cli/.eslintrc.js | 107 ++++++ cli/hardhat.config.ts | 3 +- cli/package-lock.json | 39 ++- cli/package.json | 4 +- cli/tests/constants.ts | 1 + cli/tests/e2e.subsidy.test.ts | 84 +++-- cli/tests/e2e.test.ts | 88 +++-- cli/tests/keyChange.test.ts | 45 ++- cli/tests/utils.ts | 30 +- cli/ts/commands/airdrop.ts | 40 ++- cli/ts/commands/checkVerifyingKeys.ts | 88 +++-- cli/ts/commands/deploy.ts | 18 +- cli/ts/commands/deployPoll.ts | 108 +++--- cli/ts/commands/deployVkRegistry.ts | 12 +- cli/ts/commands/fundWallet.ts | 14 +- cli/ts/commands/genKeyPair.ts | 3 +- cli/ts/commands/genLocalState.ts | 50 +-- cli/ts/commands/genProofs.ts | 283 ++++++++++------ cli/ts/commands/genPubKey.ts | 1 + cli/ts/commands/mergeMessages.ts | 92 ++++-- cli/ts/commands/mergeSignups.ts | 102 +++--- cli/ts/commands/proveOnChain.ts | 277 +++++++++++----- cli/ts/commands/publish.ts | 89 +++-- cli/ts/commands/setVerifyingKeys.ts | 132 +++++--- cli/ts/commands/showContracts.ts | 19 +- cli/ts/commands/signup.ts | 58 ++-- cli/ts/commands/timeTravel.ts | 9 +- cli/ts/commands/topup.ts | 60 +++- cli/ts/commands/verify.ts | 123 ++++--- cli/ts/index.ts | 114 +++---- cli/ts/utils/banner.ts | 2 +- cli/ts/utils/constants.ts | 6 +- cli/ts/utils/contracts.ts | 9 +- cli/ts/utils/formatting.ts | 4 +- cli/ts/utils/index.ts | 2 +- cli/ts/utils/interfaces.ts | 27 ++ cli/ts/utils/prompts.ts | 11 +- cli/ts/utils/salt.ts | 13 +- cli/ts/utils/storage.ts | 36 +- cli/ts/utils/theme.ts | 49 +-- cli/ts/utils/time.ts | 7 +- cli/ts/utils/trees.ts | 12 +- cli/ts/utils/verifiers.ts | 11 +- cli/ts/utils/vks.ts | 5 +- cli/tsconfig.json | 26 +- contracts/package-lock.json | 311 +++++++++++++++++- contracts/package.json | 2 + contracts/tests/HasherBenchmarks.test.ts | 20 +- contracts/ts/index.ts | 2 +- contracts/ts/utils.ts | 3 +- core/ts/__tests__/MaciState.test.ts | 10 +- core/ts/index.ts | 2 +- integrationTests/package.json | 2 +- .../ts/__tests__/integration.test.ts | 20 +- 55 files changed, 1872 insertions(+), 814 deletions(-) create mode 100644 cli/.eslintrc.js diff --git a/.github/workflows/reusable-e2e.yml b/.github/workflows/reusable-e2e.yml index 7e8c6df464..260615ad60 100644 --- a/.github/workflows/reusable-e2e.yml +++ b/.github/workflows/reusable-e2e.yml @@ -92,4 +92,5 @@ jobs: run: npm run ${{ matrix.command }} - name: Stop Hardhat + if: always() run: kill $(lsof -t -i:8545) diff --git a/cli/.eslintrc.js b/cli/.eslintrc.js new file mode 100644 index 0000000000..a22d4fb52c --- /dev/null +++ b/cli/.eslintrc.js @@ -0,0 +1,107 @@ +const fs = require("fs"); +const path = require("path"); + +const prettierConfig = fs.readFileSync(path.resolve(__dirname, "../.prettierrc"), "utf8"); +const prettierOptions = JSON.parse(prettierConfig); +const isProduction = process.env.NODE_ENV === "production"; + +module.exports = { + root: true, + extends: [ + "airbnb", + "prettier", + "plugin:import/recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-type-checked", + "plugin:@typescript-eslint/strict", + "plugin:@typescript-eslint/strict-type-checked", + "plugin:@typescript-eslint/stylistic", + "plugin:@typescript-eslint/stylistic-type-checked", + "plugin:import/typescript", + ], + plugins: ["json", "prettier", "unused-imports", "import", "@typescript-eslint"], + parser: "@typescript-eslint/parser", + env: { + node: true, + mocha: true, + es2022: true, + }, + settings: { + react: { + version: "999.999.999", + }, + "import/resolver": { + typescript: {}, + node: { + extensions: [".ts", ".js"], + moduleDirectory: ["node_modules", "ts", "src"], + }, + }, + }, + parserOptions: { + project: path.resolve(__dirname, "./tsconfig.json"), + sourceType: "module", + typescript: true, + ecmaVersion: 2022, + experimentalDecorators: true, + requireConfigFile: false, + ecmaFeatures: { + classes: true, + impliedStrict: true, + }, + warnOnUnsupportedTypeScriptVersion: true, + }, + reportUnusedDisableDirectives: isProduction, + rules: { + "import/no-cycle": ["error"], + "unused-imports/no-unused-imports": "error", + "import/no-extraneous-dependencies": [ + "error", + { + devDependencies: ["**/*.test.ts"], + }, + ], + "no-debugger": isProduction ? "error" : "off", + "no-console": "error", + "no-underscore-dangle": "error", + "no-redeclare": ["error", { builtinGlobals: true }], + "import/order": [ + "error", + { + groups: ["external", "builtin", "internal", "type", "parent", "sibling", "index", "object"], + alphabetize: { + order: "asc", + caseInsensitive: true, + }, + warnOnUnassignedImports: true, + "newlines-between": "always", + }, + ], + "prettier/prettier": ["error", prettierOptions], + "import/prefer-default-export": "off", + "import/extensions": ["error", { json: "always" }], + "class-methods-use-this": "off", + "prefer-promise-reject-errors": "off", + "max-classes-per-file": "off", + "no-use-before-define": ["off"], + "no-shadow": "off", + curly: ["error", "all"], + + "@typescript-eslint/explicit-member-accessibility": ["error", { accessibility: "no-public" }], + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/prefer-nullish-coalescing": "off", + "@typescript-eslint/no-floating-promises": "off", + "@typescript-eslint/no-explicit-any": "error", + "@typescript-eslint/explicit-module-boundary-types": "error", + "@typescript-eslint/no-use-before-define": ["error", { functions: false, classes: false }], + "@typescript-eslint/no-misused-promises": ["error", { checksVoidReturn: false }], + "@typescript-eslint/no-shadow": [ + "error", + { + builtinGlobals: true, + allow: ["location", "event", "history", "name", "status", "Option", "test", "expect"], + }, + ], + }, +}; diff --git a/cli/hardhat.config.ts b/cli/hardhat.config.ts index 73cc41ece0..cb2c85bba0 100644 --- a/cli/hardhat.config.ts +++ b/cli/hardhat.config.ts @@ -1,8 +1,9 @@ -import type { HardhatUserConfig } from "hardhat/config"; import "@nomicfoundation/hardhat-toolbox"; import path from "path"; +import type { HardhatUserConfig } from "hardhat/config"; + import { DEFAULT_ETH_SK, DEFAULT_ETH_PROVIDER } from "./ts/utils/defaults"; const parentDir = __dirname.includes("build") ? ".." : ""; diff --git a/cli/package-lock.json b/cli/package-lock.json index 53a2d1ed87..b100b267a8 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -8,13 +8,14 @@ "name": "maci-cli", "version": "1.1.2", "dependencies": { + "@commander-js/extra-typings": "^11.1.0", "@nomicfoundation/hardhat-toolbox": "^4.0.0", "circomlib": "^2.0.5", "commander": "^11.1.0", "dotenv": "^16.3.1", "ethers": "^6.9.0", "hardhat": "^2.19.2", - "prompt-async": "^0.9.9", + "prompt": "^1.3.0", "snarkjs": "^0.5.0", "zkey-manager": "^0.1.1" }, @@ -25,6 +26,7 @@ "@types/chai": "^4.3.9", "@types/mocha": "^10.0.6", "@types/node": "^18.11.9", + "@types/prompt": "^1.1.8", "chai": "^4.3.10", "mocha": "^10.2.0", "nyc": "^15.1.0", @@ -397,6 +399,14 @@ "node": ">=0.1.90" } }, + "node_modules/@commander-js/extra-typings": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@commander-js/extra-typings/-/extra-typings-11.1.0.tgz", + "integrity": "sha512-GuvZ38d23H+7Tz2C9DhzCepivsOsky03s5NI+KCy7ke1FNUvsJ2oO47scQ9YaGGhgjgNW5OYYNSADmbjcSoIhw==", + "peerDependencies": { + "commander": "11.1.x" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -2377,6 +2387,16 @@ "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", "peer": true }, + "node_modules/@types/prompt": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@types/prompt/-/prompt-1.1.8.tgz", + "integrity": "sha512-CF39wIJrSUJ291/M3rXyjQ7gWZfY8qyGw/zraQmFyq72CaJXRWBeQ2BS5FueFRGy38JhaBM08+Nlk/qcqSm72w==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/revalidator": "*" + } + }, "node_modules/@types/qs": { "version": "6.9.10", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", @@ -2397,6 +2417,12 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/@types/revalidator": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@types/revalidator/-/revalidator-0.3.12.tgz", + "integrity": "sha512-DsA2jHfz73JaIROVoMDd/x7nVWXBmEdDSoXB4yQlDzv/NCBkFY2fMHkyE6DGrvooLDAFe5QI6l9Wq0TgdopMtg==", + "dev": true + }, "node_modules/@types/secp256k1": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", @@ -6932,17 +6958,6 @@ "node": ">= 6.0.0" } }, - "node_modules/prompt-async": { - "version": "0.9.9", - "resolved": "https://registry.npmjs.org/prompt-async/-/prompt-async-0.9.9.tgz", - "integrity": "sha512-XHpcP55ME/MRHvvKTGYSayMMpWY7M2dEx5g6WdfHabkO4+BrJIWeZh4+qJG4lRgebr5ovT+Cnv98qfmXqQ3RXA==", - "dependencies": { - "prompt": "^1.0.0" - }, - "engines": { - "node": ">=5.12.0" - } - }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", diff --git a/cli/package.json b/cli/package.json index ab04432518..b2c229c2cc 100644 --- a/cli/package.json +++ b/cli/package.json @@ -20,6 +20,7 @@ "test:keyChange": "ts-mocha --exit tests/keyChange.test.ts" }, "dependencies": { + "@commander-js/extra-typings": "^11.1.0", "@nomicfoundation/hardhat-toolbox": "^4.0.0", "circomlib": "^2.0.5", "commander": "^11.1.0", @@ -31,7 +32,7 @@ "maci-core": "^1.1.2", "maci-crypto": "^1.1.2", "maci-domainobjs": "^1.1.2", - "prompt-async": "^0.9.9", + "prompt": "^1.3.0", "snarkjs": "^0.5.0", "zkey-manager": "^0.1.1" }, @@ -39,6 +40,7 @@ "@types/chai": "^4.3.9", "@types/mocha": "^10.0.6", "@types/node": "^18.11.9", + "@types/prompt": "^1.1.8", "chai": "^4.3.10", "mocha": "^10.2.0", "nyc": "^15.1.0", diff --git a/cli/tests/constants.ts b/cli/tests/constants.ts index f00aab3fb8..7834b8a5c6 100644 --- a/cli/tests/constants.ts +++ b/cli/tests/constants.ts @@ -1,4 +1,5 @@ import { Keypair } from "maci-domainobjs"; + import { homedir } from "os"; export const STATE_TREE_DEPTH = 10; diff --git a/cli/tests/e2e.subsidy.test.ts b/cli/tests/e2e.subsidy.test.ts index 6681af87fa..58ba69e62f 100644 --- a/cli/tests/e2e.subsidy.test.ts +++ b/cli/tests/e2e.subsidy.test.ts @@ -1,4 +1,6 @@ +import { genRandomSalt } from "maci-crypto"; import { Keypair } from "maci-domainobjs"; + import { checkVerifyingKeys, deploy, @@ -14,6 +16,8 @@ import { timeTravel, verify, } from "../ts/commands"; +import { DeployedContracts, PollContracts } from "../ts/utils"; + import { INT_STATE_TREE_DEPTH, MSG_BATCH_DEPTH, @@ -40,10 +44,8 @@ import { testTallyVotesWitnessPath, } from "./constants"; import { cleanSubsidy, isArm } from "./utils"; -import { genRandomSalt } from "maci-crypto"; -import { DeployedContracts, PollContracts } from "../ts/utils"; -describe("e2e with Subsidy tests", function () { +describe("e2e with Subsidy tests", function test() { const useWasm = isArm(); this.timeout(900000); @@ -69,9 +71,11 @@ describe("e2e with Subsidy tests", function () { }); describe("test1", () => { const user1Key = new Keypair(); - after(async () => { + + after(() => { cleanSubsidy(); }); + before(async () => { // deploy the smart contracts maciAddresses = await deploy(STATE_TREE_DEPTH); @@ -144,7 +148,9 @@ describe("e2e with Subsidy tests", function () { }); describe("test2", () => { - after(() => cleanSubsidy()); + after(() => { + cleanSubsidy(); + }); const users = [new Keypair(), new Keypair(), new Keypair(), new Keypair()]; @@ -164,8 +170,10 @@ describe("e2e with Subsidy tests", function () { ); }); - it("should signup four users", async () => { - for (const user of users) await signup(user.pubKey.serialize()); + it("should signup four users", () => { + users.forEach(async (user) => { + await signup(user.pubKey.serialize()); + }); }); it("should publish six messages", async () => { @@ -275,7 +283,9 @@ describe("e2e with Subsidy tests", function () { }); describe("test3", () => { - after(() => cleanSubsidy()); + after(() => { + cleanSubsidy(); + }); const users = [ new Keypair(), @@ -305,8 +315,10 @@ describe("e2e with Subsidy tests", function () { ); }); - it("should signup nine users", async () => { - for (const user of users) await signup(user.pubKey.serialize()); + it("should signup nine users", () => { + users.forEach(async (user) => { + await signup(user.pubKey.serialize()); + }); }); it("should publish one message", async () => { @@ -361,7 +373,9 @@ describe("e2e with Subsidy tests", function () { }); describe("test4", () => { - after(() => cleanSubsidy()); + after(() => { + cleanSubsidy(); + }); const user = new Keypair(); @@ -382,11 +396,15 @@ describe("e2e with Subsidy tests", function () { }); it("should signup eight users (same pub key)", async () => { - for (let i = 0; i < 8; i++) await signup(user.pubKey.serialize()); + for (let i = 0; i < 8; i += 1) { + // eslint-disable-next-line no-await-in-loop + await signup(user.pubKey.serialize()); + } }); it("should publish 12 messages with the same nonce", async () => { - for (let i = 0; i < 12; i++) + for (let i = 0; i < 12; i += 1) { + // eslint-disable-next-line no-await-in-loop await publish( user.pubKey.serialize(), 1, @@ -398,6 +416,7 @@ describe("e2e with Subsidy tests", function () { genRandomSalt().toString(), user.privKey.serialize(), ); + } }); it("should generate zk-SNARK proofs and verify them", async () => { @@ -438,7 +457,9 @@ describe("e2e with Subsidy tests", function () { }); describe("test5", () => { - after(() => cleanSubsidy()); + after(() => { + cleanSubsidy(); + }); const users = [new Keypair(), new Keypair(), new Keypair(), new Keypair()]; @@ -458,8 +479,10 @@ describe("e2e with Subsidy tests", function () { ); }); - it("should signup four users", async () => { - for (const user of users) await signup(user.pubKey.serialize()); + it("should signup four users", () => { + users.forEach(async (user) => { + await signup(user.pubKey.serialize()); + }); }); it("should publish four messages", async () => { @@ -547,7 +570,9 @@ describe("e2e with Subsidy tests", function () { }); describe("test6", () => { - after(() => cleanSubsidy()); + after(() => { + cleanSubsidy(); + }); const users = [new Keypair(), new Keypair(), new Keypair(), new Keypair(), new Keypair()]; @@ -567,8 +592,10 @@ describe("e2e with Subsidy tests", function () { ); }); - it("should signup five users", async () => { - for (const user of users) await signup(user.pubKey.serialize()); + it("should signup five users", () => { + users.forEach(async (user) => { + await signup(user.pubKey.serialize()); + }); }); it("should publish five messages", async () => { @@ -793,11 +820,14 @@ describe("e2e with Subsidy tests", function () { }); it("should signup an user", async () => { - for (let i = 0; i < 6; i++) await signup(publishArgs[i].pubkey); + for (let i = 0; i < 6; i += 1) { + // eslint-disable-next-line no-await-in-loop + await signup(publishArgs[i].pubkey); + } }); - it("should publish all messages", async () => { - for (const arg of publishArgs) + it("should publish all messages", () => { + publishArgs.forEach(async (arg) => { await publish( arg.pubkey, arg.stateIndex, @@ -809,6 +839,7 @@ describe("e2e with Subsidy tests", function () { genRandomSalt().toString(), arg.privateKey, ); + }); }); it("should generate zk-SNARK proofs and verify them", async () => { @@ -849,7 +880,9 @@ describe("e2e with Subsidy tests", function () { }); describe("multiplePolls1", () => { - after(() => cleanSubsidy()); + after(() => { + cleanSubsidy(); + }); const user = new Keypair(); @@ -1006,7 +1039,10 @@ describe("e2e with Subsidy tests", function () { coordinatorPubKey, ); // signup - for (let i = 0; i < 7; i++) await signup(users[i].pubKey.serialize()); + for (let i = 0; i < 7; i += 1) { + // eslint-disable-next-line no-await-in-loop + await signup(users[i].pubKey.serialize()); + } // publish await publish( users[0].pubKey.serialize(), diff --git a/cli/tests/e2e.test.ts b/cli/tests/e2e.test.ts index 3016bbaf9c..1ae0d91fd5 100644 --- a/cli/tests/e2e.test.ts +++ b/cli/tests/e2e.test.ts @@ -1,4 +1,8 @@ -import { existsSync, unlinkSync } from "fs"; +import { genRandomSalt } from "maci-crypto"; +import { Keypair } from "maci-domainobjs"; + +import fs from "fs"; + import { airdrop, checkVerifyingKeys, @@ -17,6 +21,8 @@ import { topup, verify, } from "../ts/commands"; +import { DeployedContracts, PollContracts } from "../ts/utils"; + import { INT_STATE_TREE_DEPTH, MSG_BATCH_DEPTH, @@ -39,9 +45,6 @@ import { testTallyVotesWitnessPath, } from "./constants"; import { cleanVanilla, isArm } from "./utils"; -import { DeployedContracts, PollContracts } from "../ts/utils"; -import { Keypair } from "maci-domainobjs"; -import { genRandomSalt } from "maci-crypto"; /** Test scenarios: @@ -57,7 +60,7 @@ import { genRandomSalt } from "maci-crypto"; 1 signup and 1 valid message for multiple polls 7 signups and 1 message, another polls and 6 messages */ -describe("e2e tests", function () { +describe("e2e tests", function test() { const useWasm = isArm(); this.timeout(900000); @@ -81,7 +84,7 @@ describe("e2e tests", function () { }); describe("test1", () => { - after(async () => { + after(() => { cleanVanilla(); }); @@ -158,7 +161,9 @@ describe("e2e tests", function () { }); describe("test2", () => { - after(() => cleanVanilla()); + after(() => { + cleanVanilla(); + }); const users = [new Keypair(), new Keypair(), new Keypair(), new Keypair()]; @@ -178,8 +183,10 @@ describe("e2e tests", function () { ); }); - it("should signup four users", async () => { - for (const user of users) await signup(user.pubKey.serialize()); + it("should signup four users", () => { + users.forEach(async (user) => { + await signup(user.pubKey.serialize()); + }); }); it("should publish six messages", async () => { @@ -288,7 +295,9 @@ describe("e2e tests", function () { }); describe("test3", () => { - after(() => cleanVanilla()); + after(() => { + cleanVanilla(); + }); const users = [ new Keypair(), @@ -318,8 +327,10 @@ describe("e2e tests", function () { ); }); - it("should signup nine users", async () => { - for (const user of users) await signup(user.pubKey.serialize()); + it("should signup nine users", () => { + users.forEach(async (user) => { + await signup(user.pubKey.serialize()); + }); }); it("should publish one message", async () => { @@ -373,7 +384,9 @@ describe("e2e tests", function () { }); describe("test4", () => { - after(() => cleanVanilla()); + after(() => { + cleanVanilla(); + }); const user = new Keypair(); @@ -394,11 +407,15 @@ describe("e2e tests", function () { }); it("should signup eight users (same pub key)", async () => { - for (let i = 0; i < 8; i++) await signup(user.pubKey.serialize()); + for (let i = 0; i < 8; i += 1) { + // eslint-disable-next-line no-await-in-loop + await signup(user.pubKey.serialize()); + } }); it("should publish 12 messages with the same nonce", async () => { - for (let i = 0; i < 12; i++) + for (let i = 0; i < 12; i += 1) { + // eslint-disable-next-line no-await-in-loop await publish( user.pubKey.serialize(), 1, @@ -410,6 +427,7 @@ describe("e2e tests", function () { genRandomSalt().toString(), user.privKey.serialize(), ); + } }); it("should generate zk-SNARK proofs and verify them", async () => { @@ -449,7 +467,9 @@ describe("e2e tests", function () { }); describe("test5", () => { - after(() => cleanVanilla()); + after(() => { + cleanVanilla(); + }); const users = [new Keypair(), new Keypair(), new Keypair(), new Keypair()]; @@ -469,8 +489,10 @@ describe("e2e tests", function () { ); }); - it("should signup four users", async () => { - for (const user of users) await signup(user.pubKey.serialize()); + it("should signup four users", () => { + users.forEach(async (user) => { + await signup(user.pubKey.serialize()); + }); }); it("should publish four messages", async () => { @@ -557,7 +579,9 @@ describe("e2e tests", function () { }); describe("test6", () => { - after(() => cleanVanilla()); + after(() => { + cleanVanilla(); + }); const users = [new Keypair(), new Keypair(), new Keypair(), new Keypair(), new Keypair()]; @@ -577,8 +601,10 @@ describe("e2e tests", function () { ); }); - it("should signup five users", async () => { - for (const user of users) await signup(user.pubKey.serialize()); + it("should signup five users", () => { + users.forEach(async (user) => { + await signup(user.pubKey.serialize()); + }); }); it("should publish five messages", async () => { @@ -694,7 +720,9 @@ describe("e2e tests", function () { }); describe("keyChange", () => { - after(() => cleanVanilla()); + after(() => { + cleanVanilla(); + }); const key1 = new Keypair(); const key2 = new Keypair(); @@ -794,7 +822,9 @@ describe("e2e tests", function () { }); describe("multiplePolls1", () => { - after(() => cleanVanilla()); + after(() => { + cleanVanilla(); + }); const user = new Keypair(); @@ -945,7 +975,10 @@ describe("e2e tests", function () { coordinatorPubKey, ); // signup - for (const user of users) await signup(user.pubKey.serialize()); + users.forEach(async (user) => { + await signup(user.pubKey.serialize()); + }); + // publish await publish( users[0].pubKey.serialize(), @@ -1160,9 +1193,12 @@ describe("e2e tests", function () { const user = new Keypair(); - after(async () => { + after(() => { cleanVanilla(); - if (existsSync(stateOutPath)) unlinkSync(stateOutPath); + + if (fs.existsSync(stateOutPath)) { + fs.unlinkSync(stateOutPath); + } }); before(async () => { diff --git a/cli/tests/keyChange.test.ts b/cli/tests/keyChange.test.ts index 9f7cc2578d..7f6249226b 100644 --- a/cli/tests/keyChange.test.ts +++ b/cli/tests/keyChange.test.ts @@ -1,3 +1,10 @@ +import { expect } from "chai"; +import { genRandomSalt } from "maci-crypto"; +import { Keypair } from "maci-domainobjs"; + +import fs from "fs"; + +import { DeployedContracts, TallyData } from "../ts"; import { deploy, deployPoll, @@ -12,6 +19,7 @@ import { timeTravel, verify, } from "../ts/commands"; + import { INT_STATE_TREE_DEPTH, MSG_BATCH_DEPTH, @@ -30,14 +38,9 @@ import { testTallyVotesWasmPath, testTallyVotesWitnessPath, } from "./constants"; -import { Keypair } from "maci-domainobjs"; import { cleanVanilla, isArm } from "./utils"; -import { readFileSync } from "fs"; -import { expect } from "chai"; -import { genRandomSalt } from "maci-crypto"; -import { DeployedContracts } from "../ts"; -describe("keyChange tests", function () { +describe("keyChange tests", function test() { const useWasm = isArm(); this.timeout(900000); @@ -60,9 +63,10 @@ describe("keyChange tests", function () { }); describe("keyChange and new vote (new vote has same nonce)", () => { - after(async () => { + after(() => { cleanVanilla(); }); + const keypair1 = new Keypair(); const keypair2 = new Keypair(); const initialNonce = 1; @@ -87,7 +91,7 @@ describe("keyChange tests", function () { VOTE_OPTION_TREE_DEPTH, coordinatorPubKey, ); - stateIndex = parseInt(await signup(keypair1.pubKey.serialize())); + stateIndex = Number.parseInt(await signup(keypair1.pubKey.serialize()), 10); await publish( keypair1.pubKey.serialize(), stateIndex, @@ -100,6 +104,7 @@ describe("keyChange tests", function () { keypair1.privKey.serialize(), ); }); + it("should publish a message to change the user maci key and cast a new vote", async () => { await publish( keypair2.pubKey.serialize(), @@ -113,6 +118,7 @@ describe("keyChange tests", function () { keypair1.privKey.serialize(), ); }); + it("should generate zk-SNARK proofs and verify them", async () => { await timeTravel(90, true); await mergeMessages(0); @@ -140,17 +146,19 @@ describe("keyChange tests", function () { await proveOnChain("0", testProofsDirPath); await verify("0", testTallyFilePath); }); + it("should confirm the tally is correct", () => { - const tallyData = JSON.parse(readFileSync(testTallyFilePath).toString()); + const tallyData = JSON.parse(fs.readFileSync(testTallyFilePath).toString()) as TallyData; expect(tallyData.results.tally[0]).to.equal(expectedTally.toString()); expect(tallyData.perVOSpentVoiceCredits.tally[0]).to.equal(expectedPerVoteOptionTally.toString()); }); }); describe("keyChange and new vote (new vote has greater nonce and different vote option)", () => { - after(async () => { + after(() => { cleanVanilla(); }); + const keypair1 = new Keypair(); const keypair2 = new Keypair(); const initialNonce = 1; @@ -175,7 +183,7 @@ describe("keyChange tests", function () { VOTE_OPTION_TREE_DEPTH, coordinatorPubKey, ); - stateIndex = parseInt(await signup(keypair1.pubKey.serialize())); + stateIndex = Number.parseInt(await signup(keypair1.pubKey.serialize()), 10); await publish( keypair1.pubKey.serialize(), stateIndex, @@ -188,6 +196,7 @@ describe("keyChange tests", function () { keypair1.privKey.serialize(), ); }); + it("should publish a message to change the user maci key and cast a new vote", async () => { await publish( keypair2.pubKey.serialize(), @@ -201,6 +210,7 @@ describe("keyChange tests", function () { keypair1.privKey.serialize(), ); }); + it("should generate zk-SNARK proofs and verify them", async () => { await timeTravel(90, true); await mergeMessages(0); @@ -228,17 +238,19 @@ describe("keyChange tests", function () { await proveOnChain("0", testProofsDirPath); await verify("0", testTallyFilePath); }); + it("should confirm the tally is correct", () => { - const tallyData = JSON.parse(readFileSync(testTallyFilePath).toString()); + const tallyData = JSON.parse(fs.readFileSync(testTallyFilePath).toString()) as TallyData; expect(tallyData.results.tally[0]).to.equal(expectedTally.toString()); expect(tallyData.perVOSpentVoiceCredits.tally[0]).to.equal(expectedPerVoteOptionTally.toString()); }); }); describe("keyChange and new vote (new vote has same nonce and different vote option)", () => { - after(async () => { + after(() => { cleanVanilla(); }); + const keypair1 = new Keypair(); const keypair2 = new Keypair(); const initialNonce = 1; @@ -263,7 +275,7 @@ describe("keyChange tests", function () { VOTE_OPTION_TREE_DEPTH, coordinatorPubKey, ); - stateIndex = parseInt(await signup(keypair1.pubKey.serialize())); + stateIndex = Number.parseInt(await signup(keypair1.pubKey.serialize()), 10); await publish( keypair1.pubKey.serialize(), stateIndex, @@ -276,6 +288,7 @@ describe("keyChange tests", function () { keypair1.privKey.serialize(), ); }); + it("should publish a message to change the user maci key, and a new vote", async () => { await publish( keypair2.pubKey.serialize(), @@ -289,6 +302,7 @@ describe("keyChange tests", function () { keypair1.privKey.serialize(), ); }); + it("should generate zk-SNARK proofs and verify them", async () => { await timeTravel(90, true); await mergeMessages(0); @@ -316,8 +330,9 @@ describe("keyChange tests", function () { await proveOnChain("0", testProofsDirPath); await verify("0", testTallyFilePath); }); + it("should confirm the tally is correct", () => { - const tallyData = JSON.parse(readFileSync(testTallyFilePath).toString()); + const tallyData = JSON.parse(fs.readFileSync(testTallyFilePath).toString()) as TallyData; expect(tallyData.results.tally[2]).to.equal(expectedTally.toString()); expect(tallyData.perVOSpentVoiceCredits.tally[2]).to.equal(expectedPerVoteOptionTally.toString()); }); diff --git a/cli/tests/utils.ts b/cli/tests/utils.ts index 61e7e5d60f..7a9caf9b20 100644 --- a/cli/tests/utils.ts +++ b/cli/tests/utils.ts @@ -1,33 +1,37 @@ -import { existsSync, readdirSync, rmSync } from "fs"; -import { arch } from "os"; - +import fs from "fs"; +import os from "os"; import path from "path"; /** * Test utility to clean up the proofs directory * and the tally.json file */ -export const cleanVanilla = () => { - const files = readdirSync("./proofs"); - for (const file of files) { - rmSync(path.join("./proofs", file)); +export const cleanVanilla = (): void => { + const files = fs.readdirSync("./proofs"); + + files.forEach((file) => { + fs.rmSync(path.resolve("./proofs", file)); + }); + + if (fs.existsSync("./tally.json")) { + fs.rmSync("./tally.json"); } - if (existsSync("./tally.json")) rmSync("./tally.json"); }; /** * Test utility to clean up the proofs directory * adn the subsidy.json file */ -export const cleanSubsidy = () => { +export const cleanSubsidy = (): void => { cleanVanilla(); - if (existsSync("./subsidy.json")) rmSync("./subsidy.json"); + + if (fs.existsSync("./subsidy.json")) { + fs.rmSync("./subsidy.json"); + } }; /** * Check if we are running on an arm chip * @returns whether we are running on an arm chip */ -export const isArm = (): boolean => { - return arch().includes("arm"); -}; +export const isArm = (): boolean => os.arch().includes("arm"); diff --git a/cli/ts/commands/airdrop.ts b/cli/ts/commands/airdrop.ts index 350c10b487..2e36e24112 100644 --- a/cli/ts/commands/airdrop.ts +++ b/cli/ts/commands/airdrop.ts @@ -1,9 +1,10 @@ -import { readContractAddress } from "../utils/storage"; -import { Contract } from "ethers"; +import { BaseContract } from "ethers"; +import { MACI, TopupCredit, getDefaultSigner, parseArtifact } from "maci-contracts"; + +import { banner } from "../utils/banner"; import { contractExists } from "../utils/contracts"; -import { getDefaultSigner, parseArtifact } from "maci-contracts"; +import { readContractAddress } from "../utils/storage"; import { logError, logGreen, success } from "../utils/theme"; -import { banner } from "../utils/banner"; /** * Utility that can be used to get @@ -21,7 +22,7 @@ export const airdrop = async ( pollId?: number, maciAddress?: string, quiet = true, -) => { +): Promise => { banner(quiet); // get the topup credit address from storage @@ -33,21 +34,23 @@ export const airdrop = async ( logError("Please provide an ERC20 contract address"); } - const ERC20Address = contractAddress ? contractAddress : topupCredit; + const ERC20Address = contractAddress || topupCredit; // get the signer const signer = await getDefaultSigner(); // check if the contract exists - if (!(await contractExists(signer.provider, ERC20Address))) { + if (!(await contractExists(signer.provider!, ERC20Address))) { logError("Invalid ERC20 contract address"); } const tokenAbi = parseArtifact("TopupCredit")[0]; // create the contract instance - const tokenContract = new Contract(ERC20Address, tokenAbi, signer); + const tokenContract = new BaseContract(ERC20Address, tokenAbi, signer) as TopupCredit; - if (amount < 0) logError("Invalid amount"); + if (amount < 0) { + logError("Invalid amount"); + } // try to get the tokens airdropped try { @@ -57,29 +60,30 @@ export const airdrop = async ( await tx.wait(); logGreen(quiet, success(`Airdropped ${amount} credits to ${await signer.getAddress()}`)); - } catch (error: any) { - logError(error.message); + } catch (error) { + logError((error as Error).message); } // if there is a poll id provided, we can pre-approve all of the tokens // so there is no need to do it afterwards if (pollId !== undefined) { - maciAddress = readContractAddress("MACI") ? readContractAddress("MACI") : maciAddress; - if (!maciAddress) logError("Please provide a MACI contract address"); + const maciContractAddress = readContractAddress("MACI") ? readContractAddress("MACI") : maciAddress; - const maciAbi = parseArtifact("MACI")[0]; + if (!maciAddress) { + logError("Please provide a MACI contract address"); + } - const maciContract = new Contract(maciAddress, maciAbi, signer); + const maciAbi = parseArtifact("MACI")[0]; + const maciContract = new BaseContract(maciContractAddress!, maciAbi, signer) as MACI; const pollAddr = await maciContract.getPoll(pollId); try { const tx = await tokenContract.approve(pollAddr, amount, { gasLimit: 1000000 }); - await tx.wait(); logGreen(quiet, success(`Approved ${pollAddr} to spend ${amount} credits`)); - } catch (error: any) { - logError(error.message); + } catch (error) { + logError((error as Error).message); } } }; diff --git a/cli/ts/commands/checkVerifyingKeys.ts b/cli/ts/commands/checkVerifyingKeys.ts index d79e32d0ef..7c2473c947 100644 --- a/cli/ts/commands/checkVerifyingKeys.ts +++ b/cli/ts/commands/checkVerifyingKeys.ts @@ -1,4 +1,11 @@ -import { getDefaultSigner, parseArtifact } from "maci-contracts"; +import { BaseContract } from "ethers"; +import { extractVk } from "maci-circuits"; +import { VkRegistry, getDefaultSigner, parseArtifact } from "maci-contracts"; +import { G1Point, G2Point } from "maci-crypto"; +import { VerifyingKey } from "maci-domainobjs"; + +import fs from "fs"; + import { banner, compareVks, @@ -9,11 +16,7 @@ import { logYellow, readContractAddress, success, -} from "../utils/"; -import { VerifyingKey } from "maci-domainobjs"; -import { extractVk } from "maci-circuits"; -import { existsSync } from "fs"; -import { Contract } from "ethers"; +} from "../utils"; /** * Command to confirm that the verifying keys in the contract match the @@ -46,24 +49,40 @@ export const checkVerifyingKeys = async ( const signer = await getDefaultSigner(); // ensure we have the contract addresses that we need - if (!readContractAddress("VkRegistry") && !vkRegistry) logError("Please provide a VkRegistry contract address"); - const vkContractAddress = vkRegistry ? vkRegistry : readContractAddress("VkRegistry"); - if (!(await contractExists(signer.provider, vkContractAddress))) logError("The VkRegistry contract does not exist"); + if (!readContractAddress("VkRegistry") && !vkRegistry) { + logError("Please provide a VkRegistry contract address"); + } + const vkContractAddress = vkRegistry || readContractAddress("VkRegistry"); - const vkRegistryContractInstance = new Contract(vkContractAddress, parseArtifact("VkRegistry")[0], signer); + if (!(await contractExists(signer.provider!, vkContractAddress))) { + logError("The VkRegistry contract does not exist"); + } + + const vkRegistryContractInstance = new BaseContract( + vkContractAddress, + parseArtifact("VkRegistry")[0], + signer, + ) as VkRegistry; // we need to ensure that the zkey files exist - if (!existsSync(processMessagesZkeyPath)) logError("The provided Process messages zkey does not exist"); - if (!existsSync(tallyVotesZkeyPath)) logError("The provided Tally votes zkey does not exist"); + if (!fs.existsSync(processMessagesZkeyPath)) { + logError("The provided Process messages zkey does not exist"); + } + + if (!fs.existsSync(tallyVotesZkeyPath)) { + logError("The provided Tally votes zkey does not exist"); + } // extract the verification keys from the zkey files const processVk = VerifyingKey.fromObj(await extractVk(processMessagesZkeyPath)); const tallyVk = VerifyingKey.fromObj(await extractVk(tallyVotesZkeyPath)); // check the subsidy key - let subsidyVk: VerifyingKey; + let subsidyVk: VerifyingKey | undefined; if (subsidyZkeyPath) { - if (!existsSync(subsidyZkeyPath)) logError("The provided Subsidy zkey does not exist"); + if (!fs.existsSync(subsidyZkeyPath)) { + logError("The provided Subsidy zkey does not exist"); + } subsidyVk = VerifyingKey.fromObj(await extractVk(subsidyZkeyPath)); } @@ -85,20 +104,37 @@ export const checkVerifyingKeys = async ( voteOptionTreeDepth, ); - let subsidyVkOnChain: VerifyingKey; - if (subsidyVk) - subsidyVkOnChain = await vkRegistryContractInstance.getSubsidyVk( - stateTreeDepth, - intStateTreeDepth, - voteOptionTreeDepth, - ); + let subsidyVkOnChain: VerifyingKey | undefined; + + if (subsidyVk) { + subsidyVkOnChain = await vkRegistryContractInstance + .getSubsidyVk(stateTreeDepth, intStateTreeDepth, voteOptionTreeDepth) + .then( + ({ alpha1, beta2, gamma2, delta2, ic }) => + new VerifyingKey( + new G1Point(alpha1.x, alpha1.y), + new G2Point(beta2.x, beta2.y), + new G2Point(gamma2.x, gamma2.y), + new G2Point(delta2.x, delta2.y), + ic.map(({ x, y }) => new G1Point(x, y)), + ), + ); + } // do the actual validation - if (!compareVks(processVk, processVkOnChain)) logError("Process verifying keys do not match"); - if (!compareVks(tallyVk, tallyVkOnChain)) logError("Tally verifying keys do not match"); - if (subsidyVk && !compareVks(subsidyVk, subsidyVkOnChain)) logError("Subsidy verifying keys do not match"); - } catch (error: any) { - logError(error.message); + if (!compareVks(processVk, processVkOnChain)) { + logError("Process verifying keys do not match"); + } + + if (!compareVks(tallyVk, tallyVkOnChain)) { + logError("Tally verifying keys do not match"); + } + + if (subsidyVk && !compareVks(subsidyVk, subsidyVkOnChain!)) { + logError("Subsidy verifying keys do not match"); + } + } catch (error) { + logError((error as Error).message); } logGreen(quiet, success("Verifying keys match")); diff --git a/cli/ts/commands/deploy.ts b/cli/ts/commands/deploy.ts index c782629b90..c0ae329e81 100644 --- a/cli/ts/commands/deploy.ts +++ b/cli/ts/commands/deploy.ts @@ -1,5 +1,3 @@ -import { banner } from "../utils/banner"; -import { readContractAddress, storeContractAddress } from "../utils/storage"; import { deployConstantInitialVoiceCreditProxy, deployFreeForAllSignUpGatekeeper, @@ -8,7 +6,10 @@ import { deployTopupCredit, getDefaultSigner, } from "maci-contracts"; -import { logError, logGreen, success, DEFAULT_INITIAL_VOICE_CREDITS, DeployedContracts } from "../utils/"; + +import { logError, logGreen, success, DEFAULT_INITIAL_VOICE_CREDITS, DeployedContracts } from "../utils"; +import { banner } from "../utils/banner"; +import { readContractAddress, storeContractAddress } from "../utils/storage"; /** * Deploy MACI and related contracts @@ -36,10 +37,11 @@ export const deploy = async ( const signer = await getDefaultSigner(); // if we did not deploy it before, then deploy it now - let initialVoiceCreditProxyContractAddress: string; + let initialVoiceCreditProxyContractAddress: string | undefined; + if (!initialVoiceCreditsProxyAddress) { const contract = await deployConstantInitialVoiceCreditProxy( - initialVoiceCredits ? initialVoiceCredits : DEFAULT_INITIAL_VOICE_CREDITS, + initialVoiceCredits || DEFAULT_INITIAL_VOICE_CREDITS, signer, true, ); @@ -68,7 +70,7 @@ export const deploy = async ( // deploy MACI, stateAq, PollFactory and poseidon const { maciContract, stateAqContract, pollFactoryContract, poseidonAddrs } = await deployMaci( signupGatekeeperContractAddress, - initialVoiceCreditProxyContractAddress, + initialVoiceCreditProxyContractAddress!, verifierContractAddress, topUpCreditAddress, signer, @@ -83,7 +85,7 @@ export const deploy = async ( ]); // save to the JSON File - storeContractAddress("InitialVoiceCreditProxy", initialVoiceCreditProxyContractAddress); + storeContractAddress("InitialVoiceCreditProxy", initialVoiceCreditProxyContractAddress!); storeContractAddress("SignUpGatekeeper", signupGatekeeperContractAddress); storeContractAddress("Verifier", verifierContractAddress); storeContractAddress("MACI", maciContractAddress); @@ -109,6 +111,6 @@ export const deploy = async ( poseidonT5Address: poseidonAddrs[2], poseidonT6Address: poseidonAddrs[3], signUpGatekeeperAddress: signupGatekeeperContractAddress, - initialVoiceCreditProxyAddress: initialVoiceCreditProxyContractAddress, + initialVoiceCreditProxyAddress: initialVoiceCreditProxyContractAddress!, }; }; diff --git a/cli/ts/commands/deployPoll.ts b/cli/ts/commands/deployPoll.ts index 23dedbab23..3bd313afd0 100644 --- a/cli/ts/commands/deployPoll.ts +++ b/cli/ts/commands/deployPoll.ts @@ -1,11 +1,19 @@ -import { deployMessageProcessor, deploySubsidy, deployTally, getDefaultSigner, parseArtifact } from "maci-contracts"; +import { BaseContract } from "ethers"; +import { + MACI, + deployMessageProcessor, + deploySubsidy, + deployTally, + getDefaultSigner, + parseArtifact, +} from "maci-contracts"; +import { PubKey } from "maci-domainobjs"; + import { banner } from "../utils/banner"; -import { readContractAddress, storeContractAddress } from "../utils/storage"; -import { info, logError, logGreen } from "../utils/theme"; import { contractExists } from "../utils/contracts"; -import { PubKey } from "maci-domainobjs"; -import { Contract } from "ethers"; import { PollContracts } from "../utils/interfaces"; +import { readContractAddress, storeContractAddress } from "../utils/storage"; +import { info, logError, logGreen } from "../utils/theme"; /** * Deploy a new Poll for the set of MACI's contracts already deployed @@ -43,38 +51,56 @@ export const deployPoll = async ( logError("Please provide a VkRegistry contract address"); } - const vkRegistry = vkRegistryAddress ? vkRegistryAddress : vkRegistryContractAddress; + const vkRegistry = vkRegistryAddress || vkRegistryContractAddress; - const _maciAddress = readContractAddress("MACI"); - if (!_maciAddress && !maciAddress) { + const maciContractAddress = readContractAddress("MACI"); + if (!maciContractAddress && !maciAddress) { logError("Please provide a MACI contract address"); } - const _maci = maciAddress ? maciAddress : _maciAddress; + const maci = maciAddress || maciContractAddress; // required arg -> poll duration - if (pollDuration <= 0) logError("Duration cannot be <= 0"); + if (pollDuration <= 0) { + logError("Duration cannot be <= 0"); + } // require arg -> max messages - if (maxMessages <= 0) logError("Max messages cannot be <= 0"); + if (maxMessages <= 0) { + logError("Max messages cannot be <= 0"); + } // required arg -> max vote options - if (maxVoteOptions <= 0) logError("Max vote options cannot be <= 0"); + if (maxVoteOptions <= 0) { + logError("Max vote options cannot be <= 0"); + } // required arg -> int state tree depth - if (intStateTreeDepth <= 0) logError("Int state tree depth cannot be <= 0"); + if (intStateTreeDepth <= 0) { + logError("Int state tree depth cannot be <= 0"); + } // required arg -> message tree sub depth - if (messageTreeSubDepth <= 0) logError("Message tree sub depth cannot be <= 0"); + if (messageTreeSubDepth <= 0) { + logError("Message tree sub depth cannot be <= 0"); + } // required arg -> message tree depth - if (messageTreeDepth <= 0) logError("Message tree depth cannot be <= 0"); + if (messageTreeDepth <= 0) { + logError("Message tree depth cannot be <= 0"); + } // required arg -> vote option tree depth - if (voteOptionTreeDepth <= 0) logError("Vote option tree depth cannot be <= 0"); + if (voteOptionTreeDepth <= 0) { + logError("Vote option tree depth cannot be <= 0"); + } const signer = await getDefaultSigner(); // we check that the contract is deployed - if (!(await contractExists(signer.provider, _maci))) logError("MACI contract does not exist"); + if (!(await contractExists(signer.provider!, maci))) { + logError("MACI contract does not exist"); + } // we check that the coordinator's public key is valid - if (!PubKey.isValidSerializedPubKey(coordinatorPubkey)) logError("Invalid MACI public key"); + if (!PubKey.isValidSerializedPubKey(coordinatorPubkey)) { + logError("Invalid MACI public key"); + } const unserializedKey = PubKey.deserialize(coordinatorPubkey); @@ -124,7 +150,7 @@ export const deployPoll = async ( ); const maciAbi = parseArtifact("MACI")[0]; - const maciContract = new Contract(_maci, maciAbi, signer); + const maciContract = new BaseContract(maci, maciAbi, signer) as MACI; // deploy the poll let pollAddr = ""; @@ -151,29 +177,37 @@ export const deployPoll = async ( ); const receipt = await tx.wait(); + + if (receipt?.status !== 1) { + logError("Deploy poll transaction is failed"); + } + const iface = maciContract.interface; - const log = iface.parseLog(receipt.logs[receipt.logs.length - 1]); - const name = log.name; + const receiptLog = receipt!.logs[receipt!.logs.length - 1]; + const log = iface.parseLog(receiptLog as unknown as { topics: string[]; data: string }); // we are trying to get the poll id from the event logs // if we do not find this log then we throw - if (name !== "DeployPoll") logError("Invalid event log"); - - const pollId = log.args._pollId; - pollAddr = log.args._pollAddr; - { - logGreen(quiet, info(`Poll ID: ${pollId.toString()}`)); - logGreen(quiet, info(`Poll contract: ${pollAddr}`)); - logGreen(quiet, info(`Message processor contract: ${messageProcessorContractAddress}`)); - logGreen(quiet, info(`Tally contract: ${tallyContractAddress}`)); - logGreen(quiet, info(`Subsidy contract: ${subsidyContractAddress}`)); + if (log?.name !== "DeployPoll") { + logError("Invalid event log"); } + + // eslint-disable-next-line no-underscore-dangle + const pollId = log!.args._pollId as number; + // eslint-disable-next-line no-underscore-dangle + pollAddr = log!.args._pollAddr as string; + + logGreen(quiet, info(`Poll ID: ${pollId.toString()}`)); + logGreen(quiet, info(`Poll contract: ${pollAddr}`)); + logGreen(quiet, info(`Message processor contract: ${messageProcessorContractAddress}`)); + logGreen(quiet, info(`Tally contract: ${tallyContractAddress}`)); + logGreen(quiet, info(`Subsidy contract: ${subsidyContractAddress}`)); // store the addresss - storeContractAddress("MessageProcessor-" + pollId.toString(), messageProcessorContractAddress); - storeContractAddress("Tally-" + pollId.toString(), tallyContractAddress); - storeContractAddress("Subsidy-" + pollId.toString(), subsidyContractAddress); - storeContractAddress("Poll-" + pollId.toString(), pollAddr); - } catch (error: any) { - logError(error.message); + storeContractAddress(`MessageProcessor-${pollId.toString()}`, messageProcessorContractAddress); + storeContractAddress(`Tally-${pollId.toString()}`, tallyContractAddress); + storeContractAddress(`Subsidy-${pollId.toString()}`, subsidyContractAddress); + storeContractAddress(`Poll-${pollId.toString()}`, pollAddr); + } catch (error) { + logError((error as Error).message); } // we return all of the addresses diff --git a/cli/ts/commands/deployVkRegistry.ts b/cli/ts/commands/deployVkRegistry.ts index 26b286b53b..cf9e15fcba 100644 --- a/cli/ts/commands/deployVkRegistry.ts +++ b/cli/ts/commands/deployVkRegistry.ts @@ -1,9 +1,11 @@ import { deployVkRegistry, getDefaultSigner } from "maci-contracts"; -import { existsSync, renameSync } from "fs"; -import { contractAddressesStore, oldContractAddressesStore } from "../utils/constants"; -import { logGreen, success } from "../utils/theme"; + +import fs from "fs"; + import { banner } from "../utils/banner"; +import { contractAddressesStore, oldContractAddressesStore } from "../utils/constants"; import { resetContractAddresses, storeContractAddress } from "../utils/storage"; +import { logGreen, success } from "../utils/theme"; /** * Deploy the vkRegistry contract @@ -12,8 +14,8 @@ import { resetContractAddresses, storeContractAddress } from "../utils/storage"; export const deployVkRegistryContract = async (quiet = true): Promise => { banner(quiet); // assume that the vkRegistry contract is the first one to be deployed - if (existsSync(contractAddressesStore)) { - renameSync(contractAddressesStore, oldContractAddressesStore); + if (fs.existsSync(contractAddressesStore)) { + fs.renameSync(contractAddressesStore, oldContractAddressesStore); resetContractAddresses(); } diff --git a/cli/ts/commands/fundWallet.ts b/cli/ts/commands/fundWallet.ts index 8b02b82ef9..ad648f3802 100644 --- a/cli/ts/commands/fundWallet.ts +++ b/cli/ts/commands/fundWallet.ts @@ -1,5 +1,6 @@ import { getDefaultSigner } from "maci-contracts"; -import { info, logError, logYellow, logGreen, success, banner } from "../utils/"; + +import { info, logError, logYellow, logGreen, success, banner } from "../utils"; /** * Fund a new wallet with Ether @@ -7,7 +8,7 @@ import { info, logError, logYellow, logGreen, success, banner } from "../utils/" * @param address - the address of the wallet to fund * @param quiet - whether to log the output */ -export const fundWallet = async (amount: number, address: string, quiet = true) => { +export const fundWallet = async (amount: number, address: string, quiet = true): Promise => { banner(quiet); const signer = await getDefaultSigner(); @@ -18,11 +19,14 @@ export const fundWallet = async (amount: number, address: string, quiet = true) value: amount.toString(), }); const receipt = await tx.wait(); - if (receipt.status != 1) logError("Transaction failed"); + + if (receipt?.status !== 1) { + logError("Transaction failed"); + } logYellow(quiet, info(`Transaction hash: ${tx.hash}`)); logGreen(quiet, success(`Successfully funded ${address} with ${amount} wei`)); - } catch (error: any) { - logError(error.message); + } catch (error) { + logError((error as Error).message); } }; diff --git a/cli/ts/commands/genKeyPair.ts b/cli/ts/commands/genKeyPair.ts index 69891f9708..0648abe71a 100644 --- a/cli/ts/commands/genKeyPair.ts +++ b/cli/ts/commands/genKeyPair.ts @@ -1,4 +1,5 @@ import { Keypair } from "maci-domainobjs"; + import { banner } from "../utils/banner"; import { logGreen, success } from "../utils/theme"; @@ -7,7 +8,7 @@ import { logGreen, success } from "../utils/theme"; * and print it to the screen * @param quiet - whether to log the output */ -export const genKeyPair = (quiet = true) => { +export const genKeyPair = (quiet = true): { publicKey: string; privateKey: string } => { banner(quiet); // create the new rando keypair const keypair = new Keypair(); diff --git a/cli/ts/commands/genLocalState.ts b/cli/ts/commands/genLocalState.ts index cf44660935..5e96c30b64 100644 --- a/cli/ts/commands/genLocalState.ts +++ b/cli/ts/commands/genLocalState.ts @@ -1,4 +1,9 @@ +import { JsonRpcProvider } from "ethers"; import { getDefaultSigner, genMaciStateFromContract } from "maci-contracts"; +import { Keypair, PrivKey } from "maci-domainobjs"; + +import fs from "fs"; + import { promptSensitiveValue, banner, @@ -10,9 +15,6 @@ import { logGreen, success, } from "../utils"; -import { Keypair, PrivKey } from "maci-domainobjs"; -import { JsonRpcProvider } from "ethers"; -import { writeFileSync } from "fs"; /** * Generate a local MACI state from the smart contracts events @@ -40,36 +42,43 @@ export const genLocalState = async ( transactionHash?: string, sleep?: number, quiet = true, -) => { +): Promise => { banner(quiet); // validation of the maci contract address - if (!readContractAddress("MACI") && !maciContractAddress) logError("MACI contract address is empty"); + if (!readContractAddress("MACI") && !maciContractAddress) { + logError("MACI contract address is empty"); + } - const maciAddress = maciContractAddress ? maciContractAddress : readContractAddress("MACI"); + const maciAddress = maciContractAddress || readContractAddress("MACI"); const signer = await getDefaultSigner(); - if (!(await contractExists(signer.provider, maciAddress))) logError("MACI contract does not exist"); + if (!(await contractExists(signer.provider!, maciAddress))) { + logError("MACI contract does not exist"); + } - if (!readContractAddress(`Poll-${pollId}`)) logError(`There is no poll with id ${pollId}`); - if (!(await contractExists(signer.provider, readContractAddress(`Poll-${pollId}`)))) + if (!readContractAddress(`Poll-${pollId}`)) { + logError(`There is no poll with id ${pollId}`); + } + if (!(await contractExists(signer.provider!, readContractAddress(`Poll-${pollId}`)))) { logError(`Poll-${pollId} contract's is not deployed on this network`); + } // if no private key is passed we ask it securely - const coordPrivKey = coordinatorPrivateKey - ? coordinatorPrivateKey - : await promptSensitiveValue("Insert your MACI private key"); - if (!PrivKey.isValidSerializedPrivKey(coordPrivKey)) logError("Invalid MACI private key"); + const coordPrivKey = coordinatorPrivateKey || (await promptSensitiveValue("Insert your MACI private key")); + if (!PrivKey.isValidSerializedPrivKey(coordPrivKey)) { + logError("Invalid MACI private key"); + } const coordinatorMaciPrivKey = PrivKey.deserialize(coordPrivKey); const coordinatorKeypair = new Keypair(coordinatorMaciPrivKey); // calculate the end block number - const endBlockNumber = endBlock ? endBlock : await signer.provider.getBlockNumber(); + const endBlockNumber = endBlock || (await signer.provider!.getBlockNumber()); - let fromBlock = startBlock ? startBlock : 0; + let fromBlock = startBlock || 0; if (transactionHash) { - const txn = await signer.provider.getTransaction(transactionHash); - fromBlock = txn.blockNumber; + const tx = await signer.provider!.getTransaction(transactionHash); + fromBlock = tx?.blockNumber ?? 0; } const provider = ethereumProvider ? new JsonRpcProvider(ethereumProvider) : signer.provider; @@ -78,20 +87,21 @@ export const genLocalState = async ( quiet, info(`Fetching logs from ${fromBlock} till ${endBlockNumber} and generating the offline maci state`), ); + const maciState = await genMaciStateFromContract( - provider, + provider!, maciAddress, coordinatorKeypair, pollId, fromBlock, - blockPerBatch ? blockPerBatch : 50, + blockPerBatch || 50, endBlockNumber, sleep, ); // write the state to a file const serializedState = maciState.toJSON(); - writeFileSync(outputPath, JSON.stringify(serializedState, null, 4)); + fs.writeFileSync(outputPath, JSON.stringify(serializedState, null, 4)); logGreen(quiet, success(`The state has been written to ${outputPath}`)); }; diff --git a/cli/ts/commands/genProofs.ts b/cli/ts/commands/genProofs.ts index 138de5856b..c8ac630c5f 100644 --- a/cli/ts/commands/genProofs.ts +++ b/cli/ts/commands/genProofs.ts @@ -1,4 +1,15 @@ -import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs"; +import { BaseContract, BigNumberish } from "ethers"; +import { extractVk, genProof, verifyProof } from "maci-circuits"; +import { MACI, AccQueue, Poll, genMaciStateFromContract, getDefaultSigner, parseArtifact } from "maci-contracts"; +import { CircuitInputs, IJsonMaciState, MaciState } from "maci-core"; +import { hash3, hashLeftRight, genTreeCommitment } from "maci-crypto"; +import { Keypair, PrivKey } from "maci-domainobjs"; + +import fs from "fs"; +import path from "path"; + +import type { ISnarkJSVerificationKey } from "snarkjs"; + import { DEFAULT_ETH_PROVIDER, asHex, @@ -12,16 +23,8 @@ import { promptSensitiveValue, readContractAddress, success, -} from "../utils/"; -import { Keypair, PrivKey } from "maci-domainobjs"; -import { extractVk, genProof, verifyProof } from "maci-circuits"; -import { genMaciStateFromContract, getDefaultSigner, parseArtifact } from "maci-contracts"; -import { Contract } from "ethers"; -import { MaciState } from "maci-core"; -import { hash3, hashLeftRight, genTreeCommitment } from "maci-crypto"; -import { join } from "path"; -import { TallyData } from "../utils/interfaces"; -import { ISnarkJSVerificationKey } from "snarkjs"; +} from "../utils"; +import { Proof, TallyData } from "../utils/interfaces"; /** * Generate proofs for the message processing, tally and subsidy calculations @@ -78,60 +81,105 @@ export const genProofs = async ( banner(quiet); // if we do not have the output directory just create it - if (!existsSync(outputDir)) { + if (!fs.existsSync(outputDir)) { // Create the directory - mkdirSync(outputDir); + fs.mkdirSync(outputDir); } // differentiate whether we are using wasm or rapidsnark if (useWasm) { // if no rapidsnark then we assume we go with wasm // so we expect those arguments - if (!processWasm) logError("Please specify the process wasm file location"); - if (!tallyWasm) logError("Please specify the tally wasm file location"); - const [ok, path] = doesPathExist([processWasm, tallyWasm]); - if (!ok) logError(`Could not find ${path}.`); + if (!processWasm) { + logError("Please specify the process wasm file location"); + } + + if (!tallyWasm) { + logError("Please specify the tally wasm file location"); + } + + const wasmResult = doesPathExist([processWasm!, tallyWasm!]); + + if (!wasmResult[0]) { + logError(`Could not find ${wasmResult[1]}.`); + } } else { - const processDatFile = processWitgen + ".dat"; - const tallyDatFile = tallyWitgen + ".dat"; - const [ok, path] = doesPathExist([rapidsnark, processWitgen, tallyWitgen, processDatFile, tallyDatFile]); + if (!rapidsnark) { + logError("Please specify the rapidsnark file location"); + } + + if (!processWitgen) { + logError("Please specify the process witgen file location"); + } + + if (!tallyWitgen) { + logError("Please specify the tally witgen file location"); + } - if (!ok) logError(`Could not find ${path}.`); + const processDatFile = `${processWitgen}.dat`; + const tallyDatFile = `${tallyWitgen}.dat`; + const witgenResult = doesPathExist([rapidsnark!, processWitgen!, tallyWitgen!, processDatFile, tallyDatFile]); + + if (!witgenResult[0]) { + logError(`Could not find ${witgenResult[1]}.`); + } } // check if zkeys were provided - const [ok, path] = doesPathExist([processZkey, tallyZkey]); + const zkResult = doesPathExist([processZkey, tallyZkey]); - if (!ok) logError(`Could not find ${path}.`); + if (!zkResult[0]) { + logError(`Could not find ${zkResult[1]}.`); + } // the vk for the subsidy contract (optional) let subsidyVk: ISnarkJSVerificationKey; if (subsidyFile) { - if (existsSync(subsidyFile)) logError(`${subsidyFile} exists. Please specify a different filepath.`); - if (!subsidyZkey) logError("Please specify the subsidy zkey file location"); - if (!subsidyWitgen) logError("Please specify the subsidy witnessgen file location"); + if (fs.existsSync(subsidyFile)) { + logError(`${subsidyFile} exists. Please specify a different filepath.`); + } + + if (!subsidyZkey) { + logError("Please specify the subsidy zkey file location"); + } + + if (!subsidyWitgen) { + logError("Please specify the subsidy witnessgen file location"); + } // we need different artifacts if using wasm or rapidsnark if (!useWasm) { - if (!subsidyWitgen) logError("Please specify the subsidy witnessgen file location"); - const subsidyDatFile = subsidyWitgen + ".dat"; - const [ok, path] = doesPathExist([subsidyWitgen, subsidyDatFile]); + if (!subsidyWitgen) { + logError("Please specify the subsidy witnessgen file location"); + } + + const subsidyDatFile = `${subsidyWitgen}.dat`; + const subsidyWitgenResult = doesPathExist([subsidyWitgen!, subsidyDatFile]); - if (!ok) logError(`Could not find ${path}.`); + if (!subsidyWitgenResult[0]) { + logError(`Could not find ${subsidyWitgenResult[1]}.`); + } } else { // we expect to have the wasm file - if (!subsidyWasm) logError("Please specify the subsidy wasm file location"); - const [ok, path] = doesPathExist([subsidyWasm]); + if (!subsidyWasm) { + logError("Please specify the subsidy wasm file location"); + } + + const subsidyWasmResult = doesPathExist([subsidyWasm!]); - if (!ok) logError(`Could not find ${path}.`); + if (!subsidyWasmResult[0]) { + logError(`Could not find ${subsidyWasmResult[1]}.`); + } } // either way we check the subsidy zkey - const [ok, path] = doesPathExist([subsidyZkey]); + const subsidyZkeyResult = doesPathExist([subsidyZkey!]); - if (!ok) logError(`Could not find ${path}.`); + if (!subsidyZkeyResult[0]) { + logError(`Could not find ${subsidyZkeyResult[1]}.`); + } - subsidyVk = await extractVk(subsidyZkey); + subsidyVk = await extractVk(subsidyZkey!); } // extract the rest of the verifying keys @@ -139,62 +187,77 @@ export const genProofs = async ( const tallyVk = await extractVk(tallyZkey); // the coordinator's MACI private key - const privateKey = coordinatorPrivKey - ? coordinatorPrivKey - : await promptSensitiveValue("Insert your MACI private key"); - if (!PrivKey.isValidSerializedPrivKey(privateKey)) logError("Invalid MACI private key"); + const privateKey = coordinatorPrivKey || (await promptSensitiveValue("Insert your MACI private key")); + if (!PrivKey.isValidSerializedPrivKey(privateKey)) { + logError("Invalid MACI private key"); + } const maciPrivKey = PrivKey.deserialize(privateKey); const coordinatorKeypair = new Keypair(maciPrivKey); const signer = await getDefaultSigner(); // contracts - if (!readContractAddress("MACI") && !maciAddress) logError("MACI contract address is empty"); - const maciContractAddress = maciAddress ? maciAddress : readContractAddress("MACI"); + if (!readContractAddress("MACI") && !maciAddress) { + logError("MACI contract address is empty"); + } + const maciContractAddress = maciAddress || readContractAddress("MACI"); - if (!(await contractExists(signer.provider, maciContractAddress))) logError("MACI contract does not exist"); + if (!(await contractExists(signer.provider!, maciContractAddress))) { + logError("MACI contract does not exist"); + } - if (pollId < 0) logError("Invalid poll id"); + if (pollId < 0) { + logError("Invalid poll id"); + } - const maciContract = new Contract(maciContractAddress, parseArtifact("MACI")[0], signer); + const maciContract = new BaseContract(maciContractAddress, parseArtifact("MACI")[0], signer) as MACI; const pollAddr = await maciContract.polls(pollId); - if (!(await contractExists(signer.provider, pollAddr))) logError("Poll contract does not exist"); - const pollContract = new Contract(pollAddr, parseArtifact("Poll")[0], signer); + if (!(await contractExists(signer.provider!, pollAddr))) { + logError("Poll contract does not exist"); + } + const pollContract = new BaseContract(pollAddr, parseArtifact("Poll")[0], signer) as Poll; const extContracts = await pollContract.extContracts(); const messageAqContractAddr = extContracts.messageAq; - const messageAqContract = new Contract(messageAqContractAddr, parseArtifact("AccQueue")[0], signer); + const messageAqContract = new BaseContract(messageAqContractAddr, parseArtifact("AccQueue")[0], signer) as AccQueue; // Check that the state and message trees have been merged for at least the first poll - if (!(await pollContract.stateAqMerged()) && pollId == 0) - logError("The state tree has not been merged yet. " + "Please use the mergeSignups subcommmand to do so."); + if (!(await pollContract.stateAqMerged()) && pollId.toString() === "0") { + logError("The state tree has not been merged yet. Please use the mergeSignups subcommmand to do so."); + } const messageTreeDepth = Number((await pollContract.treeDepths()).messageTreeDepth); // check that the main root is set const mainRoot = (await messageAqContract.getMainRoot(messageTreeDepth.toString())).toString(); - if (mainRoot === "0") + if (mainRoot === "0") { logError("The message tree has not been merged yet. Please use the mergeMessages subcommmand to do so."); + } - let maciState: MaciState; + let maciState: MaciState | undefined; if (stateFile) { - const content = JSON.parse(readFileSync(stateFile).toString()); + const content = JSON.parse(fs.readFileSync(stateFile).toString()) as IJsonMaciState; + const serializedPrivateKey = maciPrivKey.serialize(); + try { maciState = MaciState.fromJSON(content); - for (const poll of maciState.polls) { - poll.setCoordinatorKeypair(maciPrivKey.serialize()); - } - } catch (error: any) { - logError(error.message); + + maciState.polls.forEach((poll) => { + poll.setCoordinatorKeypair(serializedPrivateKey); + }); + } catch (error) { + logError((error as Error).message); } } else { // build an off-chain representation of the MACI contract using data in the contract storage let fromBlock = startBlock ? Number(startBlock) : 0; - fromBlock = transactionHash ? (await signer.provider.getTransaction(transactionHash)).blockNumber : 0; + fromBlock = transactionHash + ? await signer.provider!.getTransaction(transactionHash).then((tx) => tx?.blockNumber ?? 0) + : 0; logYellow(quiet, info(`starting to fetch logs from block ${fromBlock}`)); maciState = await genMaciStateFromContract( - signer.provider, + signer.provider!, await maciContract.getAddress(), coordinatorKeypair, pollId, @@ -204,20 +267,22 @@ export const genProofs = async ( ); } - const poll = maciState.polls[pollId]; + const poll = maciState!.polls[pollId]; - const processProofs: any[] = []; - const tallyProofs: any[] = []; - const subsidyProofs: any[] = []; + const processProofs: Proof[] = []; + const tallyProofs: Proof[] = []; + const subsidyProofs: Proof[] = []; // time how long it takes const startTime = Date.now(); logYellow(quiet, info(`Generating proofs of message processing...`)); - const messageBatchSize = poll.batchSizes.messageBatchSize; + const { messageBatchSize } = poll.batchSizes; const numMessages = poll.messages.length; let totalMessageBatches = numMessages <= messageBatchSize ? 1 : Math.floor(numMessages / messageBatchSize); - if (numMessages > messageBatchSize && numMessages % messageBatchSize > 0) totalMessageBatches++; + if (numMessages > messageBatchSize && numMessages % messageBatchSize > 0) { + totalMessageBatches += 1; + } // while we have unprocessed messages, process them while (poll.hasUnprocessedMessages()) { @@ -225,6 +290,7 @@ export const genProofs = async ( const circuitInputs = poll.processMessages(pollId); try { // generate the proof for this batch + // eslint-disable-next-line no-await-in-loop const r = await genProof({ inputs: circuitInputs, zkeyPath: processZkey, @@ -234,8 +300,11 @@ export const genProofs = async ( wasmPath: processWasm, }); // verify it + // eslint-disable-next-line no-await-in-loop const isValid = await verifyProof(r.publicSignals, r.proof, processVk); - if (!isValid) logError("Error: generated an invalid proof"); + if (!isValid) { + logError("Error: generated an invalid proof"); + } const thisProof = { circuitInputs, @@ -244,14 +313,14 @@ export const genProofs = async ( }; // save the proof processProofs.push(thisProof); - writeFileSync( - join(outputDir, `process_${poll.numBatchesProcessed - 1}.json`), + fs.writeFileSync( + path.resolve(outputDir, `process_${poll.numBatchesProcessed - 1}.json`), JSON.stringify(thisProof, null, 4), ); logYellow(quiet, info(`Progress: ${poll.numBatchesProcessed} / ${totalMessageBatches}`)); - } catch (error: any) { - logError(error.message); + } catch (error) { + logError((error as Error).message); } } @@ -265,7 +334,7 @@ export const genProofs = async ( logYellow(quiet, info(`Generating proofs of subsidy calculation...`)); - const subsidyBatchSize = poll.batchSizes.subsidyBatchSize; + const { subsidyBatchSize } = poll.batchSizes; const numLeaves = poll.stateLeaves.length; const totalSubsidyBatches = Math.ceil(numLeaves / subsidyBatchSize) ** 2; @@ -278,24 +347,28 @@ export const genProofs = async ( // @todo fix types in the circuits package // @todo why this next part works - let subsidyCircuitInputs: any; + let subsidyCircuitInputs: CircuitInputs; // calculate the subsidy for each batch while (poll.hasUnfinishedSubsidyCalculation()) { // calculate subsidy in batches subsidyCircuitInputs = poll.subsidyPerBatch(); try { // generate proof for this batch + // eslint-disable-next-line no-await-in-loop const r = await genProof({ inputs: subsidyCircuitInputs, - zkeyPath: subsidyZkey, + zkeyPath: subsidyZkey!, useWasm, rapidsnarkExePath: rapidsnark, witnessExePath: subsidyWitgen, wasmPath: subsidyWasm, }); // check validity of it - const isValid = await verifyProof(r.publicSignals, r.proof, subsidyVk); - if (!isValid) logError("Error: generated an invalid subsidy calc proof"); + // eslint-disable-next-line no-await-in-loop + const isValid = await verifyProof(r.publicSignals, r.proof, subsidyVk!); + if (!isValid) { + logError("Error: generated an invalid subsidy calc proof"); + } const thisProof = { circuitInputs: subsidyCircuitInputs, @@ -303,12 +376,15 @@ export const genProofs = async ( publicInputs: r.publicSignals, }; subsidyProofs.push(thisProof); - writeFileSync(join(outputDir, `subsidy_${numBatchesCalulated}.json`), JSON.stringify(thisProof, null, 4)); - numBatchesCalulated++; + fs.writeFileSync( + path.resolve(outputDir, `subsidy_${numBatchesCalulated}.json`), + JSON.stringify(thisProof, null, 4), + ); + numBatchesCalulated += 1; logYellow(quiet, info(`Progress: ${numBatchesCalulated} / ${totalSubsidyBatches}`)); - } catch (error: any) { - logError(error.message); + } catch (error) { + logError((error as Error).message); } } @@ -316,15 +392,15 @@ export const genProofs = async ( provider: process.env.ETH_PROVIDER || DEFAULT_ETH_PROVIDER, maci: maciAddress, pollId, - newSubsidyCommitment: asHex(subsidyCircuitInputs.newSubsidyCommitment), + newSubsidyCommitment: asHex(subsidyCircuitInputs!.newSubsidyCommitment as BigNumberish), results: { subsidy: poll.subsidy.map((x) => x.toString()), - salt: asHex(subsidyCircuitInputs.newSubsidySalt), + salt: asHex(subsidyCircuitInputs!.newSubsidySalt as BigNumberish), }, }; // store it - writeFileSync(subsidyFile, JSON.stringify(subsidyFileData, null, 4)); + fs.writeFileSync(subsidyFile, JSON.stringify(subsidyFileData, null, 4)); logYellow(quiet, info(`Subsidy file:\n${JSON.stringify(subsidyFileData, null, 4)}\n`)); const susbsidyEndTime = Date.now(); @@ -336,12 +412,14 @@ export const genProofs = async ( logYellow(quiet, info(`Generating proofs of vote tallying...`)); const tallyStartTime = Date.now(); - const tallyBatchSize = poll.batchSizes.tallyBatchSize; + const { tallyBatchSize } = poll.batchSizes; const numStateLeaves = poll.stateLeaves.length; let totalTallyBatches = numStateLeaves <= tallyBatchSize ? 1 : Math.floor(numStateLeaves / tallyBatchSize); - if (numStateLeaves > tallyBatchSize && numStateLeaves % tallyBatchSize > 0) totalTallyBatches++; + if (numStateLeaves > tallyBatchSize && numStateLeaves % tallyBatchSize > 0) { + totalTallyBatches += 1; + } - let tallyCircuitInputs: any; + let tallyCircuitInputs: CircuitInputs; // tally all ballots for this poll while (poll.hasUntalliedBallots()) { // tally votes in batches @@ -349,6 +427,7 @@ export const genProofs = async ( try { // generate the proof + // eslint-disable-next-line no-await-in-loop const r = await genProof({ inputs: tallyCircuitInputs, zkeyPath: tallyZkey, @@ -359,9 +438,12 @@ export const genProofs = async ( }); // verify it + // eslint-disable-next-line no-await-in-loop const isValid = await verifyProof(r.publicSignals, r.proof, tallyVk); - if (!isValid) logError("Generated an invalid tally proof"); + if (!isValid) { + logError("Generated an invalid tally proof"); + } const thisProof = { circuitInputs: tallyCircuitInputs, @@ -371,11 +453,14 @@ export const genProofs = async ( // save it tallyProofs.push(thisProof); - writeFileSync(join(outputDir, `tally_${poll.numBatchesTallied - 1}.json`), JSON.stringify(thisProof, null, 4)); + fs.writeFileSync( + path.resolve(outputDir, `tally_${poll.numBatchesTallied - 1}.json`), + JSON.stringify(thisProof, null, 4), + ); logYellow(quiet, info(`Progress: ${poll.numBatchesTallied} / ${totalTallyBatches}`)); - } catch (error: any) { - logError(error.message); + } catch (error) { + logError((error as Error).message); } } @@ -383,20 +468,20 @@ export const genProofs = async ( // Compute newResultsCommitment const newResultsCommitment = genTreeCommitment( poll.tallyResult, - BigInt(asHex(tallyCircuitInputs.newResultsRootSalt)), + BigInt(asHex(tallyCircuitInputs!.newResultsRootSalt as BigNumberish)), poll.treeDepths.voteOptionTreeDepth, ); // compute newSpentVoiceCreditsCommitment const newSpentVoiceCreditsCommitment = hashLeftRight( poll.totalSpentVoiceCredits, - BigInt(asHex(tallyCircuitInputs.newSpentVoiceCreditSubtotalSalt)), + BigInt(asHex(tallyCircuitInputs!.newSpentVoiceCreditSubtotalSalt as BigNumberish)), ); // Compute newPerVOSpentVoiceCreditsCommitment const newPerVOSpentVoiceCreditsCommitment = genTreeCommitment( poll.perVOSpentVoiceCredits, - BigInt(asHex(tallyCircuitInputs.newPerVOSpentVoiceCreditsRootSalt)), + BigInt(asHex(tallyCircuitInputs!.newPerVOSpentVoiceCreditsRootSalt as BigNumberish)), poll.treeDepths.voteOptionTreeDepth, ); @@ -409,27 +494,27 @@ export const genProofs = async ( // create the tally file data to store for verification later const tallyFileData: TallyData = { - maci: maciAddress, + maci: maciAddress!, pollId, - newTallyCommitment: asHex(tallyCircuitInputs.newTallyCommitment), + newTallyCommitment: asHex(tallyCircuitInputs!.newTallyCommitment as BigNumberish), results: { tally: poll.tallyResult.map((x) => x.toString()), - salt: asHex(tallyCircuitInputs.newResultsRootSalt), + salt: asHex(tallyCircuitInputs!.newResultsRootSalt as BigNumberish), commitment: asHex(newResultsCommitment), }, totalSpentVoiceCredits: { spent: poll.totalSpentVoiceCredits.toString(), - salt: asHex(tallyCircuitInputs.newSpentVoiceCreditSubtotalSalt), + salt: asHex(tallyCircuitInputs!.newSpentVoiceCreditSubtotalSalt as BigNumberish), commitment: asHex(newSpentVoiceCreditsCommitment), }, perVOSpentVoiceCredits: { tally: poll.perVOSpentVoiceCredits.map((x) => x.toString()), - salt: asHex(tallyCircuitInputs.newPerVOSpentVoiceCreditsRootSalt), + salt: asHex(tallyCircuitInputs!.newPerVOSpentVoiceCreditsRootSalt as BigNumberish), commitment: asHex(newPerVOSpentVoiceCreditsCommitment), }, }; - writeFileSync(tallyFile, JSON.stringify(tallyFileData, null, 4)); + fs.writeFileSync(tallyFile, JSON.stringify(tallyFileData, null, 4)); logYellow(quiet, info(`Tally file:\n${JSON.stringify(tallyFileData, null, 4)}\n`)); diff --git a/cli/ts/commands/genPubKey.ts b/cli/ts/commands/genPubKey.ts index 40cdec2de1..e06411af14 100644 --- a/cli/ts/commands/genPubKey.ts +++ b/cli/ts/commands/genPubKey.ts @@ -1,5 +1,6 @@ import { genPubKey } from "maci-crypto"; import { PrivKey, PubKey } from "maci-domainobjs"; + import { banner } from "../utils/banner"; import { logError, logGreen, success } from "../utils/theme"; diff --git a/cli/ts/commands/mergeMessages.ts b/cli/ts/commands/mergeMessages.ts index 0742bc8593..12f6c6351c 100644 --- a/cli/ts/commands/mergeMessages.ts +++ b/cli/ts/commands/mergeMessages.ts @@ -1,5 +1,6 @@ -import { getDefaultSigner, parseArtifact } from "maci-contracts"; -import { Contract } from "ethers"; +import { BaseContract } from "ethers"; +import { MACI, Poll, AccQueue, getDefaultSigner, parseArtifact } from "maci-contracts"; + import { DEFAULT_SR_QUEUE_OPS, banner, @@ -25,64 +26,88 @@ export const mergeMessages = async ( maciContractAddress?: string, numQueueOps?: string, quiet = true, -) => { +): Promise => { banner(quiet); const signer = await getDefaultSigner(); // maci contract validation - if (!readContractAddress("MACI") && !maciContractAddress) logError("Could not read contracts"); - const maciAddress = maciContractAddress ? maciContractAddress : readContractAddress("MACI"); - if (!(await contractExists(signer.provider, maciAddress))) logError("MACI contract does not exist"); + if (!readContractAddress("MACI") && !maciContractAddress) { + logError("Could not read contracts"); + } + const maciAddress = maciContractAddress || readContractAddress("MACI"); + if (!(await contractExists(signer.provider!, maciAddress))) { + logError("MACI contract does not exist"); + } - if (pollId < 0) logError("Invalid poll id"); + if (pollId < 0) { + logError("Invalid poll id"); + } const maciContractAbi = parseArtifact("MACI")[0]; const pollContractAbi = parseArtifact("Poll")[0]; const accQueueContractAbi = parseArtifact("AccQueue")[0]; - const maciContract = new Contract(maciAddress, maciContractAbi, signer); + const maciContract = new BaseContract(maciAddress, maciContractAbi, signer) as MACI; const pollAddress = await maciContract.polls(pollId); - if (!(await contractExists(signer.provider, pollAddress))) logError("Poll contract does not exist"); + if (!(await contractExists(signer.provider!, pollAddress))) { + logError("Poll contract does not exist"); + } - const pollContract = new Contract(pollAddress, pollContractAbi, signer); + const pollContract = new BaseContract(pollAddress, pollContractAbi, signer) as Poll; const extContracts = await pollContract.extContracts(); const messageAqContractAddr = extContracts.messageAq; - const accQueueContract = new Contract(messageAqContractAddr, accQueueContractAbi, signer); + const accQueueContract = new BaseContract(messageAqContractAddr, accQueueContractAbi, signer) as AccQueue; // we need to ensure that the signer is the owner of the poll contract // this is because only the owner can merge the message AQ const pollOwner = await pollContract.owner(); const signerAddress = await signer.getAddress(); - if (pollOwner.toLowerCase() !== signerAddress.toLowerCase()) + if (pollOwner.toLowerCase() !== signerAddress.toLowerCase()) { logError("The signer is not the owner of this Poll contract"); + } // check if it's time to merge the message AQ const dd = await pollContract.getDeployTimeAndDuration(); const deadline = Number(dd[0]) + Number(dd[1]); - const now = await currentBlockTimestamp(signer.provider); + const now = await currentBlockTimestamp(signer.provider!); + + if (now < deadline) { + logError("The voting period is not over yet"); + } - if (now < deadline) logError("The voting period is not over yet"); + let subTreesMerged = false; // infinite loop to merge the sub trees - while (true) { - if (await accQueueContract.subTreesMerged()) { + while (!subTreesMerged) { + // eslint-disable-next-line no-await-in-loop + subTreesMerged = await accQueueContract.subTreesMerged(); + + if (subTreesMerged) { logGreen(quiet, success("All message subtrees have been merged.")); - break; + } else { + // eslint-disable-next-line no-await-in-loop + await accQueueContract + .getSrIndices() + .then((data) => data.map((x) => Number(x))) + .then((indices) => { + logYellow(quiet, info(`Merging message subroots ${indices[0] + 1} / ${indices[1] + 1}`)); + }); + + // eslint-disable-next-line no-await-in-loop + const tx = await pollContract.mergeMessageAqSubRoots(numQueueOps || DEFAULT_SR_QUEUE_OPS); + // eslint-disable-next-line no-await-in-loop + const receipt = await tx.wait(); + + if (receipt?.status !== 1) { + logError("Transaction failed"); + } + + logGreen(quiet, success(`Executed mergeMessageAqSubRoots(); gas used: ${receipt!.gasUsed.toString()}`)); + + logYellow(quiet, info(`Transaction hash: ${receipt!.hash}`)); } - - const indices = (await accQueueContract.getSrIndices()).map((x: any) => Number(x)); - - logYellow(quiet, info(`Merging message subroots ${indices[0] + 1} / ${indices[1] + 1}`)); - - const tx = await pollContract.mergeMessageAqSubRoots(numQueueOps ? numQueueOps : DEFAULT_SR_QUEUE_OPS); - const receipt = await tx.wait(); - if (receipt.status !== 1) logError("Transaction failed"); - - logGreen(quiet, success(`Executed mergeMessageAqSubRoots(); gas used: ${receipt.gasUsed.toString()}`)); - - logYellow(quiet, info(`Transaction hash: ${receipt.hash}`)); } // check if the message AQ has been fully merged @@ -96,10 +121,13 @@ export const mergeMessages = async ( logYellow(quiet, info("Merging subroots to a main message root...")); const tx = await pollContract.mergeMessageAq(); const receipt = await tx.wait(); - if (receipt.status !== 1) logError("Transaction failed"); - logGreen(quiet, success(`Executed mergeMessageAq(); gas used: ${receipt.gasUsed.toString()}`)); - logYellow(quiet, info(`Transaction hash: ${receipt.hash}`)); + if (receipt?.status !== 1) { + logError("Transaction failed"); + } + + logGreen(quiet, success(`Executed mergeMessageAq(); gas used: ${receipt!.gasUsed.toString()}`)); + logYellow(quiet, info(`Transaction hash: ${receipt!.hash}`)); logGreen(quiet, success("The message tree has been merged.")); } else { logYellow(quiet, info("The message tree has already been merged.")); diff --git a/cli/ts/commands/mergeSignups.ts b/cli/ts/commands/mergeSignups.ts index a7b0c7b536..5fc81b5a59 100644 --- a/cli/ts/commands/mergeSignups.ts +++ b/cli/ts/commands/mergeSignups.ts @@ -1,5 +1,6 @@ -import { getDefaultSigner, parseArtifact } from "maci-contracts"; -import { Contract } from "ethers"; +import { BaseContract } from "ethers"; +import { AccQueue, MACI, Poll, getDefaultSigner, parseArtifact } from "maci-contracts"; + import { DEFAULT_SR_QUEUE_OPS, banner, @@ -11,7 +12,7 @@ import { logYellow, success, readContractAddress, -} from "../utils/"; +} from "../utils"; /** * Command to merge the signups of a MACI contract @@ -25,59 +26,81 @@ export const mergeSignups = async ( maciContractAddress?: string, numQueueOps?: string, quiet = true, -) => { +): Promise => { banner(quiet); const signer = await getDefaultSigner(); // maci contract validation - if (!readContractAddress("MACI") && !maciContractAddress) logError("Could not read contracts"); + if (!readContractAddress("MACI") && !maciContractAddress) { + logError("Could not read contracts"); + } - const maciAddress = maciContractAddress ? maciContractAddress : readContractAddress("MACI"); - if (!(await contractExists(signer.provider, maciAddress))) logError("MACI contract does not exist"); + const maciAddress = maciContractAddress || readContractAddress("MACI"); - if (pollId < 0) logError("Invalid poll id"); + if (!(await contractExists(signer.provider!, maciAddress))) { + logError("MACI contract does not exist"); + } + + if (pollId < 0) { + logError("Invalid poll id"); + } - const maciContractAbi = parseArtifact("MACI")[0]; - const pollContractAbi = parseArtifact("Poll")[0]; - const accQueueContractAbi = parseArtifact("AccQueue")[0]; + const [maciContractAbi] = parseArtifact("MACI"); + const [pollContractAbi] = parseArtifact("Poll"); + const [accQueueContractAbi] = parseArtifact("AccQueue"); - const maciContract = new Contract(maciAddress, maciContractAbi, signer); + const maciContract = new BaseContract(maciAddress, maciContractAbi, signer) as MACI; const pollAddress = await maciContract.polls(pollId); - if (!(await contractExists(signer.provider, pollAddress))) logError("Poll contract does not exist"); - const pollContract = new Contract(pollAddress, pollContractAbi, signer); + if (!(await contractExists(signer.provider!, pollAddress))) { + logError("Poll contract does not exist"); + } + + const pollContract = new BaseContract(pollAddress, pollContractAbi, signer) as Poll; - const accQueueContract = new Contract(await maciContract.stateAq(), accQueueContractAbi, signer); + const accQueueContract = new BaseContract(await maciContract.stateAq(), accQueueContractAbi, signer) as AccQueue; // check if it's time to merge the message AQ const dd = await pollContract.getDeployTimeAndDuration(); const deadline = Number(dd[0]) + Number(dd[1]); - const now = await currentBlockTimestamp(signer.provider); - if (now < deadline) logError("Voting period is not over"); + const now = await currentBlockTimestamp(signer.provider!); + + if (now < deadline) { + logError("Voting period is not over"); + } + + let subTreesMerged = false; // infinite loop to merge the sub trees - while (true) { - const subTreesMerged = await accQueueContract.subTreesMerged(); + while (!subTreesMerged) { + // eslint-disable-next-line no-await-in-loop + subTreesMerged = await accQueueContract.subTreesMerged(); + if (subTreesMerged) { logGreen(quiet, success("All state subtrees have been merged.")); - break; + } else { + // eslint-disable-next-line no-await-in-loop + await accQueueContract + .getSrIndices() + .then((data) => data.map((x) => Number(x))) + .then((indices) => { + logYellow(quiet, info(`Merging state subroots ${indices[0] + 1} / ${indices[1] + 1}`)); + }); + + // first merge the subroots + // eslint-disable-next-line no-await-in-loop + const tx = await pollContract.mergeMaciStateAqSubRoots(numQueueOps || DEFAULT_SR_QUEUE_OPS, pollId.toString()); + // eslint-disable-next-line no-await-in-loop + const receipt = await tx.wait(); + + if (receipt?.status !== 1) { + logError("Error merging state subroots"); + } + + logYellow(quiet, info(`Transaction hash: ${receipt!.hash}`)); + logGreen(quiet, success(`Executed mergeMaciStateAqSubRoots(); gas used: ${receipt!.gasUsed.toString()}`)); } - - const indices = (await accQueueContract.getSrIndices()).map((x: any) => Number(x)); - - logYellow(quiet, info(`Merging state subroots ${indices[0] + 1} / ${indices[1] + 1}`)); - - // first merge the subroots - const tx = await pollContract.mergeMaciStateAqSubRoots( - numQueueOps ? numQueueOps : DEFAULT_SR_QUEUE_OPS, - pollId.toString(), - ); - const receipt = await tx.wait(); - if (receipt.status !== 1) logError("Error merging state subroots"); - - logYellow(quiet, info(`Transaction hash: ${receipt.hash}`)); - logGreen(quiet, success(`Executed mergeMaciStateAqSubRoots(); gas used: ${receipt.gasUsed.toString()}`)); } // check if the state AQ has been fully merged @@ -89,10 +112,13 @@ export const mergeSignups = async ( logYellow(quiet, info("Merging subroots to a main state root...")); const tx = await pollContract.mergeMaciStateAq(pollId.toString()); const receipt = await tx.wait(); - if (receipt.status !== 1) logError("Error merging state subroots"); - logYellow(quiet, info(`Transaction hash: ${receipt.hash}`)); - logGreen(quiet, success(`Executed mergeStateAq(); gas used: ${receipt.gasUsed.toString()}`)); + if (receipt?.status !== 1) { + logError("Error merging state subroots"); + } + + logYellow(quiet, info(`Transaction hash: ${receipt!.hash}`)); + logGreen(quiet, success(`Executed mergeStateAq(); gas used: ${receipt!.gasUsed.toString()}`)); } else { logYellow(quiet, info("The state tree has already been merged.")); } diff --git a/cli/ts/commands/proveOnChain.ts b/cli/ts/commands/proveOnChain.ts index 80b86b0782..8d66065a7d 100644 --- a/cli/ts/commands/proveOnChain.ts +++ b/cli/ts/commands/proveOnChain.ts @@ -1,3 +1,5 @@ +/* eslint-disable no-await-in-loop */ +import { BaseContract, BigNumberish } from "ethers"; import { MACI, AccQueue, @@ -12,6 +14,12 @@ import { Verifier, IVerifyingKeyStruct, } from "maci-contracts"; +import { G1Point, G2Point, hashLeftRight } from "maci-crypto"; +import { VerifyingKey } from "maci-domainobjs"; + +import fs from "fs"; +import path from "path"; + import { asHex, banner, @@ -24,12 +32,8 @@ import { logYellow, readContractAddress, success, -} from "../utils/"; -import { BaseContract } from "ethers"; -import { readFileSync, readdirSync } from "fs"; -import { join } from "path"; -import { G1Point, G2Point, hashLeftRight } from "maci-crypto"; -import { VerifyingKey } from "maci-domainobjs"; +} from "../utils"; +import { Proof } from "../utils/interfaces"; /** * Command to prove the result of a poll on-chain @@ -49,36 +53,52 @@ export const proveOnChain = async ( tallyAddress?: string, subsidyAddress?: string, quiet = true, -) => { +): Promise => { banner(quiet); const signer = await getDefaultSigner(); // check existence of contract addresses - if (!readContractAddress("MACI") && !maciAddress) logError("MACI contract address is empty"); - if (!readContractAddress("MessageProcessor-" + pollId) && !messageProcessorAddress) + if (!readContractAddress("MACI") && !maciAddress) { + logError("MACI contract address is empty"); + } + if (!readContractAddress(`MessageProcessor-${pollId}`) && !messageProcessorAddress) { logError("MessageProcessor contract address is empty"); - if (!readContractAddress("Tally-" + pollId) && !tallyAddress) logError("Tally contract address is empty"); - if (!readContractAddress("Subsidy-" + pollId) && !subsidyAddress) logError("Subsidy contract address is empty"); + } + if (!readContractAddress(`Tally-${pollId}`) && !tallyAddress) { + logError("Tally contract address is empty"); + } + if (!readContractAddress(`Subsidy-${pollId}`) && !subsidyAddress) { + logError("Subsidy contract address is empty"); + } // check validity of contract addresses - const maciContractAddress = maciAddress ? maciAddress : readContractAddress("MACI"); - const messageProcessorContractAddress = messageProcessorAddress - ? messageProcessorAddress - : readContractAddress("MessageProcessor-" + pollId); - const tallyContractAddress = tallyAddress ? tallyAddress : readContractAddress("Tally-" + pollId); - const subsidyContractAddress = subsidyAddress ? subsidyAddress : readContractAddress("Subsidy-" + pollId); + const maciContractAddress = maciAddress || readContractAddress("MACI"); + const messageProcessorContractAddress = messageProcessorAddress || readContractAddress(`MessageProcessor-${pollId}`); + const tallyContractAddress = tallyAddress || readContractAddress(`Tally-${pollId}`); + const subsidyContractAddress = subsidyAddress || readContractAddress(`Subsidy-${pollId}`); // check contracts are deployed on chain - if (!(await contractExists(signer.provider, maciContractAddress))) logError("MACI contract does not exist"); - if (!(await contractExists(signer.provider, messageProcessorContractAddress))) + if (!(await contractExists(signer.provider!, maciContractAddress))) { + logError("MACI contract does not exist"); + } + + if (!(await contractExists(signer.provider!, messageProcessorContractAddress))) { logError("MessageProcessor contract does not exist"); - if (!(await contractExists(signer.provider, tallyContractAddress))) logError("Tally contract does not exist"); - if (!(await contractExists(signer.provider, subsidyContractAddress))) logError("Subsidy contract does not exist"); + } + + if (!(await contractExists(signer.provider!, tallyContractAddress))) { + logError("Tally contract does not exist"); + } + + if (!(await contractExists(signer.provider!, subsidyContractAddress))) { + logError("Subsidy contract does not exist"); + } const maciContract = new BaseContract(maciContractAddress, parseArtifact("MACI")[0], signer) as MACI; const pollAddr = await maciContract.polls(pollId); - if (!(await contractExists(signer.provider, pollAddr))) { + + if (!(await contractExists(signer.provider!, pollAddr))) { logError("There is no Poll contract with this poll ID linked to the specified MACI contract."); } @@ -95,7 +115,8 @@ export const proveOnChain = async ( const subsidyContract = new BaseContract(subsidyContractAddress, parseArtifact("Subsidy")[0], signer) as Subsidy; const messageAqContractAddress = (await pollContract.extContracts()).messageAq; - if (!(await contractExists(signer.provider, messageAqContractAddress))) { + + if (!(await contractExists(signer.provider!, messageAqContractAddress))) { logError("There is no MessageAq contract linked to the specified MACI contract."); } @@ -106,9 +127,11 @@ export const proveOnChain = async ( ) as AccQueue; const vkRegistryContractAddress = await tallyContract.vkRegistry(); - if (!(await contractExists(signer.provider, vkRegistryContractAddress))) { + + if (!(await contractExists(signer.provider!, vkRegistryContractAddress))) { logError("There is no VkRegistry contract linked to the specified MACI contract."); } + const vkRegsitryContract = new BaseContract( vkRegistryContractAddress, parseArtifact("VkRegistry")[0], @@ -116,9 +139,11 @@ export const proveOnChain = async ( ) as VkRegistry; const verifierContractAddress = await mpContract.verifier(); - if (!(await contractExists(signer.provider, verifierContractAddress))) { + + if (!(await contractExists(signer.provider!, verifierContractAddress))) { logError("There is no Verifier contract linked to the specified MACI contract."); } + const verifierContract = new BaseContract(verifierContractAddress, parseArtifact("Verifier")[0], signer) as Verifier; const [pollContractAddress, mpContractAddress] = await Promise.all([ @@ -127,36 +152,37 @@ export const proveOnChain = async ( ]); const data = { - processProofs: {}, - tallyProofs: {}, - subsidyProofs: {}, + processProofs: [] as Proof[], + tallyProofs: [] as Proof[], + subsidyProofs: [] as Proof[], }; let numProcessProofs = 0; // read the proof directory - const filenames = readdirSync(proofDir); + const filenames = fs.readdirSync(proofDir); // extract all the proofs data - for (const filename of filenames) { - const filepath = join(proofDir, filename); + filenames.forEach((filename) => { + const filepath = path.resolve(proofDir, filename); let match = filename.match(/process_(\d+)/); + if (match) { - data.processProofs[Number(match[1])] = JSON.parse(readFileSync(filepath).toString()); - numProcessProofs++; - continue; + data.processProofs[Number(match[1])] = JSON.parse(fs.readFileSync(filepath).toString()) as Proof; + numProcessProofs += 1; + return; } match = filename.match(/tally_(\d+)/); if (match) { - data.tallyProofs[Number(match[1])] = JSON.parse(readFileSync(filepath).toString()); - continue; + data.tallyProofs[Number(match[1])] = JSON.parse(fs.readFileSync(filepath).toString()) as Proof; + return; } match = filename.match(/subsidy_(\d+)/); if (match) { - data.subsidyProofs[Number(match[1])] = JSON.parse(readFileSync(filepath).toString()); + data.subsidyProofs[Number(match[1])] = JSON.parse(fs.readFileSync(filepath).toString()) as Proof; } - } + }); // retrieve the values we need from the smart contracts const numSignUpsAndMessages = await pollContract.numSignUpsAndMessages(); @@ -169,7 +195,7 @@ export const proveOnChain = async ( let totalMessageBatches = numMessages <= messageBatchSize ? 1 : Math.floor(numMessages / messageBatchSize); if (numMessages > messageBatchSize && numMessages % messageBatchSize > 0) { - totalMessageBatches++; + totalMessageBatches += 1; } // perform validation @@ -198,51 +224,75 @@ export const proveOnChain = async ( const dd = await pollContract.getDeployTimeAndDuration(); const pollEndTimestampOnChain = BigInt(dd[0]) + BigInt(dd[1]); - if (numberBatchesProcessed < totalMessageBatches) + if (numberBatchesProcessed < totalMessageBatches) { logYellow(quiet, info("Submitting proofs of message processing...")); + } // process all batches left - for (let i = numberBatchesProcessed; i < totalMessageBatches; i++) { + for (let i = numberBatchesProcessed; i < totalMessageBatches; i += 1) { let currentMessageBatchIndex: number; if (numberBatchesProcessed === 0) { const r = numMessages % messageBatchSize; - if (r === 0) currentMessageBatchIndex = Math.floor(numMessages / messageBatchSize) * messageBatchSize; - else currentMessageBatchIndex = numMessages; + + if (r === 0) { + currentMessageBatchIndex = Math.floor(numMessages / messageBatchSize) * messageBatchSize; + } else { + currentMessageBatchIndex = numMessages; + } if (currentMessageBatchIndex > 0) { if (r === 0) { currentMessageBatchIndex -= messageBatchSize; - } else currentMessageBatchIndex -= r; + } else { + currentMessageBatchIndex -= r; + } } - } else currentMessageBatchIndex = (totalMessageBatches - numberBatchesProcessed) * messageBatchSize; + } else { + currentMessageBatchIndex = (totalMessageBatches - numberBatchesProcessed) * messageBatchSize; + } - if (numberBatchesProcessed > 0 && currentMessageBatchIndex > 0) currentMessageBatchIndex -= messageBatchSize; + if (numberBatchesProcessed > 0 && currentMessageBatchIndex > 0) { + currentMessageBatchIndex -= messageBatchSize; + } const { proof, circuitInputs, publicInputs } = data.processProofs[i]; // validation - if (circuitInputs.pollEndTimestamp !== pollEndTimestampOnChain.toString()) logError("pollEndTimestamp mismatch."); - if (BigInt(circuitInputs.msgRoot).toString() !== messageRootOnChain.toString()) logError("message root mismatch."); + if (circuitInputs.pollEndTimestamp !== pollEndTimestampOnChain.toString()) { + logError("pollEndTimestamp mismatch."); + } + if (BigInt(circuitInputs.msgRoot as BigNumberish).toString() !== messageRootOnChain.toString()) { + logError("message root mismatch."); + } let currentSbCommitmentOnChain: bigint; - if (numberBatchesProcessed === 0) currentSbCommitmentOnChain = BigInt(await pollContract.currentSbCommitment()); - else currentSbCommitmentOnChain = BigInt(await mpContract.sbCommitment()); + if (numberBatchesProcessed === 0) { + currentSbCommitmentOnChain = BigInt(await pollContract.currentSbCommitment()); + } else { + currentSbCommitmentOnChain = BigInt(await mpContract.sbCommitment()); + } - if (currentSbCommitmentOnChain.toString() !== circuitInputs.currentSbCommitment) + if (currentSbCommitmentOnChain.toString() !== circuitInputs.currentSbCommitment) { logError("currentSbCommitment mismatch."); + } const coordPubKeyHashOnChain = BigInt(await pollContract.coordinatorPubKeyHash()); if ( - hashLeftRight(BigInt(circuitInputs.coordPubKey[0]), BigInt(circuitInputs.coordPubKey[1])).toString() !== - coordPubKeyHashOnChain.toString() - ) + hashLeftRight( + BigInt((circuitInputs.coordPubKey as BigNumberish[])[0]), + BigInt((circuitInputs.coordPubKey as BigNumberish[])[1]), + ).toString() !== coordPubKeyHashOnChain.toString() + ) { logError("coordPubKey mismatch."); + } const packedValsOnChain = BigInt( await mpContract.genProcessMessagesPackedVals(pollContractAddress, currentMessageBatchIndex, numSignUps), ).toString(); - if (circuitInputs.packedVals !== packedValsOnChain) logError("packedVals mismatch."); + if (circuitInputs.packedVals !== packedValsOnChain) { + logError("packedVals mismatch."); + } const formattedProof = formatProofForVerifierContract(proof); @@ -252,12 +302,14 @@ export const proveOnChain = async ( currentMessageBatchIndex, messageRootOnChain.toString(), numSignUps, - circuitInputs.currentSbCommitment, - circuitInputs.newSbCommitment, + circuitInputs.currentSbCommitment as BigNumberish, + circuitInputs.newSbCommitment as BigNumberish, ), ); - if (publicInputHashOnChain.toString() !== publicInputs[0].toString()) logError("Public input mismatch."); + if (publicInputHashOnChain.toString() !== publicInputs[0].toString()) { + logError("Public input mismatch."); + } const vk = new VerifyingKey( new G1Point(onChainProcessVk.alpha1[0], onChainProcessVk.alpha1[1]), @@ -268,30 +320,40 @@ export const proveOnChain = async ( ); // verify the proof onchain using the verifier contract + const isValidOnChain = await verifierContract.verify( formattedProof, vk.asContractParam() as IVerifyingKeyStruct, publicInputHashOnChain.toString(), ); - if (!isValidOnChain) logError("The verifier contract found the proof invalid."); + + if (!isValidOnChain) { + logError("The verifier contract found the proof invalid."); + } try { // validate process messaging proof and store the new state and ballot root commitment + const tx = await mpContract.processMessages( pollContractAddress, - asHex(circuitInputs.newSbCommitment), + asHex(circuitInputs.newSbCommitment as BigNumberish), formattedProof, ); const receipt = await tx.wait(); - if (receipt.status !== 1) logError("processMessages() failed."); - logYellow(quiet, info(`Transaction hash: ${tx.hash}`)); + + if (receipt?.status !== 1) { + logError("processMessages() failed."); + } + + logYellow(quiet, info(`Transaction hash: ${receipt!.hash}`)); // Wait for the node to catch up + numberBatchesProcessed = Number(await mpContract.numBatchesProcessed()); logYellow(quiet, info(`Progress: ${numberBatchesProcessed} / ${totalMessageBatches}`)); - } catch (error: any) { - logError(`processMessages() failed: ${error}`); + } catch (err) { + logError(`processMessages() failed: ${(err as Error).message}`); } } @@ -310,27 +372,37 @@ export const proveOnChain = async ( logYellow(quiet, info(`number of subsidy batch processed: ${subsidyBatchNum}, numleaf=${numSignUps}`)); // process all batches - for (let i = subsidyBatchNum; i < totalBatchNum; i++) { - if (i == 0) await subsidyContract.updateSbCommitment(mpContractAddress); + for (let i = subsidyBatchNum; i < totalBatchNum; i += 1) { + if (i === 0) { + await subsidyContract.updateSbCommitment(mpContractAddress); + } + const { proof, circuitInputs, publicInputs } = data.subsidyProofs[i]; // ensure the commitment matches + const subsidyCommitmentOnChain = await subsidyContract.subsidyCommitment(); + if (subsidyCommitmentOnChain.toString() !== circuitInputs.currentSubsidyCommitment) { logError(`subsidycommitment mismatch`); } + const packedValsOnChain = BigInt(await subsidyContract.genSubsidyPackedVals(numSignUps)); + if (circuitInputs.packedVals !== packedValsOnChain.toString()) { logError("subsidy packedVals mismatch."); } // ensure the state and ballot root commitment matches + const currentSbCommitmentOnChain = await subsidyContract.sbCommitment(); + if (currentSbCommitmentOnChain.toString() !== circuitInputs.sbCommitment) { logError("currentSbCommitment mismatch."); } + const publicInputHashOnChain = await subsidyContract.genSubsidyPublicInputHash( numSignUps, - circuitInputs.newSubsidyCommitment, + circuitInputs.newSubsidyCommitment as BigNumberish, ); if (publicInputHashOnChain.toString() !== publicInputs[0]) { @@ -342,27 +414,32 @@ export const proveOnChain = async ( try { // verify the proof on chain and set the new subsidy commitment + const tx = await subsidyContract.updateSubsidy( pollContractAddress, mpContractAddress, - circuitInputs.newSubsidyCommitment, + circuitInputs.newSubsidyCommitment as BigNumberish, formattedProof, ); const receipt = await tx.wait(); - if (receipt.status !== 1) logError("updateSubsidy() failed."); + if (receipt?.status !== 1) { + logError("updateSubsidy() failed."); + } - logYellow(quiet, info(`Transaction hash: ${tx.hash}`)); + logYellow(quiet, info(`Transaction hash: ${receipt!.hash}`)); logYellow(quiet, info(`Progress: ${subsidyBatchNum + 1} / ${totalBatchNum}`)); - const nrbi = Number(await subsidyContract.rbi()); - const ncbi = Number(await subsidyContract.cbi()); + const [nrbi, ncbi] = await Promise.all([ + subsidyContract.rbi().then(Number), + subsidyContract.cbi().then(Number), + ]); rbi = nrbi; cbi = ncbi; subsidyBatchNum = rbi * num1DBatches + cbi; - } catch (error: any) { - logError(error.message); + } catch (err) { + logError((err as Error).message); } } @@ -379,60 +456,78 @@ export const proveOnChain = async ( let tallyBatchNum = Number(await tallyContract.tallyBatchNum()); - if (tallyBatchNum < totalTallyBatches) logYellow(quiet, info("Submitting proofs of vote tallying...")); + if (tallyBatchNum < totalTallyBatches) { + logYellow(quiet, info("Submitting proofs of vote tallying...")); + } + + for (let i = tallyBatchNum; i < totalTallyBatches; i += 1) { + if (i === 0) { + await tallyContract.updateSbCommitment(mpContractAddress); + } - for (let i = tallyBatchNum; i < totalTallyBatches; i++) { - if (i === 0) await tallyContract.updateSbCommitment(mpContractAddress); const batchStartIndex = i * tallyBatchSize; const { proof, circuitInputs, publicInputs } = data.tallyProofs[i]; const currentTallyCommitmentOnChain = await tallyContract.tallyCommitment(); - if (currentTallyCommitmentOnChain.toString() !== circuitInputs.currentTallyCommitment) + + if (currentTallyCommitmentOnChain.toString() !== circuitInputs.currentTallyCommitment) { logError("currentTallyCommitment mismatch."); + } const packedValsOnChain = BigInt( await tallyContract.genTallyVotesPackedVals(numSignUps, batchStartIndex, tallyBatchSize), ); - if (circuitInputs.packedVals !== packedValsOnChain.toString()) logError("packedVals mismatch."); + + if (circuitInputs.packedVals !== packedValsOnChain.toString()) { + logError("packedVals mismatch."); + } const currentSbCommitmentOnChain = await mpContract.sbCommitment(); - if (currentSbCommitmentOnChain.toString() !== circuitInputs.sbCommitment) logError("currentSbCommitment mismatch."); + + if (currentSbCommitmentOnChain.toString() !== circuitInputs.sbCommitment) { + logError("currentSbCommitment mismatch."); + } const publicInputHashOnChain = await tallyContract.genTallyVotesPublicInputHash( numSignUps, batchStartIndex, tallyBatchSize, - circuitInputs.newTallyCommitment, + circuitInputs.newTallyCommitment as BigNumberish, ); - if (publicInputHashOnChain.toString() !== publicInputs[0]) + + if (publicInputHashOnChain.toString() !== publicInputs[0]) { logError( - `public input mismatch. tallyBatchNum=${i}, onchain=${publicInputHashOnChain.toString()}, offchain=${ - publicInputs[0] - }`, + `public input mismatch. tallyBatchNum=${i}, onchain=${publicInputHashOnChain.toString()}, offchain=${publicInputs[0].toString()}`, ); + } // format the tally proof so it can be verified on chain const formattedProof = formatProofForVerifierContract(proof); try { // verify the proof on chain + const tx = await tallyContract.tallyVotes( pollContractAddress, mpContractAddress, - asHex(circuitInputs.newTallyCommitment), + asHex(circuitInputs.newTallyCommitment as BigNumberish), formattedProof, ); const receipt = await tx.wait(); - if (receipt.status !== 1) logError("tallyVotes() failed"); + if (receipt?.status !== 1) { + logError("tallyVotes() failed"); + } logYellow(quiet, info(`Progress: ${tallyBatchNum + 1} / ${totalTallyBatches}`)); - logYellow(quiet, info(`Transaction hash: ${tx.hash}`)); + logYellow(quiet, info(`Transaction hash: ${receipt!.hash}`)); tallyBatchNum = Number(await tallyContract.tallyBatchNum()); - } catch (error: any) { - logError(error.message); + } catch (err) { + logError((err as Error).message); } } - if (tallyBatchNum === totalTallyBatches) logGreen(quiet, success("All vote tallying proofs have been submitted.")); + if (tallyBatchNum === totalTallyBatches) { + logGreen(quiet, success("All vote tallying proofs have been submitted.")); + } }; diff --git a/cli/ts/commands/publish.ts b/cli/ts/commands/publish.ts index e6cc70780d..bff188215a 100644 --- a/cli/ts/commands/publish.ts +++ b/cli/ts/commands/publish.ts @@ -1,13 +1,14 @@ +import { BaseContract } from "ethers"; +import { MACI, Poll, getDefaultSigner, parseArtifact } from "maci-contracts"; +import { genRandomSalt } from "maci-crypto"; import { Keypair, PCommand, PrivKey, PubKey } from "maci-domainobjs"; -import { info, logError, logGreen, logYellow } from "../utils/theme"; -import { readContractAddress } from "../utils/storage"; + +import { banner } from "../utils/banner"; import { contractExists } from "../utils/contracts"; -import { getDefaultSigner, parseArtifact } from "maci-contracts"; import { promptSensitiveValue } from "../utils/prompts"; import { validateSalt } from "../utils/salt"; -import { genRandomSalt } from "maci-crypto"; -import { Contract } from "ethers"; -import { banner } from "../utils/banner"; +import { readContractAddress } from "../utils/storage"; +import { info, logError, logGreen, logYellow } from "../utils/theme"; /** * Publish a new message to a MACI Poll contract @@ -38,56 +39,86 @@ export const publish = async ( banner(quiet); // validate that the pub key of the user is valid - if (!PubKey.isValidSerializedPubKey(pubkey)) logError("invalid MACI public key"); + if (!PubKey.isValidSerializedPubKey(pubkey)) { + logError("invalid MACI public key"); + } // deserialize const userMaciPubKey = PubKey.deserialize(pubkey); // validation of the maci contract address - if (!readContractAddress("MACI") && !maciContractAddress) logError("MACI contract address is empty"); + if (!readContractAddress("MACI") && !maciContractAddress) { + logError("MACI contract address is empty"); + } - const maciAddress = maciContractAddress ? maciContractAddress : readContractAddress("MACI"); + const maciAddress = maciContractAddress || readContractAddress("MACI"); const signer = await getDefaultSigner(); - if (!(await contractExists(signer.provider, maciAddress))) logError("MACI contract does not exist"); + + if (!(await contractExists(signer.provider!, maciAddress))) { + logError("MACI contract does not exist"); + } // if no private key is passed we ask it securely - const userPrivKey = privateKey ? privateKey : await promptSensitiveValue("Insert your MACI private key"); - if (!PrivKey.isValidSerializedPrivKey(userPrivKey)) logError("Invalid MACI private key"); + const userPrivKey = privateKey || (await promptSensitiveValue("Insert your MACI private key")); + + if (!PrivKey.isValidSerializedPrivKey(userPrivKey)) { + logError("Invalid MACI private key"); + } const userMaciPrivKey = PrivKey.deserialize(userPrivKey); // validate args - if (voteOptionIndex < 0) logError("invalid vote option index"); + if (voteOptionIndex < 0) { + logError("invalid vote option index"); + } + // check < 1 cause index zero is a blank state leaf - if (stateIndex < 1) logError("invalid state index"); - if (nonce < 0) logError("invalid nonce"); - if (salt) if (!validateSalt(salt)) logError("Invalid salt"); + if (stateIndex < 1) { + logError("invalid state index"); + } + + if (nonce < 0) { + logError("invalid nonce"); + } + + if (salt && !validateSalt(salt)) { + logError("Invalid salt"); + } + const userSalt = salt ? BigInt(salt) : genRandomSalt(); - if (pollId < 0) logError("Invalid poll id"); + + if (pollId < 0) { + logError("Invalid poll id"); + } const maciContractAbi = parseArtifact("MACI")[0]; const pollContractAbi = parseArtifact("Poll")[0]; - const maciContract = new Contract(maciAddress, maciContractAbi, signer); + const maciContract = new BaseContract(maciAddress, maciContractAbi, signer) as MACI; const pollAddress = await maciContract.getPoll(pollId); - if (!(await contractExists(signer.provider, pollAddress))) logError("Poll contract does not exist"); - const pollContract = new Contract(pollAddress, pollContractAbi, signer); + if (!(await contractExists(signer.provider!, pollAddress))) { + logError("Poll contract does not exist"); + } + + const pollContract = new BaseContract(pollAddress, pollContractAbi, signer) as Poll; const maxValues = await pollContract.maxValues(); const coordinatorPubKeyResult = await pollContract.coordinatorPubKey(); const maxVoteOptions = Number(maxValues.maxVoteOptions); // validate the vote options index against the max leaf index on-chain - if (maxVoteOptions < voteOptionIndex) logError("Invalid vote option index"); + if (maxVoteOptions < voteOptionIndex) { + logError("Invalid vote option index"); + } const coordinatorPubKey = new PubKey([ BigInt(coordinatorPubKeyResult.x.toString()), BigInt(coordinatorPubKeyResult.y.toString()), ]); - const _newVoteWeight = BigInt(newVoteWeight); + const weight = BigInt(newVoteWeight); const encKeypair = new Keypair(); @@ -96,7 +127,7 @@ export const publish = async ( BigInt(stateIndex), userMaciPubKey, BigInt(voteOptionIndex), - _newVoteWeight, + weight, BigInt(nonce), BigInt(pollId), userSalt, @@ -112,14 +143,16 @@ export const publish = async ( const tx = await pollContract.publishMessage(message.asContractParam(), encKeypair.pubKey.asContractParam(), { gasLimit: 10000000, }); - const receipt = await tx.wait(); - if (receipt.status !== 1) logError("Transaction failed"); - logYellow(quiet, info(`Transaction hash: ${tx.hash}`)); + if (receipt?.status !== 1) { + logError("Transaction failed"); + } + + logYellow(quiet, info(`Transaction hash: ${receipt!.hash}`)); logGreen(quiet, info(`Ephemeral private key: ${encKeypair.privKey.serialize()}`)); - } catch (error: any) { - logError(error.message); + } catch (error) { + logError((error as Error).message); } // we want the user to have the ephemeral private key diff --git a/cli/ts/commands/setVerifyingKeys.ts b/cli/ts/commands/setVerifyingKeys.ts index da1314669d..9ab0849464 100644 --- a/cli/ts/commands/setVerifyingKeys.ts +++ b/cli/ts/commands/setVerifyingKeys.ts @@ -1,14 +1,16 @@ -import { VerifyingKey } from "maci-domainobjs"; -import { readContractAddress } from "../utils/storage"; -import { info, logError, logGreen, logYellow, success } from "../utils/theme"; -import { existsSync } from "fs"; +import { BaseContract } from "ethers"; import { extractVk } from "maci-circuits"; -import { getDefaultSigner, parseArtifact } from "maci-contracts"; -import { contractExists } from "../utils/contracts"; -import { Contract } from "ethers"; +import { IVerifyingKeyStruct, VkRegistry, getDefaultSigner, parseArtifact } from "maci-contracts"; import { genProcessVkSig, genSubsidyVkSig, genTallyVkSig } from "maci-core"; -import { compareVks } from "../utils/"; +import { VerifyingKey } from "maci-domainobjs"; + +import fs from "fs"; + +import { compareVks } from "../utils"; import { banner } from "../utils/banner"; +import { contractExists } from "../utils/contracts"; +import { readContractAddress } from "../utils/storage"; +import { info, logError, logGreen, logYellow, success } from "../utils/theme"; /** * Function that sets the verifying keys in the VkRegistry contract @@ -34,19 +36,27 @@ export const setVerifyingKeys = async ( vkRegistry?: string, subsidyZkeyPath?: string, quiet = true, -) => { +): Promise => { banner(quiet); // we must either have the contract as param or stored to file if (!readContractAddress("VkRegistry") && !vkRegistry) { logError("vkRegistry contract address is empty"); } - const vkRegistryAddress = vkRegistry ? vkRegistry : readContractAddress("VkRegistry"); + const vkRegistryAddress = vkRegistry || readContractAddress("VkRegistry"); // check if zKey files exist - if (!existsSync(processMessagesZkeyPath)) logError(`1 ${processMessagesZkeyPath} does not exist.`); - if (!existsSync(tallyVotesZkeyPath)) logError(`2 ${tallyVotesZkeyPath} does not exist.`); - if (subsidyZkeyPath && !existsSync(subsidyZkeyPath)) logError(`3 ${subsidyZkeyPath} does not exist.`); + if (!fs.existsSync(processMessagesZkeyPath)) { + logError(`${processMessagesZkeyPath} does not exist.`); + } + + if (!fs.existsSync(tallyVotesZkeyPath)) { + logError(`${tallyVotesZkeyPath} does not exist.`); + } + + if (subsidyZkeyPath && !fs.existsSync(subsidyZkeyPath)) { + logError(`${subsidyZkeyPath} does not exist.`); + } // extract the vks const processVk = VerifyingKey.fromObj(await extractVk(processMessagesZkeyPath)); @@ -59,14 +69,21 @@ export const setVerifyingKeys = async ( messageTreeDepth < 1 || voteOptionTreeDepth < 1 || messageBatchDepth < 1 - ) + ) { logError("Invalid depth or batch size parameters"); + } - if (stateTreeDepth < intStateTreeDepth) logError("Invalid state tree depth or intermediate state tree depth"); + if (stateTreeDepth < intStateTreeDepth) { + logError("Invalid state tree depth or intermediate state tree depth"); + } // Check the pm zkey filename against specified params const pmMatch = processMessagesZkeyPath.match(/.+_(\d+)-(\d+)-(\d+)-(\d+)/); - if (!pmMatch) logError(`${processMessagesZkeyPath} has an invalid filename`); + + if (!pmMatch) { + logError(`${processMessagesZkeyPath} has an invalid filename`); + return; + } const pmStateTreeDepth = Number(pmMatch[1]); const pmMsgTreeDepth = Number(pmMatch[2]); @@ -74,7 +91,11 @@ export const setVerifyingKeys = async ( const pmVoteOptionTreeDepth = Number(pmMatch[4]); const tvMatch = tallyVotesZkeyPath.match(/.+_(\d+)-(\d+)-(\d+)/); - if (!tvMatch) logError(`${tallyVotesZkeyPath} has an invalid filename`); + + if (!tvMatch) { + logError(`${tallyVotesZkeyPath} has an invalid filename`); + return; + } const tvStateTreeDepth = Number(tvMatch[1]); const tvIntStateTreeDepth = Number(tvMatch[2]); @@ -88,34 +109,45 @@ export const setVerifyingKeys = async ( stateTreeDepth !== tvStateTreeDepth || intStateTreeDepth !== tvIntStateTreeDepth || voteOptionTreeDepth !== tvVoteOptionTreeDepth - ) + ) { logError("Incorrect .zkey file; please check the circuit params"); + } // ensure we have a contract deployed at the provided address const signer = await getDefaultSigner(); - if (!(await contractExists(signer.provider, vkRegistryAddress))) + + if (!(await contractExists(signer.provider!, vkRegistryAddress))) { logError(`A VkRegistry contract is not deployed at ${vkRegistryAddress}`); + } // connect to VkRegistry contract const vkRegistryAbi = parseArtifact("VkRegistry")[0]; - const vkRegistryContract = new Contract(vkRegistryAddress, vkRegistryAbi, signer); + const vkRegistryContract = new BaseContract(vkRegistryAddress, vkRegistryAbi, signer) as VkRegistry; const messageBatchSize = 5 ** messageBatchDepth; // check if the process messages vk was already set const processVkSig = genProcessVkSig(stateTreeDepth, messageTreeDepth, voteOptionTreeDepth, messageBatchSize); - if (await vkRegistryContract.isProcessVkSet(processVkSig)) + + if (await vkRegistryContract.isProcessVkSet(processVkSig)) { logError("This process verifying key is already set in the contract"); + } // do the same for the tally votes vk const tallyVkSig = genTallyVkSig(stateTreeDepth, intStateTreeDepth, voteOptionTreeDepth); - if (await vkRegistryContract.isTallyVkSet(tallyVkSig)) + + if (await vkRegistryContract.isTallyVkSet(tallyVkSig)) { logError("This tally verifying key is already set in the contract"); + } // do the same for the subsidy vk if any if (subsidyZkeyPath) { const ssMatch = subsidyZkeyPath.match(/.+_(\d+)-(\d+)-(\d+)/); - if (!ssMatch) logError(`${subsidyZkeyPath} has an invalid filename`); + + if (!ssMatch) { + logError(`${subsidyZkeyPath} has an invalid filename`); + return; + } const ssStateTreeDepth = Number(ssMatch[1]); const ssIntStateTreeDepth = Number(ssMatch[2]); @@ -125,12 +157,15 @@ export const setVerifyingKeys = async ( stateTreeDepth !== ssStateTreeDepth || intStateTreeDepth !== ssIntStateTreeDepth || voteOptionTreeDepth !== ssVoteOptionTreeDepth - ) + ) { logError("Incorrect .zkey file; please check the circuit params"); + } const subsidyVkSig = genSubsidyVkSig(stateTreeDepth, intStateTreeDepth, voteOptionTreeDepth); - if (await vkRegistryContract.isSubsidyVkSet(subsidyVkSig)) + + if (await vkRegistryContract.isSubsidyVkSet(subsidyVkSig)) { info("This subsidy verifying key is already set in the contract"); + } } // actually set those values @@ -143,14 +178,17 @@ export const setVerifyingKeys = async ( messageTreeDepth, voteOptionTreeDepth, messageBatchSize, - processVk.asContractParam(), - tallyVk.asContractParam(), + processVk.asContractParam() as IVerifyingKeyStruct, + tallyVk.asContractParam() as IVerifyingKeyStruct, ); const receipt = await tx.wait(); - if (receipt.status !== 1) logError("Set verifying keys transaction failed"); - logYellow(quiet, info(`Transaction hash: ${tx.hash}`)); + if (receipt?.status !== 1) { + logError("Set verifying keys transaction failed"); + } + + logYellow(quiet, info(`Transaction hash: ${receipt!.hash}`)); // confirm that they were actually set correctly const processVkOnChain = await vkRegistryContract.getProcessVk( @@ -162,22 +200,30 @@ export const setVerifyingKeys = async ( const tallyVkOnChain = await vkRegistryContract.getTallyVk(stateTreeDepth, intStateTreeDepth, voteOptionTreeDepth); - if (!compareVks(processVk, processVkOnChain)) logError("processVk mismatch"); - if (!compareVks(tallyVk, tallyVkOnChain)) logError("tallyVk mismatch"); + if (!compareVks(processVk, processVkOnChain)) { + logError("processVk mismatch"); + } + + if (!compareVks(tallyVk, tallyVkOnChain)) { + logError("tallyVk mismatch"); + } // set subsidy keys if any if (subsidyZkeyPath) { const subsidyVk = VerifyingKey.fromObj(await extractVk(subsidyZkeyPath)); - const tx = await vkRegistryContract.setSubsidyKeys( - stateTreeDepth, - intStateTreeDepth, - voteOptionTreeDepth, - subsidyVk.asContractParam(), - ); + const txReceipt = await vkRegistryContract + .setSubsidyKeys( + stateTreeDepth, + intStateTreeDepth, + voteOptionTreeDepth, + subsidyVk.asContractParam() as IVerifyingKeyStruct, + ) + .then((transaction) => transaction.wait(2)); - const receipt = await tx.wait(); - if (receipt.status !== 1) logError("Set subsidy keys transaction failed"); + if (txReceipt?.status !== 1) { + logError("Set subsidy keys transaction failed"); + } logYellow(quiet, info(`Transaction hash: ${tx.hash}`)); @@ -186,10 +232,12 @@ export const setVerifyingKeys = async ( intStateTreeDepth, voteOptionTreeDepth, ); - if (!compareVks(subsidyVk, subsidyVkOnChain)) logError("subsidyVk mismatch"); + if (!compareVks(subsidyVk, subsidyVkOnChain)) { + logError("subsidyVk mismatch"); + } } - } catch (error: any) { - logError(error.message); + } catch (error) { + logError((error as Error).message); } logGreen(quiet, success("Verifying keys set successfully")); diff --git a/cli/ts/commands/showContracts.ts b/cli/ts/commands/showContracts.ts index d5e4ab3f06..78b0f7bafa 100644 --- a/cli/ts/commands/showContracts.ts +++ b/cli/ts/commands/showContracts.ts @@ -1,20 +1,23 @@ -import { existsSync, readFileSync } from "fs"; -import { contractAddressesStore } from "../utils/constants"; +import fs from "fs"; + import { banner } from "../utils/banner"; +import { contractAddressesStore } from "../utils/constants"; import { logGreen, info, logError } from "../utils/theme"; /** * Utility to print all contracts that have been deployed using maci-cli * @param quiet - whether to log the output */ -export const showContracts = (quiet?: boolean) => { +export const showContracts = (quiet = false): void => { banner(quiet); - if (!existsSync(contractAddressesStore)) logError("No contracts have been deployed yet"); + if (!fs.existsSync(contractAddressesStore)) { + logError("No contracts have been deployed yet"); + } - const data = JSON.parse(readFileSync(contractAddressesStore, "utf8").toString()); + const data = JSON.parse(fs.readFileSync(contractAddressesStore, "utf8").toString()) as Record; - for (const entry of Object.entries(data)) { - logGreen(quiet, info(`${entry[0]}: ${entry[1]}`)); - } + Object.entries(data).forEach(([key, value]) => { + logGreen(quiet, info(`${key}: ${value}`)); + }); }; diff --git a/cli/ts/commands/signup.ts b/cli/ts/commands/signup.ts index 226071b33b..b64c2b7e5a 100644 --- a/cli/ts/commands/signup.ts +++ b/cli/ts/commands/signup.ts @@ -1,11 +1,12 @@ +import { BaseContract } from "ethers"; +import { MACI, getDefaultSigner, parseArtifact } from "maci-contracts"; import { PubKey } from "maci-domainobjs"; -import { info, logError, logGreen, logYellow, success } from "../utils/theme"; -import { readContractAddress } from "../utils/storage"; + +import { banner } from "../utils"; import { contractExists } from "../utils/contracts"; -import { getDefaultSigner, parseArtifact } from "maci-contracts"; import { DEFAULT_IVCP_DATA, DEFAULT_SG_DATA } from "../utils/defaults"; -import { Contract } from "ethers"; -import { banner } from "../utils"; +import { readContractAddress } from "../utils/storage"; +import { info, logError, logGreen, logYellow, success } from "../utils/theme"; /** * Signup a user to the MACI contract @@ -27,27 +28,39 @@ export const signup = async ( const signer = await getDefaultSigner(); // validate user key - if (!PubKey.isValidSerializedPubKey(maciPubKey)) logError("Invalid MACI public key"); + if (!PubKey.isValidSerializedPubKey(maciPubKey)) { + logError("Invalid MACI public key"); + } + const userMaciPubKey = PubKey.deserialize(maciPubKey); // ensure we have the contract addresses - if (!readContractAddress("MACI") && !maciAddress) logError("Invalid MACI contract address"); + if (!readContractAddress("MACI") && !maciAddress) { + logError("Invalid MACI contract address"); + } + + const maciContractAddress = maciAddress || readContractAddress("MACI"); - const maciContractAddress = maciAddress ? maciAddress : readContractAddress("MACI"); - if (!(await contractExists(signer.provider, maciContractAddress))) + if (!(await contractExists(signer.provider!, maciContractAddress))) { logError("There is no contract deployed at the specified address"); + } - const sgData = sgDataArg ? sgDataArg : DEFAULT_SG_DATA; - const ivcpData = ivcpDataArg ? ivcpDataArg : DEFAULT_IVCP_DATA; + const sgData = sgDataArg || DEFAULT_SG_DATA; + const ivcpData = ivcpDataArg || DEFAULT_IVCP_DATA; const regex32ByteHex = /^0x[a-fA-F0-9]{64}$/; // we validate that the signup data and voice credit data is valid - if (!sgData.match(regex32ByteHex)) logError("invalid signup gateway data"); - if (!ivcpData.match(regex32ByteHex)) logError("invalid initial voice credit proxy data"); + if (!sgData.match(regex32ByteHex)) { + logError("invalid signup gateway data"); + } + + if (!ivcpData.match(regex32ByteHex)) { + logError("invalid initial voice credit proxy data"); + } const maciContractAbi = parseArtifact("MACI")[0]; - const maciContract = new Contract(maciContractAddress, maciContractAbi, signer); + const maciContract = new BaseContract(maciContractAddress, maciContractAbi, signer) as MACI; let stateIndex = ""; try { @@ -57,19 +70,24 @@ export const signup = async ( logYellow(quiet, info(`Transaction hash: ${tx.hash}`)); - if (receipt.status !== 1) logError("The transaction failed"); + if (receipt?.status !== 1) { + logError("The transaction failed"); + } + const iface = maciContract.interface; // get state index from the event - if (receipt && receipt.logs) { - stateIndex = iface.parseLog(receipt.logs[0]).args[0]; + if (receipt?.logs) { + const [log] = receipt.logs; + const { args } = iface.parseLog(log as unknown as { topics: string[]; data: string }) || { args: [] }; + [stateIndex] = args; logGreen(quiet, success(`State index: ${stateIndex.toString()}`)); } else { logError("Unable to retrieve the transaction receipt"); } - } catch (error: any) { - logError(error.message); + } catch (error) { + logError((error as Error).message); } - return stateIndex.toString(); + return stateIndex ? stateIndex.toString() : ""; }; diff --git a/cli/ts/commands/timeTravel.ts b/cli/ts/commands/timeTravel.ts index 522d3aac82..f000afadea 100644 --- a/cli/ts/commands/timeTravel.ts +++ b/cli/ts/commands/timeTravel.ts @@ -1,6 +1,7 @@ -import type { JsonRpcProvider } from "ethers"; import { getDefaultSigner } from "maci-contracts"; +import type { JsonRpcProvider } from "ethers"; + import { banner } from "../utils/banner"; import { logError, logGreen, success } from "../utils/theme"; @@ -9,7 +10,7 @@ import { logError, logGreen, success } from "../utils/theme"; * @param seconds - the number of seconds to travel in time * @param quiet - whether to log the output */ -export const timeTravel = async (seconds: number, quiet = true) => { +export const timeTravel = async (seconds: number, quiet = true): Promise => { banner(quiet); const signer = await getDefaultSigner(); @@ -19,7 +20,7 @@ export const timeTravel = async (seconds: number, quiet = true) => { await (signer.provider as JsonRpcProvider).send("evm_mine", []); logGreen(quiet, success(`Fast-forwarded ${seconds} seconds`)); - } catch (error: any) { - logError(error.message); + } catch (error) { + logError((error as Error).message); } }; diff --git a/cli/ts/commands/topup.ts b/cli/ts/commands/topup.ts index 23270599c9..1a99c6370f 100644 --- a/cli/ts/commands/topup.ts +++ b/cli/ts/commands/topup.ts @@ -1,9 +1,10 @@ -import { getDefaultSigner, parseArtifact } from "maci-contracts"; -import { readContractAddress } from "../utils/storage"; -import { logError } from "../utils/theme"; +import { BaseContract } from "ethers"; +import { MACI, Poll, getDefaultSigner, parseArtifact } from "maci-contracts"; + import { contractExists } from "../utils/contracts"; -import { Contract } from "ethers"; import { banner } from "../utils/index"; +import { readContractAddress } from "../utils/storage"; +import { logError } from "../utils/theme"; /** * Publish a topup message @@ -13,29 +14,51 @@ import { banner } from "../utils/index"; * @param maciAddress - the address of the MACI contract * @param quiet - whether to log the output */ -export const topup = async (amount: number, stateIndex: number, pollId: number, maciAddress?: string, quiet = true) => { +export const topup = async ( + amount: number, + stateIndex: number, + pollId: number, + maciAddress?: string, + quiet = true, +): Promise => { banner(quiet); const signer = await getDefaultSigner(); // ensure we have a valid MACI contract address - if (!readContractAddress(maciAddress) && !maciAddress) logError("Invalid MACI contract address"); + if (!maciAddress && !readContractAddress(maciAddress!)) { + logError("Invalid MACI contract address"); + return; + } + + const maciContractAddress = maciAddress || readContractAddress(maciAddress!); - const maciContractAddress = maciAddress ? maciAddress : readContractAddress(maciAddress); - if (!(await contractExists(signer.provider, maciContractAddress))) + if (!(await contractExists(signer.provider!, maciContractAddress))) { logError("There is no contract deployed at the specified address"); + } // validate the params - if (amount < 1) logError("Topup amount must be greater than 0"); - if (stateIndex < 1) logError("State index must be greater than 0"); - if (pollId < 0) logError("Poll ID must be a positive integer"); + if (amount < 1) { + logError("Topup amount must be greater than 0"); + } + + if (stateIndex < 1) { + logError("State index must be greater than 0"); + } + + if (pollId < 0) { + logError("Poll ID must be a positive integer"); + } const maciContractAbi = parseArtifact("MACI")[0]; - const maciContract = new Contract(maciContractAddress, maciContractAbi, signer); + const maciContract = new BaseContract(maciContractAddress, maciContractAbi, signer) as MACI; const pollContractAbi = parseArtifact("Poll")[0]; const pollAddr = await maciContract.getPoll(pollId); - if (!(await contractExists(signer.provider, pollAddr))) + + if (!(await contractExists(signer.provider!, pollAddr))) { logError("There is no Poll contract with this poll ID linked to the specified MACI contract."); - const pollContract = new Contract(pollAddr, pollContractAbi, signer); + } + + const pollContract = new BaseContract(pollAddr, pollContractAbi, signer) as Poll; try { // submit the topup message on chain @@ -43,8 +66,11 @@ export const topup = async (amount: number, stateIndex: number, pollId: number, gasLimit: 1000000, }); const receipt = await tx.wait(); - if (receipt.status !== 1) logError("The transaction failed"); - } catch (error: any) { - logError(error.message); + + if (receipt?.status !== 1) { + logError("The transaction failed"); + } + } catch (error) { + logError((error as Error).message); } }; diff --git a/cli/ts/commands/verify.ts b/cli/ts/commands/verify.ts index bbc11251b7..2985b46095 100644 --- a/cli/ts/commands/verify.ts +++ b/cli/ts/commands/verify.ts @@ -1,9 +1,11 @@ -import { getDefaultSigner, parseArtifact } from "maci-contracts"; -import { banner, contractExists, info, logError, logGreen, logYellow, readContractAddress, success } from "../utils/"; -import { Contract } from "ethers"; -import { existsSync, readFileSync } from "fs"; +import { BaseContract } from "ethers"; +import { Tally, MACI, getDefaultSigner, parseArtifact, Subsidy, Poll } from "maci-contracts"; import { hash2, hash3, genTreeCommitment } from "maci-crypto"; -import { TallyData } from "../utils/interfaces"; + +import fs from "fs"; + +import { banner, contractExists, info, logError, logGreen, logYellow, readContractAddress, success } from "../utils"; +import { SubsidyData, TallyData } from "../utils/interfaces"; import { verifyPerVOSpentVoiceCredits, verifyTallyResults } from "../utils/verifiers"; /** @@ -25,37 +27,47 @@ export const verify = async ( subsidyAddress?: string, subsidyFile?: string, quiet = true, -) => { +): Promise => { banner(quiet); const signer = await getDefaultSigner(); // check existence of MACI, Tally and Subsidy contract addresses - if (!readContractAddress("MACI") && !maciAddress) logError("MACI contract address is empty"); - if (!readContractAddress("Tally-" + pollId) && !tallyAddress) logError("Tally contract address is empty"); - if (!readContractAddress("Subsidy-" + pollId) && !subsidyAddress) logError("Subsidy contract address is empty"); + if (!readContractAddress("MACI") && !maciAddress) { + logError("MACI contract address is empty"); + } - const maciContractAddress = maciAddress ? maciAddress : readContractAddress("MACI"); - const tallyContractAddress = tallyAddress ? tallyAddress : readContractAddress("Tally-" + pollId); - const subsidyContractAddress = subsidyAddress ? subsidyAddress : readContractAddress("Subsidy-" + pollId); + if (!readContractAddress(`Tally-${pollId}`) && !tallyAddress) { + logError("Tally contract address is empty"); + } + + if (!readContractAddress(`Subsidy-${pollId}`) && !subsidyAddress) { + logError("Subsidy contract address is empty"); + } - if (!(await contractExists(signer.provider, maciContractAddress))) { + const maciContractAddress = maciAddress || readContractAddress("MACI"); + const tallyContractAddress = tallyAddress || readContractAddress(`Tally-${pollId}`); + const subsidyContractAddress = subsidyAddress || readContractAddress(`Subsidy-${pollId}`); + + if (!(await contractExists(signer.provider!, maciContractAddress))) { logError(`Error: there is no contract deployed at ${maciContractAddress}.`); } - if (!(await contractExists(signer.provider, tallyContractAddress))) { + + if (!(await contractExists(signer.provider!, tallyContractAddress))) { logError(`Error: there is no contract deployed at ${tallyContractAddress}.`); } - if (!(await contractExists(signer.provider, subsidyContractAddress))) { + + if (!(await contractExists(signer.provider!, subsidyContractAddress))) { logError(`Error: there is no contract deployed at ${subsidyContractAddress}.`); } - const maciContract = new Contract(maciContractAddress, parseArtifact("MACI")[0], signer); + const maciContract = new BaseContract(maciContractAddress, parseArtifact("MACI")[0], signer) as MACI; const pollAddr = await maciContract.polls(pollId); - const pollContract = new Contract(pollAddr, parseArtifact("Poll")[0], signer); + const pollContract = new BaseContract(pollAddr, parseArtifact("Poll")[0], signer) as Poll; - const tallyContract = new Contract(tallyContractAddress, parseArtifact("Tally")[0], signer); + const tallyContract = new BaseContract(tallyContractAddress, parseArtifact("Tally")[0], signer) as Tally; - const subsidyContract = new Contract(subsidyContractAddress, parseArtifact("Subsidy")[0], signer); + const subsidyContract = new BaseContract(subsidyContractAddress, parseArtifact("Subsidy")[0], signer) as Subsidy; // verification const onChainTallycomment = BigInt(await tallyContract.tallyCommitment()); @@ -63,34 +75,47 @@ export const verify = async ( logYellow(quiet, info(`on-chain tally commitment: ${onChainTallycomment.toString(16)}`)); // ensure we have either tally data or tally file - if (!(tallyData || tallyFile)) logError("No tally data or tally file provided."); + if (!(tallyData || tallyFile)) { + logError("No tally data or tally file provided."); + } // if we have the data as param, then use that let tallyResults: TallyData; if (tallyData) { tallyResults = tallyData; } else { // read the tally file - if (!existsSync(tallyFile)) logError(`Unable to open ${tallyFile}`); - tallyResults = JSON.parse(readFileSync(tallyFile, { encoding: "utf8" })); + if (!tallyFile || !fs.existsSync(tallyFile)) { + logError(`Unable to open ${tallyFile}`); + } + + tallyResults = JSON.parse(fs.readFileSync(tallyFile!, { encoding: "utf8" })) as TallyData; } // check the results commitment - const validResultsCommitment = - tallyResults.newTallyCommitment && tallyResults.newTallyCommitment.match(/0x[a-fA-F0-9]+/); - if (!validResultsCommitment) logError("Invalid results commitment format"); + const validResultsCommitment = tallyResults.newTallyCommitment.match(/0x[a-fA-F0-9]+/); + + if (!validResultsCommitment) { + logError("Invalid results commitment format"); + } const treeDepths = await pollContract.treeDepths(); const voteOptionTreeDepth = Number(treeDepths.voteOptionTreeDepth); const numVoteOptions = 5 ** voteOptionTreeDepth; - if (tallyResults.results.tally.length != numVoteOptions) logError("Wrong number of vote options."); - if (tallyResults.perVOSpentVoiceCredits.tally.length != numVoteOptions) logError("Wrong number of vote options."); + + if (tallyResults.results.tally.length !== numVoteOptions) { + logError("Wrong number of vote options."); + } + + if (tallyResults.perVOSpentVoiceCredits.tally.length !== numVoteOptions) { + logError("Wrong number of vote options."); + } // verify that the results commitment matches the output of genTreeCommitment() // verify the results // compute newResultsCommitment const newResultsCommitment = genTreeCommitment( - tallyResults.results.tally.map((x: any) => BigInt(x)), + tallyResults.results.tally.map((x) => BigInt(x)), BigInt(tallyResults.results.salt), voteOptionTreeDepth, ); @@ -103,7 +128,7 @@ export const verify = async ( // compute newPerVOSpentVoiceCreditsCommitment const newPerVOSpentVoiceCreditsCommitment = genTreeCommitment( - tallyResults.perVOSpentVoiceCredits.tally.map((x: any) => BigInt(x)), + tallyResults.perVOSpentVoiceCredits.tally.map((x) => BigInt(x)), BigInt(tallyResults.perVOSpentVoiceCredits.salt), voteOptionTreeDepth, ); @@ -115,7 +140,9 @@ export const verify = async ( newPerVOSpentVoiceCreditsCommitment, ]); - if (onChainTallycomment !== newTallyCommitment) logError("The on-chain tally commitment does not match."); + if (onChainTallycomment !== newTallyCommitment) { + logError("The on-chain tally commitment does not match."); + } logGreen(quiet, success("The on-chain tally commitment matches.")); // verify total spent voice credits on-chain @@ -143,7 +170,9 @@ export const verify = async ( logGreen(quiet, success("The on-chain verification of per vote option spent voice credits passed")); } else { logError( - `At least one tally result failed the on-chain verification. Please check your Tally data at these indexes: ${failedSpentCredits}`, + `At least one tally result failed the on-chain verification. Please check your Tally data at these indexes: ${failedSpentCredits.join( + ", ", + )}`, ); } @@ -155,11 +184,14 @@ export const verify = async ( newSpentVoiceCreditsCommitment, newPerVOSpentVoiceCreditsCommitment, ); + if (failedPerVOSpentCredits.length === 0) { logGreen(quiet, success("The on-chain verification of tally results passed")); } else { logError( - `At least one spent voice credits entry in the tally results failed the on-chain verification. Please check your tally results at these indexes: ${failedPerVOSpentCredits}`, + `At least one spent voice credits entry in the tally results failed the on-chain verification. Please check your tally results at these indexes: ${failedPerVOSpentCredits.join( + ", ", + )}`, ); } @@ -170,24 +202,33 @@ export const verify = async ( logYellow(quiet, info(`on-chain subsidy commitment: ${onChainSubsidyCommitment.toString(16)}`)); // read the subsidy file - if (!existsSync(subsidyFile)) logError(`There is no such file: ${subsidyFile}`); - const subsidyData = JSON.parse(readFileSync(subsidyFile, { encoding: "utf8" })); + if (!fs.existsSync(subsidyFile)) { + logError(`There is no such file: ${subsidyFile}`); + } + + const subsidyData = JSON.parse(fs.readFileSync(subsidyFile, { encoding: "utf8" })) as SubsidyData; // check the results commitment - const validResultsCommitment = - subsidyData.newSubsidyCommitment && subsidyData.newSubsidyCommitment.match(/0x[a-fA-F0-9]+/); - if (!validResultsCommitment) logError("Invalid results commitment format"); + const validResultsSubsidyCommitment = subsidyData.newSubsidyCommitment.match(/0x[a-fA-F0-9]+/); + + if (!validResultsSubsidyCommitment) { + logError("Invalid results commitment format"); + } - if (subsidyData.results.subsidy.length !== numVoteOptions) logError("Wrong number of vote options."); + if (subsidyData.results.subsidy.length !== numVoteOptions) { + logError("Wrong number of vote options."); + } // compute the new SubsidyCommitment const newSubsidyCommitment = genTreeCommitment( - subsidyData.results.subsidy.map((x: any) => BigInt(x)), - subsidyData.results.salt, + subsidyData.results.subsidy.map((x) => BigInt(x)), + BigInt(subsidyData.results.salt), voteOptionTreeDepth, ); - if (onChainSubsidyCommitment !== newSubsidyCommitment) logError("The on-chain subsidy commitment does not match."); + if (onChainSubsidyCommitment !== newSubsidyCommitment) { + logError("The on-chain subsidy commitment does not match."); + } logGreen(quiet, success("The on-chain subsidy commitment matches.")); } diff --git a/cli/ts/index.ts b/cli/ts/index.ts index 9dd22c204e..9bc5bbdd86 100644 --- a/cli/ts/index.ts +++ b/cli/ts/index.ts @@ -1,5 +1,9 @@ #!/usr/bin/env node -import { createCommand } from "commander"; +import { Command } from "@commander-js/extra-typings"; + +import fs from "fs"; +import path from "path"; + import { genKeyPair, genMaciPubKey, @@ -22,14 +26,12 @@ import { checkVerifyingKeys, genLocalState, } from "./commands"; -import fs from "fs"; -import path from "path"; // set the description version and name of the cli tool const { description, version, name } = JSON.parse( fs.readFileSync(path.resolve(__dirname, "..", "package.json"), "utf8"), -); -const program = createCommand(); +) as { description: string; version: string; name: string }; +const program = new Command(); program.name(name).description(description).version(version); // add the commands program @@ -40,10 +42,10 @@ program "-p, --initialVoiceCreditsProxyAddress ", "the initial voice credits proxy contract address", ) - .option("-g", "--signupGatekeeperAddress ", "the signup gatekeeper contract address") + .option("-g, --signupGatekeeperAddress ", "the signup gatekeeper contract address") .option("-q, --quiet ", "whether to print values to the console", (value) => value === "true", false) .option("-r, --rpc-provider ", "the rpc provider URL") - .requiredOption("-s, --stateTreeDepth ", "the state tree depth") + .requiredOption("-s, --stateTreeDepth ", "the state tree depth", parseInt) .action(async (cmdOptions) => { try { await deploy( @@ -53,8 +55,8 @@ program cmdOptions.signupGatekeeperAddress, cmdOptions.quiet, ); - } catch (error: any) { - program.error(error.message, { exitCode: 1 }); + } catch (error) { + program.error((error as Error).message, { exitCode: 1 }); } }); program @@ -85,8 +87,8 @@ program cmdOptions.subsidyZkey, cmdOptions.quiet, ); - } catch (error: any) { - program.error(error.message, { exitCode: 1 }); + } catch (error) { + program.error((error as Error).message, { exitCode: 1 }); } }); program @@ -109,7 +111,7 @@ program program .command("airdrop") .description("airdrop topup credits to the coordinator") - .requiredOption("-a, --amount ", "the amount of topup") + .requiredOption("-a, --amount ", "the amount of topup", parseInt) .option("-x, --contract ", "the MACI contract address") .option("-o, --poll-id ", "poll id", parseInt) .option("-t, --token-address ", "the token address") @@ -118,8 +120,8 @@ program .action(async (cmdObj) => { try { await airdrop(cmdObj.amount, cmdObj.contract, cmdObj.pollId, cmdObj.tokenAddress, cmdObj.quiet); - } catch (error: any) { - program.error(error.message, { exitCode: 1 }); + } catch (error) { + program.error((error as Error).message, { exitCode: 1 }); } }); program @@ -130,8 +132,8 @@ program .action(async (cmdObj) => { try { await deployVkRegistryContract(cmdObj.quiet); - } catch (error: any) { - program.error(error.message, { exitCode: 1 }); + } catch (error) { + program.error((error as Error).message, { exitCode: 1 }); } }); program @@ -142,8 +144,8 @@ program .action((cmdObj) => { try { showContracts(cmdObj.quiet); - } catch (error: any) { - program.error(error.message, { exitCode: 1 }); + } catch (error) { + program.error((error as Error).message, { exitCode: 1 }); } }); program @@ -176,8 +178,8 @@ program cmdObj.vkRegistryAddress, cmdObj.quiet, ); - } catch (error: any) { - program.error(error.message, { exitCode: 1 }); + } catch (error) { + program.error((error as Error).message, { exitCode: 1 }); } }); program @@ -208,8 +210,8 @@ program cmdObj.subsidyZkey, cmdObj.quiet, ); - } catch (error: any) { - program.error(error.message, { exitCode: 1 }); + } catch (error) { + program.error((error as Error).message, { exitCode: 1 }); } }); program @@ -243,8 +245,8 @@ program cmdObj.privkey, cmdObj.quiet, ); - } catch (error: any) { - program.error(error.message, { exitCode: 1 }); + } catch (error) { + program.error((error as Error).message, { exitCode: 1 }); } }); program @@ -257,9 +259,9 @@ program .option("-n, --num-queue-ops ", "the number of queue operations", parseInt) .action(async (cmdObj) => { try { - await mergeMessages(cmdObj.pollId, cmdObj.maciContractAddress, cmdObj.numQueueOps, cmdObj.quiet); - } catch (error: any) { - program.error(error.message, { exitCode: 1 }); + await mergeMessages(cmdObj.pollId, cmdObj.maciContractAddress, cmdObj.numQueueOps?.toString(), cmdObj.quiet); + } catch (error) { + program.error((error as Error).message, { exitCode: 1 }); } }); program @@ -268,13 +270,13 @@ program .option("-q, --quiet ", "whether to print values to the console", (value) => value === "true", false) .option("-r, --rpc-provider ", "the rpc provider URL") .option("-x, --maci-contract-address ", "the MACI contract address") - .requiredOption("-o, --poll-id ", "the poll id") + .requiredOption("-o, --poll-id ", "the poll id", parseInt) .option("-n, --num-queue-ops ", "the number of queue operations", parseInt) .action(async (cmdObj) => { try { - await mergeSignups(cmdObj.pollId, cmdObj.maciContractAddress, cmdObj.numQueueOps, cmdObj.quiet); - } catch (error: any) { - program.error(error.message, { exitCode: 1 }); + await mergeSignups(cmdObj.pollId, cmdObj.maciContractAddress, cmdObj.numQueueOps?.toString(), cmdObj.quiet); + } catch (error) { + program.error((error as Error).message, { exitCode: 1 }); } }); program @@ -286,8 +288,8 @@ program .action(async (cmdObj) => { try { await timeTravel(cmdObj.seconds, cmdObj.quiet); - } catch (error: any) { - program.error(error.message, { exitCode: 1 }); + } catch (error) { + program.error((error as Error).message, { exitCode: 1 }); } }); program @@ -302,8 +304,8 @@ program .action(async (cmdObj) => { try { await signup(cmdObj.pubkey, cmdObj.maciAddress, cmdObj.sgData, cmdObj.ivcpData, cmdObj.quiet); - } catch (error: any) { - program.error(error.message, { exitCode: 1 }); + } catch (error) { + program.error((error as Error).message, { exitCode: 1 }); } }); program @@ -318,8 +320,8 @@ program .action(async (cmdObj) => { try { await topup(cmdObj.amount, cmdObj.stateIndex, cmdObj.pollId, cmdObj.maciAddress, cmdObj.quiet); - } catch (error: any) { - program.error(error.message, { exitCode: 1 }); + } catch (error) { + program.error((error as Error).message, { exitCode: 1 }); } }); program @@ -332,8 +334,8 @@ program .action(async (cmdObj) => { try { await fundWallet(cmdObj.amount, cmdObj.address, cmdObj.quiet); - } catch (error: any) { - program.error(error.message, { exitCode: 1 }); + } catch (error) { + program.error((error as Error).message, { exitCode: 1 }); } }); program @@ -350,7 +352,7 @@ program .action(async (cmdObj) => { try { await verify( - cmdObj.pollId, + cmdObj.pollId.toString(), cmdObj.tallyFile, undefined, cmdObj.contract, @@ -359,8 +361,8 @@ program cmdObj.subsidyFile, cmdObj.quiet, ); - } catch (error: any) { - program.error(error.message, { exitCode: 1 }); + } catch (error) { + program.error((error as Error).message, { exitCode: 1 }); } }); program @@ -369,7 +371,7 @@ program .option("-sk, --privkey ", "your serialized MACI private key") .option("-x, --contract ", "the MACI contract address") .requiredOption("-o, --poll-id ", "the poll id", parseInt) - .option("-t, --tally-file ", "the tally file") + .requiredOption("-t, --tally-file ", "the tally file") .option("-s, --subsidy-file ", "the subsidy file") .option("-r, --rapidsnark ", "the path to the rapidsnark binary") .option("-wp, --process-witnessgen ", "the path to the process witness generation binary") @@ -389,7 +391,7 @@ program .option("-st, --state-file ", "the path to the state file containing the serialized maci state") .option("-sb, --start-block ", "the block number to start looking for events from", parseInt) .option("-eb, --end-block ", "the block number to end looking for events from", parseInt) - .option("-bb, --blocks-per-batch ", "the number of blocks to process per batch") + .option("-bb, --blocks-per-batch ", "the number of blocks to process per batch", parseInt) .action(async (cmdObj) => { try { await genProofs( @@ -417,15 +419,15 @@ program cmdObj.blocksPerBatch, cmdObj.quiet, ); - } catch (error: any) { - program.error(error.message, { exitCode: 1 }); + } catch (error) { + program.error((error as Error).message, { exitCode: 1 }); } }); program .command("genLocalState") .description("generate a local MACI state from the smart contracts events") .requiredOption("-o, --output ", "the path where to write the state", parseInt) - .option("-p, --poll-id ", "the id of the poll", parseInt) + .requiredOption("-p, --poll-id ", "the id of the poll", parseInt) .option("-x, --contract ", "the MACI contract address") .option("-sk, --privkey ", "your serialized MACI private key") .option("-eb, --end-block ", "the end block number", parseInt) @@ -438,20 +440,20 @@ program .action(async (cmdObj) => { try { await genLocalState( - cmdObj.output, + cmdObj.output.toString(), cmdObj.pollId, cmdObj.contract, cmdObj.privkey, - cmdObj.provider, + cmdObj.rpcProvider, cmdObj.endBlock, cmdObj.startBlock, - cmdObj.blockPerBatch, + cmdObj.blocksPerBatch, cmdObj.transactionHash, cmdObj.sleep, cmdObj.quiet, ); - } catch (error: any) { - program.error(error.message, { exitCode: 1 }); + } catch (error) { + program.error((error as Error).message, { exitCode: 1 }); } }); program @@ -468,7 +470,7 @@ program .action(async (cmdObj) => { try { await proveOnChain( - cmdObj.pollId, + cmdObj.pollId.toString(), cmdObj.proofDir, cmdObj.contract, cmdObj.messageProcessorAddress, @@ -476,8 +478,8 @@ program cmdObj.subsidyContract, cmdObj.quiet, ); - } catch (error: any) { - program.error(error.message, { exitCode: 1 }); + } catch (error) { + program.error((error as Error).message, { exitCode: 1 }); } }); @@ -507,4 +509,4 @@ export { verify, } from "./commands"; -export { DeployedContracts, PollContracts, TallyData } from "./utils"; +export type { DeployedContracts, PollContracts, TallyData } from "./utils"; diff --git a/cli/ts/utils/banner.ts b/cli/ts/utils/banner.ts index ef2a102aae..840a406a89 100644 --- a/cli/ts/utils/banner.ts +++ b/cli/ts/utils/banner.ts @@ -4,7 +4,7 @@ import { logRed, logYellow } from "./theme"; * Print a nice MACI banner * @param quiet - whether to print the text or not */ -export const banner = (quiet: boolean) => { +export const banner = (quiet: boolean): void => { logRed( quiet, ` diff --git a/cli/ts/utils/constants.ts b/cli/ts/utils/constants.ts index 50aa4b0f3e..07522cc7a0 100644 --- a/cli/ts/utils/constants.ts +++ b/cli/ts/utils/constants.ts @@ -1,10 +1,10 @@ -import { join } from "path"; +import path from "path"; // local file name where we are storing the contract addresses export const contractAddressStoreName = "contractAddresses.json"; // local file name where we are storing a previous deployment's contract addresses export const oldContractAddressStoreName = "contractAddresses.old.json"; // local file path where we are storing the contract addresses -export const contractAddressesStore = join(__dirname, "..", "..", contractAddressStoreName); +export const contractAddressesStore = path.resolve(__dirname, "..", "..", contractAddressStoreName); // local file path where we are storing a previous deployment's contract addresses -export const oldContractAddressesStore = join(__dirname, "..", "..", oldContractAddressStoreName); +export const oldContractAddressesStore = path.resolve(__dirname, "..", "..", oldContractAddressStoreName); diff --git a/cli/ts/utils/contracts.ts b/cli/ts/utils/contracts.ts index 9a337c13b0..72ea0d6f6a 100644 --- a/cli/ts/utils/contracts.ts +++ b/cli/ts/utils/contracts.ts @@ -1,10 +1,12 @@ +import type { Provider } from "ethers"; + /** * Small utility function to check whether a contract exists at a given address * @param provider - the provider to use to interact with the chain * @param address - the address of the contract to check * @returns a boolean indicating whether the contract exists */ -export const contractExists = async (provider: any, address: string): Promise => { +export const contractExists = async (provider: Provider, address: string): Promise => { const code = await provider.getCode(address); return code.length > 2; }; @@ -14,8 +16,9 @@ export const contractExists = async (provider: any, address: string): Promise => { +export const currentBlockTimestamp = async (provider: Provider): Promise => { const blockNum = await provider.getBlockNumber(); const block = await provider.getBlock(blockNum); - return Number(block.timestamp); + + return Number(block?.timestamp); }; diff --git a/cli/ts/utils/formatting.ts b/cli/ts/utils/formatting.ts index 3bf61180b8..ca401c180e 100644 --- a/cli/ts/utils/formatting.ts +++ b/cli/ts/utils/formatting.ts @@ -1,6 +1,8 @@ +import type { BigNumberish } from "ethers"; + /** * Convert a value to its hex representation * @param val - the value to convert * @returns the value converted as a hex string */ -export const asHex = (val: any): string => `0x${BigInt(val).toString(16)}`; +export const asHex = (val: BigNumberish): string => `0x${BigInt(val).toString(16)}`; diff --git a/cli/ts/utils/index.ts b/cli/ts/utils/index.ts index 8d94fc10c1..e6515478ef 100644 --- a/cli/ts/utils/index.ts +++ b/cli/ts/utils/index.ts @@ -14,7 +14,7 @@ export { DEFAULT_IVCP_DATA, DEFAULT_SR_QUEUE_OPS, } from "./defaults"; -export { DeployedContracts, PollContracts, TallyData } from "./interfaces"; +export type { DeployedContracts, PollContracts, TallyData } from "./interfaces"; export { compareVks } from "./vks"; export { delay } from "./time"; export { diff --git a/cli/ts/utils/interfaces.ts b/cli/ts/utils/interfaces.ts index 140e272fec..d82d9b984c 100644 --- a/cli/ts/utils/interfaces.ts +++ b/cli/ts/utils/interfaces.ts @@ -1,3 +1,7 @@ +import type { SnarkProof } from "maci-contracts"; +import type { CircuitInputs } from "maci-core"; +import type { Groth16Proof, PublicSignals } from "snarkjs"; + export interface DeployedContracts { maciAddress: string; stateAqAddress: string; @@ -98,3 +102,26 @@ export interface TallyData { commitment: string; }; } + +/** + * A util interface that represents a subsidy file + */ +export interface SubsidyData { + provider: string; + maci: string; + pollId: number; + newSubsidyCommitment: string; + results: { + subsidy: string[]; + salt: string; + }; +} + +/** + * Proof interface for cli commands + */ +export interface Proof { + proof: SnarkProof | Groth16Proof; + circuitInputs: CircuitInputs; + publicInputs: PublicSignals; +} diff --git a/cli/ts/utils/prompts.ts b/cli/ts/utils/prompts.ts index affb827093..248d33f664 100644 --- a/cli/ts/utils/prompts.ts +++ b/cli/ts/utils/prompts.ts @@ -1,4 +1,4 @@ -import { start, get } from "prompt-async"; +import { start, get } from "prompt"; /** * Ask for a sensitive value @@ -7,12 +7,7 @@ import { start, get } from "prompt-async"; */ export const promptSensitiveValue = async (name: string): Promise => { start(); - const input = await get([ - { - name, - hidden: true, - }, - ]); + const input = await get([{ name, hidden: true }]); - return input[name]; + return input[name] as string; }; diff --git a/cli/ts/utils/salt.ts b/cli/ts/utils/salt.ts index bc8c5080e7..b966c7c58b 100644 --- a/cli/ts/utils/salt.ts +++ b/cli/ts/utils/salt.ts @@ -1,19 +1,8 @@ import { SNARK_FIELD_SIZE } from "maci-crypto"; -/** - * Validate a salt's size - * @param salt the salt to validate - * @returns whether it is valid or not - */ -const validateSaltSize = (salt: string): boolean => { - return BigInt(salt) < SNARK_FIELD_SIZE; -}; - /** * Run both format check and size check on a salt value * @param salt the salt to validate * @returns whether it is valid or not */ -export const validateSalt = (salt: string): boolean => { - return validateSaltSize(salt); -}; +export const validateSalt = (salt: string): boolean => BigInt(salt) < SNARK_FIELD_SIZE; diff --git a/cli/ts/utils/storage.ts b/cli/ts/utils/storage.ts index 9fc577571a..0ef7ce72be 100644 --- a/cli/ts/utils/storage.ts +++ b/cli/ts/utils/storage.ts @@ -1,5 +1,6 @@ +import fs from "fs"; + import { contractAddressesStore } from "./constants"; -import { writeFileSync, readFileSync, existsSync } from "fs"; import { logError } from "./theme"; /** @@ -7,9 +8,12 @@ import { logError } from "./theme"; * @param path - the path of the file * @returns the JSON object */ -export const readJSONFile = (path: string): object => { - if (!existsSync(path)) logError(`File ${path} does not exist`); - return JSON.parse(readFileSync(path).toString()); +export const readJSONFile = (path: string): Record => { + if (!fs.existsSync(path)) { + logError(`File ${path} does not exist`); + } + + return JSON.parse(fs.readFileSync(path).toString()) as Record; }; /** @@ -17,12 +21,15 @@ export const readJSONFile = (path: string): object => { * @param contractName - the name of the contract * @param address - the address of the contract */ -export const storeContractAddress = (contractName: string, address: string) => { +export const storeContractAddress = (contractName: string, address: string): void => { // if it does not exist yet, then create it - if (!existsSync(contractAddressesStore)) writeFileSync(contractAddressesStore, "{}"); + if (!fs.existsSync(contractAddressesStore)) { + fs.writeFileSync(contractAddressesStore, "{}"); + } + const contractAddrs = readJSONFile(contractAddressesStore); contractAddrs[contractName] = address; - writeFileSync(contractAddressesStore, JSON.stringify(contractAddrs, null, 4)); + fs.writeFileSync(contractAddressesStore, JSON.stringify(contractAddrs, null, 4)); }; /** @@ -38,8 +45,8 @@ export const readContractAddress = (contractName: string): string => { /** * Delete the content of the contract address file file */ -export const resetContractAddresses = () => { - writeFileSync(contractAddressesStore, JSON.stringify({}, null, 4)); +export const resetContractAddresses = (): void => { + fs.writeFileSync(contractAddressesStore, JSON.stringify({}, null, 4)); }; /** @@ -49,11 +56,8 @@ export const resetContractAddresses = () => { * where the boolean indicates whether all paths exist, and the string * is the path that does not exist */ -export const doesPathExist = (paths: Array): [boolean, string] => { - for (const path of paths) { - if (!existsSync(path)) { - return [false, path]; - } - } - return [true, null]; +export const doesPathExist = (paths: string[]): [boolean, string | null] => { + const notFoundPath = paths.find((path) => !fs.existsSync(path)); + + return notFoundPath ? [false, notFoundPath] : [true, null]; }; diff --git a/cli/ts/utils/theme.ts b/cli/ts/utils/theme.ts index e94112a35d..ed66f952da 100644 --- a/cli/ts/utils/theme.ts +++ b/cli/ts/utils/theme.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ // Description: This file contains the theme for the CLI const RESET = "\x1b[0m"; const RED = "\x1b[31m"; @@ -10,8 +11,10 @@ const MAGENTA = "\x1b[35m"; * @param quiet - whether to print the text or not * @param text - the text to print */ -export function logRed(quiet: boolean, text: string) { - if (!quiet) console.log(RED + text + RESET); +export function logRed(quiet: boolean, text: string): void { + if (!quiet) { + console.log(RED + text + RESET); + } } /** @@ -19,8 +22,10 @@ export function logRed(quiet: boolean, text: string) { * @param quiet - whether to print the text or not * @param text - the text to print */ -export function logGreen(quiet: boolean, text: string) { - if (!quiet) console.log(GREEN + text + RESET); +export function logGreen(quiet: boolean, text: string): void { + if (!quiet) { + console.log(GREEN + text + RESET); + } } /** @@ -28,8 +33,10 @@ export function logGreen(quiet: boolean, text: string) { * @param quiet - whether to print the text or not * @param text - the text to print */ -export function logYellow(quiet: boolean, text: string) { - if (!quiet) console.log(YELLOW + text + RESET); +export function logYellow(quiet: boolean, text: string): void { + if (!quiet) { + console.log(YELLOW + text + RESET); + } } /** @@ -37,16 +44,10 @@ export function logYellow(quiet: boolean, text: string) { * @param quiet - whether to print the text or not * @param text - the text to print */ -export function logMagenta(quiet: boolean, text: string) { - if (!quiet) console.log(MAGENTA + text + RESET); -} - -/** - * Log an error and throw an error - * @param text - */ -export function logError(text: string) { - throw new Error(error(text)); +export function logMagenta(quiet: boolean, text: string): void { + if (!quiet) { + console.log(MAGENTA + text + RESET); + } } /** @@ -54,25 +55,33 @@ export function logError(text: string) { * @param text - the text to print * @returns the text with a prefix */ -export const info = (text: string) => `[i] ${text}`; +export const info = (text: string): string => `[i] ${text}`; /** * create a success message * @param text - the text to print * @returns the text with a prefix */ -export const success = (text: string) => `[✓] ${text}`; +export const success = (text: string): string => `[✓] ${text}`; /** * create a success message * @param text - the text to print * @returns the text with a prefix */ -export const warning = (text: string) => `[!] ${text}`; +export const warning = (text: string): string => `[!] ${text}`; /** * create an error message * @param text - the text to print * @returns the text with a prefix */ -export const error = (text: string) => `[✗] ${text}`; +export const error = (text: string): string => `[✗] ${text}`; + +/** + * Log an error and throw an error + * @param text + */ +export function logError(text: string): void { + throw new Error(error(text)); +} diff --git a/cli/ts/utils/time.ts b/cli/ts/utils/time.ts index de52bc8f33..c3cbc8689f 100644 --- a/cli/ts/utils/time.ts +++ b/cli/ts/utils/time.ts @@ -3,6 +3,7 @@ * @param ms the number of milliseconds to sleep for * @returns a promise that resolves after the specified number of milliseconds */ -export const delay = (ms: number): Promise => { - return new Promise((resolve: any) => setTimeout(resolve, ms)); -}; +export const delay = (ms: number): Promise => + new Promise((resolve) => { + setTimeout(resolve, ms); + }); diff --git a/cli/ts/utils/trees.ts b/cli/ts/utils/trees.ts index b85e6c7428..87dd7186fd 100644 --- a/cli/ts/utils/trees.ts +++ b/cli/ts/utils/trees.ts @@ -3,11 +3,13 @@ * @param maxLeaves - the number of leaves in the tree * @returns the depth of the tree */ -export const calcBinaryTreeDepthFromMaxLeaves = (maxLeaves: number) => { +export const calcBinaryTreeDepthFromMaxLeaves = (maxLeaves: number): number => { let result = 0; + while (2 ** result < maxLeaves) { - result++; + result += 1; } + return result; }; @@ -16,10 +18,12 @@ export const calcBinaryTreeDepthFromMaxLeaves = (maxLeaves: number) => { * @param maxLeaves the number of leaves in the tree * @returns the depth of the tree */ -export const calcQuinTreeDepthFromMaxLeaves = (maxLeaves: number) => { +export const calcQuinTreeDepthFromMaxLeaves = (maxLeaves: number): number => { let result = 0; + while (5 ** result < maxLeaves) { - result++; + result += 1; } + return result; }; diff --git a/cli/ts/utils/verifiers.ts b/cli/ts/utils/verifiers.ts index efee5d58b0..abac254d6b 100644 --- a/cli/ts/utils/verifiers.ts +++ b/cli/ts/utils/verifiers.ts @@ -1,6 +1,7 @@ -import { Contract } from "ethers"; import { genTreeProof } from "maci-crypto"; -import { TallyData } from "./interfaces"; + +import type { TallyData } from "./interfaces"; +import type { Tally } from "maci-contracts"; /** * Loop through each per vote option spent voice credits and verify it on-chain @@ -14,7 +15,7 @@ import { TallyData } from "./interfaces"; * @returns list of the indexes of the tally result that failed on-chain verification */ export const verifyPerVOSpentVoiceCredits = async ( - tallyContract: Contract, + tallyContract: Tally, tallyData: TallyData, voteOptionTreeDepth: number, newSpentVoiceCreditsCommitment: bigint, @@ -29,6 +30,7 @@ export const verifyPerVOSpentVoiceCredits = async ( voteOptionTreeDepth, ); + // eslint-disable-next-line no-await-in-loop const isValid = await tallyContract.verifyPerVOSpentVoiceCredits( i, tallyData.perVOSpentVoiceCredits.tally[i], @@ -56,7 +58,7 @@ export const verifyPerVOSpentVoiceCredits = async ( * @returns list of the indexes of the tally result that failed on-chain verification */ export const verifyTallyResults = async ( - tallyContract: Contract, + tallyContract: Tally, tallyData: TallyData, voteOptionTreeDepth: number, newSpentVoiceCreditsCommitment: bigint, @@ -71,6 +73,7 @@ export const verifyTallyResults = async ( voteOptionTreeDepth, ); + // eslint-disable-next-line no-await-in-loop const isValid = await tallyContract.verifyTallyResult( i, tallyData.results.tally[i], diff --git a/cli/ts/utils/vks.ts b/cli/ts/utils/vks.ts index 345b7729fc..2c6af23681 100644 --- a/cli/ts/utils/vks.ts +++ b/cli/ts/utils/vks.ts @@ -1,4 +1,4 @@ -import { IVkContractParams, VerifyingKey } from "maci-domainobjs"; +import type { IVkContractParams, VerifyingKey } from "maci-domainobjs"; /** * Compare two verifying keys @@ -8,10 +8,11 @@ import { IVkContractParams, VerifyingKey } from "maci-domainobjs"; */ export const compareVks = (vk: VerifyingKey, vkOnChain: IVkContractParams): boolean => { let isEqual = vk.ic.length === vkOnChain.ic.length; - for (let i = 0; i < vk.ic.length; i++) { + for (let i = 0; i < vk.ic.length; i += 1) { isEqual = isEqual && vk.ic[i].x.toString() === vkOnChain.ic[i].x.toString(); isEqual = isEqual && vk.ic[i].y.toString() === vkOnChain.ic[i].y.toString(); } + isEqual = isEqual && vk.alpha1.x.toString() === vkOnChain.alpha1.x.toString(); isEqual = isEqual && vk.alpha1.y.toString() === vkOnChain.alpha1.y.toString(); isEqual = isEqual && vk.beta2.x[0].toString() === vkOnChain.beta2.x[0].toString(); diff --git a/cli/tsconfig.json b/cli/tsconfig.json index 58b3fd62a3..74aed8a08f 100644 --- a/cli/tsconfig.json +++ b/cli/tsconfig.json @@ -1,11 +1,33 @@ { "extends": "../tsconfig.json", "compilerOptions": { + "outDir": "./build", + "declaration": true, + "allowJs": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, "target": "ES2020", "lib": ["es2020"], + "experimentalDecorators": true, + "strict": true, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "strictPropertyInitialization": true, + "strictNullChecks": true, "module": "commonjs", - "outDir": "./build", - "esModuleInterop": true + "moduleResolution": "node", + "resolveJsonModule": true, + "skipLibCheck": true, + "esModuleInterop": true, + "isolatedModules": true, + "forceConsistentCasingInFileNames": true, + "allowSyntheticDefaultImports": true, + "composite": true, + "incremental": true, + "declarationMap": true, + "sourceMap": true, + "stripInternal": true }, "include": ["./ts", "./tests"], "files": ["./hardhat.config.ts"] diff --git a/contracts/package-lock.json b/contracts/package-lock.json index c6afa1eeff..b1b6d2e5d3 100644 --- a/contracts/package-lock.json +++ b/contracts/package-lock.json @@ -13,6 +13,7 @@ "circomlibjs": "^0.1.7", "ethers": "^6.9.0", "hardhat": "^2.19.1", + "snarkjs": "^0.7.2", "solidity-docgen": "^0.6.0-beta.36" }, "devDependencies": { @@ -20,6 +21,7 @@ "@types/circomlibjs": "^0.1.6", "@types/mocha": "^10.0.6", "@types/node": "^18.11.9", + "@types/snarkjs": "^0.7.7", "chai": "^4.3.10", "hardhat-artifactor": "^0.2.0", "hardhat-contract-sizer": "^2.10.0", @@ -844,6 +846,20 @@ "node": ">=14" } }, + "node_modules/@iden3/bigarray": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@iden3/bigarray/-/bigarray-0.0.2.tgz", + "integrity": "sha512-Xzdyxqm1bOFF6pdIsiHLLl3HkSLjbhqJHVyqaTxXt3RqXBEnmsUmEW47H7VOi/ak7TdkRpNkxjyK5Zbkm+y52g==" + }, + "node_modules/@iden3/binfileutils": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/@iden3/binfileutils/-/binfileutils-0.0.11.tgz", + "integrity": "sha512-LylnJoZ0CTdgErnKY8OxohvW4K+p6UHD3sxt+3P9AmMyBQjYR4IpoqoYZZ+9aMj89cmCQ21UvdhndAx04er3NA==", + "dependencies": { + "fastfile": "0.0.20", + "ffjavascript": "^0.2.48" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", @@ -1889,6 +1905,12 @@ "@types/node": "*" } }, + "node_modules/@types/snarkjs": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/@types/snarkjs/-/snarkjs-0.7.7.tgz", + "integrity": "sha512-t/fYLdqUDM7W/XP+CKh4kvo9SS2ejtqHJz/2LQf/UsrrCsDYRjQ85DQFdvIJ6FvJjUvtEEPpTSCPk9gDDjcBWQ==", + "dev": true + }, "node_modules/abbrev": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", @@ -1997,7 +2019,6 @@ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", "optional": true, - "peer": true, "engines": { "node": ">=0.4.2" } @@ -2256,6 +2277,21 @@ "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" }, + "node_modules/bfj": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.1.0.tgz", + "integrity": "sha512-I6MMLkn+anzNdCUp9hMRyui1HaNEUCco50lxbvNS4+EyXg8lN3nJ48PjPWtbH8UVS9CuMoaKE9U2V3l29DaRQw==", + "dependencies": { + "bluebird": "^3.7.2", + "check-types": "^11.2.3", + "hoopy": "^0.1.4", + "jsonpath": "^1.1.1", + "tryer": "^1.0.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/bigint-crypto-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz", @@ -2309,6 +2345,11 @@ "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, "node_modules/bn.js": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", @@ -2561,6 +2602,11 @@ "node": "*" } }, + "node_modules/check-types": { + "version": "11.2.3", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz", + "integrity": "sha512-+67P1GkJRaxQD6PKK0Et9DhwQB+vGg3PM5+aavopCpZT1lj9jeqfvpgTLAWErNj8qApkkmXlu/Ug74kmhagkXg==" + }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -2601,6 +2647,27 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/circom_runtime": { + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.1.24.tgz", + "integrity": "sha512-H7/7I2J/cBmRnZm9docOCGhfxzS61BEm4TMCWcrZGsWNBQhePNfQq88Oj2XpUfzmBTCd8pRvRb3Mvazt3TMrJw==", + "dependencies": { + "ffjavascript": "0.2.60" + }, + "bin": { + "calcwit": "calcwit.js" + } + }, + "node_modules/circom_runtime/node_modules/ffjavascript": { + "version": "0.2.60", + "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.60.tgz", + "integrity": "sha512-T/9bnEL5xAZRDbQoEMf+pM9nrhK+C3JyZNmqiWub26EQorW7Jt+jR54gpqDhceA4Nj0YctPQwYnl8xa52/A26A==", + "dependencies": { + "wasmbuilder": "0.0.16", + "wasmcurves": "0.2.2", + "web-worker": "^1.2.0" + } + }, "node_modules/circomlibjs": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/circomlibjs/-/circomlibjs-0.1.7.tgz", @@ -2976,8 +3043,7 @@ "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "peer": true + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, "node_modules/define-data-property": { "version": "1.1.1", @@ -3071,6 +3137,20 @@ "node": ">=8" } }, + "node_modules/ejs": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/elliptic": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", @@ -3224,7 +3304,6 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", - "peer": true, "dependencies": { "esprima": "^2.7.1", "estraverse": "^1.9.1", @@ -3246,7 +3325,6 @@ "version": "2.7.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", - "peer": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -3259,7 +3337,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -3268,7 +3345,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -3648,8 +3724,12 @@ "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "peer": true + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "node_modules/fastfile": { + "version": "0.0.20", + "resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.20.tgz", + "integrity": "sha512-r5ZDbgImvVWCP0lA/cGNgQcZqR+aYdFx3u+CtJqUE510pBUVGMn4ulL/iRTI4tACTYsNJ736uzFxEBXesPAktA==" }, "node_modules/fastq": { "version": "1.15.0", @@ -3670,6 +3750,33 @@ "web-worker": "^1.2.0" } }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -4434,6 +4541,14 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "node_modules/hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/http-basic": { "version": "8.1.3", "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", @@ -4867,6 +4982,92 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "peer": true }, + "node_modules/jake": { + "version": "10.8.7", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", + "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jake/node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + }, + "node_modules/jake/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jake/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jake/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jake/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jake/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/js-sdsl": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.2.tgz", @@ -4910,6 +5111,28 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonpath": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", + "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", + "dependencies": { + "esprima": "1.2.2", + "static-eval": "2.0.2", + "underscore": "1.12.1" + } + }, + "node_modules/jsonpath/node_modules/esprima": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", + "integrity": "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/jsonschema": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", @@ -4995,7 +5218,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "peer": true, "dependencies": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" @@ -5124,6 +5346,11 @@ "node": ">=8" } }, + "node_modules/logplease": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/logplease/-/logplease-1.2.15.tgz", + "integrity": "sha512-jLlHnlsPSJjpwUfcNyUxXCl33AYg2cHhIf9QhGL2T4iPT0XPB+xP1LRKFPgIg1M/sg9kAJvy94w9CzBNrfnstA==" + }, "node_modules/loupe": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", @@ -5633,7 +5860,6 @@ "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "peer": true, "dependencies": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.6", @@ -5787,7 +6013,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "peer": true, "engines": { "node": ">= 0.8.0" } @@ -5871,6 +6096,27 @@ } ] }, + "node_modules/r1csfile": { + "version": "0.0.47", + "resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.47.tgz", + "integrity": "sha512-oI4mAwuh1WwuFg95eJDNDDL8hCaZkwnPuNZrQdLBWvDoRU7EG+L/MOHL7SwPW2Y+ZuYcTLpj3rBkgllBQZN/JA==", + "dependencies": { + "@iden3/bigarray": "0.0.2", + "@iden3/binfileutils": "0.0.11", + "fastfile": "0.0.20", + "ffjavascript": "0.2.60" + } + }, + "node_modules/r1csfile/node_modules/ffjavascript": { + "version": "0.2.60", + "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.60.tgz", + "integrity": "sha512-T/9bnEL5xAZRDbQoEMf+pM9nrhK+C3JyZNmqiWub26EQorW7Jt+jR54gpqDhceA4Nj0YctPQwYnl8xa52/A26A==", + "dependencies": { + "wasmbuilder": "0.0.16", + "wasmcurves": "0.2.2", + "web-worker": "^1.2.0" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -6463,6 +6709,26 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "peer": true }, + "node_modules/snarkjs": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/snarkjs/-/snarkjs-0.7.2.tgz", + "integrity": "sha512-A8yPFm9pRnZ7XYXfPSjSFnugEV1rsHGjb8W7c0Qk7nzXl5h3WANTkpVC5FYxakmw/GKWekz7wjjHaOFtPp823Q==", + "dependencies": { + "@iden3/binfileutils": "0.0.11", + "bfj": "^7.0.2", + "blake2b-wasm": "^2.4.0", + "circom_runtime": "0.1.24", + "ejs": "^3.1.6", + "fastfile": "0.0.20", + "ffjavascript": "0.2.62", + "js-sha3": "^0.8.0", + "logplease": "^1.2.15", + "r1csfile": "0.0.47" + }, + "bin": { + "snarkjs": "build/cli.cjs" + } + }, "node_modules/solc": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", @@ -6646,7 +6912,6 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", "optional": true, - "peer": true, "dependencies": { "amdefine": ">=0.0.4" }, @@ -6696,6 +6961,14 @@ "node": ">=8" } }, + "node_modules/static-eval": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", + "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", + "dependencies": { + "escodegen": "^1.8.1" + } + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -6962,6 +7235,11 @@ "node": ">=0.6" } }, + "node_modules/tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" + }, "node_modules/ts-command-line-args": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz", @@ -7130,7 +7408,6 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "peer": true, "dependencies": { "prelude-ls": "~1.1.2" }, @@ -7359,6 +7636,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==" + }, "node_modules/undici": { "version": "5.28.2", "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.2.tgz", @@ -7561,7 +7843,6 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "peer": true, "engines": { "node": ">=0.10.0" } diff --git a/contracts/package.json b/contracts/package.json index b34fdb7118..2d74b71459 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -38,6 +38,7 @@ "maci-core": "^1.1.2", "maci-crypto": "^1.1.2", "maci-domainobjs": "^1.1.2", + "snarkjs": "^0.7.2", "solidity-docgen": "^0.6.0-beta.36" }, "devDependencies": { @@ -45,6 +46,7 @@ "@types/circomlibjs": "^0.1.6", "@types/mocha": "^10.0.6", "@types/node": "^18.11.9", + "@types/snarkjs": "^0.7.7", "chai": "^4.3.10", "hardhat-artifactor": "^0.2.0", "hardhat-contract-sizer": "^2.10.0", diff --git a/contracts/tests/HasherBenchmarks.test.ts b/contracts/tests/HasherBenchmarks.test.ts index 2b1a5b448d..a3fa5e4f28 100644 --- a/contracts/tests/HasherBenchmarks.test.ts +++ b/contracts/tests/HasherBenchmarks.test.ts @@ -37,12 +37,11 @@ describe("Hasher", () => { const left = genRandomSalt(); const right = genRandomSalt(); - const tx = await hasherContract.hashLeftRightBenchmark(left.toString(), right.toString()); - const receipt = await tx.wait(); + const result = await hasherContract + .hashLeftRightBenchmark(left.toString(), right.toString()) + .then((res) => Number(res)); - expect(receipt).to.not.eq(null); - expect(receipt?.gasUsed.toString()).to.not.eq(""); - expect(receipt?.gasUsed.toString()).to.not.eq("0"); + expect(result).to.not.eq(null); }); it("hash5", async () => { @@ -52,13 +51,10 @@ describe("Hasher", () => { values.push(genRandomSalt().toString()); } - const tx = await hasherContract.hash5Benchmark( - values as [BigNumberish, BigNumberish, BigNumberish, BigNumberish, BigNumberish], - ); - const receipt = await tx.wait(); + const result = await hasherContract + .hash5Benchmark(values as [BigNumberish, BigNumberish, BigNumberish, BigNumberish, BigNumberish]) + .then((res) => Number(res)); - expect(receipt).to.not.eq(null); - expect(receipt?.gasUsed.toString()).to.not.eq(""); - expect(receipt?.gasUsed.toString()).to.not.eq("0"); + expect(result).to.not.eq(null); }); }); diff --git a/contracts/ts/index.ts b/contracts/ts/index.ts index 8f83d11f2c..e09661b18b 100644 --- a/contracts/ts/index.ts +++ b/contracts/ts/index.ts @@ -22,5 +22,5 @@ export { formatProofForVerifierContract, getDefaultSigner, getSigners } from "./ export { abiDir, solDir } from "./constants"; export { parseArtifact } from "./abi"; -export type { IVerifyingKeyStruct } from "./types"; +export type { IVerifyingKeyStruct, SnarkProof } from "./types"; export * from "../typechain-types"; diff --git a/contracts/ts/utils.ts b/contracts/ts/utils.ts index 0b52ae1716..4785e1413c 100644 --- a/contracts/ts/utils.ts +++ b/contracts/ts/utils.ts @@ -4,6 +4,7 @@ import { FeeData, Signer } from "ethers"; import { ethers } from "hardhat"; import type { Action, SnarkProof } from "./types"; +import type { Groth16Proof } from "snarkjs"; import { Ownable } from "../typechain-types"; @@ -13,7 +14,7 @@ import { Ownable } from "../typechain-types"; * @param proof the SnarkProof to format * @returns an array of strings */ -export const formatProofForVerifierContract = (proof: SnarkProof): string[] => +export const formatProofForVerifierContract = (proof: SnarkProof | Groth16Proof): string[] => [ proof.pi_a[0], proof.pi_a[1], diff --git a/core/ts/__tests__/MaciState.test.ts b/core/ts/__tests__/MaciState.test.ts index 2d7adb337b..5d597419d0 100644 --- a/core/ts/__tests__/MaciState.test.ts +++ b/core/ts/__tests__/MaciState.test.ts @@ -1,7 +1,7 @@ import { expect } from "chai"; import { PCommand, Message, Keypair, StateLeaf, PrivKey, Ballot } from "maci-domainobjs"; -import { existsSync, readFileSync, unlinkSync, writeFileSync } from "fs"; +import fs from "fs"; import { MaciState } from "../MaciState"; import { STATE_TREE_DEPTH } from "../utils/constants"; @@ -19,8 +19,8 @@ describe("MaciState", function test() { const stateFile = "./state.json"; after(() => { - if (existsSync(stateFile)) { - unlinkSync(stateFile); + if (fs.existsSync(stateFile)) { + fs.unlinkSync(stateFile); } }); @@ -127,8 +127,8 @@ describe("MaciState", function test() { it("should create a JSON object from a MaciState object", () => { const json = m1.toJSON(); - writeFileSync(stateFile, JSON.stringify(json, null, 4)); - const content = JSON.parse(readFileSync(stateFile).toString()) as IJsonMaciState; + fs.writeFileSync(stateFile, JSON.stringify(json, null, 4)); + const content = JSON.parse(fs.readFileSync(stateFile).toString()) as IJsonMaciState; const state = MaciState.fromJSON(content); state.polls.forEach((poll) => { poll.setCoordinatorKeypair(coordinatorKeypair.privKey.serialize()); diff --git a/core/ts/index.ts b/core/ts/index.ts index 89a9290abf..5b61860f6b 100644 --- a/core/ts/index.ts +++ b/core/ts/index.ts @@ -11,7 +11,7 @@ export { packSubsidySmallVals, } from "./utils/utils"; -export type { CircuitInputs, MaxValues, TreeDepths, BatchSizes } from "./utils/types"; +export type { CircuitInputs, MaxValues, TreeDepths, BatchSizes, IJsonMaciState } from "./utils/types"; export { STATE_TREE_DEPTH, STATE_TREE_ARITY, diff --git a/integrationTests/package.json b/integrationTests/package.json index 1f8e76d556..6e7fd73c28 100644 --- a/integrationTests/package.json +++ b/integrationTests/package.json @@ -2,7 +2,7 @@ "name": "maci-integrationtests", "version": "1.1.2", "description": "", - "main": "build/index.js", + "main": "build/ts/index.js", "scripts": { "watch": "tsc --watch", "build": "tsc", diff --git a/integrationTests/ts/__tests__/integration.test.ts b/integrationTests/ts/__tests__/integration.test.ts index 2762e21ff1..a9ce3ac91f 100644 --- a/integrationTests/ts/__tests__/integration.test.ts +++ b/integrationTests/ts/__tests__/integration.test.ts @@ -21,7 +21,7 @@ import { MaciState, MaxValues, TreeDepths } from "maci-core"; import { genPubKey, genRandomSalt } from "maci-crypto"; import { Keypair, PCommand, PrivKey, PubKey } from "maci-domainobjs"; -import { existsSync, readFileSync, readdir, unlinkSync } from "fs"; +import fs from "fs"; import { homedir } from "os"; import path from "path"; @@ -128,33 +128,33 @@ describe("integration tests", function test() { // after each test we need to cleanup some files afterEach(() => { - if (existsSync(path.resolve(__dirname, "../../../cli/tally.json"))) { - unlinkSync(path.resolve(__dirname, "../../../cli/tally.json")); + if (fs.existsSync(path.resolve(__dirname, "../../../cli/tally.json"))) { + fs.unlinkSync(path.resolve(__dirname, "../../../cli/tally.json")); } - if (existsSync(path.resolve(__dirname, "../../../cli/subsidy.json"))) { - unlinkSync(path.resolve(__dirname, "../../../cli/subsidy.json")); + if (fs.existsSync(path.resolve(__dirname, "../../../cli/subsidy.json"))) { + fs.unlinkSync(path.resolve(__dirname, "../../../cli/subsidy.json")); } const directory = path.resolve(__dirname, "../../../cli/proofs/"); - if (!existsSync(directory)) { + if (!fs.existsSync(directory)) { return; } - readdir(directory, (err, files) => { + fs.readdir(directory, (err, files) => { if (err) { throw err; } files.forEach((file) => { - unlinkSync(path.resolve(directory, file)); + fs.unlinkSync(path.resolve(directory, file)); }); }); }); // read the test suite data - const data = JSON.parse(readFileSync(path.resolve(__dirname, `./data/suites.json`)).toString()) as { + const data = JSON.parse(fs.readFileSync(path.resolve(__dirname, `./data/suites.json`)).toString()) as { suites: ITestSuite[]; }; @@ -267,7 +267,7 @@ describe("integration tests", function test() { if (subsidyEnabled) { const subsidy = JSON.parse( - readFileSync(path.resolve(__dirname, "../../../cli/subsidy.json")).toString(), + fs.readFileSync(path.resolve(__dirname, "../../../cli/subsidy.json")).toString(), ) as Subsidy; expectSubsidy(maxMessages, testCase.subsidy?.expectedSubsidy ?? [], subsidy); } From e5ad3452b77be5007b0ddbe593606a7bcd2a9fc5 Mon Sep 17 00:00:00 2001 From: 0xmad <0xmad@users.noreply.github.com> Date: Fri, 5 Jan 2024 15:20:36 -0600 Subject: [PATCH 26/37] fix(cli): add auto mining option for hardhat --- contracts/hardhat.config.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contracts/hardhat.config.ts b/contracts/hardhat.config.ts index 88e871dd87..4ace0da419 100644 --- a/contracts/hardhat.config.ts +++ b/contracts/hardhat.config.ts @@ -23,6 +23,10 @@ const config: HardhatUserConfig = { }, loggingEnabled: false, allowUnlimitedContractSize: true, + mining: { + auto: true, + interval: 100, + }, }, }, contractSizer: { From fe336a269c62b3b8dc40b9c387ca1796759be49b Mon Sep 17 00:00:00 2001 From: 0xmad <0xmad@users.noreply.github.com> Date: Fri, 5 Jan 2024 16:00:12 -0600 Subject: [PATCH 27/37] fix(integrationTests): add auto mining option for hardhat --- integrationTests/hardhat.config.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/integrationTests/hardhat.config.ts b/integrationTests/hardhat.config.ts index c33a70e0fb..8a2eda20c6 100644 --- a/integrationTests/hardhat.config.ts +++ b/integrationTests/hardhat.config.ts @@ -12,6 +12,10 @@ const config: HardhatUserConfig = { gas: GAS_LIMIT, blockGasLimit: GAS_LIMIT, accounts: { count: 30, mnemonic: WALLET_MNEMONIC }, + mining: { + auto: true, + interval: 100, + }, }, }, solidity: { From 5c92154fc09f0c59ca5054229798f3c8ad7d134d Mon Sep 17 00:00:00 2001 From: 0xmad <0xmad@users.noreply.github.com> Date: Fri, 5 Jan 2024 16:37:34 -0600 Subject: [PATCH 28/37] chore(contracts): enable linter - [x] Lint fixes - [x] Update ci workflows --- .github/workflows/checks.yml | 2 +- .lintstagedrc.json | 1 + .solhint.json | 2 +- cli/ts/commands/proveOnChain.ts | 1 + contracts/contracts/MACI.sol | 26 +- contracts/contracts/MessageProcessor.sol | 2 +- contracts/contracts/Poll.sol | 5 - contracts/contracts/PollFactory.sol | 3 +- contracts/contracts/SignUpToken.sol | 2 +- contracts/contracts/Subsidy.sol | 2 +- contracts/contracts/Tally.sol | 5 +- contracts/contracts/TopupCredit.sol | 19 +- .../contracts/benchmarks/HasherBenchmarks.sol | 4 +- contracts/contracts/crypto/Hasher.sol | 24 +- contracts/contracts/crypto/IVerifier.sol | 11 + contracts/contracts/crypto/MockVerifier.sol | 15 + contracts/contracts/crypto/Pairing.sol | 30 +- contracts/contracts/crypto/PoseidonT3.sol | 8 + contracts/contracts/crypto/PoseidonT4.sol | 8 + contracts/contracts/crypto/PoseidonT5.sol | 8 + contracts/contracts/crypto/PoseidonT6.sol | 8 + contracts/contracts/crypto/Verifier.sol | 71 ++--- .../FreeForAllSignUpGatekeeper.sol | 3 +- .../gatekeepers/SignUpGatekeeper.sol | 2 + .../gatekeepers/SignUpTokenGatekeeper.sol | 2 +- .../ConstantInitialVoiceCreditProxy.sol | 6 +- .../InitialVoiceCreditProxy.sol | 1 + contracts/contracts/interfaces/IMACI.sol | 1 - contracts/contracts/trees/AccQueue.sol | 284 +++--------------- contracts/contracts/trees/AccQueueBinary.sol | 59 ++++ contracts/contracts/trees/AccQueueBinary0.sol | 22 ++ .../contracts/trees/AccQueueBinaryMaci.sol | 21 ++ contracts/contracts/trees/AccQueueQuinary.sol | 82 +++++ .../contracts/trees/AccQueueQuinary0.sol | 22 ++ .../trees/AccQueueQuinaryBlankSl.sol | 22 ++ .../contracts/trees/AccQueueQuinaryMaci.sol | 22 ++ .../contracts/utilities/CommonUtilities.sol | 23 ++ contracts/contracts/utilities/DomainObjs.sol | 2 +- contracts/contracts/utilities/Params.sol | 1 - contracts/contracts/utilities/Utilities.sol | 30 +- contracts/ts/abi.ts | 2 +- package.json | 4 +- 42 files changed, 479 insertions(+), 389 deletions(-) create mode 100644 contracts/contracts/crypto/IVerifier.sol create mode 100644 contracts/contracts/crypto/MockVerifier.sol create mode 100644 contracts/contracts/crypto/PoseidonT3.sol create mode 100644 contracts/contracts/crypto/PoseidonT4.sol create mode 100644 contracts/contracts/crypto/PoseidonT5.sol create mode 100644 contracts/contracts/crypto/PoseidonT6.sol create mode 100644 contracts/contracts/trees/AccQueueBinary.sol create mode 100644 contracts/contracts/trees/AccQueueBinary0.sol create mode 100644 contracts/contracts/trees/AccQueueBinaryMaci.sol create mode 100644 contracts/contracts/trees/AccQueueQuinary.sol create mode 100644 contracts/contracts/trees/AccQueueQuinary0.sol create mode 100644 contracts/contracts/trees/AccQueueQuinaryBlankSl.sol create mode 100644 contracts/contracts/trees/AccQueueQuinaryMaci.sol create mode 100644 contracts/contracts/utilities/CommonUtilities.sol diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 1dc2c8ffd3..73256f7c98 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -14,7 +14,7 @@ jobs: strategy: fail-fast: false matrix: - command: ["prettier", "lint:ts"] + command: ["prettier", "lint:ts", "lint:sol"] runs-on: ubuntu-22.04 diff --git a/.lintstagedrc.json b/.lintstagedrc.json index 362bb409fc..58ca4bc286 100644 --- a/.lintstagedrc.json +++ b/.lintstagedrc.json @@ -1,4 +1,5 @@ { "**/*.{ts,js}": ["prettier --ignore-unknown --write", "eslint --fix"], + "**/*.sol": ["prettier --ignore-unknown --write", "solhint --fix --noPrompt"], "*": ["prettier --ignore-unknown --write"] } diff --git a/.solhint.json b/.solhint.json index 31d88b6fcd..b058eb99b3 100644 --- a/.solhint.json +++ b/.solhint.json @@ -4,7 +4,7 @@ "avoid-suicide": "error", "avoid-sha3": "warn", "max-line-length": ["warn", 120], - "quotes": ["error", "single"], + "quotes": ["error", "double"], "func-visibility": ["error", { "ignoreConstructors": true }], "state-visibility": "error" } diff --git a/cli/ts/commands/proveOnChain.ts b/cli/ts/commands/proveOnChain.ts index 8d66065a7d..cb4bb53d1e 100644 --- a/cli/ts/commands/proveOnChain.ts +++ b/cli/ts/commands/proveOnChain.ts @@ -423,6 +423,7 @@ export const proveOnChain = async ( ); const receipt = await tx.wait(); + if (receipt?.status !== 1) { logError("updateSubsidy() failed."); } diff --git a/contracts/contracts/MACI.sol b/contracts/contracts/MACI.sol index 67ef936bed..81254972ee 100644 --- a/contracts/contracts/MACI.sol +++ b/contracts/contracts/MACI.sol @@ -5,14 +5,12 @@ import { Poll } from "./Poll.sol"; import { PollFactory } from "./PollFactory.sol"; import { InitialVoiceCreditProxy } from "./initialVoiceCreditProxy/InitialVoiceCreditProxy.sol"; import { SignUpGatekeeper } from "./gatekeepers/SignUpGatekeeper.sol"; -import { AccQueue, AccQueueQuinaryBlankSl } from "./trees/AccQueue.sol"; +import { AccQueue } from "./trees/AccQueue.sol"; +import { AccQueueQuinaryBlankSl } from "./trees/AccQueueQuinaryBlankSl.sol"; import { IMACI } from "./interfaces/IMACI.sol"; import { Params } from "./utilities/Params.sol"; import { DomainObjs } from "./utilities/DomainObjs.sol"; import { TopupCredit } from "./TopupCredit.sol"; -import { SnarkCommon } from "./crypto/SnarkCommon.sol"; -import { SnarkConstants } from "./crypto/SnarkConstants.sol"; -import { Hasher } from "./crypto/Hasher.sol"; import { Utilities } from "./utilities/Utilities.sol"; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; @@ -22,7 +20,7 @@ contract MACI is IMACI, Params, Utilities, Ownable { /// @notice The state tree depth is fixed. As such it should be as large as feasible /// so that there can be as many users as possible. i.e. 5 ** 10 = 9765625 /// this should also match the parameter of the circom circuits. - uint8 public immutable stateTreeDepth; + uint8 public immutable STATE_TREE_DEPTH; /// @notice IMPORTANT: remember to change the ballot tree depth /// in contracts/ts/genEmptyBallotRootsContract.ts file @@ -111,7 +109,7 @@ contract MACI is IMACI, Params, Utilities, Ownable { topupCredit = _topupCredit; signUpGatekeeper = _signUpGatekeeper; initialVoiceCreditProxy = _initialVoiceCreditProxy; - stateTreeDepth = _stateTreeDepth; + STATE_TREE_DEPTH = _stateTreeDepth; signUpTimestamp = block.timestamp; @@ -119,6 +117,12 @@ contract MACI is IMACI, Params, Utilities, Ownable { if (hash2([uint256(1), uint256(1)]) == 0) revert PoseidonHashLibrariesNotLinked(); } + /// @notice Get the depth of the state tree + /// @return The depth of the state tree + function stateTreeDepth() external view returns (uint8) { + return STATE_TREE_DEPTH; + } + /// @notice Allows any eligible user sign up. The sign-up gatekeeper should prevent /// double sign-ups or ineligible users from doing so. This function will /// only succeed if the sign-up deadline has not passed. It also enqueues a @@ -137,15 +141,15 @@ contract MACI is IMACI, Params, Utilities, Ownable { bytes memory _initialVoiceCreditProxyData ) public { // ensure we do not have more signups than what the circuits support - if (numSignUps == uint256(TREE_ARITY) ** uint256(stateTreeDepth)) revert TooManySignups(); + if (numSignUps == uint256(TREE_ARITY) ** uint256(STATE_TREE_DEPTH)) revert TooManySignups(); if (_pubKey.x >= SNARK_SCALAR_FIELD || _pubKey.y >= SNARK_SCALAR_FIELD) { revert MaciPubKeyLargerThanSnarkFieldSize(); } // Increment the number of signups - // cannot overflow with realistic stateTreeDepth - // values as numSignUps < 5 ** stateTreeDepth -1 + // cannot overflow with realistic STATE_TREE_DEPTH + // values as numSignUps < 5 ** STATE_TREE_DEPTH -1 unchecked { numSignUps++; } @@ -226,13 +230,13 @@ contract MACI is IMACI, Params, Utilities, Ownable { /// @param _pollId The active Poll ID /// @return root The calculated Merkle root function mergeStateAq(uint256 _pollId) public override onlyPoll(_pollId) returns (uint256 root) { - root = stateAq.merge(stateTreeDepth); + root = stateAq.merge(STATE_TREE_DEPTH); } /// @notice Return the main root of the StateAq contract /// @return root The Merkle root function getStateAqRoot() public view override returns (uint256 root) { - root = stateAq.getMainRoot(stateTreeDepth); + root = stateAq.getMainRoot(STATE_TREE_DEPTH); } /// @notice Get the Poll details diff --git a/contracts/contracts/MessageProcessor.sol b/contracts/contracts/MessageProcessor.sol index 1cf6d3b049..1214b7264b 100644 --- a/contracts/contracts/MessageProcessor.sol +++ b/contracts/contracts/MessageProcessor.sol @@ -7,7 +7,7 @@ import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { Poll } from "./Poll.sol"; import { SnarkCommon } from "./crypto/SnarkCommon.sol"; import { Hasher } from "./crypto/Hasher.sol"; -import { CommonUtilities } from "./utilities/Utilities.sol"; +import { CommonUtilities } from "./utilities/CommonUtilities.sol"; import { Verifier } from "./crypto/Verifier.sol"; import { VkRegistry } from "./VkRegistry.sol"; diff --git a/contracts/contracts/Poll.sol b/contracts/contracts/Poll.sol index e9b5df31b6..938ba5156b 100644 --- a/contracts/contracts/Poll.sol +++ b/contracts/contracts/Poll.sol @@ -3,16 +3,11 @@ pragma solidity ^0.8.10; import { Params } from "./utilities/Params.sol"; import { SnarkCommon } from "./crypto/SnarkCommon.sol"; -import { DomainObjs } from "./utilities/DomainObjs.sol"; -import { AccQueue, AccQueueQuinaryMaci } from "./trees/AccQueue.sol"; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import { Verifier } from "./crypto/Verifier.sol"; import { EmptyBallotRoots } from "./trees/EmptyBallotRoots.sol"; -import { TopupCredit } from "./TopupCredit.sol"; import { Utilities } from "./utilities/Utilities.sol"; -import { MessageProcessor } from "./MessageProcessor.sol"; /// @title Poll /// @notice A Poll contract allows voters to submit encrypted messages diff --git a/contracts/contracts/PollFactory.sol b/contracts/contracts/PollFactory.sol index 86604e3076..353a256a30 100644 --- a/contracts/contracts/PollFactory.sol +++ b/contracts/contracts/PollFactory.sol @@ -2,7 +2,8 @@ pragma solidity ^0.8.10; import { IMACI } from "./interfaces/IMACI.sol"; -import { AccQueue, AccQueueQuinaryMaci } from "./trees/AccQueue.sol"; +import { AccQueue } from "./trees/AccQueue.sol"; +import { AccQueueQuinaryMaci } from "./trees/AccQueueQuinaryMaci.sol"; import { TopupCredit } from "./TopupCredit.sol"; import { Params } from "./utilities/Params.sol"; import { DomainObjs } from "./utilities/DomainObjs.sol"; diff --git a/contracts/contracts/SignUpToken.sol b/contracts/contracts/SignUpToken.sol index 702f525572..759a719d13 100644 --- a/contracts/contracts/SignUpToken.sol +++ b/contracts/contracts/SignUpToken.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.10; import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import "@openzeppelin/contracts/access/Ownable.sol"; +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; /// @title SignUpToken /// @notice This contract is an ERC721 token contract which diff --git a/contracts/contracts/Subsidy.sol b/contracts/contracts/Subsidy.sol index 714774e37b..5b702b1257 100644 --- a/contracts/contracts/Subsidy.sol +++ b/contracts/contracts/Subsidy.sol @@ -7,7 +7,7 @@ import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { Poll } from "./Poll.sol"; import { SnarkCommon } from "./crypto/SnarkCommon.sol"; import { Hasher } from "./crypto/Hasher.sol"; -import { CommonUtilities } from "./utilities/Utilities.sol"; +import { CommonUtilities } from "./utilities/CommonUtilities.sol"; import { Verifier } from "./crypto/Verifier.sol"; import { VkRegistry } from "./VkRegistry.sol"; diff --git a/contracts/contracts/Tally.sol b/contracts/contracts/Tally.sol index 8f5686922f..9b09a3c3d5 100644 --- a/contracts/contracts/Tally.sol +++ b/contracts/contracts/Tally.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import { AccQueue } from "./trees/AccQueue.sol"; import { IMACI } from "./interfaces/IMACI.sol"; import { Hasher } from "./crypto/Hasher.sol"; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; @@ -10,7 +9,7 @@ import { MessageProcessor } from "./MessageProcessor.sol"; import { SnarkCommon } from "./crypto/SnarkCommon.sol"; import { Verifier } from "./crypto/Verifier.sol"; import { VkRegistry } from "./VkRegistry.sol"; -import { CommonUtilities } from "./utilities/Utilities.sol"; +import { CommonUtilities } from "./utilities/CommonUtilities.sol"; /// @title Tally /// @notice The Tally contract is used during votes tallying @@ -217,7 +216,7 @@ contract Tally is Ownable, SnarkCommon, CommonUtilities, Hasher { /// @param _totalSpent spent field retrieved in the totalSpentVoiceCredits object /// @param _totalSpentSalt the corresponding salt in the totalSpentVoiceCredit object /// @param _resultCommitment hashLeftRight(merkle root of the results.tally, results.salt) in tally.json file - /// @param _perVOSpentVoiceCreditsHash hashLeftRight(merkle root of the no spent voice credits per vote option, perVOSpentVoiceCredits salt) + /// @param _perVOSpentVoiceCreditsHash hashLeftRight(merkle root of the no spent voice credits per vote option, salt) /// @return isValid Whether the provided values are valid function verifySpentVoiceCredits( uint256 _totalSpent, diff --git a/contracts/contracts/TopupCredit.sol b/contracts/contracts/TopupCredit.sol index db0d4d08af..e3c09f71a8 100644 --- a/contracts/contracts/TopupCredit.sol +++ b/contracts/contracts/TopupCredit.sol @@ -2,14 +2,17 @@ pragma solidity ^0.8.10; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import "@openzeppelin/contracts/access/Ownable.sol"; +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; /// @title TopupCredit /// @notice A contract representing a token used to topup a MACI's voter /// credits contract TopupCredit is ERC20, Ownable { - uint8 public constant _decimals = 1; - uint256 public constant MAXIMUM_AIRDROP_AMOUNT = 100000 * 10 ** _decimals; + uint8 public constant DECIMALS = 1; + uint256 public constant MAXIMUM_AIRDROP_AMOUNT = 100000 * 10 ** DECIMALS; + + /// @notice custom errors + error ExceedLimit(); /// @notice create a new TopupCredit token constructor() payable ERC20("TopupCredit", "TopupCredit") {} @@ -18,14 +21,20 @@ contract TopupCredit is ERC20, Ownable { /// @param account the account to mint tokens to /// @param amount the amount of tokens to mint function airdropTo(address account, uint256 amount) public onlyOwner { - require(amount < MAXIMUM_AIRDROP_AMOUNT); + if (amount >= MAXIMUM_AIRDROP_AMOUNT) { + revert ExceedLimit(); + } + _mint(account, amount); } /// @notice mint tokens to the contract owner /// @param amount the amount of tokens to mint function airdrop(uint256 amount) public onlyOwner { - require(amount < MAXIMUM_AIRDROP_AMOUNT, "amount exceed maximum limit"); + if (amount >= MAXIMUM_AIRDROP_AMOUNT) { + revert ExceedLimit(); + } + _mint(msg.sender, amount); } } diff --git a/contracts/contracts/benchmarks/HasherBenchmarks.sol b/contracts/contracts/benchmarks/HasherBenchmarks.sol index 7ceedc1a05..27327ef87e 100644 --- a/contracts/contracts/benchmarks/HasherBenchmarks.sol +++ b/contracts/contracts/benchmarks/HasherBenchmarks.sol @@ -9,7 +9,7 @@ contract HasherBenchmarks is Hasher { /// @notice Benchmark the poseidon hash function with 5 inputs /// @param array The array of inputs to hash /// @return result The hash of the inputs - function hash5Benchmark(uint256[5] memory array) public returns (uint256 result) { + function hash5Benchmark(uint256[5] memory array) public pure returns (uint256 result) { result = hash5(array); } @@ -17,7 +17,7 @@ contract HasherBenchmarks is Hasher { /// @param _left The left input to hash /// @param _right The right input to hash /// @return result The hash of the two inputs - function hashLeftRightBenchmark(uint256 _left, uint256 _right) public returns (uint256 result) { + function hashLeftRightBenchmark(uint256 _left, uint256 _right) public pure returns (uint256 result) { result = hashLeftRight(_left, _right); } } diff --git a/contracts/contracts/crypto/Hasher.sol b/contracts/contracts/crypto/Hasher.sol index 47bf831824..d332a8bcc0 100644 --- a/contracts/contracts/crypto/Hasher.sol +++ b/contracts/contracts/crypto/Hasher.sol @@ -2,26 +2,10 @@ pragma solidity ^0.8.10; import { SnarkConstants } from "./SnarkConstants.sol"; - -/// @notice A library which provides functions for computing Pedersen hashes. -library PoseidonT3 { - function poseidon(uint256[2] memory input) public pure returns (uint256) {} -} - -/// @notice A library which provides functions for computing Pedersen hashes. -library PoseidonT4 { - function poseidon(uint256[3] memory input) public pure returns (uint256) {} -} - -/// @notice A library which provides functions for computing Pedersen hashes. -library PoseidonT5 { - function poseidon(uint256[4] memory input) public pure returns (uint256) {} -} - -/// @notice A library which provides functions for computing Pedersen hashes. -library PoseidonT6 { - function poseidon(uint256[5] memory input) public pure returns (uint256) {} -} +import { PoseidonT3 } from "./PoseidonT3.sol"; +import { PoseidonT4 } from "./PoseidonT4.sol"; +import { PoseidonT5 } from "./PoseidonT5.sol"; +import { PoseidonT6 } from "./PoseidonT6.sol"; /// @notice A SHA256 hash function for any number of input elements, and Poseidon hash /// functions for 2, 3, 4, 5, and 12 input elements. diff --git a/contracts/contracts/crypto/IVerifier.sol b/contracts/contracts/crypto/IVerifier.sol new file mode 100644 index 0000000000..6e8cfe21b5 --- /dev/null +++ b/contracts/contracts/crypto/IVerifier.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +import { SnarkCommon } from "./SnarkCommon.sol"; + +/// @title IVerifier +/// @notice an interface for a Groth16 verifier contract +abstract contract IVerifier is SnarkCommon { + /// @notice Verify a zk-SNARK proof + function verify(uint256[8] memory, VerifyingKey memory, uint256) public view virtual returns (bool); +} diff --git a/contracts/contracts/crypto/MockVerifier.sol b/contracts/contracts/crypto/MockVerifier.sol new file mode 100644 index 0000000000..f471fa4435 --- /dev/null +++ b/contracts/contracts/crypto/MockVerifier.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +import { SnarkConstants } from "./SnarkConstants.sol"; +import { IVerifier } from "./IVerifier.sol"; + +/// @title MockVerifier +/// @notice a MockVerifier to be used for testing +contract MockVerifier is IVerifier, SnarkConstants { + /// @notice Verify a zk-SNARK proof (test only return always true) + /// @return result Whether the proof is valid given the verifying key and public + function verify(uint256[8] memory, VerifyingKey memory, uint256) public pure override returns (bool result) { + result = true; + } +} diff --git a/contracts/contracts/crypto/Pairing.sol b/contracts/contracts/crypto/Pairing.sol index 1e318ae7eb..eed929f519 100644 --- a/contracts/contracts/crypto/Pairing.sol +++ b/contracts/contracts/crypto/Pairing.sol @@ -23,7 +23,7 @@ pragma solidity ^0.8.10; /// @title Pairing /// @notice A library implementing the alt_bn128 elliptic curve operations. library Pairing { - uint256 constant PRIME_Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; + uint256 public constant PRIME_Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; struct G1Point { uint256 x; @@ -36,6 +36,11 @@ library Pairing { uint256[2] y; } + /// @notice custom errors + error PairingAddFailed(); + error PairingMulFailed(); + error PairingOpcodeFailed(); + /// @notice The negation of p, i.e. p.plus(p.negate()) should be zero. function negate(G1Point memory p) internal pure returns (G1Point memory) { // The prime q in the base field F_q for G1 @@ -55,7 +60,7 @@ library Pairing { input[3] = p2.y; bool success; - // solium-disable-next-line security/no-inline-assembly + // solhint-disable-next-line no-inline-assembly assembly { success := staticcall(sub(gas(), 2000), 6, input, 0xc0, r, 0x60) // Use "invalid" to make gas estimation work @@ -65,19 +70,21 @@ library Pairing { } } - require(success, "pairing-add-failed"); + if (!success) { + revert PairingAddFailed(); + } } /// @notice r Return the product of a point on G1 and a scalar, i.e. - /// p == p.scalar_mul(1) and p.plus(p) == p.scalar_mul(2) for all + /// p == p.scalarMul(1) and p.plus(p) == p.scalarMul(2) for all /// points p. - function scalar_mul(G1Point memory p, uint256 s) internal view returns (G1Point memory r) { + function scalarMul(G1Point memory p, uint256 s) internal view returns (G1Point memory r) { uint256[3] memory input; input[0] = p.x; input[1] = p.y; input[2] = s; bool success; - // solium-disable-next-line security/no-inline-assembly + // solhint-disable-next-line no-inline-assembly assembly { success := staticcall(sub(gas(), 2000), 7, input, 0x80, r, 0x60) // Use "invalid" to make gas estimation work @@ -86,7 +93,10 @@ library Pairing { invalid() } } - require(success, "pairing-mul-failed"); + + if (!success) { + revert PairingMulFailed(); + } } /// @return isValid The result of computing the pairing check @@ -122,7 +132,7 @@ library Pairing { uint256[1] memory out; bool success; - // solium-disable-next-line security/no-inline-assembly + // solhint-disable-next-line no-inline-assembly assembly { success := staticcall(sub(gas(), 2000), 8, add(input, 0x20), mul(inputSize, 0x20), out, 0x20) // Use "invalid" to make gas estimation work @@ -132,7 +142,9 @@ library Pairing { } } - require(success, "pairing-opcode-failed"); + if (!success) { + revert PairingOpcodeFailed(); + } isValid = out[0] != 0; } diff --git a/contracts/contracts/crypto/PoseidonT3.sol b/contracts/contracts/crypto/PoseidonT3.sol new file mode 100644 index 0000000000..c9825d32de --- /dev/null +++ b/contracts/contracts/crypto/PoseidonT3.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +/// @notice A library which provides functions for computing Pedersen hashes. +library PoseidonT3 { + // solhint-disable-next-line no-empty-blocks + function poseidon(uint256[2] memory input) public pure returns (uint256) {} +} diff --git a/contracts/contracts/crypto/PoseidonT4.sol b/contracts/contracts/crypto/PoseidonT4.sol new file mode 100644 index 0000000000..615c955f9e --- /dev/null +++ b/contracts/contracts/crypto/PoseidonT4.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +/// @notice A library which provides functions for computing Pedersen hashes. +library PoseidonT4 { + // solhint-disable-next-line no-empty-blocks + function poseidon(uint256[3] memory input) public pure returns (uint256) {} +} diff --git a/contracts/contracts/crypto/PoseidonT5.sol b/contracts/contracts/crypto/PoseidonT5.sol new file mode 100644 index 0000000000..46bb22e028 --- /dev/null +++ b/contracts/contracts/crypto/PoseidonT5.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +/// @notice A library which provides functions for computing Pedersen hashes. +library PoseidonT5 { + // solhint-disable-next-line no-empty-blocks + function poseidon(uint256[4] memory input) public pure returns (uint256) {} +} diff --git a/contracts/contracts/crypto/PoseidonT6.sol b/contracts/contracts/crypto/PoseidonT6.sol new file mode 100644 index 0000000000..1f677da10d --- /dev/null +++ b/contracts/contracts/crypto/PoseidonT6.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +/// @notice A library which provides functions for computing Pedersen hashes. +library PoseidonT6 { + // solhint-disable-next-line no-empty-blocks + function poseidon(uint256[5] memory input) public pure returns (uint256) {} +} diff --git a/contracts/contracts/crypto/Verifier.sol b/contracts/contracts/crypto/Verifier.sol index 72ca7f3d60..6fe010c49a 100644 --- a/contracts/contracts/crypto/Verifier.sol +++ b/contracts/contracts/crypto/Verifier.sol @@ -3,31 +3,7 @@ pragma solidity ^0.8.10; import { Pairing } from "./Pairing.sol"; import { SnarkConstants } from "./SnarkConstants.sol"; -import { SnarkCommon } from "./SnarkCommon.sol"; - -/// @title IVerifier -/// @notice an interface for a Groth16 verifier contract -abstract contract IVerifier is SnarkCommon { - /// @notice Verify a zk-SNARK proof - function verify(uint256[8] memory, VerifyingKey memory, uint256) public view virtual returns (bool); -} - -/// @title MockVerifier -/// @notice a MockVerifier to be used for testing -contract MockVerifier is IVerifier, SnarkConstants { - /// @notice Verify a zk-SNARK proof (test only return always true) - /// @param proof The proof - /// @param vk The verifying key - /// @param input The public inputs to the circuit - /// @return result Whether the proof is valid given the verifying key and public - function verify( - uint256[8] memory proof, - VerifyingKey memory vk, - uint256 input - ) public view override returns (bool result) { - result = true; - } -} +import { IVerifier } from "./IVerifier.sol"; /// @title Verifier /// @notice a Groth16 verifier contract @@ -40,9 +16,11 @@ contract Verifier is IVerifier, SnarkConstants { using Pairing for *; - uint256 constant PRIME_Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; - string constant ERROR_PROOF_Q = "VE1"; - string constant ERROR_INPUT_VAL = "VE2"; + uint256 public constant PRIME_Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; + + /// @notice custom errors + error InvalidProofQ(); + error InvalidInputVal(); /// @notice Verify a zk-SNARK proof /// @param _proof The proof @@ -63,37 +41,42 @@ contract Verifier is IVerifier, SnarkConstants { proof.c = Pairing.G1Point(_proof[6], _proof[7]); // Make sure that proof.A, B, and C are each less than the prime q - require(proof.a.x < PRIME_Q, ERROR_PROOF_Q); - require(proof.a.y < PRIME_Q, ERROR_PROOF_Q); - - require(proof.b.x[0] < PRIME_Q, ERROR_PROOF_Q); - require(proof.b.y[0] < PRIME_Q, ERROR_PROOF_Q); - - require(proof.b.x[1] < PRIME_Q, ERROR_PROOF_Q); - require(proof.b.y[1] < PRIME_Q, ERROR_PROOF_Q); - - require(proof.c.x < PRIME_Q, ERROR_PROOF_Q); - require(proof.c.y < PRIME_Q, ERROR_PROOF_Q); + checkPoint(proof.a.x); + checkPoint(proof.a.y); + checkPoint(proof.b.x[0]); + checkPoint(proof.b.y[0]); + checkPoint(proof.b.x[1]); + checkPoint(proof.b.y[1]); + checkPoint(proof.c.x); + checkPoint(proof.c.y); // Make sure that the input is less than the snark scalar field - require(input < SNARK_SCALAR_FIELD, ERROR_INPUT_VAL); + if (input >= SNARK_SCALAR_FIELD) { + revert InvalidInputVal(); + } // Compute the linear combination vk_x - Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0); + Pairing.G1Point memory vkX = Pairing.G1Point(0, 0); - vk_x = Pairing.plus(vk_x, Pairing.scalar_mul(vk.ic[1], input)); + vkX = Pairing.plus(vkX, Pairing.scalarMul(vk.ic[1], input)); - vk_x = Pairing.plus(vk_x, vk.ic[0]); + vkX = Pairing.plus(vkX, vk.ic[0]); isValid = Pairing.pairing( Pairing.negate(proof.a), proof.b, vk.alpha1, vk.beta2, - vk_x, + vkX, vk.gamma2, proof.c, vk.delta2 ); } + + function checkPoint(uint256 point) internal pure { + if (point >= PRIME_Q) { + revert InvalidProofQ(); + } + } } diff --git a/contracts/contracts/gatekeepers/FreeForAllSignUpGatekeeper.sol b/contracts/contracts/gatekeepers/FreeForAllSignUpGatekeeper.sol index 2a94417a38..8b167cc4c3 100644 --- a/contracts/contracts/gatekeepers/FreeForAllSignUpGatekeeper.sol +++ b/contracts/contracts/gatekeepers/FreeForAllSignUpGatekeeper.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import { SignUpGatekeeper } from "./SignUpGatekeeper.sol"; import { MACI } from "../MACI.sol"; +import { SignUpGatekeeper } from "./SignUpGatekeeper.sol"; /// @title FreeForAllGatekeeper /// @notice A SignUpGatekeeper which allows anyone to sign up. @@ -17,5 +17,6 @@ contract FreeForAllGatekeeper is SignUpGatekeeper { /// @notice Registers the user without any restrictions. /// @param _address The address of the user /// @param _data memory additional data + // solhint-disable-next-line no-empty-blocks function register(address _address, bytes memory _data) public override {} } diff --git a/contracts/contracts/gatekeepers/SignUpGatekeeper.sol b/contracts/contracts/gatekeepers/SignUpGatekeeper.sol index 97788711b3..527e7b9889 100644 --- a/contracts/contracts/gatekeepers/SignUpGatekeeper.sol +++ b/contracts/contracts/gatekeepers/SignUpGatekeeper.sol @@ -7,10 +7,12 @@ import { MACI } from "../MACI.sol"; /// @notice A gatekeeper contract which allows users to sign up for a poll. abstract contract SignUpGatekeeper { /// @notice Allows to set the MACI contract + // solhint-disable-next-line no-empty-blocks function setMaciInstance(MACI _maci) public virtual {} /// @notice Registers the user /// @param _user The address of the user /// @param _data additional data + // solhint-disable-next-line no-empty-blocks function register(address _user, bytes memory _data) public virtual {} } diff --git a/contracts/contracts/gatekeepers/SignUpTokenGatekeeper.sol b/contracts/contracts/gatekeepers/SignUpTokenGatekeeper.sol index 19a017e79d..cd38bf75a4 100644 --- a/contracts/contracts/gatekeepers/SignUpTokenGatekeeper.sol +++ b/contracts/contracts/gatekeepers/SignUpTokenGatekeeper.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import "@openzeppelin/contracts/access/Ownable.sol"; +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { SignUpGatekeeper } from "./SignUpGatekeeper.sol"; import { SignUpToken } from "../SignUpToken.sol"; diff --git a/contracts/contracts/initialVoiceCreditProxy/ConstantInitialVoiceCreditProxy.sol b/contracts/contracts/initialVoiceCreditProxy/ConstantInitialVoiceCreditProxy.sol index c9c326ded7..d9aefa7a0d 100644 --- a/contracts/contracts/initialVoiceCreditProxy/ConstantInitialVoiceCreditProxy.sol +++ b/contracts/contracts/initialVoiceCreditProxy/ConstantInitialVoiceCreditProxy.sol @@ -17,10 +17,8 @@ contract ConstantInitialVoiceCreditProxy is InitialVoiceCreditProxy { } /// @notice Returns the constant balance for any new MACI's voter - /// @param _address the address of the voter - /// @param _data additional data - /// @return the balance - function getVoiceCredits(address _address, bytes memory _data) public view override returns (uint256) { + /// @return balance + function getVoiceCredits(address, bytes memory) public view override returns (uint256) { return balance; } } diff --git a/contracts/contracts/initialVoiceCreditProxy/InitialVoiceCreditProxy.sol b/contracts/contracts/initialVoiceCreditProxy/InitialVoiceCreditProxy.sol index 6d6e86d6cc..246ec33729 100644 --- a/contracts/contracts/initialVoiceCreditProxy/InitialVoiceCreditProxy.sol +++ b/contracts/contracts/initialVoiceCreditProxy/InitialVoiceCreditProxy.sol @@ -10,5 +10,6 @@ abstract contract InitialVoiceCreditProxy { /// @param _user the address of the voter /// @param _data additional data /// @return the balance + // solhint-disable-next-line no-empty-blocks function getVoiceCredits(address _user, bytes memory _data) public view virtual returns (uint256) {} } diff --git a/contracts/contracts/interfaces/IMACI.sol b/contracts/contracts/interfaces/IMACI.sol index ca9321c345..752797e1fc 100644 --- a/contracts/contracts/interfaces/IMACI.sol +++ b/contracts/contracts/interfaces/IMACI.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.10; -import { VkRegistry } from "../VkRegistry.sol"; import { AccQueue } from "../trees/AccQueue.sol"; /// @title IMACI interface diff --git a/contracts/contracts/trees/AccQueue.sol b/contracts/contracts/trees/AccQueue.sol index 76b9fc95b2..dd8a348fdf 100644 --- a/contracts/contracts/trees/AccQueue.sol +++ b/contracts/contracts/trees/AccQueue.sol @@ -2,13 +2,7 @@ pragma solidity ^0.8.10; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; -import { PoseidonT3, PoseidonT6, Hasher } from "../crypto/Hasher.sol"; -import { MerkleZeros as MerkleBinary0 } from "./zeros/MerkleBinary0.sol"; -import { MerkleZeros as MerkleBinaryMaci } from "./zeros/MerkleBinaryMaci.sol"; -import { MerkleZeros as MerkleQuinary0 } from "./zeros/MerkleQuinary0.sol"; -import { MerkleZeros as MerkleQuinaryMaci } from "./zeros/MerkleQuinaryMaci.sol"; -import { MerkleZeros as MerkleQuinaryBlankSl } from "./zeros/MerkleQuinaryBlankSl.sol"; -import { MerkleZeros as MerkleQuinaryMaciWithSha256 } from "./zeros/MerkleQuinaryMaciWithSha256.sol"; +import { Hasher } from "../crypto/Hasher.sol"; /// @title AccQueue /// @notice This contract defines a Merkle tree where each leaf insertion only updates a @@ -18,7 +12,7 @@ import { MerkleZeros as MerkleQuinaryMaciWithSha256 } from "./zeros/MerkleQuinar /// the mergeSubRoots() can be performed in multiple transactions. abstract contract AccQueue is Ownable, Hasher { // The maximum tree depth - uint256 constant MAX_DEPTH = 32; + uint256 public constant MAX_DEPTH = 32; /// @notice A Queue is a 2D array of Merkle roots and indices which represents nodes /// in a Merkle tree while it is progressively updated. @@ -32,16 +26,16 @@ abstract contract AccQueue is Ownable, Hasher { } // The depth of each subtree - uint256 internal immutable subDepth; + uint256 internal immutable SUB_DEPTH; // The number of elements per hash operation. Should be either 2 (for // binary trees) or 5 (quinary trees). The limit is 5 because that is the // maximum supported number of inputs for the EVM implementation of the // Poseidon hash function - uint256 internal immutable hashLength; + uint256 internal immutable HASH_LENGTH; // hashLength ** subDepth - uint256 internal immutable subTreeCapacity; + uint256 internal immutable SUB_TREE_CAPACITY; // True hashLength == 2, false if hashLength == 5 bool internal isBinary; @@ -89,6 +83,7 @@ abstract contract AccQueue is Ownable, Hasher { error DepthTooLarge(uint256 _depth, uint256 max); error DepthTooSmall(uint256 _depth, uint256 min); error InvalidIndex(uint256 _index); + error InvalidLevel(); /// @notice Create a new AccQueue /// @param _subDepth The depth of each subtree. @@ -100,9 +95,9 @@ abstract contract AccQueue is Ownable, Hasher { if (_hashLength != 2 && _hashLength != 5) revert InvalidHashLength(); isBinary = _hashLength == 2; - subDepth = _subDepth; - hashLength = _hashLength; - subTreeCapacity = _hashLength ** _subDepth; + SUB_DEPTH = _subDepth; + HASH_LENGTH = _hashLength; + SUB_TREE_CAPACITY = _hashLength ** _subDepth; } /// @notice Hash the contents of the specified level and the specified leaf. @@ -112,6 +107,7 @@ abstract contract AccQueue is Ownable, Hasher { /// @param _level The level to hash. /// @param _leaf The leaf include with the level. /// @return _hash The hash of the level and leaf. + // solhint-disable-next-line no-empty-blocks function hashLevel(uint256 _level, uint256 _leaf) internal virtual returns (uint256 _hash) {} /// @notice Hash the contents of the specified level and the specified leaf. @@ -121,6 +117,7 @@ abstract contract AccQueue is Ownable, Hasher { /// @param _level The level to hash. /// @param _leaf The leaf include with the level. /// @return _hash The hash of the level and leaf. + // solhint-disable-next-line no-empty-blocks function hashLevelLeaf(uint256 _level, uint256 _leaf) public view virtual returns (uint256 _hash) {} /// @notice Returns the zero leaf at a specified level. @@ -131,6 +128,7 @@ abstract contract AccQueue is Ownable, Hasher { /// nothing-up-my-sleeve value. /// @param _level The level at which to return the zero leaf. /// @return zero The zero leaf at the specified level. + // solhint-disable-next-line no-empty-blocks function getZero(uint256 _level) internal virtual returns (uint256 zero) {} /// @notice Add a leaf to the queue for the current subtree. @@ -151,15 +149,15 @@ abstract contract AccQueue is Ownable, Hasher { subTreesMerged = false; // If a subtree is full - if (numLeaves % subTreeCapacity == 0) { + if (numLeaves % SUB_TREE_CAPACITY == 0) { // Store the subroot - subRoots[currentSubtreeIndex] = leafQueue.levels[subDepth][0]; + subRoots[currentSubtreeIndex] = leafQueue.levels[SUB_DEPTH][0]; // Increment the index currentSubtreeIndex++; // Delete ancillary data - delete leafQueue.levels[subDepth][0]; + delete leafQueue.levels[SUB_DEPTH][0]; delete leafQueue.indices; } } @@ -169,16 +167,18 @@ abstract contract AccQueue is Ownable, Hasher { /// @param _leaf The leaf to add. /// @param _level The level at which to queue the leaf. function _enqueue(uint256 _leaf, uint256 _level) internal { - require(_level <= subDepth, "AccQueue: invalid level"); + if (_level > SUB_DEPTH) { + revert InvalidLevel(); + } while (true) { uint256 n = leafQueue.indices[_level]; - if (n != hashLength - 1) { + if (n != HASH_LENGTH - 1) { // Just store the leaf leafQueue.levels[_level][n] = _leaf; - if (_level != subDepth) { + if (_level != SUB_DEPTH) { // Update the index leafQueue.indices[_level]++; } @@ -200,16 +200,16 @@ abstract contract AccQueue is Ownable, Hasher { /// @notice Fill any empty leaves of the current subtree with zeros and store the /// resulting subroot. function fill() public onlyOwner { - if (numLeaves % subTreeCapacity == 0) { + if (numLeaves % SUB_TREE_CAPACITY == 0) { // If the subtree is completely empty, then the subroot is a // precalculated zero value - subRoots[currentSubtreeIndex] = getZero(subDepth); + subRoots[currentSubtreeIndex] = getZero(SUB_DEPTH); } else { // Otherwise, fill the rest of the subtree with zeros _fill(0); // Store the subroot - subRoots[currentSubtreeIndex] = leafQueue.levels[subDepth][0]; + subRoots[currentSubtreeIndex] = leafQueue.levels[SUB_DEPTH][0]; // Reset the subtree data delete leafQueue.levels; @@ -223,7 +223,7 @@ abstract contract AccQueue is Ownable, Hasher { currentSubtreeIndex = curr; // Update the number of leaves - numLeaves = curr * subTreeCapacity; + numLeaves = curr * SUB_TREE_CAPACITY; // Reset the subroot tree root now that it is obsolete delete smallSRTroot; @@ -234,6 +234,7 @@ abstract contract AccQueue is Ownable, Hasher { /// @notice A function that queues zeros to the specified level, hashes, /// the level, and enqueues the hash to the next level. /// @param _level The level at which to queue zeros. + // solhint-disable-next-line no-empty-blocks function _fill(uint256 _level) internal virtual {} /// Insert a subtree. Used for batch enqueues. @@ -244,7 +245,7 @@ abstract contract AccQueue is Ownable, Hasher { currentSubtreeIndex++; // Update the number of leaves - numLeaves += subTreeCapacity; + numLeaves += SUB_TREE_CAPACITY; // Reset the subroot tree root now that it is obsolete delete smallSRTroot; @@ -258,7 +259,7 @@ abstract contract AccQueue is Ownable, Hasher { function calcMinHeight() public view returns (uint256 depth) { depth = 1; while (true) { - if (hashLength ** depth >= currentSubtreeIndex) { + if (HASH_LENGTH ** depth >= currentSubtreeIndex) { break; } depth++; @@ -286,7 +287,7 @@ abstract contract AccQueue is Ownable, Hasher { // Fill any empty leaves in the current subtree with zeros ony if the // current subtree is not full - if (numLeaves % subTreeCapacity != 0) { + if (numLeaves % SUB_TREE_CAPACITY != 0) { fill(); } @@ -317,11 +318,11 @@ abstract contract AccQueue is Ownable, Hasher { } // The height of the tree of subroots - uint256 m = hashLength ** depth; + uint256 m = HASH_LENGTH ** depth; // Queue zeroes to fill out the SRT if (nextSubRootIndex == currentSubtreeIndex) { - uint256 z = getZero(subDepth); + uint256 z = getZero(SUB_DEPTH); for (uint256 i = currentSubtreeIndex; i < m; i++) { queueSubRoot(z, 0, depth); } @@ -343,7 +344,7 @@ abstract contract AccQueue is Ownable, Hasher { uint256 n = subRootQueue.indices[_level]; - if (n != hashLength - 1) { + if (n != HASH_LENGTH - 1) { // Just store the leaf subRootQueue.levels[_level][n] = _leaf; subRootQueue.indices[_level]++; @@ -386,9 +387,9 @@ abstract contract AccQueue is Ownable, Hasher { if (_depth > MAX_DEPTH) revert DepthTooLarge(_depth, MAX_DEPTH); // Calculate the SRT depth - uint256 srtDepth = subDepth; + uint256 srtDepth = SUB_DEPTH; while (true) { - if (hashLength ** srtDepth >= numLeaves) { + if (HASH_LENGTH ** srtDepth >= numLeaves) { break; } srtDepth++; @@ -453,7 +454,7 @@ abstract contract AccQueue is Ownable, Hasher { /// using mergeSubRoots() and merge(). /// @return mainRoot The root of the main tree. function getMainRoot(uint256 _depth) public view returns (uint256 mainRoot) { - if (hashLength ** _depth < numLeaves) revert DepthTooSmall(_depth, numLeaves); + if (HASH_LENGTH ** _depth < numLeaves) revert DepthTooSmall(_depth, numLeaves); mainRoot = mainRoots[_depth]; } @@ -464,220 +465,3 @@ abstract contract AccQueue is Ownable, Hasher { current = currentSubtreeIndex; } } - -/// @title AccQueueBinary -/// @notice This contract defines a Merkle tree where each leaf insertion only updates a -/// subtree. To obtain the main tree root, the contract owner must merge the -/// subtrees together. Merging subtrees requires at least 2 operations: -/// mergeSubRoots(), and merge(). To get around the gas limit, -/// the mergeSubRoots() can be performed in multiple transactions. -/// @dev This contract is for a binary tree (2 leaves per node) -abstract contract AccQueueBinary is AccQueue { - /// @notice Create a new AccQueueBinary - constructor(uint256 _subDepth) AccQueue(_subDepth, 2) {} - - /// @notice Hash the contents of the specified level and the specified leaf. - /// @param _level The level to hash. - /// @param _leaf The leaf include with the level. - /// @return hashed The hash of the level and leaf. - function hashLevel(uint256 _level, uint256 _leaf) internal override returns (uint256 hashed) { - hashed = hashLeftRight(leafQueue.levels[_level][0], _leaf); - - // Free up storage slots to refund gas. - delete leafQueue.levels[_level][0]; - } - - /// @notice Hash the contents of the specified level and the specified leaf. - function hashLevelLeaf(uint256 _level, uint256 _leaf) public view override returns (uint256 hashed) { - hashed = hashLeftRight(leafQueue.levels[_level][0], _leaf); - } - - /// @notice An internal function which fills a subtree. - /// @param _level The level at which to fill the subtree. - function _fill(uint256 _level) internal override { - while (_level < subDepth) { - uint256 n = leafQueue.indices[_level]; - - if (n != 0) { - // Fill the subtree level with zeros and hash the level - uint256 hashed; - - uint256[2] memory inputs; - uint256 z = getZero(_level); - inputs[0] = leafQueue.levels[_level][0]; - inputs[1] = z; - hashed = hash2(inputs); - - // Update the subtree from the next level onwards with the new leaf - _enqueue(hashed, _level + 1); - } - - // Reset the current level - delete leafQueue.indices[_level]; - - _level++; - } - } -} - -/// @title AccQueueQuinary -/// @notice This contract defines a Merkle tree where each leaf insertion only updates a -/// subtree. To obtain the main tree root, the contract owner must merge the -/// subtrees together. Merging subtrees requires at least 2 operations: -/// mergeSubRoots(), and merge(). To get around the gas limit, -/// the mergeSubRoots() can be performed in multiple transactions. -/// @dev This contract is for a quinary tree (5 leaves per node) -abstract contract AccQueueQuinary is AccQueue { - /// @notice Create a new AccQueueQuinary instance - constructor(uint256 _subDepth) AccQueue(_subDepth, 5) {} - - /// @notice Hash the contents of the specified level and the specified leaf. - /// @dev it also frees up storage slots to refund gas. - /// @param _level The level to hash. - /// @param _leaf The leaf include with the level. - /// @return hashed The hash of the level and leaf. - function hashLevel(uint256 _level, uint256 _leaf) internal override returns (uint256 hashed) { - uint256[5] memory inputs; - inputs[0] = leafQueue.levels[_level][0]; - inputs[1] = leafQueue.levels[_level][1]; - inputs[2] = leafQueue.levels[_level][2]; - inputs[3] = leafQueue.levels[_level][3]; - inputs[4] = _leaf; - hashed = hash5(inputs); - - // Free up storage slots to refund gas. Note that using a loop here - // would result in lower gas savings. - delete leafQueue.levels[_level]; - } - - /// @notice Hash the contents of the specified level and the specified leaf. - /// @param _level The level to hash. - /// @param _leaf The leaf include with the level. - /// @return hashed The hash of the level and leaf. - function hashLevelLeaf(uint256 _level, uint256 _leaf) public view override returns (uint256 hashed) { - uint256[5] memory inputs; - inputs[0] = leafQueue.levels[_level][0]; - inputs[1] = leafQueue.levels[_level][1]; - inputs[2] = leafQueue.levels[_level][2]; - inputs[3] = leafQueue.levels[_level][3]; - inputs[4] = _leaf; - hashed = hash5(inputs); - } - - /// @notice An internal function which fills a subtree - /// @param _level The level at which to fill the subtree - function _fill(uint256 _level) internal override { - while (_level < subDepth) { - uint256 n = leafQueue.indices[_level]; - - if (n != 0) { - // Fill the subtree level with zeros and hash the level - uint256 hashed; - - uint256[5] memory inputs; - uint256 z = getZero(_level); - uint8 i = 0; - for (; i < n; i++) { - inputs[i] = leafQueue.levels[_level][i]; - } - - for (; i < hashLength; i++) { - inputs[i] = z; - } - hashed = hash5(inputs); - - // Update the subtree from the next level onwards with the new leaf - _enqueue(hashed, _level + 1); - } - - // Reset the current level - delete leafQueue.indices[_level]; - - _level++; - } - } -} - -/// @title AccQueueBinary0 -/// @notice This contract extends AccQueueBinary and MerkleBinary0 -/// @dev This contract is used for creating a -/// Merkle tree with binary (2 leaves per node) structure -contract AccQueueBinary0 is AccQueueBinary, MerkleBinary0 { - /// @notice Constructor for creating AccQueueBinary0 contract - /// @param _subDepth The depth of each subtree - constructor(uint256 _subDepth) AccQueueBinary(_subDepth) {} - - /// @notice Returns the zero leaf at a specified level - /// @param _level The level at which to return the zero leaf - /// @return zero The zero leaf at the specified level - function getZero(uint256 _level) internal view override returns (uint256 zero) { - zero = zeros[_level]; - } -} - -/// @title AccQueueBinaryMaci -/// @notice This contract extends AccQueueBinary and MerkleBinaryMaci -/// @dev This contract is used for creating a -/// Merkle tree with binary (2 leaves per node) structure -contract AccQueueBinaryMaci is AccQueueBinary, MerkleBinaryMaci { - /// @notice Constructor for creating AccQueueBinaryMaci contract - /// @param _subDepth The depth of each subtree - constructor(uint256 _subDepth) AccQueueBinary(_subDepth) {} - - /// @notice Returns the zero leaf at a specified level - /// @param _level The level at which to return the zero leaf - function getZero(uint256 _level) internal view override returns (uint256 zero) { - zero = zeros[_level]; - } -} - -/// @title AccQueueQuinary0 -/// @notice This contract extends AccQueueQuinary and MerkleQuinary0 -/// @dev This contract is used for creating a -/// Merkle tree with quinary (5 leaves per node) structure -contract AccQueueQuinary0 is AccQueueQuinary, MerkleQuinary0 { - /// @notice Constructor for creating AccQueueQuinary0 contract - /// @param _subDepth The depth of each subtree - constructor(uint256 _subDepth) AccQueueQuinary(_subDepth) {} - - /// @notice Returns the zero leaf at a specified level - /// @param _level The level at which to return the zero leaf - /// @return zero The zero leaf at the specified level - function getZero(uint256 _level) internal view override returns (uint256 zero) { - zero = zeros[_level]; - } -} - -/// @title AccQueueQuinaryMaci -/// @notice This contract extends AccQueueQuinary and MerkleQuinaryMaci -/// @dev This contract is used for creating a -/// Merkle tree with quinary (5 leaves per node) structure -contract AccQueueQuinaryMaci is AccQueueQuinary, MerkleQuinaryMaci { - /// @notice Constructor for creating AccQueueQuinaryMaci contract - /// @param _subDepth The depth of each subtree - constructor(uint256 _subDepth) AccQueueQuinary(_subDepth) {} - - /// @notice Returns the zero leaf at a specified level - /// @param _level The level at which to return the zero leaf - /// @return zero The zero leaf at the specified level - function getZero(uint256 _level) internal view override returns (uint256 zero) { - zero = zeros[_level]; - } -} - -/// @title AccQueueQuinaryBlankSl -/// @notice This contract extends AccQueueQuinary and MerkleQuinaryBlankSl -/// @dev This contract is used for creating a -/// Merkle tree with quinary (5 leaves per node) structure -contract AccQueueQuinaryBlankSl is AccQueueQuinary, MerkleQuinaryBlankSl { - /// @notice Constructor for creating AccQueueQuinaryBlankSl contract - /// @param _subDepth The depth of each subtree - constructor(uint256 _subDepth) AccQueueQuinary(_subDepth) {} - - /// @notice Returns the zero leaf at a specified level - /// @param _level The level at which to return the zero leaf - /// @return zero The zero leaf at the specified level - function getZero(uint256 _level) internal view override returns (uint256 zero) { - zero = zeros[_level]; - } -} diff --git a/contracts/contracts/trees/AccQueueBinary.sol b/contracts/contracts/trees/AccQueueBinary.sol new file mode 100644 index 0000000000..53beed17ca --- /dev/null +++ b/contracts/contracts/trees/AccQueueBinary.sol @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +import { AccQueue } from "./AccQueue.sol"; + +/// @title AccQueueBinary +/// @notice This contract defines a Merkle tree where each leaf insertion only updates a +/// subtree. To obtain the main tree root, the contract owner must merge the +/// subtrees together. Merging subtrees requires at least 2 operations: +/// mergeSubRoots(), and merge(). To get around the gas limit, +/// the mergeSubRoots() can be performed in multiple transactions. +/// @dev This contract is for a binary tree (2 leaves per node) +abstract contract AccQueueBinary is AccQueue { + /// @notice Create a new AccQueueBinary + constructor(uint256 _subDepth) AccQueue(_subDepth, 2) {} + + /// @notice Hash the contents of the specified level and the specified leaf. + /// @param _level The level to hash. + /// @param _leaf The leaf include with the level. + /// @return hashed The hash of the level and leaf. + function hashLevel(uint256 _level, uint256 _leaf) internal override returns (uint256 hashed) { + hashed = hashLeftRight(leafQueue.levels[_level][0], _leaf); + + // Free up storage slots to refund gas. + delete leafQueue.levels[_level][0]; + } + + /// @notice Hash the contents of the specified level and the specified leaf. + function hashLevelLeaf(uint256 _level, uint256 _leaf) public view override returns (uint256 hashed) { + hashed = hashLeftRight(leafQueue.levels[_level][0], _leaf); + } + + /// @notice An internal function which fills a subtree. + /// @param _level The level at which to fill the subtree. + function _fill(uint256 _level) internal override { + while (_level < SUB_DEPTH) { + uint256 n = leafQueue.indices[_level]; + + if (n != 0) { + // Fill the subtree level with zeros and hash the level + uint256 hashed; + + uint256[2] memory inputs; + uint256 z = getZero(_level); + inputs[0] = leafQueue.levels[_level][0]; + inputs[1] = z; + hashed = hash2(inputs); + + // Update the subtree from the next level onwards with the new leaf + _enqueue(hashed, _level + 1); + } + + // Reset the current level + delete leafQueue.indices[_level]; + + _level++; + } + } +} diff --git a/contracts/contracts/trees/AccQueueBinary0.sol b/contracts/contracts/trees/AccQueueBinary0.sol new file mode 100644 index 0000000000..93fe50ce56 --- /dev/null +++ b/contracts/contracts/trees/AccQueueBinary0.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +import { MerkleZeros as MerkleBinary0 } from "./zeros/MerkleBinary0.sol"; +import { AccQueueBinary } from "./AccQueueBinary.sol"; + +/// @title AccQueueBinary0 +/// @notice This contract extends AccQueueBinary and MerkleBinary0 +/// @dev This contract is used for creating a +/// Merkle tree with binary (2 leaves per node) structure +contract AccQueueBinary0 is AccQueueBinary, MerkleBinary0 { + /// @notice Constructor for creating AccQueueBinary0 contract + /// @param _subDepth The depth of each subtree + constructor(uint256 _subDepth) AccQueueBinary(_subDepth) {} + + /// @notice Returns the zero leaf at a specified level + /// @param _level The level at which to return the zero leaf + /// @return zero The zero leaf at the specified level + function getZero(uint256 _level) internal view override returns (uint256 zero) { + zero = zeros[_level]; + } +} diff --git a/contracts/contracts/trees/AccQueueBinaryMaci.sol b/contracts/contracts/trees/AccQueueBinaryMaci.sol new file mode 100644 index 0000000000..5d545f2b00 --- /dev/null +++ b/contracts/contracts/trees/AccQueueBinaryMaci.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +import { MerkleZeros as MerkleBinaryMaci } from "./zeros/MerkleBinaryMaci.sol"; +import { AccQueueBinary } from "./AccQueueBinary.sol"; + +/// @title AccQueueBinaryMaci +/// @notice This contract extends AccQueueBinary and MerkleBinaryMaci +/// @dev This contract is used for creating a +/// Merkle tree with binary (2 leaves per node) structure +contract AccQueueBinaryMaci is AccQueueBinary, MerkleBinaryMaci { + /// @notice Constructor for creating AccQueueBinaryMaci contract + /// @param _subDepth The depth of each subtree + constructor(uint256 _subDepth) AccQueueBinary(_subDepth) {} + + /// @notice Returns the zero leaf at a specified level + /// @param _level The level at which to return the zero leaf + function getZero(uint256 _level) internal view override returns (uint256 zero) { + zero = zeros[_level]; + } +} diff --git a/contracts/contracts/trees/AccQueueQuinary.sol b/contracts/contracts/trees/AccQueueQuinary.sol new file mode 100644 index 0000000000..63e185cf44 --- /dev/null +++ b/contracts/contracts/trees/AccQueueQuinary.sol @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +import { AccQueue } from "./AccQueue.sol"; + +/// @title AccQueueQuinary +/// @notice This contract defines a Merkle tree where each leaf insertion only updates a +/// subtree. To obtain the main tree root, the contract owner must merge the +/// subtrees together. Merging subtrees requires at least 2 operations: +/// mergeSubRoots(), and merge(). To get around the gas limit, +/// the mergeSubRoots() can be performed in multiple transactions. +/// @dev This contract is for a quinary tree (5 leaves per node) +abstract contract AccQueueQuinary is AccQueue { + /// @notice Create a new AccQueueQuinary instance + constructor(uint256 _subDepth) AccQueue(_subDepth, 5) {} + + /// @notice Hash the contents of the specified level and the specified leaf. + /// @dev it also frees up storage slots to refund gas. + /// @param _level The level to hash. + /// @param _leaf The leaf include with the level. + /// @return hashed The hash of the level and leaf. + function hashLevel(uint256 _level, uint256 _leaf) internal override returns (uint256 hashed) { + uint256[5] memory inputs; + inputs[0] = leafQueue.levels[_level][0]; + inputs[1] = leafQueue.levels[_level][1]; + inputs[2] = leafQueue.levels[_level][2]; + inputs[3] = leafQueue.levels[_level][3]; + inputs[4] = _leaf; + hashed = hash5(inputs); + + // Free up storage slots to refund gas. Note that using a loop here + // would result in lower gas savings. + delete leafQueue.levels[_level]; + } + + /// @notice Hash the contents of the specified level and the specified leaf. + /// @param _level The level to hash. + /// @param _leaf The leaf include with the level. + /// @return hashed The hash of the level and leaf. + function hashLevelLeaf(uint256 _level, uint256 _leaf) public view override returns (uint256 hashed) { + uint256[5] memory inputs; + inputs[0] = leafQueue.levels[_level][0]; + inputs[1] = leafQueue.levels[_level][1]; + inputs[2] = leafQueue.levels[_level][2]; + inputs[3] = leafQueue.levels[_level][3]; + inputs[4] = _leaf; + hashed = hash5(inputs); + } + + /// @notice An internal function which fills a subtree + /// @param _level The level at which to fill the subtree + function _fill(uint256 _level) internal override { + while (_level < SUB_DEPTH) { + uint256 n = leafQueue.indices[_level]; + + if (n != 0) { + // Fill the subtree level with zeros and hash the level + uint256 hashed; + + uint256[5] memory inputs; + uint256 z = getZero(_level); + uint8 i = 0; + for (; i < n; i++) { + inputs[i] = leafQueue.levels[_level][i]; + } + + for (; i < HASH_LENGTH; i++) { + inputs[i] = z; + } + hashed = hash5(inputs); + + // Update the subtree from the next level onwards with the new leaf + _enqueue(hashed, _level + 1); + } + + // Reset the current level + delete leafQueue.indices[_level]; + + _level++; + } + } +} diff --git a/contracts/contracts/trees/AccQueueQuinary0.sol b/contracts/contracts/trees/AccQueueQuinary0.sol new file mode 100644 index 0000000000..f8edfcfc04 --- /dev/null +++ b/contracts/contracts/trees/AccQueueQuinary0.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +import { MerkleZeros as MerkleQuinary0 } from "./zeros/MerkleQuinary0.sol"; +import { AccQueueQuinary } from "./AccQueueQuinary.sol"; + +/// @title AccQueueQuinary0 +/// @notice This contract extends AccQueueQuinary and MerkleQuinary0 +/// @dev This contract is used for creating a +/// Merkle tree with quinary (5 leaves per node) structure +contract AccQueueQuinary0 is AccQueueQuinary, MerkleQuinary0 { + /// @notice Constructor for creating AccQueueQuinary0 contract + /// @param _subDepth The depth of each subtree + constructor(uint256 _subDepth) AccQueueQuinary(_subDepth) {} + + /// @notice Returns the zero leaf at a specified level + /// @param _level The level at which to return the zero leaf + /// @return zero The zero leaf at the specified level + function getZero(uint256 _level) internal view override returns (uint256 zero) { + zero = zeros[_level]; + } +} diff --git a/contracts/contracts/trees/AccQueueQuinaryBlankSl.sol b/contracts/contracts/trees/AccQueueQuinaryBlankSl.sol new file mode 100644 index 0000000000..ca7e8c1741 --- /dev/null +++ b/contracts/contracts/trees/AccQueueQuinaryBlankSl.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +import { MerkleZeros as MerkleQuinaryBlankSl } from "./zeros/MerkleQuinaryBlankSl.sol"; +import { AccQueueQuinary } from "./AccQueueQuinary.sol"; + +/// @title AccQueueQuinaryBlankSl +/// @notice This contract extends AccQueueQuinary and MerkleQuinaryBlankSl +/// @dev This contract is used for creating a +/// Merkle tree with quinary (5 leaves per node) structure +contract AccQueueQuinaryBlankSl is AccQueueQuinary, MerkleQuinaryBlankSl { + /// @notice Constructor for creating AccQueueQuinaryBlankSl contract + /// @param _subDepth The depth of each subtree + constructor(uint256 _subDepth) AccQueueQuinary(_subDepth) {} + + /// @notice Returns the zero leaf at a specified level + /// @param _level The level at which to return the zero leaf + /// @return zero The zero leaf at the specified level + function getZero(uint256 _level) internal view override returns (uint256 zero) { + zero = zeros[_level]; + } +} diff --git a/contracts/contracts/trees/AccQueueQuinaryMaci.sol b/contracts/contracts/trees/AccQueueQuinaryMaci.sol new file mode 100644 index 0000000000..01980fc37a --- /dev/null +++ b/contracts/contracts/trees/AccQueueQuinaryMaci.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +import { MerkleZeros as MerkleQuinaryMaci } from "./zeros/MerkleQuinaryMaci.sol"; +import { AccQueueQuinary } from "./AccQueueQuinary.sol"; + +/// @title AccQueueQuinaryMaci +/// @notice This contract extends AccQueueQuinary and MerkleQuinaryMaci +/// @dev This contract is used for creating a +/// Merkle tree with quinary (5 leaves per node) structure +contract AccQueueQuinaryMaci is AccQueueQuinary, MerkleQuinaryMaci { + /// @notice Constructor for creating AccQueueQuinaryMaci contract + /// @param _subDepth The depth of each subtree + constructor(uint256 _subDepth) AccQueueQuinary(_subDepth) {} + + /// @notice Returns the zero leaf at a specified level + /// @param _level The level at which to return the zero leaf + /// @return zero The zero leaf at the specified level + function getZero(uint256 _level) internal view override returns (uint256 zero) { + zero = zeros[_level]; + } +} diff --git a/contracts/contracts/utilities/CommonUtilities.sol b/contracts/contracts/utilities/CommonUtilities.sol new file mode 100644 index 0000000000..4268366417 --- /dev/null +++ b/contracts/contracts/utilities/CommonUtilities.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +import { Poll } from "../Poll.sol"; + +/// @title CommonUtilities +/// @notice A contract that holds common utilities +/// which are to be used by multiple contracts +/// namely Subsidy, Tally and MessageProcessor +contract CommonUtilities { + error VotingPeriodNotPassed(); + + /// @notice common function for MessageProcessor, Tally and Subsidy + /// @param _poll the poll to be checked + function _votingPeriodOver(Poll _poll) internal view { + (uint256 deployTime, uint256 duration) = _poll.getDeployTimeAndDuration(); + // Require that the voting period is over + uint256 secondsPassed = block.timestamp - deployTime; + if (secondsPassed <= duration) { + revert VotingPeriodNotPassed(); + } + } +} diff --git a/contracts/contracts/utilities/DomainObjs.sol b/contracts/contracts/utilities/DomainObjs.sol index 6b65a52afc..e4d7858215 100644 --- a/contracts/contracts/utilities/DomainObjs.sol +++ b/contracts/contracts/utilities/DomainObjs.sol @@ -6,7 +6,7 @@ pragma solidity ^0.8.10; /// a number of domain objects and functions contract DomainObjs { /// @notice the length of a MACI message - uint8 constant MESSAGE_DATA_LENGTH = 10; + uint8 public constant MESSAGE_DATA_LENGTH = 10; /// @title Message /// @notice this struct represents a MACI message diff --git a/contracts/contracts/utilities/Params.sol b/contracts/contracts/utilities/Params.sol index e32f7f06e3..ccff030c68 100644 --- a/contracts/contracts/utilities/Params.sol +++ b/contracts/contracts/utilities/Params.sol @@ -4,7 +4,6 @@ pragma solidity ^0.8.10; import { IMACI } from "../interfaces/IMACI.sol"; import { AccQueue } from "../trees/AccQueue.sol"; import { TopupCredit } from "../TopupCredit.sol"; -import { VkRegistry } from "../VkRegistry.sol"; /// @title Params /// @notice This contracts contains a number of structures diff --git a/contracts/contracts/utilities/Utilities.sol b/contracts/contracts/utilities/Utilities.sol index b58e133c96..2b9231b20e 100644 --- a/contracts/contracts/utilities/Utilities.sol +++ b/contracts/contracts/utilities/Utilities.sol @@ -3,26 +3,6 @@ pragma solidity ^0.8.10; import { DomainObjs } from "./DomainObjs.sol"; import { Hasher } from "../crypto/Hasher.sol"; import { SnarkConstants } from "../crypto/SnarkConstants.sol"; -import { Poll } from "../Poll.sol"; - -/// @title CommonUtilities -/// @notice A contract that holds common utilities -/// which are to be used by multiple contracts -/// namely Subsidy, Tally and MessageProcessor -contract CommonUtilities { - error VotingPeriodNotPassed(); - - /// @notice common function for MessageProcessor, Tally and Subsidy - /// @param _poll the poll to be checked - function _votingPeriodOver(Poll _poll) internal view { - (uint256 deployTime, uint256 duration) = _poll.getDeployTimeAndDuration(); - // Require that the voting period is over - uint256 secondsPassed = block.timestamp - deployTime; - if (secondsPassed <= duration) { - revert VotingPeriodNotPassed(); - } - } -} /// @title Utilities /// @notice An utility contract that can be used to: @@ -30,6 +10,9 @@ contract CommonUtilities { /// * pad and hash a MACI message /// * hash a MACI message and an encryption public key contract Utilities is SnarkConstants, DomainObjs, Hasher { + /// @notice custom errors + error InvalidMessage(); + /// @notice An utility function used to hash a state leaf /// @param _stateLeaf the state leaf to be hashed /// @return ciphertext The hash of the state leaf @@ -56,7 +39,7 @@ contract Utilities is SnarkConstants, DomainObjs, Hasher { uint256[10] memory dat; dat[0] = dataToPad[0]; dat[1] = dataToPad[1]; - for (uint i = 2; i < 10; ) { + for (uint256 i = 2; i < 10; ) { dat[i] = 0; unchecked { ++i; @@ -75,7 +58,10 @@ contract Utilities is SnarkConstants, DomainObjs, Hasher { Message memory _message, PubKey memory _encPubKey ) public pure returns (uint256 msgHash) { - require(_message.data.length == 10, "Invalid message"); + if (_message.data.length != 10) { + revert InvalidMessage(); + } + uint256[5] memory n; n[0] = _message.data[0]; n[1] = _message.data[1]; diff --git a/contracts/ts/abi.ts b/contracts/ts/abi.ts index 52805211bc..51ba90ae57 100644 --- a/contracts/ts/abi.ts +++ b/contracts/ts/abi.ts @@ -26,7 +26,7 @@ export const parseArtifact = (filename: string): [TAbi, string] => { } if (filename.includes("AccQueue")) { - filePath += "trees/AccQueue.sol/"; + filePath += `trees/${filename}.sol/`; } if (filename.includes("Poll") || filename.includes("MessageAq")) { diff --git a/package.json b/package.json index 4168b6e438..d08f740a7d 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,8 @@ "prettier:fix": "prettier -w .", "lint:ts": "eslint './**/**/*.ts' './**/**/*.tsx'", "lint:ts:fix": "npm run lint:ts -- --fix", - "lint:sol": "solhint './contracts/**/*.sol'", - "lint:sol:fix": "npm run lint:sol -- --fix", + "lint:sol": "solhint './contracts/contracts/**/*.sol'", + "lint:sol:fix": "npm run lint:sol -- --fix --noPrompt", "test:cli": "lerna run test --scope \"maci-cli\"", "test:integration": "lerna run test --scope \"maci-integrationtests\"", "test": "lerna run test --ignore maci-integrationtests --ignore maci-cli", From bfecd5be779b5564d0a4436ad7725d2aedcbb320 Mon Sep 17 00:00:00 2001 From: Anton <14254374+0xmad@users.noreply.github.com> Date: Fri, 5 Jan 2024 21:33:04 -0600 Subject: [PATCH 29/37] fix(cli): signup loop length --- cli/tests/e2e.subsidy.test.ts | 66 +++++++++++++++++++++-------------- cli/tests/e2e.test.ts | 49 ++++++++++++++++---------- 2 files changed, 69 insertions(+), 46 deletions(-) diff --git a/cli/tests/e2e.subsidy.test.ts b/cli/tests/e2e.subsidy.test.ts index 58ba69e62f..45f23bf784 100644 --- a/cli/tests/e2e.subsidy.test.ts +++ b/cli/tests/e2e.subsidy.test.ts @@ -170,10 +170,12 @@ describe("e2e with Subsidy tests", function test() { ); }); - it("should signup four users", () => { - users.forEach(async (user) => { - await signup(user.pubKey.serialize()); - }); + it("should signup four users", async () => { + // eslint-disable-next-line @typescript-eslint/prefer-for-of + for (let i = 0; i < users.length; i += 1) { + // eslint-disable-next-line no-await-in-loop + await signup(users[i].pubKey.serialize()); + } }); it("should publish six messages", async () => { @@ -315,10 +317,12 @@ describe("e2e with Subsidy tests", function test() { ); }); - it("should signup nine users", () => { - users.forEach(async (user) => { - await signup(user.pubKey.serialize()); - }); + it("should signup nine users", async () => { + // eslint-disable-next-line @typescript-eslint/prefer-for-of + for (let i = 0; i < users.length; i += 1) { + // eslint-disable-next-line no-await-in-loop + await signup(users[i].pubKey.serialize()); + } }); it("should publish one message", async () => { @@ -479,10 +483,12 @@ describe("e2e with Subsidy tests", function test() { ); }); - it("should signup four users", () => { - users.forEach(async (user) => { - await signup(user.pubKey.serialize()); - }); + it("should signup four users", async () => { + // eslint-disable-next-line @typescript-eslint/prefer-for-of + for (let i = 0; i < users.length; i += 1) { + // eslint-disable-next-line no-await-in-loop + await signup(users[i].pubKey.serialize()); + } }); it("should publish four messages", async () => { @@ -592,10 +598,12 @@ describe("e2e with Subsidy tests", function test() { ); }); - it("should signup five users", () => { - users.forEach(async (user) => { - await signup(user.pubKey.serialize()); - }); + it("should signup five users", async () => { + // eslint-disable-next-line @typescript-eslint/prefer-for-of + for (let i = 0; i < users.length; i += 1) { + // eslint-disable-next-line no-await-in-loop + await signup(users[i].pubKey.serialize()); + } }); it("should publish five messages", async () => { @@ -820,26 +828,29 @@ describe("e2e with Subsidy tests", function test() { }); it("should signup an user", async () => { + // eslint-disable-next-line @typescript-eslint/prefer-for-of for (let i = 0; i < 6; i += 1) { // eslint-disable-next-line no-await-in-loop await signup(publishArgs[i].pubkey); } }); - it("should publish all messages", () => { - publishArgs.forEach(async (arg) => { + it("should publish all messages", async () => { + // eslint-disable-next-line @typescript-eslint/prefer-for-of + for (let i = 0; i < publishArgs.length; i += 1) { + // eslint-disable-next-line no-await-in-loop await publish( - arg.pubkey, - arg.stateIndex, - arg.voteOptionIndex, - arg.nonce, - arg.pollId, - arg.newVoteWeight, + publishArgs[i].pubkey, + publishArgs[i].stateIndex, + publishArgs[i].voteOptionIndex, + publishArgs[i].nonce, + publishArgs[i].pollId, + publishArgs[i].newVoteWeight, maciAddresses.maciAddress, genRandomSalt().toString(), - arg.privateKey, + publishArgs[i].privateKey, ); - }); + } }); it("should generate zk-SNARK proofs and verify them", async () => { @@ -1039,7 +1050,8 @@ describe("e2e with Subsidy tests", function test() { coordinatorPubKey, ); // signup - for (let i = 0; i < 7; i += 1) { + // eslint-disable-next-line @typescript-eslint/prefer-for-of + for (let i = 0; i < users.length; i += 1) { // eslint-disable-next-line no-await-in-loop await signup(users[i].pubKey.serialize()); } diff --git a/cli/tests/e2e.test.ts b/cli/tests/e2e.test.ts index 1ae0d91fd5..87dd48e779 100644 --- a/cli/tests/e2e.test.ts +++ b/cli/tests/e2e.test.ts @@ -183,10 +183,12 @@ describe("e2e tests", function test() { ); }); - it("should signup four users", () => { - users.forEach(async (user) => { - await signup(user.pubKey.serialize()); - }); + it("should signup four users", async () => { + // eslint-disable-next-line @typescript-eslint/prefer-for-of + for (let i = 0; i < users.length; i += 1) { + // eslint-disable-next-line no-await-in-loop + await signup(users[i].pubKey.serialize()); + } }); it("should publish six messages", async () => { @@ -327,10 +329,12 @@ describe("e2e tests", function test() { ); }); - it("should signup nine users", () => { - users.forEach(async (user) => { - await signup(user.pubKey.serialize()); - }); + it("should signup nine users", async () => { + // eslint-disable-next-line @typescript-eslint/prefer-for-of + for (let i = 0; i < users.length; i += 1) { + // eslint-disable-next-line no-await-in-loop + await signup(users[i].pubKey.serialize()); + } }); it("should publish one message", async () => { @@ -489,10 +493,12 @@ describe("e2e tests", function test() { ); }); - it("should signup four users", () => { - users.forEach(async (user) => { - await signup(user.pubKey.serialize()); - }); + it("should signup four users", async () => { + // eslint-disable-next-line @typescript-eslint/prefer-for-of + for (let i = 0; i < users.length; i += 1) { + // eslint-disable-next-line no-await-in-loop + await signup(users[i].pubKey.serialize()); + } }); it("should publish four messages", async () => { @@ -601,10 +607,12 @@ describe("e2e tests", function test() { ); }); - it("should signup five users", () => { - users.forEach(async (user) => { - await signup(user.pubKey.serialize()); - }); + it("should signup five users", async () => { + // eslint-disable-next-line @typescript-eslint/prefer-for-of + for (let i = 0; i < users.length; i += 1) { + // eslint-disable-next-line no-await-in-loop + await signup(users[i].pubKey.serialize()); + } }); it("should publish five messages", async () => { @@ -974,10 +982,13 @@ describe("e2e tests", function test() { VOTE_OPTION_TREE_DEPTH, coordinatorPubKey, ); + // signup - users.forEach(async (user) => { - await signup(user.pubKey.serialize()); - }); + // eslint-disable-next-line @typescript-eslint/prefer-for-of + for (let i = 0; i < users.length; i += 1) { + // eslint-disable-next-line no-await-in-loop + await signup(users[i].pubKey.serialize()); + } // publish await publish( From 0af7dd2d448c4796c3872665d43654343f9fc3e3 Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Fri, 5 Jan 2024 18:42:30 +0000 Subject: [PATCH 30/37] refactor(core): refactor the core package subsidy and tally functions Refactor the last few functions left inside the Poll.ts file, as well as add interfaces for circuit inputs --- circuits/ts/__tests__/CeremonyParams.test.ts | 2 +- circuits/ts/__tests__/TallyVotes.test.ts | 6 +- cli/ts/commands/genProofs.ts | 10 +- contracts/tests/MessageProcessor.test.ts | 12 +- contracts/tests/Subsidy.test.ts | 10 +- contracts/tests/Tally.test.ts | 16 ++- core/ts/Poll.ts | 144 +++++++++---------- core/ts/__tests__/MaciState.test.ts | 82 ++--------- core/ts/index.ts | 14 +- core/ts/utils/types.ts | 82 ++++++++++- core/ts/utils/utils.ts | 6 +- integrationTests/package.json | 2 +- 12 files changed, 206 insertions(+), 180 deletions(-) diff --git a/circuits/ts/__tests__/CeremonyParams.test.ts b/circuits/ts/__tests__/CeremonyParams.test.ts index 9dc8ba2609..60fcec82ba 100644 --- a/circuits/ts/__tests__/CeremonyParams.test.ts +++ b/circuits/ts/__tests__/CeremonyParams.test.ts @@ -277,7 +277,7 @@ describe("Ceremony param tests", () => { randIdx = generateRandomIndex(Object.keys(generatedInputs).length); } - (generatedInputs.currentResults as string[])[randIdx] = "1"; + generatedInputs.currentResults[randIdx] = "1"; const witness = await testCircuit.calculateWitness(generatedInputs); await testCircuit.checkConstraints(witness); }); diff --git a/circuits/ts/__tests__/TallyVotes.test.ts b/circuits/ts/__tests__/TallyVotes.test.ts index 60683417c4..a6a52cece1 100644 --- a/circuits/ts/__tests__/TallyVotes.test.ts +++ b/circuits/ts/__tests__/TallyVotes.test.ts @@ -117,7 +117,7 @@ describe("TallyVotes circuit", function test() { randIdx = generateRandomIndex(Object.keys(generatedInputs).length); } - (generatedInputs.currentResults as string[])[randIdx] = "1"; + generatedInputs.currentResults[randIdx] = "1"; const witness = await circuit.calculateWitness(generatedInputs); await circuit.checkConstraints(witness); }); @@ -176,9 +176,9 @@ describe("TallyVotes circuit", function test() { // currentSpentVoiceCreditSubtotal, and // currentPerVOSpentVoiceCredits if (i === 0) { - (generatedInputs.currentResults as string[])[0] = "123"; + generatedInputs.currentResults[0] = "123"; generatedInputs.currentSpentVoiceCreditSubtotal = "456"; - (generatedInputs.currentPerVOSpentVoiceCredits as string[])[0] = "789"; + generatedInputs.currentPerVOSpentVoiceCredits[0] = "789"; } // eslint-disable-next-line no-await-in-loop diff --git a/cli/ts/commands/genProofs.ts b/cli/ts/commands/genProofs.ts index c8ac630c5f..4083f1031e 100644 --- a/cli/ts/commands/genProofs.ts +++ b/cli/ts/commands/genProofs.ts @@ -236,7 +236,7 @@ export const genProofs = async ( let maciState: MaciState | undefined; if (stateFile) { - const content = JSON.parse(fs.readFileSync(stateFile).toString()) as IJsonMaciState; + const content = JSON.parse(fs.readFileSync(stateFile).toString()) as unknown as IJsonMaciState; const serializedPrivateKey = maciPrivKey.serialize(); try { @@ -287,7 +287,7 @@ export const genProofs = async ( // while we have unprocessed messages, process them while (poll.hasUnprocessedMessages()) { // process messages in batches - const circuitInputs = poll.processMessages(pollId); + const circuitInputs = poll.processMessages(pollId) as unknown as CircuitInputs; try { // generate the proof for this batch // eslint-disable-next-line no-await-in-loop @@ -345,13 +345,11 @@ export const genProofs = async ( let numBatchesCalulated = 0; - // @todo fix types in the circuits package - // @todo why this next part works let subsidyCircuitInputs: CircuitInputs; // calculate the subsidy for each batch while (poll.hasUnfinishedSubsidyCalculation()) { // calculate subsidy in batches - subsidyCircuitInputs = poll.subsidyPerBatch(); + subsidyCircuitInputs = poll.subsidyPerBatch() as unknown as CircuitInputs; try { // generate proof for this batch // eslint-disable-next-line no-await-in-loop @@ -423,7 +421,7 @@ export const genProofs = async ( // tally all ballots for this poll while (poll.hasUntalliedBallots()) { // tally votes in batches - tallyCircuitInputs = poll.tallyVotes(); + tallyCircuitInputs = poll.tallyVotes() as unknown as CircuitInputs; try { // generate the proof diff --git a/contracts/tests/MessageProcessor.test.ts b/contracts/tests/MessageProcessor.test.ts index 35c9b40d48..988ec55fa0 100644 --- a/contracts/tests/MessageProcessor.test.ts +++ b/contracts/tests/MessageProcessor.test.ts @@ -2,7 +2,13 @@ import { expect } from "chai"; import { BaseContract, Signer } from "ethers"; import { EthereumProvider } from "hardhat/types"; -import { MaciState, Poll, STATE_TREE_DEPTH, packProcessMessageSmallVals } from "maci-core"; +import { + MaciState, + Poll, + STATE_TREE_DEPTH, + packProcessMessageSmallVals, + IProcessMessagesCircuitInputs, +} from "maci-core"; import { NOTHING_UP_MY_SLEEVE } from "maci-crypto"; import { Keypair, Message, PubKey } from "maci-domainobjs"; @@ -36,7 +42,7 @@ describe("MessageProcessor", () => { const maciState = new MaciState(STATE_TREE_DEPTH); let signer: Signer; - let generatedInputs: { newSbCommitment: bigint }; + let generatedInputs: IProcessMessagesCircuitInputs; const coordinator = new Keypair(); const users = [new Keypair(), new Keypair()]; @@ -87,7 +93,7 @@ describe("MessageProcessor", () => { maciState.polls[pollId].publishMessage(message, padKey); poll = maciState.polls[pollId]; - generatedInputs = poll.processMessages(pollId) as typeof generatedInputs; + generatedInputs = poll.processMessages(pollId); // set the verification keys on the vk smart contract const vkContract = r.vkRegistryContract; diff --git a/contracts/tests/Subsidy.test.ts b/contracts/tests/Subsidy.test.ts index 95f43a0d0a..4bde80c2b3 100644 --- a/contracts/tests/Subsidy.test.ts +++ b/contracts/tests/Subsidy.test.ts @@ -2,7 +2,7 @@ import { expect } from "chai"; import { BaseContract, Signer } from "ethers"; import { EthereumProvider } from "hardhat/types"; -import { MaciState, Poll, packSubsidySmallVals } from "maci-core"; +import { MaciState, Poll, packSubsidySmallVals, IProcessMessagesCircuitInputs, ISubsidyCircuitInputs } from "maci-core"; import { NOTHING_UP_MY_SLEEVE } from "maci-crypto"; import { Keypair, Message, PubKey } from "maci-domainobjs"; @@ -37,7 +37,7 @@ describe("Subsidy", () => { let pollId: number; let poll: Poll; - let generatedInputs: { newSbCommitment: bigint }; + let generatedInputs: IProcessMessagesCircuitInputs; before(async () => { signer = await getDefaultSigner(); @@ -87,7 +87,7 @@ describe("Subsidy", () => { poll = maciState.polls[pollId]; // process messages locally - generatedInputs = poll.processMessages(pollId) as typeof generatedInputs; + generatedInputs = poll.processMessages(pollId); // set the verification keys on the vk smart contract const vkContract = r.vkRegistryContract; @@ -145,14 +145,14 @@ describe("Subsidy", () => { }); describe("after merging acc queues", () => { - let subsidyGeneratedInputs: { newSubsidyCommitment: bigint }; + let subsidyGeneratedInputs: ISubsidyCircuitInputs; before(async () => { await pollContract.mergeMaciStateAqSubRoots(0, pollId); await pollContract.mergeMaciStateAq(0); await pollContract.mergeMessageAqSubRoots(0); await pollContract.mergeMessageAq(); - subsidyGeneratedInputs = poll.subsidyPerBatch() as { newSubsidyCommitment: bigint }; + subsidyGeneratedInputs = poll.subsidyPerBatch(); }); it("updateSubsidy() should update the tally commitment", async () => { // do the processing on the message processor contract diff --git a/contracts/tests/Tally.test.ts b/contracts/tests/Tally.test.ts index 3f1ef77b50..80fde86c59 100644 --- a/contracts/tests/Tally.test.ts +++ b/contracts/tests/Tally.test.ts @@ -2,7 +2,13 @@ import { expect } from "chai"; import { BaseContract, Signer } from "ethers"; import { EthereumProvider } from "hardhat/types"; -import { MaciState, Poll, packTallyVotesSmallVals } from "maci-core"; +import { + MaciState, + Poll, + packTallyVotesSmallVals, + IProcessMessagesCircuitInputs, + ITallyCircuitInputs, +} from "maci-core"; import { NOTHING_UP_MY_SLEEVE } from "maci-crypto"; import { Keypair, Message, PubKey } from "maci-domainobjs"; @@ -39,7 +45,7 @@ describe("TallyVotes", () => { let pollId: number; let poll: Poll; - let generatedInputs: { newSbCommitment: bigint }; + let generatedInputs: IProcessMessagesCircuitInputs; before(async () => { signer = await getDefaultSigner(); @@ -89,7 +95,7 @@ describe("TallyVotes", () => { poll = maciState.polls[pollId]; // process messages locally - generatedInputs = poll.processMessages(pollId) as typeof generatedInputs; + generatedInputs = poll.processMessages(pollId); // set the verification keys on the vk smart contract const vkContract = r.vkRegistryContract; @@ -140,14 +146,14 @@ describe("TallyVotes", () => { }); describe("after merging acc queues", () => { - let tallyGeneratedInputs: { newTallyCommitment: bigint }; + let tallyGeneratedInputs: ITallyCircuitInputs; before(async () => { await pollContract.mergeMaciStateAqSubRoots(0, pollId); await pollContract.mergeMaciStateAq(0); await pollContract.mergeMessageAqSubRoots(0); await pollContract.mergeMessageAq(); - tallyGeneratedInputs = poll.tallyVotes() as { newTallyCommitment: bigint }; + tallyGeneratedInputs = poll.tallyVotes(); }); it("tallyVotes() should update the tally commitment", async () => { // do the processing on the message processor contract diff --git a/core/ts/Poll.ts b/core/ts/Poll.ts index c7beade4d8..f254b07925 100644 --- a/core/ts/Poll.ts +++ b/core/ts/Poll.ts @@ -32,7 +32,7 @@ import assert from "assert"; import type { MaciState } from "./MaciState"; import type { PathElements } from "maci-crypto"; -import { STATE_TREE_ARITY, MESSAGE_TREE_ARITY, VOTE_OPTION_TREE_ARITY } from "./utils/constants"; +import { STATE_TREE_ARITY, MESSAGE_TREE_ARITY } from "./utils/constants"; import { ProcessMessageErrors, ProcessMessageError } from "./utils/errors"; import { CircuitInputs, @@ -42,6 +42,9 @@ import { IPoll, IJsonPoll, IProcessMessagesOutput, + ITallyCircuitInputs, + ISubsidyCircuitInputs, + IProcessMessagesCircuitInputs, } from "./utils/types"; import { packTallyVotesSmallVals, packSubsidySmallVals } from "./utils/utils"; @@ -407,7 +410,7 @@ export class Poll implements IPoll { * process * @returns stringified circuit inputs */ - processMessages = (pollId: number): CircuitInputs => { + processMessages = (pollId: number): IProcessMessagesCircuitInputs => { assert(this.hasUnprocessedMessages(), "No more messages to process"); const batchSize = this.batchSizes.messageBatchSize; @@ -530,12 +533,7 @@ export class Poll implements IPoll { currentVoteWeights.unshift(this.ballots[0].votes[0]); // create a new quinary tree and add an empty vote - const vt = new IncrementalQuinTree( - this.treeDepths.voteOptionTreeDepth, - BigInt(0), - STATE_TREE_ARITY, - hash5, - ); + const vt = new IncrementalQuinTree(this.treeDepths.voteOptionTreeDepth, 0n, STATE_TREE_ARITY, hash5); vt.insert(this.ballots[0].votes[0]); // get the path elements for this empty vote weight leaf currentVoteWeightsPathElements.unshift(vt.genMerklePath(0).pathElements); @@ -570,12 +568,7 @@ export class Poll implements IPoll { currentVoteWeights.unshift(currentBallot.votes[0]); // create a quinary tree to fill with the votes of the current ballot - const vt = new IncrementalQuinTree( - this.treeDepths.voteOptionTreeDepth, - BigInt(0), - STATE_TREE_ARITY, - hash5, - ); + const vt = new IncrementalQuinTree(this.treeDepths.voteOptionTreeDepth, 0n, STATE_TREE_ARITY, hash5); for (let j = 0; j < this.ballots[0].votes.length; j += 1) { vt.insert(currentBallot.votes[j]); @@ -660,7 +653,8 @@ export class Poll implements IPoll { if (this.numBatchesProcessed * batchSize >= this.messages.length) { this.maciStateRef.pollBeingProcessed = false; } - return stringifyBigInts(circuitInputs) as CircuitInputs; + + return stringifyBigInts(circuitInputs) as unknown as IProcessMessagesCircuitInputs; }; /** @@ -777,10 +771,7 @@ export class Poll implements IPoll { * Checks whether there are any untallied ballots. * @returns Whether there are any untallied ballots */ - hasUntalliedBallots = (): boolean => { - const batchSize = this.batchSizes.tallyBatchSize; - return this.numBatchesTallied * batchSize < this.ballots.length; - }; + hasUntalliedBallots = (): boolean => this.numBatchesTallied * this.batchSizes.tallyBatchSize < this.ballots.length; /** * This method checks if there are any unfinished subsidy calculations. @@ -798,7 +789,7 @@ export class Poll implements IPoll { * This method calculates the subsidy per batch. * @returns Returns an array of big integers which represent the circuit inputs for the subsidy calculation. */ - subsidyPerBatch = (): CircuitInputs => { + subsidyPerBatch = (): ISubsidyCircuitInputs => { const batchSize = this.batchSizes.subsidyBatchSize; assert(this.hasUnfinishedSubsidyCalculation(), "No more subsidy batches to calculate"); @@ -854,10 +845,10 @@ export class Poll implements IPoll { votes2: ballots2.map((x) => x.votes), ballotPathElements1: ballotSubrootProof1!.pathElements, ballotPathElements2: ballotSubrootProof2!.pathElements, - }); + }) as unknown as ISubsidyCircuitInputs; this.increaseSubsidyIndex(); - return circuitInputs as CircuitInputs; + return circuitInputs; }; /** @@ -865,6 +856,7 @@ export class Poll implements IPoll { */ private increaseSubsidyIndex = (): void => { const batchSize = this.batchSizes.subsidyBatchSize; + if (this.cbi * batchSize + batchSize < this.ballots.length) { this.cbi += 1; } else { @@ -882,6 +874,7 @@ export class Poll implements IPoll { private previousSubsidyIndexToString = (): string => { const batchSize = this.batchSizes.subsidyBatchSize; const numBatches = Math.ceil(this.ballots.length / batchSize); + let { cbi } = this; let { rbi } = this; @@ -895,6 +888,7 @@ export class Poll implements IPoll { rbi -= 1; cbi = numBatches - 1; } + return `${rbi.toString()}-${cbi.toString()}`; }; @@ -908,7 +902,7 @@ export class Poll implements IPoll { private coefficientCalculation = (rowBallot: Ballot, colBallot: Ballot): bigint => { let sum = BigInt(0); for (let p = 0; p < this.maxValues.maxVoteOptions; p += 1) { - sum += BigInt(rowBallot.votes[p].valueOf()) * BigInt(colBallot.votes[p].valueOf()); + sum += BigInt(rowBallot.votes[p].valueOf()) * colBallot.votes[p]; } const res = BigInt(this.MM * 10 ** this.WW) / (BigInt(this.MM) + BigInt(sum)); return res; @@ -946,7 +940,7 @@ export class Poll implements IPoll { const vip = BigInt(rowBallot.votes[p].valueOf()); const vjp = BigInt(colBallot.votes[p].valueOf()); if (rowStartIndex !== colStartIndex || (rowStartIndex === colStartIndex && i < j)) { - this.subsidy[p] = BigInt(this.subsidy[p].valueOf()) + BigInt(2) * BigInt(kij.valueOf()) * vip * vjp; + this.subsidy[p] += 2n * kij * vip * vjp; } } } @@ -959,15 +953,16 @@ export class Poll implements IPoll { * This method tallies a ballots and updates the tally results. * @returns the circuit inputs for the TallyVotes circuit. */ - tallyVotes = (): CircuitInputs => { + tallyVotes = (): ITallyCircuitInputs => { const batchSize = this.batchSizes.tallyBatchSize; assert(this.hasUntalliedBallots(), "No more ballots to tally"); + // calculate where we start tallying next const batchStartIndex = this.numBatchesTallied * batchSize; - const currentResultsRootSalt = - batchStartIndex === 0 ? BigInt(0) : this.resultRootSalts[batchStartIndex - batchSize]; + // get the salts needed for the commitments + const currentResultsRootSalt = batchStartIndex === 0 ? 0n : this.resultRootSalts[batchStartIndex - batchSize]; const currentPerVOSpentVoiceCreditsRootSalt = batchStartIndex === 0 ? BigInt(0) : this.preVOSpentVoiceCreditsRootSalts[batchStartIndex - batchSize]; @@ -975,18 +970,32 @@ export class Poll implements IPoll { const currentSpentVoiceCreditSubtotalSalt = batchStartIndex === 0 ? BigInt(0) : this.spentVoiceCreditSubtotalSalts[batchStartIndex - batchSize]; - const currentResultsCommitment = this.genResultsCommitment(currentResultsRootSalt); + // generate a commitment to the current results + const currentResultsCommitment = genTreeCommitment( + this.tallyResult, + currentResultsRootSalt, + this.treeDepths.voteOptionTreeDepth, + ); + // generate a commitment to the current per VO spent voice credits const currentPerVOSpentVoiceCreditsCommitment = this.genPerVOSpentVoiceCreditsCommitment( currentPerVOSpentVoiceCreditsRootSalt, batchStartIndex, ); + // generate a commitment to the current spent voice credits const currentSpentVoiceCreditsCommitment = this.genSpentVoiceCreditSubtotalCommitment( currentSpentVoiceCreditSubtotalSalt, batchStartIndex, ); + // the current commitment for the first batch will be 0 + // otherwise calculate as + // hash([ + // currentResultsCommitment, + // currentSpentVoiceCreditsCommitment, + // currentPerVOSpentVoiceCreditsCommitment + // ]) const currentTallyCommitment = batchStartIndex === 0 ? BigInt(0) @@ -1001,56 +1010,75 @@ export class Poll implements IPoll { const currentPerVOSpentVoiceCredits = this.perVOSpentVoiceCredits.map((x) => BigInt(x.toString())); const currentSpentVoiceCreditSubtotal = BigInt(this.totalSpentVoiceCredits.toString()); + // loop in normal order to tally the ballots one by one for (let i = this.numBatchesTallied * batchSize; i < this.numBatchesTallied * batchSize + batchSize; i += 1) { + // we stop if we have no more ballots to tally if (i >= this.ballots.length) { break; } + // save to the local ballot array ballots.push(this.ballots[i]); + // for each possible vote option we loop and calculate for (let j = 0; j < this.maxValues.maxVoteOptions; j += 1) { - const v = BigInt(`${this.ballots[i].votes[j]}`); + const v = this.ballots[i].votes[j]; - this.tallyResult[j] = BigInt(`${this.tallyResult[j]}`) + v; + // the vote itself will be a quadratic vote (sqrt(voiceCredits)) + this.tallyResult[j] += v; - this.perVOSpentVoiceCredits[j] = BigInt(`${this.perVOSpentVoiceCredits[j]}`) + BigInt(v) * BigInt(v); + // the per vote option spent voice credits will be the sum of the squares of the votes + this.perVOSpentVoiceCredits[j] += v * v; - this.totalSpentVoiceCredits = BigInt(`${this.totalSpentVoiceCredits}`) + BigInt(v) * BigInt(v); + // the total spent voice credits will be the sum of the squares of the votes + this.totalSpentVoiceCredits += v * v; } } const emptyBallot = new Ballot(this.maxValues.maxVoteOptions, this.treeDepths.voteOptionTreeDepth); + // pad the ballots array while (ballots.length < batchSize) { ballots.push(emptyBallot); } + // generate the new salts const newResultsRootSalt = genRandomSalt(); const newPerVOSpentVoiceCreditsRootSalt = genRandomSalt(); const newSpentVoiceCreditSubtotalSalt = genRandomSalt(); + // and save them to be used in the next batch this.resultRootSalts[batchStartIndex] = newResultsRootSalt; this.preVOSpentVoiceCreditsRootSalts[batchStartIndex] = newPerVOSpentVoiceCreditsRootSalt; this.spentVoiceCreditSubtotalSalts[batchStartIndex] = newSpentVoiceCreditSubtotalSalt; - const newResultsCommitment = this.genResultsCommitment(newResultsRootSalt); + // generate the new results commitment with the new salts and data + const newResultsCommitment = genTreeCommitment( + this.tallyResult, + newResultsRootSalt, + this.treeDepths.voteOptionTreeDepth, + ); + // generate the new spent voice credits commitment with the new salts and data const newSpentVoiceCreditsCommitment = this.genSpentVoiceCreditSubtotalCommitment( newSpentVoiceCreditSubtotalSalt, batchStartIndex + batchSize, ); + // generate the new per VO spent voice credits commitment with the new salts and data const newPerVOSpentVoiceCreditsCommitment = this.genPerVOSpentVoiceCreditsCommitment( newPerVOSpentVoiceCreditsRootSalt, batchStartIndex + batchSize, ); + // generate the new tally commitment const newTallyCommitment = hash3([ newResultsCommitment, newSpentVoiceCreditsCommitment, newPerVOSpentVoiceCreditsCommitment, ]); + // cache vars const stateRoot = this.stateTree!.root; const ballotRoot = this.ballotTree!.root; const sbSalt = this.sbSalts[this.currentMessageBatchIndex!]; @@ -1084,32 +1112,11 @@ export class Poll implements IPoll { newResultsRootSalt, newPerVOSpentVoiceCreditsRootSalt, newSpentVoiceCreditSubtotalSalt, - }); + }) as unknown as ITallyCircuitInputs; this.numBatchesTallied += 1; - return circuitInputs as CircuitInputs; - }; - - /** - * This method generates a commitment to the votes per option. - * This is the hash of the Merkle root of the votes and a salt, computed as Poseidon([root, _salt]). - * @param _salt - The salt used in the hash function. - * @returns Returns the hash of the Merkle root of the votes and a salt, computed as Poseidon([root, _salt]). - */ - private genResultsCommitment = (salt: bigint): bigint => { - const resultsTree = new IncrementalQuinTree( - this.treeDepths.voteOptionTreeDepth, - BigInt(0), - VOTE_OPTION_TREE_ARITY, - hash5, - ); - - this.tallyResult.forEach((r) => { - resultsTree.insert(r); - }); - - return hashLeftRight(resultsTree.root, salt); + return circuitInputs; }; /** @@ -1145,34 +1152,21 @@ export class Poll implements IPoll { * @returns Returns the hash of the Merkle root of the spent voice credits per vote option and a salt, computed as Poseidon([root, _salt]). */ private genPerVOSpentVoiceCreditsCommitment = (salt: bigint, numBallotsToCount: number): bigint => { - const resultsTree = new IncrementalQuinTree( - this.treeDepths.voteOptionTreeDepth, - BigInt(0), - VOTE_OPTION_TREE_ARITY, - hash5, - ); - - const leaves: bigint[] = []; - - this.tallyResult.forEach(() => { - leaves.push(BigInt(0)); - }); + const leaves: bigint[] = Array(this.tallyResult.length).fill(0n); for (let i = 0; i < numBallotsToCount; i += 1) { + // check that is a valid index if (i >= this.ballots.length) { break; } + for (let j = 0; j < this.tallyResult.length; j += 1) { - const v = BigInt(`${this.ballots[i].votes[j]}`); - leaves[j] = BigInt(`${leaves[j]}`) + v * v; + const v = this.ballots[i].votes[j]; + leaves[j] += v * v; } } - leaves.forEach((leaf) => { - resultsTree.insert(leaf); - }); - - return hashLeftRight(resultsTree.root, salt); + return genTreeCommitment(leaves, salt, this.treeDepths.voteOptionTreeDepth); }; /** diff --git a/core/ts/__tests__/MaciState.test.ts b/core/ts/__tests__/MaciState.test.ts index 5d597419d0..0165597686 100644 --- a/core/ts/__tests__/MaciState.test.ts +++ b/core/ts/__tests__/MaciState.test.ts @@ -34,15 +34,7 @@ describe("MaciState", function test() { messageBatchSize, coordinatorKeypair, ); - const command = new PCommand( - BigInt(0), - userKeypair.pubKey, - BigInt(0), - BigInt(0), - BigInt(0), - BigInt(pollId), - BigInt(0), - ); + const command = new PCommand(0n, userKeypair.pubKey, 0n, 0n, 0n, BigInt(pollId), 0n); const encKeypair = new Keypair(); const signature = command.sign(encKeypair.privKey); @@ -186,14 +178,7 @@ describe("MaciState", function test() { }); it("should throw if a message has an invalid nonce", () => { - const command = new PCommand( - BigInt(user1StateIndex), - user1Keypair.pubKey, - BigInt(0), - BigInt(0), - BigInt(0), - BigInt(pollId), - ); + const command = new PCommand(BigInt(user1StateIndex), user1Keypair.pubKey, 0n, 0n, 0n, BigInt(pollId)); const signature = command.sign(user1Keypair.privKey); @@ -209,14 +194,7 @@ describe("MaciState", function test() { }); it("should throw if a message has an invalid signature", () => { - const command = new PCommand( - BigInt(user1StateIndex), - user1Keypair.pubKey, - BigInt(0), - BigInt(0), - BigInt(0), - BigInt(pollId), - ); + const command = new PCommand(BigInt(user1StateIndex), user1Keypair.pubKey, 0n, 0n, 0n, BigInt(pollId)); const signature = command.sign(new PrivKey(BigInt(0))); const ecdhKeypair = new Keypair(); @@ -279,14 +257,7 @@ describe("MaciState", function test() { }); it("should throw if a message has an invalid vote option index (< 0)", () => { - const command = new PCommand( - BigInt(user1StateIndex), - user1Keypair.pubKey, - BigInt(-1), - BigInt(1), - BigInt(1), - BigInt(pollId), - ); + const command = new PCommand(BigInt(user1StateIndex), user1Keypair.pubKey, BigInt(-1), 1n, 1n, BigInt(pollId)); const signature = command.sign(user1Keypair.privKey); @@ -302,14 +273,7 @@ describe("MaciState", function test() { }); it("should throw when passed a message that cannot be decrypted (wrong encPubKey)", () => { - const command = new PCommand( - BigInt(user1StateIndex), - user1Keypair.pubKey, - BigInt(0), - BigInt(1), - BigInt(1), - BigInt(pollId), - ); + const command = new PCommand(BigInt(user1StateIndex), user1Keypair.pubKey, 0n, 1n, 1n, BigInt(pollId)); const signature = command.sign(user1Keypair.privKey); @@ -325,14 +289,7 @@ describe("MaciState", function test() { }); it("should throw when passed a corrupted message", () => { - const command = new PCommand( - BigInt(user1StateIndex), - user1Keypair.pubKey, - BigInt(0), - BigInt(1), - BigInt(1), - BigInt(pollId), - ); + const command = new PCommand(BigInt(user1StateIndex), user1Keypair.pubKey, 0n, 1n, 1n, BigInt(pollId)); const signature = command.sign(user1Keypair.privKey); @@ -371,14 +328,7 @@ describe("MaciState", function test() { ); it("should throw if this is the first batch and currentMessageBatchIndex is defined", () => { - const command = new PCommand( - BigInt(user1StateIndex), - user1Keypair.pubKey, - BigInt(0), - BigInt(1), - BigInt(0), - BigInt(pollId), - ); + const command = new PCommand(BigInt(user1StateIndex), user1Keypair.pubKey, 0n, 1n, 0n, BigInt(pollId)); const signature = command.sign(user1Keypair.privKey); @@ -490,14 +440,7 @@ describe("MaciState", function test() { }); it("should return the correct state leaves and ballots", () => { - const command = new PCommand( - BigInt(user1StateIndex + 1), - user1Keypair.pubKey, - BigInt(0), - BigInt(1), - BigInt(0), - BigInt(pollId), - ); + const command = new PCommand(BigInt(user1StateIndex + 1), user1Keypair.pubKey, 0n, 1n, 0n, BigInt(pollId)); const signature = command.sign(user1Keypair.privKey); @@ -517,14 +460,7 @@ describe("MaciState", function test() { }); it("should have processed all messages", () => { - const command = new PCommand( - BigInt(user1StateIndex + 1), - user1Keypair.pubKey, - BigInt(0), - BigInt(1), - BigInt(0), - BigInt(pollId), - ); + const command = new PCommand(BigInt(user1StateIndex + 1), user1Keypair.pubKey, 0n, 1n, 0n, BigInt(pollId)); const signature = command.sign(user1Keypair.privKey); diff --git a/core/ts/index.ts b/core/ts/index.ts index 5b61860f6b..ed26a5bea1 100644 --- a/core/ts/index.ts +++ b/core/ts/index.ts @@ -1,5 +1,7 @@ export { MaciState } from "./MaciState"; + export { Poll } from "./Poll"; + export { genProcessVkSig, genTallyVkSig, @@ -11,7 +13,17 @@ export { packSubsidySmallVals, } from "./utils/utils"; -export type { CircuitInputs, MaxValues, TreeDepths, BatchSizes, IJsonMaciState } from "./utils/types"; +export type { + ITallyCircuitInputs, + IProcessMessagesCircuitInputs, + ISubsidyCircuitInputs, + CircuitInputs, + MaxValues, + TreeDepths, + BatchSizes, + IJsonMaciState, +} from "./utils/types"; + export { STATE_TREE_DEPTH, STATE_TREE_ARITY, diff --git a/core/ts/utils/types.ts b/core/ts/utils/types.ts index 9199c003c6..974f50ebf8 100644 --- a/core/ts/utils/types.ts +++ b/core/ts/utils/types.ts @@ -86,14 +86,14 @@ export interface IPoll { publishMessage(message: Message, encPubKey: PubKey): void; topupMessage(message: Message): void; // These methods are used to generate circuit inputs - processMessages(pollId: number): CircuitInputs; - tallyVotes(): CircuitInputs; + processMessages(pollId: number): IProcessMessagesCircuitInputs; + tallyVotes(): ITallyCircuitInputs; // These methods are helper functions hasUnprocessedMessages(): boolean; processAllMessages(): { stateLeaves: StateLeaf[]; ballots: Ballot[] }; hasUntalliedBallots(): boolean; hasUnfinishedSubsidyCalculation(): boolean; - subsidyPerBatch(): CircuitInputs; + subsidyPerBatch(): ISubsidyCircuitInputs; copy(): Poll; equals(p: Poll): boolean; toJSON(): IJsonPoll; @@ -145,3 +145,79 @@ export interface IProcessMessagesOutput { originalBallotPathElements?: PathElements; command?: PCommand | TCommand; } + +/** + * An interface describing the circuit inputs to the ProcessMessage circuit + */ +export interface IProcessMessagesCircuitInputs { + pollEndTimestamp: string; + packedVals: string; + msgRoot: string; + msgs: string[]; + msgSubrootPathElements: string[][]; + coordPrivKey: string; + coordPubKey: string; + encPubKeys: string[]; + currentStateRoot: string; + currentBallotRoot: string; + currentSbCommitment: string; + currentSbSalt: string; + currentStateLeaves: string[]; + currentStateLeavesPathElements: string[][]; + currentBallots: string[]; + currentBallotsPathElements: string[][]; + currentVoteWeights: string[]; + currentVoteWeightsPathElements: string[][]; + inputHash: string; + newSbSalt: string; + newSbCommitment: string; +} + +/** + * An interface describing the circuit inputs to the TallyVotes circuit + */ +export interface ITallyCircuitInputs { + stateRoot: string; + ballotRoot: string; + sbSalt: string; + sbCommitment: string; + currentTallyCommitment: string; + newTallyCommitment: string; + packedVals: string; + inputHash: string; + ballots: string[]; + ballotPathElements: PathElements; + votes: string[][]; + currentResults: string[]; + currentResultsRootSalt: string; + currentSpentVoiceCreditSubtotal: string; + currentSpentVoiceCreditSubtotalSalt: string; + currentPerVOSpentVoiceCredits: string[]; + currentPerVOSpentVoiceCreditsRootSalt: string; + newResultsRootSalt: string; + newPerVOSpentVoiceCreditsRootSalt: string; + newSpentVoiceCreditSubtotalSalt: string; +} + +/** + * An interface describing the circuit inputs to the Subsidy circuit + */ +export interface ISubsidyCircuitInputs { + stateRoot: string; + ballotRoot: string; + sbSalt: string; + currentSubsidySalt: string; + newSubsidySalt: string; + sbCommitment: string; + currentSubsidyCommitment: string; + newSubsidyCommitment: string; + currentSubsidy: string[]; + packedVals: string; + inputHash: string; + ballots1: string[]; + ballots2: string[]; + votes1: number[]; + votes2: number[]; + ballotPathElements1: string[]; + ballotPathElements2: string[]; +} diff --git a/core/ts/utils/utils.ts b/core/ts/utils/utils.ts index c509343638..cc6653eaaa 100644 --- a/core/ts/utils/utils.ts +++ b/core/ts/utils/utils.ts @@ -36,8 +36,7 @@ export const genTallyVkSig = ( _stateTreeDepth: number, _intStateTreeDepth: number, _voteOptionTreeDepth: number, -): bigint => - (BigInt(_stateTreeDepth) << BigInt(128)) + (BigInt(_intStateTreeDepth) << BigInt(64)) + BigInt(_voteOptionTreeDepth); +): bigint => (BigInt(_stateTreeDepth) << 128n) + (BigInt(_intStateTreeDepth) << 64n) + BigInt(_voteOptionTreeDepth); /** * This function generates the signature of a Subsidy Verifying Key(VK). @@ -53,8 +52,7 @@ export const genSubsidyVkSig = ( _stateTreeDepth: number, _intStateTreeDepth: number, _voteOptionTreeDepth: number, -): bigint => - (BigInt(_stateTreeDepth) << BigInt(128)) + (BigInt(_intStateTreeDepth) << BigInt(64)) + BigInt(_voteOptionTreeDepth); +): bigint => (BigInt(_stateTreeDepth) << 128n) + (BigInt(_intStateTreeDepth) << 64n) + BigInt(_voteOptionTreeDepth); /** * This function packs it's parameters into a single bigint. diff --git a/integrationTests/package.json b/integrationTests/package.json index 6e7fd73c28..9b6f144d03 100644 --- a/integrationTests/package.json +++ b/integrationTests/package.json @@ -9,7 +9,7 @@ "test": "ts-mocha --exit ./ts/__tests__/**.test.ts", "test:genMaciKeypair": "ts-mocha --exit ./ts/__tests__/cli-genMaciKeypair.test.ts", "test:genMaciPubkey": "ts-mocha --exit ./ts/__tests__/cli-genMaciPubkey.test.ts", - "test:suites": "NODE_OPTIONS=--max-old-space-size=4096 ts-mocha --exit ./ts/__tests__/suites.test.ts", + "test:integration": "NODE_OPTIONS=--max-old-space-size=4096 ts-mocha --exit ./ts/__tests__/integration.test.ts", "test:maciKeys": "ts-mocha --exit ./ts/__tests__/maci-keys.test.ts", "download-zkeys": "./scripts/download_zkeys.sh" }, From 4aedb83c917c0590f88a982a4b2eb910a2aab893 Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Fri, 5 Jan 2024 19:40:33 +0000 Subject: [PATCH 31/37] test(core): refactor and add tests for the core package --- core/package.json | 5 +- core/ts/__tests__/MaciState.test.ts | 371 ++---------------- core/ts/__tests__/Poll.test.ts | 570 ++++++++++++++++++++++++++++ core/ts/__tests__/utils.test.ts | 62 +++ 4 files changed, 658 insertions(+), 350 deletions(-) create mode 100644 core/ts/__tests__/Poll.test.ts create mode 100644 core/ts/__tests__/utils.test.ts diff --git a/core/package.json b/core/package.json index 9b2a184691..3201ce0397 100644 --- a/core/package.json +++ b/core/package.json @@ -7,8 +7,11 @@ "scripts": { "watch": "tsc --watch", "build": "tsc", + "test:processMessage": "ts-mocha --exit ts/__tests__/ProcessMessage.test.ts", + "test:maciState": "ts-mocha --exit ts/__tests__/MaciState.test.ts", "test:e2e": "ts-mocha --exit ts/__tests__/e2e.test.ts", - "test:unit": "ts-mocha --exit ts/__tests__/MaciState.test.ts", + "test:utils": "ts-mocha --exit ts/__tests__/utils.test.ts", + "test:poll": "ts-mocha --exit ts/__tests__/Poll.test.ts", "test": "nyc ts-mocha --exit ts/__tests__/*.test.ts" }, "dependencies": { diff --git a/core/ts/__tests__/MaciState.test.ts b/core/ts/__tests__/MaciState.test.ts index 0165597686..709e9f1fb6 100644 --- a/core/ts/__tests__/MaciState.test.ts +++ b/core/ts/__tests__/MaciState.test.ts @@ -1,5 +1,5 @@ import { expect } from "chai"; -import { PCommand, Message, Keypair, StateLeaf, PrivKey, Ballot } from "maci-domainobjs"; +import { PCommand, Message, Keypair } from "maci-domainobjs"; import fs from "fs"; @@ -12,7 +12,7 @@ import { coordinatorKeypair, duration, maxValues, messageBatchSize, treeDepths, describe("MaciState", function test() { this.timeout(100000); - describe("Deep copy", () => { + describe("copy", () => { let pollId: number; let m1: MaciState; const userKeypair = new Keypair(); @@ -34,7 +34,15 @@ describe("MaciState", function test() { messageBatchSize, coordinatorKeypair, ); - const command = new PCommand(0n, userKeypair.pubKey, 0n, 0n, 0n, BigInt(pollId), 0n); + const command = new PCommand( + BigInt(0), + userKeypair.pubKey, + BigInt(0), + BigInt(0), + BigInt(0), + BigInt(pollId), + BigInt(0), + ); const encKeypair = new Keypair(); const signature = command.sign(encKeypair.privKey); @@ -42,6 +50,7 @@ describe("MaciState", function test() { const message: Message = command.encrypt(signature, sharedKey); m1.polls[pollId].publishMessage(message, encKeypair.pubKey); + m1.polls[pollId].publishMessage(message, encKeypair.pubKey); }); it("should correctly deep-copy a MaciState object", () => { @@ -118,6 +127,11 @@ describe("MaciState", function test() { }); it("should create a JSON object from a MaciState object", () => { + // test loading a topup message + m1.polls[pollId].topupMessage(new Message(2n, [0n, 5n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n])); + + // mock a message with invalid message type + m1.polls[pollId].messages[1].msgType = 3n; const json = m1.toJSON(); fs.writeFileSync(stateFile, JSON.stringify(json, null, 4)); const content = JSON.parse(fs.readFileSync(stateFile).toString()) as IJsonMaciState; @@ -131,352 +145,11 @@ describe("MaciState", function test() { }); }); - describe("processMessage", () => { - const maciState = new MaciState(STATE_TREE_DEPTH); - const pollId = maciState.deployPoll( - BigInt(Math.floor(Date.now() / 1000) + duration), - maxValues, - treeDepths, - messageBatchSize, - coordinatorKeypair, - ); - - const poll = maciState.polls[pollId]; - - const user1Keypair = new Keypair(); - // signup the user - const user1StateIndex = maciState.signUp( - user1Keypair.pubKey, - voiceCreditBalance, - BigInt(Math.floor(Date.now() / 1000)), - ); - - // copy the state from the MaciState ref - poll.copyStateFromMaci(); - - it("should throw if a message has an invalid state index", () => { - const command = new PCommand( - // invalid state index as it is one more than the number of state leaves - BigInt(user1StateIndex + 1), - user1Keypair.pubKey, - BigInt(0), - BigInt(1), - BigInt(0), - BigInt(pollId), - ); - - const signature = command.sign(user1Keypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); - - const message = command.encrypt(signature, sharedKey); - poll.publishMessage(message, ecdhKeypair.pubKey); - expect(() => { - poll.processMessage(message, ecdhKeypair.pubKey); - }).to.throw("invalid state leaf index"); - }); - - it("should throw if a message has an invalid nonce", () => { - const command = new PCommand(BigInt(user1StateIndex), user1Keypair.pubKey, 0n, 0n, 0n, BigInt(pollId)); - - const signature = command.sign(user1Keypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); - - const message = command.encrypt(signature, sharedKey); - poll.publishMessage(message, ecdhKeypair.pubKey); - - expect(() => { - poll.processMessage(message, ecdhKeypair.pubKey); - }).to.throw("invalid nonce"); - }); - - it("should throw if a message has an invalid signature", () => { - const command = new PCommand(BigInt(user1StateIndex), user1Keypair.pubKey, 0n, 0n, 0n, BigInt(pollId)); - - const signature = command.sign(new PrivKey(BigInt(0))); - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); - - const message = command.encrypt(signature, sharedKey); - poll.publishMessage(message, ecdhKeypair.pubKey); - - expect(() => { - poll.processMessage(message, ecdhKeypair.pubKey); - }).to.throw("invalid signature"); - }); - - it("should throw if a message consumes more than the available voice credits for a user", () => { - const command = new PCommand( - BigInt(user1StateIndex), - user1Keypair.pubKey, - BigInt(0), - // voice credits spent would be this value ** this value - BigInt(Math.sqrt(Number.parseInt(voiceCreditBalance.toString(), 10)) + 1), - BigInt(1), - BigInt(pollId), - ); - - const signature = command.sign(user1Keypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); - - const message = command.encrypt(signature, sharedKey); - poll.publishMessage(message, ecdhKeypair.pubKey); - - expect(() => { - poll.processMessage(message, ecdhKeypair.pubKey); - }).to.throw("insufficient voice credits"); - }); - - it("should throw if a message has an invalid vote option index (>= max vote options)", () => { - const command = new PCommand( - BigInt(user1StateIndex), - user1Keypair.pubKey, - BigInt(maxValues.maxVoteOptions), - // voice credits spent would be this value ** this value - BigInt(1), - BigInt(1), - BigInt(pollId), - ); - - const signature = command.sign(user1Keypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); - - const message = command.encrypt(signature, sharedKey); - poll.publishMessage(message, ecdhKeypair.pubKey); - - expect(() => { - poll.processMessage(message, ecdhKeypair.pubKey); - }).to.throw("invalid vote option index"); - }); - - it("should throw if a message has an invalid vote option index (< 0)", () => { - const command = new PCommand(BigInt(user1StateIndex), user1Keypair.pubKey, BigInt(-1), 1n, 1n, BigInt(pollId)); - - const signature = command.sign(user1Keypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); - - const message = command.encrypt(signature, sharedKey); - poll.publishMessage(message, ecdhKeypair.pubKey); - - expect(() => { - poll.processMessage(message, ecdhKeypair.pubKey); - }).to.throw("invalid vote option index"); - }); - - it("should throw when passed a message that cannot be decrypted (wrong encPubKey)", () => { - const command = new PCommand(BigInt(user1StateIndex), user1Keypair.pubKey, 0n, 1n, 1n, BigInt(pollId)); - - const signature = command.sign(user1Keypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(new Keypair().privKey, coordinatorKeypair.pubKey); - - const message = command.encrypt(signature, sharedKey); - poll.publishMessage(message, ecdhKeypair.pubKey); - - expect(() => { - poll.processMessage(message, user1Keypair.pubKey); - }).to.throw("failed decryption due to either wrong encryption public key or corrupted ciphertext"); - }); - - it("should throw when passed a corrupted message", () => { - const command = new PCommand(BigInt(user1StateIndex), user1Keypair.pubKey, 0n, 1n, 1n, BigInt(pollId)); - - const signature = command.sign(user1Keypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(user1Keypair.privKey, coordinatorKeypair.pubKey); - - const message = command.encrypt(signature, sharedKey); - poll.publishMessage(message, ecdhKeypair.pubKey); - - message.data[0] = BigInt(0); - - expect(() => { - poll.processMessage(message, user1Keypair.pubKey); - }).to.throw("failed decryption due to either wrong encryption public key or corrupted ciphertext"); - }); - }); - - describe("processMessages", () => { - const maciState = new MaciState(STATE_TREE_DEPTH); - const pollId = maciState.deployPoll( - BigInt(Math.floor(Date.now() / 1000) + duration), - maxValues, - treeDepths, - messageBatchSize, - coordinatorKeypair, - ); - - const poll = maciState.polls[pollId]; - - const user1Keypair = new Keypair(); - // signup the user - const user1StateIndex = maciState.signUp( - user1Keypair.pubKey, - voiceCreditBalance, - BigInt(Math.floor(Date.now() / 1000)), - ); - - it("should throw if this is the first batch and currentMessageBatchIndex is defined", () => { - const command = new PCommand(BigInt(user1StateIndex), user1Keypair.pubKey, 0n, 1n, 0n, BigInt(pollId)); - - const signature = command.sign(user1Keypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); - - const message = command.encrypt(signature, sharedKey); - - poll.publishMessage(message, ecdhKeypair.pubKey); - - // mock - poll.currentMessageBatchIndex = 0; - expect(() => poll.processMessages(pollId)).to.throw( - "The current message batch index should not be defined if this is the first batch", - ); - poll.currentMessageBatchIndex = undefined; - }); - - it("should succeed even if send an invalid message", () => { - const command = new PCommand( - // we only signed up one user so the state index is invalid - BigInt(user1StateIndex + 1), - user1Keypair.pubKey, - BigInt(0), - BigInt(1), - BigInt(0), - BigInt(pollId), - ); - - const signature = command.sign(user1Keypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); - - const message = command.encrypt(signature, sharedKey); - - poll.publishMessage(message, ecdhKeypair.pubKey); - poll.publishMessage(message, ecdhKeypair.pubKey); - poll.copyStateFromMaci(); - expect(() => { - poll.processMessage(message, ecdhKeypair.pubKey); - }).to.throw("invalid state leaf index"); - - // keep this call to complete processing - // eslint-disable-next-line no-unused-expressions - expect(() => poll.processMessages(pollId)).to.not.throw; - }); - - it("should correctly process a topup message and increase an user's voice credit balance", () => { - const topupMessage = new Message(2n, [BigInt(user1StateIndex), 50n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n]); - - poll.topupMessage(topupMessage); - - const balanceBefore = poll.stateLeaves[user1StateIndex].voiceCreditBalance; - poll.processMessages(pollId); - - // check balance - expect(poll.stateLeaves[user1StateIndex].voiceCreditBalance.toString()).to.eq((balanceBefore + 50n).toString()); - }); - - it("should throw when called after all messages have been processed", () => { - expect(() => poll.processMessages(pollId)).to.throw("No more messages to process"); - }); - }); - - describe("processAllMessages", () => { - const maciState = new MaciState(STATE_TREE_DEPTH); - const pollId = maciState.deployPoll( - BigInt(Math.floor(Date.now() / 1000) + duration), - maxValues, - treeDepths, - messageBatchSize, - coordinatorKeypair, - ); - - const poll = maciState.polls[pollId]; - - const user1Keypair = new Keypair(); - // signup the user - const user1StateIndex = maciState.signUp( - user1Keypair.pubKey, - voiceCreditBalance, - BigInt(Math.floor(Date.now() / 1000)), - ); - - it("it should succeed even if send an invalid message", () => { - const command = new PCommand( - // we only signed up one user so the state index is invalid - BigInt(user1StateIndex + 1), - user1Keypair.pubKey, - BigInt(0), - BigInt(1), - BigInt(0), - BigInt(pollId), - ); - - const signature = command.sign(user1Keypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); - - const message = command.encrypt(signature, sharedKey); - poll.publishMessage(message, ecdhKeypair.pubKey); - expect(() => { - poll.processMessage(message, ecdhKeypair.pubKey); - }).to.throw("invalid state leaf index"); - - expect(() => poll.processAllMessages()).to.not.throw(); - }); - - it("should return the correct state leaves and ballots", () => { - const command = new PCommand(BigInt(user1StateIndex + 1), user1Keypair.pubKey, 0n, 1n, 0n, BigInt(pollId)); - - const signature = command.sign(user1Keypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); - - const message = command.encrypt(signature, sharedKey); - poll.publishMessage(message, ecdhKeypair.pubKey); - expect(() => { - poll.processMessage(message, ecdhKeypair.pubKey); - }).to.throw("invalid state leaf index"); - - const { stateLeaves, ballots } = poll.processAllMessages(); - - stateLeaves.forEach((leaf: StateLeaf, index: number) => expect(leaf.equals(poll.stateLeaves[index])).to.eq(true)); - ballots.forEach((ballot: Ballot, index: number) => expect(ballot.equals(poll.ballots[index])).to.eq(true)); - }); - - it("should have processed all messages", () => { - const command = new PCommand(BigInt(user1StateIndex + 1), user1Keypair.pubKey, 0n, 1n, 0n, BigInt(pollId)); - - const signature = command.sign(user1Keypair.privKey); - - const ecdhKeypair = new Keypair(); - const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); - - const message = command.encrypt(signature, sharedKey); - - // publish batch size + 1 - for (let i = 0; i <= messageBatchSize; i += 1) { - poll.publishMessage(message, ecdhKeypair.pubKey); - } - - poll.processAllMessages(); - - expect(poll.hasUnprocessedMessages()).to.eq(false); + describe("deployNullPoll ", () => { + it("should deploy a Poll that is null", () => { + const maciState = new MaciState(STATE_TREE_DEPTH); + maciState.deployNullPoll(); + expect(maciState.polls[0]).to.eq(null); }); }); diff --git a/core/ts/__tests__/Poll.test.ts b/core/ts/__tests__/Poll.test.ts new file mode 100644 index 0000000000..1cec8680e2 --- /dev/null +++ b/core/ts/__tests__/Poll.test.ts @@ -0,0 +1,570 @@ +import { expect } from "chai"; +import { PCommand, Message, Keypair, StateLeaf, PrivKey, Ballot } from "maci-domainobjs"; + +import { MaciState } from "../MaciState"; +import { Poll } from "../Poll"; +import { STATE_TREE_DEPTH } from "../utils/constants"; + +import { coordinatorKeypair, duration, maxValues, messageBatchSize, treeDepths, voiceCreditBalance } from "./constants"; + +describe("Poll", function test() { + this.timeout(90000); + + describe("processMessage", () => { + const maciState = new MaciState(STATE_TREE_DEPTH); + const pollId = maciState.deployPoll( + BigInt(Math.floor(Date.now() / 1000) + duration), + maxValues, + treeDepths, + messageBatchSize, + coordinatorKeypair, + ); + + const poll = maciState.polls[pollId]; + + const user1Keypair = new Keypair(); + // signup the user + const user1StateIndex = maciState.signUp( + user1Keypair.pubKey, + voiceCreditBalance, + BigInt(Math.floor(Date.now() / 1000)), + ); + + // copy the state from the MaciState ref + poll.copyStateFromMaci(); + + it("should throw if a message has an invalid state index", () => { + const command = new PCommand( + // invalid state index as it is one more than the number of state leaves + BigInt(user1StateIndex + 1), + user1Keypair.pubKey, + BigInt(0), + BigInt(1), + BigInt(0), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + expect(() => { + poll.processMessage(message, ecdhKeypair.pubKey); + }).to.throw("invalid state leaf index"); + }); + + it("should throw if a message has an invalid nonce", () => { + const command = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + BigInt(0), + BigInt(0), + BigInt(0), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + + expect(() => { + poll.processMessage(message, ecdhKeypair.pubKey); + }).to.throw("invalid nonce"); + }); + + it("should throw if a message has an invalid signature", () => { + const command = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + BigInt(0), + BigInt(0), + BigInt(0), + BigInt(pollId), + ); + + const signature = command.sign(new PrivKey(BigInt(0))); + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + + expect(() => { + poll.processMessage(message, ecdhKeypair.pubKey); + }).to.throw("invalid signature"); + }); + + it("should throw if a message consumes more than the available voice credits for a user", () => { + const command = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + BigInt(0), + // voice credits spent would be this value ** this value + BigInt(Math.sqrt(Number.parseInt(voiceCreditBalance.toString(), 10)) + 1), + BigInt(1), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + + expect(() => { + poll.processMessage(message, ecdhKeypair.pubKey); + }).to.throw("insufficient voice credits"); + }); + + it("should throw if a message has an invalid vote option index (>= max vote options)", () => { + const command = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + BigInt(maxValues.maxVoteOptions), + // voice credits spent would be this value ** this value + BigInt(1), + BigInt(1), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + + expect(() => { + poll.processMessage(message, ecdhKeypair.pubKey); + }).to.throw("invalid vote option index"); + }); + + it("should throw if a message has an invalid vote option index (< 0)", () => { + const command = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + BigInt(-1), + BigInt(1), + BigInt(1), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + + expect(() => { + poll.processMessage(message, ecdhKeypair.pubKey); + }).to.throw("invalid vote option index"); + }); + + it("should throw when passed a message that cannot be decrypted (wrong encPubKey)", () => { + const command = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + BigInt(0), + BigInt(1), + BigInt(1), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(new Keypair().privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + + expect(() => { + poll.processMessage(message, user1Keypair.pubKey); + }).to.throw("failed decryption due to either wrong encryption public key or corrupted ciphertext"); + }); + + it("should throw when passed a corrupted message", () => { + const command = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + BigInt(0), + BigInt(1), + BigInt(1), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(user1Keypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + + message.data[0] = BigInt(0); + + expect(() => { + poll.processMessage(message, user1Keypair.pubKey); + }).to.throw("failed decryption due to either wrong encryption public key or corrupted ciphertext"); + }); + }); + + describe("processMessages", () => { + const maciState = new MaciState(STATE_TREE_DEPTH); + const pollId = maciState.deployPoll( + BigInt(Math.floor(Date.now() / 1000) + duration), + maxValues, + treeDepths, + messageBatchSize, + coordinatorKeypair, + ); + + const poll = maciState.polls[pollId]; + + const user1Keypair = new Keypair(); + // signup the user + const user1StateIndex = maciState.signUp( + user1Keypair.pubKey, + voiceCreditBalance, + BigInt(Math.floor(Date.now() / 1000)), + ); + + it("should throw if this is the first batch and currentMessageBatchIndex is defined", () => { + const command = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + BigInt(0), + BigInt(1), + BigInt(0), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + + poll.publishMessage(message, ecdhKeypair.pubKey); + + // mock + poll.currentMessageBatchIndex = 0; + expect(() => poll.processMessages(pollId)).to.throw( + "The current message batch index should not be defined if this is the first batch", + ); + poll.currentMessageBatchIndex = undefined; + }); + + it("should succeed even if send an invalid message", () => { + const command = new PCommand( + // we only signed up one user so the state index is invalid + BigInt(user1StateIndex + 1), + user1Keypair.pubKey, + BigInt(0), + BigInt(1), + BigInt(0), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + + poll.publishMessage(message, ecdhKeypair.pubKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + poll.copyStateFromMaci(); + expect(() => { + poll.processMessage(message, ecdhKeypair.pubKey); + }).to.throw("invalid state leaf index"); + + // keep this call to complete processing + // eslint-disable-next-line no-unused-expressions + expect(() => poll.processMessages(pollId)).to.not.throw; + }); + + it("should correctly process a topup message and increase an user's voice credit balance", () => { + const topupMessage = new Message(2n, [BigInt(user1StateIndex), 50n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n]); + + poll.topupMessage(topupMessage); + + const balanceBefore = poll.stateLeaves[user1StateIndex].voiceCreditBalance; + poll.processMessages(pollId); + + // check balance + expect(poll.stateLeaves[user1StateIndex].voiceCreditBalance.toString()).to.eq((balanceBefore + 50n).toString()); + }); + + it("should throw when called after all messages have been processed", () => { + expect(() => poll.processMessages(pollId)).to.throw("No more messages to process"); + }); + }); + + describe("processAllMessages", () => { + const maciState = new MaciState(STATE_TREE_DEPTH); + const pollId = maciState.deployPoll( + BigInt(Math.floor(Date.now() / 1000) + duration), + maxValues, + treeDepths, + messageBatchSize, + coordinatorKeypair, + ); + + const poll = maciState.polls[pollId]; + + const user1Keypair = new Keypair(); + // signup the user + const user1StateIndex = maciState.signUp( + user1Keypair.pubKey, + voiceCreditBalance, + BigInt(Math.floor(Date.now() / 1000)), + ); + + it("it should succeed even if send an invalid message", () => { + const command = new PCommand( + // we only signed up one user so the state index is invalid + BigInt(user1StateIndex + 1), + user1Keypair.pubKey, + BigInt(0), + BigInt(1), + BigInt(0), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + expect(() => { + poll.processMessage(message, ecdhKeypair.pubKey); + }).to.throw("invalid state leaf index"); + + expect(() => poll.processAllMessages()).to.not.throw(); + }); + + it("should return the correct state leaves and ballots", () => { + const command = new PCommand( + BigInt(user1StateIndex + 1), + user1Keypair.pubKey, + BigInt(0), + BigInt(1), + BigInt(0), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + expect(() => { + poll.processMessage(message, ecdhKeypair.pubKey); + }).to.throw("invalid state leaf index"); + + const { stateLeaves, ballots } = poll.processAllMessages(); + + stateLeaves.forEach((leaf: StateLeaf, index: number) => expect(leaf.equals(poll.stateLeaves[index])).to.eq(true)); + ballots.forEach((ballot: Ballot, index: number) => expect(ballot.equals(poll.ballots[index])).to.eq(true)); + }); + + it("should have processed all messages", () => { + const command = new PCommand( + BigInt(user1StateIndex + 1), + user1Keypair.pubKey, + BigInt(0), + BigInt(1), + BigInt(0), + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + + // publish batch size + 1 + for (let i = 0; i <= messageBatchSize; i += 1) { + poll.publishMessage(message, ecdhKeypair.pubKey); + } + + poll.processAllMessages(); + + expect(poll.hasUnprocessedMessages()).to.eq(false); + }); + }); + + describe("tallyVotes", () => { + const maciState = new MaciState(STATE_TREE_DEPTH); + const pollId = maciState.deployPoll( + BigInt(Math.floor(Date.now() / 1000) + duration), + maxValues, + treeDepths, + messageBatchSize, + coordinatorKeypair, + ); + + const poll = maciState.polls[pollId]; + + const user1Keypair = new Keypair(); + // signup the user + const user1StateIndex = maciState.signUp( + user1Keypair.pubKey, + voiceCreditBalance, + BigInt(Math.floor(Date.now() / 1000)), + ); + + const voteWeight = 5n; + const voteOption = 0n; + + const command = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + voteOption, + voteWeight, + 1n, + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + + it("should throw if called before all messages have been processed", () => { + expect(() => poll.tallyVotes()).to.throw("Cannot read properties of undefined (reading 'root')"); + }); + + it("should generate the correct results", () => { + poll.processAllMessages(); + poll.tallyVotes(); + + const spentVoiceCredits = poll.totalSpentVoiceCredits; + const results = poll.tallyResult; + expect(spentVoiceCredits).to.eq(voteWeight * voteWeight); + expect(results[Number.parseInt(voteOption.toString(), 10)]).to.eq(voteWeight); + }); + + it("should throw when there are no more ballots to tally", () => { + expect(() => poll.tallyVotes()).to.throw("No more ballots to tally"); + }); + }); + + describe("subsidy", () => { + const maciState = new MaciState(STATE_TREE_DEPTH); + const pollId = maciState.deployPoll( + BigInt(Math.floor(Date.now() / 1000) + duration), + maxValues, + treeDepths, + messageBatchSize, + coordinatorKeypair, + ); + + const poll = maciState.polls[pollId]; + + const user1Keypair = new Keypair(); + // signup the user + const user1StateIndex = maciState.signUp( + user1Keypair.pubKey, + voiceCreditBalance, + BigInt(Math.floor(Date.now() / 1000)), + ); + + const voteWeight = 5n; + const voteOption = 0n; + + const command = new PCommand( + BigInt(user1StateIndex), + user1Keypair.pubKey, + voteOption, + voteWeight, + 1n, + BigInt(pollId), + ); + + const signature = command.sign(user1Keypair.privKey); + + const ecdhKeypair = new Keypair(); + const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey); + + const message = command.encrypt(signature, sharedKey); + poll.publishMessage(message, ecdhKeypair.pubKey); + poll.processAllMessages(); + poll.tallyVotes(); + + it("should calculate the subsidy", () => { + const { rbi, cbi } = poll; + expect(() => poll.subsidyPerBatch()).to.not.throw(); + const { rbi: newRbi, cbi: newCbi } = poll; + expect(newRbi).to.eq(rbi + 1); + expect(newCbi).to.eq(cbi + 1); + }); + + it("should throw when the subsidy was already calculated", () => { + expect(() => poll.subsidyPerBatch()).to.throw("No more subsidy batches to calculate"); + }); + }); + + describe("setCoordinatorKeypair", () => { + it("should update the coordinator's Keypair", () => { + const maciState = new MaciState(STATE_TREE_DEPTH); + const pollId = maciState.deployPoll( + BigInt(Math.floor(Date.now() / 1000) + duration), + maxValues, + treeDepths, + messageBatchSize, + coordinatorKeypair, + ); + + const poll = maciState.polls[pollId]; + const newCoordinatorKeypair = new Keypair(); + poll.setCoordinatorKeypair(newCoordinatorKeypair.privKey.serialize()); + expect(poll.coordinatorKeypair.privKey.serialize()).to.deep.eq(newCoordinatorKeypair.privKey.serialize()); + expect(poll.coordinatorKeypair.pubKey.serialize()).to.deep.eq(newCoordinatorKeypair.pubKey.serialize()); + }); + }); + + describe("toJSON", () => { + it("should return the correct JSON", () => { + const maciState = new MaciState(STATE_TREE_DEPTH); + const pollId = maciState.deployPoll( + BigInt(Math.floor(Date.now() / 1000) + duration), + maxValues, + treeDepths, + messageBatchSize, + coordinatorKeypair, + ); + + const poll = maciState.polls[pollId]; + const json = poll.toJSON(); + + const pollFromJson = Poll.fromJSON(json, maciState); + pollFromJson.setCoordinatorKeypair(coordinatorKeypair.privKey.serialize()); + expect(pollFromJson.equals(poll)).to.eq(true); + }); + }); +}); diff --git a/core/ts/__tests__/utils.test.ts b/core/ts/__tests__/utils.test.ts new file mode 100644 index 0000000000..4e49e292a0 --- /dev/null +++ b/core/ts/__tests__/utils.test.ts @@ -0,0 +1,62 @@ +import { expect } from "chai"; + +import { + genProcessVkSig, + genTallyVkSig, + genSubsidyVkSig, + packProcessMessageSmallVals, + unpackProcessMessageSmallVals, + packTallyVotesSmallVals, + unpackTallyVotesSmallVals, + packSubsidySmallVals, +} from "../utils/utils"; + +describe("Utils", () => { + it("genProcessVkSig should work", () => { + const result = genProcessVkSig(1, 2, 3, 4); + expect(result).to.equal(25108406941546723055683440059751604127909689873435325366275n); + }); + + it("genTallyVkSig should work", () => { + const result = genTallyVkSig(1, 2, 3); + expect(result).to.equal(340282366920938463500268095579187314691n); + }); + + it("genSubsidyVkSig should work", () => { + const result = genSubsidyVkSig(1, 2, 3); + expect(result).to.equal(340282366920938463500268095579187314691n); + }); + + it("packProcessMessageSmallVals should work", () => { + const result = packProcessMessageSmallVals(1n, 2n, 3, 4); + expect(result).to.equal(5708990770823843327184944562488436835454287873n); + }); + + it("unpackProcessMessageSmallVals should work", () => { + const result = unpackProcessMessageSmallVals(5708990770823843327184944562488436835454287873n); + expect(result).to.deep.equal({ + maxVoteOptions: 1n, + numUsers: 2n, + batchStartIndex: 3n, + batchEndIndex: 4n, + }); + }); + + it("packTallyVotesSmallVals should work", () => { + const result = packTallyVotesSmallVals(1, 2, 3); + expect(result).to.equal(3377699720527872n); + }); + + it("unpackTallyVotesSmallVals should work", () => { + const result = unpackTallyVotesSmallVals(3377699720527872n); + expect(result).to.deep.equal({ + numSignUps: 3n, + batchStartIndex: 0n, + }); + }); + + it("packSubsidySmallVals should work", () => { + const result = packSubsidySmallVals(1, 2, 3); + expect(result).to.equal(3802951800684689330390016458754n); + }); +}); From 6000227231bee3917686b64685c14ca329fcf38b Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Sun, 7 Jan 2024 19:48:59 +0000 Subject: [PATCH 32/37] test(cli): reorganize e2e tests and add more tests for cli commands --- cli/package.json | 16 +- cli/tests/{ => e2e}/e2e.subsidy.test.ts | 647 +----------------- cli/tests/{ => e2e}/e2e.test.ts | 420 +++--------- cli/tests/{ => e2e}/keyChange.test.ts | 9 +- cli/tests/unit/airdrop.test.ts | 26 + cli/tests/unit/data/testVk.json | 94 +++ cli/tests/unit/fundWallet.test.ts | 16 + .../tests/unit/genKeyPair.test.ts | 3 +- .../tests/unit/genPubkey.test.ts | 9 +- cli/tests/unit/timeTravel.test.ts | 16 + cli/tests/unit/topup.test.ts | 47 ++ cli/tests/unit/utils.test.ts | 36 + contracts/hardhat.config.ts | 1 + .../ts/__tests__/artifacts/test_vk.json | 124 ++-- integrationTests/package.json | 4 +- 15 files changed, 426 insertions(+), 1042 deletions(-) rename cli/tests/{ => e2e}/e2e.subsidy.test.ts (50%) rename cli/tests/{ => e2e}/e2e.test.ts (82%) rename cli/tests/{ => e2e}/keyChange.test.ts (98%) create mode 100644 cli/tests/unit/airdrop.test.ts create mode 100644 cli/tests/unit/data/testVk.json create mode 100644 cli/tests/unit/fundWallet.test.ts rename integrationTests/ts/__tests__/cli-genMaciKeypair.test.ts => cli/tests/unit/genKeyPair.test.ts (96%) rename integrationTests/ts/__tests__/cli-genMaciPubkey.test.ts => cli/tests/unit/genPubkey.test.ts (72%) create mode 100644 cli/tests/unit/timeTravel.test.ts create mode 100644 cli/tests/unit/topup.test.ts create mode 100644 cli/tests/unit/utils.test.ts diff --git a/cli/package.json b/cli/package.json index b2c229c2cc..193caffe99 100644 --- a/cli/package.json +++ b/cli/package.json @@ -14,10 +14,17 @@ "watch": "tsc --watch", "build": "tsc", "postbuild": "cp package.json ./build", - "test": "nyc ts-mocha --exit tests/*.test.ts", + "test": "nyc ts-mocha --exit tests/**/*.test.ts", "test:e2e": "ts-mocha --exit tests/e2e.test.ts", "test:e2e-subsidy": "ts-mocha --exit tests/e2e.subsidy.test.ts", - "test:keyChange": "ts-mocha --exit tests/keyChange.test.ts" + "test:keyChange": "ts-mocha --exit tests/keyChange.test.ts", + "test:unit": "nyc ts-mocha --exit tests/unit/*.test.ts", + "test:airdrop": "nyc ts-mocha --exit tests/unit/airdrop.test.ts", + "test:genPubKey": "ts-mocha --exit tests/unit/genPubKey.test.ts", + "test:genKeypair": "ts-mocha --exit tests/unit/genKeyPair.test.ts", + "test:timeTravel": "ts-mocha --exit tests/unit/timeTravel.test.ts", + "test:fundWallet": "ts-mocha --exit tests/unit/fundWallet.test.ts", + "test:utils": "ts-mocha --exit tests/unit/utils.test.ts" }, "dependencies": { "@commander-js/extra-typings": "^11.1.0", @@ -57,10 +64,11 @@ ], "all": true, "exclude": [ - "**/tests/*.ts", "**/*.js", "**/*.d.ts", - "hardhat.config.ts" + "hardhat.config.ts", + "tests/**/*.ts", + "ts/index.ts" ], "branches": ">50%", "lines": ">50%", diff --git a/cli/tests/e2e.subsidy.test.ts b/cli/tests/e2e/e2e.subsidy.test.ts similarity index 50% rename from cli/tests/e2e.subsidy.test.ts rename to cli/tests/e2e/e2e.subsidy.test.ts index 45f23bf784..fc8d3afbf2 100644 --- a/cli/tests/e2e.subsidy.test.ts +++ b/cli/tests/e2e/e2e.subsidy.test.ts @@ -15,9 +15,8 @@ import { signup, timeTravel, verify, -} from "../ts/commands"; -import { DeployedContracts, PollContracts } from "../ts/utils"; - +} from "../../ts/commands"; +import { DeployedContracts, PollContracts } from "../../ts/utils"; import { INT_STATE_TREE_DEPTH, MSG_BATCH_DEPTH, @@ -42,8 +41,8 @@ import { testTallyFilePath, testTallyVotesWasmPath, testTallyVotesWitnessPath, -} from "./constants"; -import { cleanSubsidy, isArm } from "./utils"; +} from "../constants"; +import { cleanSubsidy, isArm } from "../utils"; describe("e2e with Subsidy tests", function test() { const useWasm = isArm(); @@ -69,85 +68,8 @@ describe("e2e with Subsidy tests", function test() { subsidyTestZkeyPath, ); }); - describe("test1", () => { - const user1Key = new Keypair(); - - after(() => { - cleanSubsidy(); - }); - - before(async () => { - // deploy the smart contracts - maciAddresses = await deploy(STATE_TREE_DEPTH); - // deploy a poll contract - pollAddresses = await deployPoll( - pollDuration, - maxMessages, - maxVoteOptions, - INT_STATE_TREE_DEPTH, - MSG_BATCH_DEPTH, - MSG_TREE_DEPTH, - VOTE_OPTION_TREE_DEPTH, - coordinatorPubKey, - ); - }); - - it("should signup one user", async () => { - await signup(user1Key.pubKey.serialize()); - }); - - it("should publish one message", async () => { - await publish( - user1Key.pubKey.serialize(), - 1, - 0, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - user1Key.privKey.serialize(), - ); - }); - - it("should generate zk-SNARK proofs and verify them", async () => { - await timeTravel(pollDuration, true); - await mergeMessages(0); - await mergeSignups(0); - const tallyData = await genProofs( - testProofsDirPath, - testTallyFilePath, - tallyVotesTestZkeyPath, - processMessageTestZkeyPath, - 0, - testSubsidyFilePath, - subsidyTestZkeyPath, - testRapidsnarkPath, - testProcessMessagesWitnessPath, - testTallyVotesWitnessPath, - testSubsidyWitnessPath, - coordinatorPrivKey, - maciAddresses.maciAddress, - undefined, - testProcessMessagesWasmPath, - testTallyVotesWasmPath, - testSubsidyWasmPath, - useWasm, - ); - await proveOnChain("0", testProofsDirPath); - await verify( - "0", - testTallyFilePath, - tallyData, - maciAddresses.maciAddress, - pollAddresses.tally, - pollAddresses.subsidy, - testSubsidyFilePath, - ); - }); - }); - describe("test2", () => { + describe("4 signups, 6 messages", () => { after(() => { cleanSubsidy(); }); @@ -284,7 +206,7 @@ describe("e2e with Subsidy tests", function test() { }); }); - describe("test3", () => { + describe("9 signups, 1 message", () => { after(() => { cleanSubsidy(); }); @@ -376,7 +298,7 @@ describe("e2e with Subsidy tests", function test() { }); }); - describe("test4", () => { + describe("8 signups (same key), 12 messages (same message)", () => { after(() => { cleanSubsidy(); }); @@ -460,561 +382,6 @@ describe("e2e with Subsidy tests", function test() { }); }); - describe("test5", () => { - after(() => { - cleanSubsidy(); - }); - - const users = [new Keypair(), new Keypair(), new Keypair(), new Keypair()]; - - before(async () => { - // deploy the smart contracts - maciAddresses = await deploy(STATE_TREE_DEPTH); - // deploy a poll contract - pollAddresses = await deployPoll( - pollDuration, - maxMessages, - maxVoteOptions, - INT_STATE_TREE_DEPTH, - MSG_BATCH_DEPTH, - MSG_TREE_DEPTH, - VOTE_OPTION_TREE_DEPTH, - coordinatorPubKey, - ); - }); - - it("should signup four users", async () => { - // eslint-disable-next-line @typescript-eslint/prefer-for-of - for (let i = 0; i < users.length; i += 1) { - // eslint-disable-next-line no-await-in-loop - await signup(users[i].pubKey.serialize()); - } - }); - - it("should publish four messages", async () => { - await publish( - users[0].pubKey.serialize(), - 1, - 0, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - users[0].privKey.serialize(), - ); - await publish( - users[1].pubKey.serialize(), - 2, - 1, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - users[1].privKey.serialize(), - ); - await publish( - users[2].pubKey.serialize(), - 3, - 2, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - users[2].privKey.serialize(), - ); - await publish( - users[3].pubKey.serialize(), - 4, - 3, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - users[0].privKey.serialize(), - ); - }); - - it("should generate zk-SNARK proofs and verify them", async () => { - await timeTravel(pollDuration, true); - await mergeMessages(0); - await mergeSignups(0); - const tallyData = await genProofs( - testProofsDirPath, - testTallyFilePath, - tallyVotesTestZkeyPath, - processMessageTestZkeyPath, - 0, - testSubsidyFilePath, - subsidyTestZkeyPath, - testRapidsnarkPath, - testProcessMessagesWitnessPath, - testTallyVotesWitnessPath, - testSubsidyWitnessPath, - coordinatorPrivKey, - maciAddresses.maciAddress, - undefined, - testProcessMessagesWasmPath, - testTallyVotesWasmPath, - testSubsidyWasmPath, - useWasm, - ); - await proveOnChain("0", testProofsDirPath); - await verify( - "0", - testTallyFilePath, - tallyData, - maciAddresses.maciAddress, - pollAddresses.tally, - pollAddresses.subsidy, - testSubsidyFilePath, - ); - }); - }); - - describe("test6", () => { - after(() => { - cleanSubsidy(); - }); - - const users = [new Keypair(), new Keypair(), new Keypair(), new Keypair(), new Keypair()]; - - before(async () => { - // deploy the smart contracts - maciAddresses = await deploy(STATE_TREE_DEPTH); - // deploy a poll contract - pollAddresses = await deployPoll( - pollDuration, - maxMessages, - maxVoteOptions, - INT_STATE_TREE_DEPTH, - MSG_BATCH_DEPTH, - MSG_TREE_DEPTH, - VOTE_OPTION_TREE_DEPTH, - coordinatorPubKey, - ); - }); - - it("should signup five users", async () => { - // eslint-disable-next-line @typescript-eslint/prefer-for-of - for (let i = 0; i < users.length; i += 1) { - // eslint-disable-next-line no-await-in-loop - await signup(users[i].pubKey.serialize()); - } - }); - - it("should publish five messages", async () => { - await publish( - users[0].pubKey.serialize(), - 1, - 0, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - users[0].privKey.serialize(), - ); - await publish( - users[1].pubKey.serialize(), - 2, - 1, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - users[1].privKey.serialize(), - ); - await publish( - users[2].pubKey.serialize(), - 3, - 2, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - users[2].privKey.serialize(), - ); - await publish( - users[3].pubKey.serialize(), - 4, - 3, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - users[3].privKey.serialize(), - ); - await publish( - users[4].pubKey.serialize(), - 5, - 4, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - users[4].privKey.serialize(), - ); - }); - - it("should generate zk-SNARK proofs and verify them", async () => { - await timeTravel(pollDuration, true); - await mergeMessages(0); - await mergeSignups(0); - const tallyData = await genProofs( - testProofsDirPath, - testTallyFilePath, - tallyVotesTestZkeyPath, - processMessageTestZkeyPath, - 0, - testSubsidyFilePath, - subsidyTestZkeyPath, - testRapidsnarkPath, - testProcessMessagesWitnessPath, - testTallyVotesWitnessPath, - testSubsidyWitnessPath, - coordinatorPrivKey, - maciAddresses.maciAddress, - undefined, - testProcessMessagesWasmPath, - testTallyVotesWasmPath, - testSubsidyWasmPath, - useWasm, - ); - await proveOnChain("0", testProofsDirPath); - await verify( - "0", - testTallyFilePath, - tallyData, - maciAddresses.maciAddress, - pollAddresses.tally, - pollAddresses.subsidy, - testSubsidyFilePath, - ); - }); - }); - - describe("test7", () => { - after(() => { - cleanSubsidy(); - }); - - const user = new Keypair(); - - const publishArgs = [ - { - quiet: true, - pubkey: user.pubKey.serialize(), - privateKey: user.privKey.serialize(), - stateIndex: 6, - voteOptionIndex: 5, - nonce: 1, - newVoteWeight: 6, - pollId: 0, - }, - { - quiet: true, - pubkey: user.pubKey.serialize(), - privateKey: user.privKey.serialize(), - stateIndex: 5, - voteOptionIndex: 5, - nonce: 2, - newVoteWeight: 5, - pollId: 0, - }, - { - quiet: true, - pubkey: user.pubKey.serialize(), - privateKey: user.privKey.serialize(), - stateIndex: 5, - voteOptionIndex: 4, - nonce: 1, - pollId: 0, - newVoteWeight: 5, - }, - { - quiet: true, - pubkey: user.pubKey.serialize(), - privateKey: user.privKey.serialize(), - stateIndex: 4, - voteOptionIndex: 4, - nonce: 2, - pollId: 0, - newVoteWeight: 4, - }, - { - quiet: true, - pubkey: user.pubKey.serialize(), - privateKey: user.privKey.serialize(), - stateIndex: 4, - voteOptionIndex: 3, - nonce: 1, - pollId: 0, - newVoteWeight: 4, - }, - { - quiet: true, - pubkey: user.pubKey.serialize(), - privateKey: user.privKey.serialize(), - stateIndex: 3, - voteOptionIndex: 3, - nonce: 2, - pollId: 0, - newVoteWeight: 3, - }, - { - quiet: true, - pubkey: user.pubKey.serialize(), - privateKey: user.privKey.serialize(), - stateIndex: 2, - voteOptionIndex: 2, - nonce: 2, - pollId: 0, - newVoteWeight: 2, - }, - { - quiet: true, - pubkey: user.pubKey.serialize(), - privateKey: user.privKey.serialize(), - stateIndex: 2, - voteOptionIndex: 1, - nonce: 1, - pollId: 0, - newVoteWeight: 2, - }, - { - quiet: true, - pubkey: user.pubKey.serialize(), - privateKey: user.privKey.serialize(), - stateIndex: 1, - voteOptionIndex: 1, - nonce: 2, - pollId: 0, - newVoteWeight: 1, - }, - { - quiet: true, - pubkey: user.pubKey.serialize(), - privateKey: user.privKey.serialize(), - stateIndex: 1, - voteOptionIndex: 0, - nonce: 1, - pollId: 0, - newVoteWeight: 1, - }, - ]; - - before(async () => { - // deploy the smart contracts - maciAddresses = await deploy(STATE_TREE_DEPTH); - // deploy a poll contract - pollAddresses = await deployPoll( - pollDuration, - maxMessages, - maxVoteOptions, - INT_STATE_TREE_DEPTH, - MSG_BATCH_DEPTH, - MSG_TREE_DEPTH, - VOTE_OPTION_TREE_DEPTH, - coordinatorPubKey, - ); - }); - - it("should signup an user", async () => { - // eslint-disable-next-line @typescript-eslint/prefer-for-of - for (let i = 0; i < 6; i += 1) { - // eslint-disable-next-line no-await-in-loop - await signup(publishArgs[i].pubkey); - } - }); - - it("should publish all messages", async () => { - // eslint-disable-next-line @typescript-eslint/prefer-for-of - for (let i = 0; i < publishArgs.length; i += 1) { - // eslint-disable-next-line no-await-in-loop - await publish( - publishArgs[i].pubkey, - publishArgs[i].stateIndex, - publishArgs[i].voteOptionIndex, - publishArgs[i].nonce, - publishArgs[i].pollId, - publishArgs[i].newVoteWeight, - maciAddresses.maciAddress, - genRandomSalt().toString(), - publishArgs[i].privateKey, - ); - } - }); - - it("should generate zk-SNARK proofs and verify them", async () => { - await timeTravel(pollDuration, true); - await mergeMessages(0); - await mergeSignups(0); - const tallyData = await genProofs( - testProofsDirPath, - testTallyFilePath, - tallyVotesTestZkeyPath, - processMessageTestZkeyPath, - 0, - testSubsidyFilePath, - subsidyTestZkeyPath, - testRapidsnarkPath, - testProcessMessagesWitnessPath, - testTallyVotesWitnessPath, - testSubsidyWitnessPath, - coordinatorPrivKey, - maciAddresses.maciAddress, - undefined, - testProcessMessagesWasmPath, - testTallyVotesWasmPath, - testSubsidyWasmPath, - useWasm, - ); - await proveOnChain("0", testProofsDirPath); - await verify( - "0", - testTallyFilePath, - tallyData, - maciAddresses.maciAddress, - pollAddresses.tally, - pollAddresses.subsidy, - testSubsidyFilePath, - ); - }); - }); - - describe("multiplePolls1", () => { - after(() => { - cleanSubsidy(); - }); - - const user = new Keypair(); - - before(async () => { - // deploy the smart contracts - maciAddresses = await deploy(STATE_TREE_DEPTH); - // deploy a poll contract - pollAddresses = await deployPoll( - pollDuration, - 25, - 25, - INT_STATE_TREE_DEPTH, - MSG_BATCH_DEPTH, - MSG_TREE_DEPTH, - VOTE_OPTION_TREE_DEPTH, - coordinatorPubKey, - ); - // signup - await signup(user.pubKey.serialize()); - // publish - await publish( - user.pubKey.serialize(), - 1, - 0, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - user.privKey.serialize(), - ); - // time travel - await timeTravel(pollDuration, true); - // generate proofs - await mergeMessages(0); - await mergeSignups(0); - const tallyData = await genProofs( - testProofsDirPath, - testTallyFilePath, - tallyVotesTestZkeyPath, - processMessageTestZkeyPath, - 0, - testSubsidyFilePath, - subsidyTestZkeyPath, - testRapidsnarkPath, - testProcessMessagesWitnessPath, - testTallyVotesWitnessPath, - testSubsidyWitnessPath, - coordinatorPrivKey, - maciAddresses.maciAddress, - undefined, - testProcessMessagesWasmPath, - testTallyVotesWasmPath, - testSubsidyWasmPath, - useWasm, - ); - await proveOnChain("0", testProofsDirPath); - await verify( - "0", - testTallyFilePath, - tallyData, - maciAddresses.maciAddress, - pollAddresses.tally, - pollAddresses.subsidy, - testSubsidyFilePath, - ); - cleanSubsidy(); - }); - - it("should deploy a new poll", async () => { - pollAddresses = await deployPoll( - pollDuration, - maxMessages, - maxVoteOptions, - INT_STATE_TREE_DEPTH, - MSG_BATCH_DEPTH, - MSG_TREE_DEPTH, - VOTE_OPTION_TREE_DEPTH, - coordinatorPubKey, - ); - }); - it("should publish a new message", async () => { - await publish(user.pubKey.serialize(), 1, 0, 1, 1, 7, undefined, undefined, user.privKey.serialize()); - }); - it("should generate proofs and verify them", async () => { - await timeTravel(pollDuration, true); - await mergeMessages(1); - await mergeSignups(1); - const tallyData = await genProofs( - testProofsDirPath, - testTallyFilePath, - tallyVotesTestZkeyPath, - processMessageTestZkeyPath, - 1, - testSubsidyFilePath, - subsidyTestZkeyPath, - testRapidsnarkPath, - testProcessMessagesWitnessPath, - testTallyVotesWitnessPath, - testSubsidyWitnessPath, - coordinatorPrivKey, - maciAddresses.maciAddress, - undefined, - testProcessMessagesWasmPath, - testTallyVotesWasmPath, - testSubsidyWasmPath, - useWasm, - ); - await proveOnChain("1", testProofsDirPath); - await verify( - "1", - testTallyFilePath, - tallyData, - maciAddresses.maciAddress, - pollAddresses.tally, - pollAddresses.subsidy, - testSubsidyFilePath, - ); - }); - }); - describe("multiplePolls2", () => { const users = [ new Keypair(), diff --git a/cli/tests/e2e.test.ts b/cli/tests/e2e/e2e.test.ts similarity index 82% rename from cli/tests/e2e.test.ts rename to cli/tests/e2e/e2e.test.ts index 87dd48e779..13d0ab394e 100644 --- a/cli/tests/e2e.test.ts +++ b/cli/tests/e2e/e2e.test.ts @@ -20,9 +20,8 @@ import { timeTravel, topup, verify, -} from "../ts/commands"; -import { DeployedContracts, PollContracts } from "../ts/utils"; - +} from "../../ts/commands"; +import { DeployedContracts, PollContracts } from "../../ts/utils"; import { INT_STATE_TREE_DEPTH, MSG_BATCH_DEPTH, @@ -43,8 +42,8 @@ import { testTallyFilePath, testTallyVotesWasmPath, testTallyVotesWitnessPath, -} from "./constants"; -import { cleanVanilla, isArm } from "./utils"; +} from "../constants"; +import { cleanVanilla, isArm } from "../utils"; /** Test scenarios: @@ -53,12 +52,10 @@ import { cleanVanilla, isArm } from "./utils"; 5 signups, 1 message 8 signups, 10 messages 4 signups, 4 messages - 5 signups, 5 messages test if keys are set correctly given a set of files - test if key change works - multiple batch: Sign up 6 times, Publish 6 times 1 signup and 1 valid message for multiple polls 7 signups and 1 message, another polls and 6 messages + 1 signup, 1 topup message and 1 vote message */ describe("e2e tests", function test() { const useWasm = isArm(); @@ -83,7 +80,7 @@ describe("e2e tests", function test() { ); }); - describe("test1", () => { + describe("1 signup, 1 message", () => { after(() => { cleanVanilla(); }); @@ -160,7 +157,7 @@ describe("e2e tests", function test() { }); }); - describe("test2", () => { + describe("4 signups, 4 messages", () => { after(() => { cleanVanilla(); }); @@ -173,8 +170,8 @@ describe("e2e tests", function test() { // deploy a poll contract pollAddresses = await deployPoll( pollDuration, - maxMessages, - maxVoteOptions, + 25, + 25, INT_STATE_TREE_DEPTH, MSG_BATCH_DEPTH, MSG_TREE_DEPTH, @@ -191,7 +188,7 @@ describe("e2e tests", function test() { } }); - it("should publish six messages", async () => { + it("should publish four messages", async () => { await publish( users[0].pubKey.serialize(), 1, @@ -234,119 +231,6 @@ describe("e2e tests", function test() { 9, maciAddresses.maciAddress, genRandomSalt().toString(), - users[3].privKey.serialize(), - ); - await publish( - users[3].pubKey.serialize(), - 4, - 3, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - users[3].privKey.serialize(), - ); - await publish( - users[3].pubKey.serialize(), - 4, - 3, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - users[3].privKey.serialize(), - ); - }); - - it("should generate zk-SNARK proofs and verify them", async () => { - await timeTravel(pollDuration); - await mergeMessages(0, maciAddresses.maciAddress); - await mergeSignups(0, maciAddresses.maciAddress); - const tallyFileData = await genProofs( - testProofsDirPath, - testTallyFilePath, - tallyVotesTestZkeyPath, - processMessageTestZkeyPath, - 0, - undefined, - undefined, - testRapidsnarkPath, - testProcessMessagesWitnessPath, - testTallyVotesWitnessPath, - undefined, - coordinatorPrivKey, - maciAddresses.maciAddress, - undefined, - testProcessMessagesWasmPath, - testTallyVotesWasmPath, - undefined, - useWasm, - ); - await proveOnChain("0", testProofsDirPath); - await verify( - "0", - testTallyFilePath, - tallyFileData, - maciAddresses.maciAddress, - pollAddresses.tally, - pollAddresses.subsidy, - ); - }); - }); - - describe("test3", () => { - after(() => { - cleanVanilla(); - }); - - const users = [ - new Keypair(), - new Keypair(), - new Keypair(), - new Keypair(), - new Keypair(), - new Keypair(), - new Keypair(), - new Keypair(), - new Keypair(), - ]; - - before(async () => { - // deploy the smart contracts - maciAddresses = await deploy(STATE_TREE_DEPTH); - // deploy a poll contract - pollAddresses = await deployPoll( - pollDuration, - 25, - 25, - INT_STATE_TREE_DEPTH, - MSG_BATCH_DEPTH, - MSG_TREE_DEPTH, - VOTE_OPTION_TREE_DEPTH, - coordinatorPubKey, - ); - }); - - it("should signup nine users", async () => { - // eslint-disable-next-line @typescript-eslint/prefer-for-of - for (let i = 0; i < users.length; i += 1) { - // eslint-disable-next-line no-await-in-loop - await signup(users[i].pubKey.serialize()); - } - }); - - it("should publish one message", async () => { - await publish( - users[0].pubKey.serialize(), - 1, - 0, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), users[0].privKey.serialize(), ); }); @@ -387,90 +271,7 @@ describe("e2e tests", function test() { }); }); - describe("test4", () => { - after(() => { - cleanVanilla(); - }); - - const user = new Keypair(); - - before(async () => { - // deploy the smart contracts - maciAddresses = await deploy(STATE_TREE_DEPTH); - // deploy a poll contract - pollAddresses = await deployPoll( - pollDuration, - 25, - 25, - INT_STATE_TREE_DEPTH, - MSG_BATCH_DEPTH, - MSG_TREE_DEPTH, - VOTE_OPTION_TREE_DEPTH, - coordinatorPubKey, - ); - }); - - it("should signup eight users (same pub key)", async () => { - for (let i = 0; i < 8; i += 1) { - // eslint-disable-next-line no-await-in-loop - await signup(user.pubKey.serialize()); - } - }); - - it("should publish 12 messages with the same nonce", async () => { - for (let i = 0; i < 12; i += 1) { - // eslint-disable-next-line no-await-in-loop - await publish( - user.pubKey.serialize(), - 1, - 0, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - user.privKey.serialize(), - ); - } - }); - - it("should generate zk-SNARK proofs and verify them", async () => { - await timeTravel(pollDuration); - await mergeMessages(0, maciAddresses.maciAddress); - await mergeSignups(0, maciAddresses.maciAddress); - const tallyFileData = await genProofs( - testProofsDirPath, - testTallyFilePath, - tallyVotesTestZkeyPath, - processMessageTestZkeyPath, - 0, - undefined, - undefined, - testRapidsnarkPath, - testProcessMessagesWitnessPath, - testTallyVotesWitnessPath, - undefined, - coordinatorPrivKey, - maciAddresses.maciAddress, - undefined, - testProcessMessagesWasmPath, - testTallyVotesWasmPath, - undefined, - useWasm, - ); - await proveOnChain("0", testProofsDirPath); - await verify( - "0", - testTallyFilePath, - tallyFileData, - maciAddresses.maciAddress, - pollAddresses.tally, - pollAddresses.subsidy, - ); - }); - }); - - describe("test5", () => { + describe("4 signups, 6 messages", () => { after(() => { cleanVanilla(); }); @@ -483,8 +284,8 @@ describe("e2e tests", function test() { // deploy a poll contract pollAddresses = await deployPoll( pollDuration, - 25, - 25, + maxMessages, + maxVoteOptions, INT_STATE_TREE_DEPTH, MSG_BATCH_DEPTH, MSG_TREE_DEPTH, @@ -501,7 +302,7 @@ describe("e2e tests", function test() { } }); - it("should publish four messages", async () => { + it("should publish six messages", async () => { await publish( users[0].pubKey.serialize(), 1, @@ -544,7 +345,29 @@ describe("e2e tests", function test() { 9, maciAddresses.maciAddress, genRandomSalt().toString(), - users[0].privKey.serialize(), + users[3].privKey.serialize(), + ); + await publish( + users[3].pubKey.serialize(), + 4, + 3, + 1, + 0, + 9, + maciAddresses.maciAddress, + genRandomSalt().toString(), + users[3].privKey.serialize(), + ); + await publish( + users[3].pubKey.serialize(), + 4, + 3, + 1, + 0, + 9, + maciAddresses.maciAddress, + genRandomSalt().toString(), + users[3].privKey.serialize(), ); }); @@ -584,12 +407,22 @@ describe("e2e tests", function test() { }); }); - describe("test6", () => { + describe("5 signups, 1 message", () => { after(() => { cleanVanilla(); }); - const users = [new Keypair(), new Keypair(), new Keypair(), new Keypair(), new Keypair()]; + const users = [ + new Keypair(), + new Keypair(), + new Keypair(), + new Keypair(), + new Keypair(), + new Keypair(), + new Keypair(), + new Keypair(), + new Keypair(), + ]; before(async () => { // deploy the smart contracts @@ -597,8 +430,8 @@ describe("e2e tests", function test() { // deploy a poll contract pollAddresses = await deployPoll( pollDuration, - maxMessages, - maxVoteOptions, + 25, + 25, INT_STATE_TREE_DEPTH, MSG_BATCH_DEPTH, MSG_TREE_DEPTH, @@ -607,7 +440,7 @@ describe("e2e tests", function test() { ); }); - it("should signup five users", async () => { + it("should signup nine users", async () => { // eslint-disable-next-line @typescript-eslint/prefer-for-of for (let i = 0; i < users.length; i += 1) { // eslint-disable-next-line no-await-in-loop @@ -615,7 +448,7 @@ describe("e2e tests", function test() { } }); - it("should publish five messages", async () => { + it("should publish one message", async () => { await publish( users[0].pubKey.serialize(), 1, @@ -627,50 +460,6 @@ describe("e2e tests", function test() { genRandomSalt().toString(), users[0].privKey.serialize(), ); - await publish( - users[1].pubKey.serialize(), - 2, - 1, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - users[1].privKey.serialize(), - ); - await publish( - users[2].pubKey.serialize(), - 3, - 2, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - users[2].privKey.serialize(), - ); - await publish( - users[3].pubKey.serialize(), - 4, - 3, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - users[3].privKey.serialize(), - ); - await publish( - users[4].pubKey.serialize(), - 5, - 4, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - users[4].privKey.serialize(), - ); }); it("should generate zk-SNARK proofs and verify them", async () => { @@ -709,31 +498,12 @@ describe("e2e tests", function test() { }); }); - describe("checkKeys", () => { - before(async () => { - // deploy maci as we need the address - await deploy(STATE_TREE_DEPTH); - }); - it("should check if the verifying keys have been set correctly", async () => { - await checkVerifyingKeys( - STATE_TREE_DEPTH, - INT_STATE_TREE_DEPTH, - MSG_TREE_DEPTH, - VOTE_OPTION_TREE_DEPTH, - MSG_BATCH_DEPTH, - processMessageTestZkeyPath, - tallyVotesTestZkeyPath, - ); - }); - }); - - describe("keyChange", () => { + describe("8 signups (same key), 12 messages (same message)", () => { after(() => { cleanVanilla(); }); - const key1 = new Keypair(); - const key2 = new Keypair(); + const user = new Keypair(); before(async () => { // deploy the smart contracts @@ -741,56 +511,38 @@ describe("e2e tests", function test() { // deploy a poll contract pollAddresses = await deployPoll( pollDuration, - maxMessages, - maxVoteOptions, + 25, + 25, INT_STATE_TREE_DEPTH, MSG_BATCH_DEPTH, MSG_TREE_DEPTH, VOTE_OPTION_TREE_DEPTH, coordinatorPubKey, ); - // signup a user - await signup(key1.pubKey.serialize()); - // publish messages - await publish( - key1.pubKey.serialize(), - 1, - 0, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - key1.privKey.serialize(), - ); }); - it("should publish a message to change the user maci key", async () => { - await publish( - key1.pubKey.serialize(), - 1, - 0, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - key1.privKey.serialize(), - ); + it("should signup eight users (same pub key)", async () => { + for (let i = 0; i < 8; i += 1) { + // eslint-disable-next-line no-await-in-loop + await signup(user.pubKey.serialize()); + } }); - it("should vote for a different option using the new key", async () => { - await publish( - key2.pubKey.serialize(), - 1, - 1, - 1, - 0, - 9, - maciAddresses.maciAddress, - genRandomSalt().toString(), - key2.privKey.serialize(), - ); + it("should publish 12 messages with the same nonce", async () => { + for (let i = 0; i < 12; i += 1) { + // eslint-disable-next-line no-await-in-loop + await publish( + user.pubKey.serialize(), + 1, + 0, + 1, + 0, + 9, + maciAddresses.maciAddress, + genRandomSalt().toString(), + user.privKey.serialize(), + ); + } }); it("should generate zk-SNARK proofs and verify them", async () => { @@ -829,6 +581,24 @@ describe("e2e tests", function test() { }); }); + describe("checkKeys", () => { + before(async () => { + // deploy maci as we need the address + await deploy(STATE_TREE_DEPTH); + }); + it("should check if the verifying keys have been set correctly", async () => { + await checkVerifyingKeys( + STATE_TREE_DEPTH, + INT_STATE_TREE_DEPTH, + MSG_TREE_DEPTH, + VOTE_OPTION_TREE_DEPTH, + MSG_BATCH_DEPTH, + processMessageTestZkeyPath, + tallyVotesTestZkeyPath, + ); + }); + }); + describe("multiplePolls1", () => { after(() => { cleanVanilla(); diff --git a/cli/tests/keyChange.test.ts b/cli/tests/e2e/keyChange.test.ts similarity index 98% rename from cli/tests/keyChange.test.ts rename to cli/tests/e2e/keyChange.test.ts index 7f6249226b..360068357a 100644 --- a/cli/tests/keyChange.test.ts +++ b/cli/tests/e2e/keyChange.test.ts @@ -4,7 +4,7 @@ import { Keypair } from "maci-domainobjs"; import fs from "fs"; -import { DeployedContracts, TallyData } from "../ts"; +import { DeployedContracts, TallyData } from "../../ts"; import { deploy, deployPoll, @@ -18,8 +18,7 @@ import { signup, timeTravel, verify, -} from "../ts/commands"; - +} from "../../ts/commands"; import { INT_STATE_TREE_DEPTH, MSG_BATCH_DEPTH, @@ -37,8 +36,8 @@ import { testTallyFilePath, testTallyVotesWasmPath, testTallyVotesWitnessPath, -} from "./constants"; -import { cleanVanilla, isArm } from "./utils"; +} from "../constants"; +import { cleanVanilla, isArm } from "../utils"; describe("keyChange tests", function test() { const useWasm = isArm(); diff --git a/cli/tests/unit/airdrop.test.ts b/cli/tests/unit/airdrop.test.ts new file mode 100644 index 0000000000..e06ce77dfc --- /dev/null +++ b/cli/tests/unit/airdrop.test.ts @@ -0,0 +1,26 @@ +import { expect } from "chai"; +import { ZeroAddress } from "ethers"; +import { deployTopupCredit } from "maci-contracts"; + +import { airdrop } from "../../ts"; + +describe("airdrop", () => { + let topupContractAddress: string | undefined; + + before(async () => { + const topupContract = await deployTopupCredit(); + topupContractAddress = await topupContract.getAddress(); + }); + + it("should airdrop tokens to the coordinator", async () => { + await expect(airdrop(100, topupContractAddress)).to.be.fulfilled; + }); + + it("should throw when the amount is negative", async () => { + await expect(airdrop(-1, topupContractAddress)).to.be.rejectedWith("Invalid amount"); + }); + + it("should throw when the ERC20 contract address is invalid", async () => { + await expect(airdrop(100, ZeroAddress)).to.be.rejectedWith("Invalid ERC20 contract address"); + }); +}); diff --git a/cli/tests/unit/data/testVk.json b/cli/tests/unit/data/testVk.json new file mode 100644 index 0000000000..9dc76b1056 --- /dev/null +++ b/cli/tests/unit/data/testVk.json @@ -0,0 +1,94 @@ +{ + "protocol": "groth16", + "curve": "bn128", + "nPublic": 1, + "vk_alpha_1": [ + "20491192805390485299153009773594534940189261866228447918068658471970481763042", + "9383485363053290200918347156157836566562967994039712273449902621266178545958", + "1" + ], + "vk_beta_2": [ + [ + "6375614351688725206403948262868962793625744043794305715222011528459656738731", + "4252822878758300859123897981450591353533073413197771768651442665752259397132" + ], + [ + "10505242626370262277552901082094356697409835680220590971873171140371331206856", + "21847035105528745403288232691147584728191162732299865338377159692350059136679" + ], + [ + "1", + "0" + ] + ], + "vk_gamma_2": [ + [ + "10857046999023057135944570762232829481370756359578518086990519993285655852781", + "11559732032986387107991004021392285783925812861821192530917403151452391805634" + ], + [ + "8495653923123431417604973247489272438418190587263600148770280649306958101930", + "4082367875863433681332203403145435568316851327593401208105741076214120093531" + ], + [ + "1", + "0" + ] + ], + "vk_delta_2": [ + [ + "10857046999023057135944570762232829481370756359578518086990519993285655852781", + "11559732032986387107991004021392285783925812861821192530917403151452391805634" + ], + [ + "8495653923123431417604973247489272438418190587263600148770280649306958101930", + "4082367875863433681332203403145435568316851327593401208105741076214120093531" + ], + [ + "1", + "0" + ] + ], + "vk_alphabeta_12": [ + [ + [ + "2029413683389138792403550203267699914886160938906632433982220835551125967885", + "21072700047562757817161031222997517981543347628379360635925549008442030252106" + ], + [ + "5940354580057074848093997050200682056184807770593307860589430076672439820312", + "12156638873931618554171829126792193045421052652279363021382169897324752428276" + ], + [ + "7898200236362823042373859371574133993780991612861777490112507062703164551277", + "7074218545237549455313236346927434013100842096812539264420499035217050630853" + ] + ], + [ + [ + "7077479683546002997211712695946002074877511277312570035766170199895071832130", + "10093483419865920389913245021038182291233451549023025229112148274109565435465" + ], + [ + "4595479056700221319381530156280926371456704509942304414423590385166031118820", + "19831328484489333784475432780421641293929726139240675179672856274388269393268" + ], + [ + "11934129596455521040620786944827826205713621633706285934057045369193958244500", + "8037395052364110730298837004334506829870972346962140206007064471173334027475" + ] + ] + ], + "IC": [ + [ + "10217961970561191542644673983819768829937049061556810432559046731768416748444", + "6614275190456400384394041626145087414551326824635999101683327156828330915037", + "1" + ], + [ + "11971344866240172007938968889867162918709454623842568616296127157079254314975", + "10060981430167258432297298832690153434217272087448231305232740724870906593798", + "1" + ] + ] +} diff --git a/cli/tests/unit/fundWallet.test.ts b/cli/tests/unit/fundWallet.test.ts new file mode 100644 index 0000000000..4249daa1b8 --- /dev/null +++ b/cli/tests/unit/fundWallet.test.ts @@ -0,0 +1,16 @@ +import { expect } from "chai"; +import { ZeroAddress } from "ethers"; +import { getDefaultSigner } from "maci-contracts"; + +import { fundWallet } from "../../ts"; + +describe("fundWallet", () => { + it("should increase the balance of a wallet", async () => { + const signer = await getDefaultSigner(); + + const balanceBefore = await signer.provider?.getBalance(ZeroAddress); + await fundWallet(1000000000, ZeroAddress); + const balanceAfter = await signer.provider?.getBalance(ZeroAddress); + expect(balanceAfter).to.be.gt(balanceBefore!); + }); +}); diff --git a/integrationTests/ts/__tests__/cli-genMaciKeypair.test.ts b/cli/tests/unit/genKeyPair.test.ts similarity index 96% rename from integrationTests/ts/__tests__/cli-genMaciKeypair.test.ts rename to cli/tests/unit/genKeyPair.test.ts index 108598e36c..dbc2dbf253 100644 --- a/integrationTests/ts/__tests__/cli-genMaciKeypair.test.ts +++ b/cli/tests/unit/genKeyPair.test.ts @@ -1,8 +1,9 @@ import { expect } from "chai"; -import { genKeyPair } from "maci-cli"; import { genPubKey } from "maci-crypto"; import { PubKey, PrivKey } from "maci-domainobjs"; +import { genKeyPair } from "../../ts"; + describe("genMaciKeypair CLI subcommand", () => { it("genMaciKeypair should output a random private key and public key", () => { const keypair1 = genKeyPair(true); diff --git a/integrationTests/ts/__tests__/cli-genMaciPubkey.test.ts b/cli/tests/unit/genPubkey.test.ts similarity index 72% rename from integrationTests/ts/__tests__/cli-genMaciPubkey.test.ts rename to cli/tests/unit/genPubkey.test.ts index 0470a31bb4..6ced0877dd 100644 --- a/integrationTests/ts/__tests__/cli-genMaciPubkey.test.ts +++ b/cli/tests/unit/genPubkey.test.ts @@ -1,10 +1,11 @@ import { expect } from "chai"; -import { genKeyPair, genMaciPubKey } from "maci-cli"; import { genPubKey } from "maci-crypto"; import { PubKey, PrivKey } from "maci-domainobjs"; +import { genKeyPair, genMaciPubKey } from "../../ts"; + describe("genMaciPubkey CLI subcommand", () => { - it("genMaciPubkey should output a correct public key", () => { + it("should output a valid public key", () => { const keypair = genKeyPair(true); const pubKey = genMaciPubKey(keypair.privateKey, true); @@ -16,4 +17,8 @@ describe("genMaciPubkey CLI subcommand", () => { expect(unserializedPk.rawPubKey[0].toString()).to.eq(pk2[0].toString()); expect(unserializedPk.rawPubKey[1].toString()).to.eq(pk2[1].toString()); }); + + it("should throw when given an invalid private key", () => { + expect(() => genMaciPubKey("invalid", true)).to.throw("Invalid private key"); + }); }); diff --git a/cli/tests/unit/timeTravel.test.ts b/cli/tests/unit/timeTravel.test.ts new file mode 100644 index 0000000000..b387aed234 --- /dev/null +++ b/cli/tests/unit/timeTravel.test.ts @@ -0,0 +1,16 @@ +import { expect } from "chai"; +import { getDefaultSigner } from "maci-contracts"; + +import { timeTravel } from "../../ts"; + +describe("timeTravel", () => { + it("should work when given a valid integer number", async () => { + const signer = await getDefaultSigner(); + const blockNumber = await signer.provider?.getBlock("latest"); + + await expect(timeTravel(5)).to.be.fulfilled; + + const blockNumberAfter = await signer.provider?.getBlock("latest"); + expect(blockNumberAfter!.timestamp).to.be.gt(blockNumber!.timestamp); + }); +}); diff --git a/cli/tests/unit/topup.test.ts b/cli/tests/unit/topup.test.ts new file mode 100644 index 0000000000..2090973608 --- /dev/null +++ b/cli/tests/unit/topup.test.ts @@ -0,0 +1,47 @@ +import { expect } from "chai"; +import { Signer } from "ethers"; +import { + deployConstantInitialVoiceCreditProxy, + deployFreeForAllSignUpGatekeeper, + deployMaci, + deployMockVerifier, + deployTopupCredit, + getDefaultSigner, +} from "maci-contracts"; + +import { topup } from "../../ts"; + +describe("topup", () => { + let signer: Signer; + let maciAddress: string; + + before(async () => { + signer = await getDefaultSigner(); + const signupGatekepper = await deployFreeForAllSignUpGatekeeper(signer, true); + const verifier = await deployMockVerifier(signer, true); + const topupCredit = await deployTopupCredit(signer, true); + const initialVoiceCreditProxyAddress = await deployConstantInitialVoiceCreditProxy(100, signer, true); + const maciContracts = await deployMaci( + await signupGatekepper.getAddress(), + await initialVoiceCreditProxyAddress.getAddress(), + await verifier.getAddress(), + await topupCredit.getAddress(), + signer, + 10, + true, + ); + maciAddress = await maciContracts.maciContract.getAddress(); + }); + + it("should throw when the state index is invalid", async () => { + await expect(topup(100, 0, 0, maciAddress)).to.be.rejectedWith("State index must be greater than 0"); + }); + + it("should throw when the poll ID is invalid", async () => { + await expect(topup(100, 1, -1, maciAddress)).to.be.rejectedWith("Poll ID must be a positive integer"); + }); + + it("should throw when the amount is invalid", async () => { + await expect(topup(0, 1, 0, maciAddress)).to.be.rejectedWith("Topup amount must be greater than 0"); + }); +}); diff --git a/cli/tests/unit/utils.test.ts b/cli/tests/unit/utils.test.ts new file mode 100644 index 0000000000..7e17314408 --- /dev/null +++ b/cli/tests/unit/utils.test.ts @@ -0,0 +1,36 @@ +import { expect } from "chai"; +import { SNARK_FIELD_SIZE, genRandomSalt } from "maci-crypto"; +import { VerifyingKey } from "maci-domainobjs"; + +import fs from "fs"; +import path from "path"; + +import { compareVks } from "../../ts/utils"; +import { validateSalt } from "../../ts/utils/salt"; + +describe("utils", () => { + const vkPath = path.resolve(__dirname, "data", "testVk.json"); + const vk1 = VerifyingKey.fromJSON(fs.readFileSync(vkPath).toString()); + + describe("vks", () => { + it("should return true for two equal VKs", () => { + expect(compareVks(vk1, vk1.asContractParam())).to.eq(true); + }); + + it("should return false for two unequal VKs", () => { + const vk2 = vk1.asContractParam(); + vk2.alpha1.x = 9999n; + expect(compareVks(vk1, vk2)).to.eq(false); + }); + }); + + describe("validateSalt", () => { + it("should return true for a valid salt", () => { + expect(validateSalt(genRandomSalt().toString())).to.eq(true); + }); + + it("should return false for an invalid salt", () => { + expect(validateSalt(SNARK_FIELD_SIZE.toString())).to.eq(false); + }); + }); +}); diff --git a/contracts/hardhat.config.ts b/contracts/hardhat.config.ts index 4ace0da419..31a29ca13e 100644 --- a/contracts/hardhat.config.ts +++ b/contracts/hardhat.config.ts @@ -20,6 +20,7 @@ const config: HardhatUserConfig = { hardhat: { accounts: { mnemonic: "candy maple cake sugar pudding cream honey rich smooth crumble sweet treat", + count: 20, }, loggingEnabled: false, allowUnlimitedContractSize: true, diff --git a/domainobjs/ts/__tests__/artifacts/test_vk.json b/domainobjs/ts/__tests__/artifacts/test_vk.json index 88f3006178..9dc76b1056 100644 --- a/domainobjs/ts/__tests__/artifacts/test_vk.json +++ b/domainobjs/ts/__tests__/artifacts/test_vk.json @@ -1,94 +1,94 @@ { - "protocol": "groth16", - "curve": "bn128", - "nPublic": 1, - "vk_alpha_1": [ - "20491192805390485299153009773594534940189261866228447918068658471970481763042", - "9383485363053290200918347156157836566562967994039712273449902621266178545958", - "1" - ], - "vk_beta_2": [ - [ - "6375614351688725206403948262868962793625744043794305715222011528459656738731", - "4252822878758300859123897981450591353533073413197771768651442665752259397132" - ], - [ - "10505242626370262277552901082094356697409835680220590971873171140371331206856", - "21847035105528745403288232691147584728191162732299865338377159692350059136679" - ], - [ - "1", - "0" - ] - ], - "vk_gamma_2": [ - [ + "protocol": "groth16", + "curve": "bn128", + "nPublic": 1, + "vk_alpha_1": [ + "20491192805390485299153009773594534940189261866228447918068658471970481763042", + "9383485363053290200918347156157836566562967994039712273449902621266178545958", + "1" + ], + "vk_beta_2": [ + [ + "6375614351688725206403948262868962793625744043794305715222011528459656738731", + "4252822878758300859123897981450591353533073413197771768651442665752259397132" + ], + [ + "10505242626370262277552901082094356697409835680220590971873171140371331206856", + "21847035105528745403288232691147584728191162732299865338377159692350059136679" + ], + [ + "1", + "0" + ] + ], + "vk_gamma_2": [ + [ "10857046999023057135944570762232829481370756359578518086990519993285655852781", "11559732032986387107991004021392285783925812861821192530917403151452391805634" - ], - [ + ], + [ "8495653923123431417604973247489272438418190587263600148770280649306958101930", "4082367875863433681332203403145435568316851327593401208105741076214120093531" - ], - [ + ], + [ "1", "0" - ] - ], - "vk_delta_2": [ - [ + ] + ], + "vk_delta_2": [ + [ "10857046999023057135944570762232829481370756359578518086990519993285655852781", "11559732032986387107991004021392285783925812861821192530917403151452391805634" - ], - [ + ], + [ "8495653923123431417604973247489272438418190587263600148770280649306958101930", "4082367875863433681332203403145435568316851327593401208105741076214120093531" - ], - [ + ], + [ "1", "0" - ] - ], - "vk_alphabeta_12": [ - [ + ] + ], + "vk_alphabeta_12": [ + [ [ - "2029413683389138792403550203267699914886160938906632433982220835551125967885", - "21072700047562757817161031222997517981543347628379360635925549008442030252106" + "2029413683389138792403550203267699914886160938906632433982220835551125967885", + "21072700047562757817161031222997517981543347628379360635925549008442030252106" ], [ - "5940354580057074848093997050200682056184807770593307860589430076672439820312", - "12156638873931618554171829126792193045421052652279363021382169897324752428276" + "5940354580057074848093997050200682056184807770593307860589430076672439820312", + "12156638873931618554171829126792193045421052652279363021382169897324752428276" ], [ - "7898200236362823042373859371574133993780991612861777490112507062703164551277", - "7074218545237549455313236346927434013100842096812539264420499035217050630853" + "7898200236362823042373859371574133993780991612861777490112507062703164551277", + "7074218545237549455313236346927434013100842096812539264420499035217050630853" ] - ], - [ + ], + [ [ - "7077479683546002997211712695946002074877511277312570035766170199895071832130", - "10093483419865920389913245021038182291233451549023025229112148274109565435465" + "7077479683546002997211712695946002074877511277312570035766170199895071832130", + "10093483419865920389913245021038182291233451549023025229112148274109565435465" ], [ - "4595479056700221319381530156280926371456704509942304414423590385166031118820", - "19831328484489333784475432780421641293929726139240675179672856274388269393268" + "4595479056700221319381530156280926371456704509942304414423590385166031118820", + "19831328484489333784475432780421641293929726139240675179672856274388269393268" ], [ - "11934129596455521040620786944827826205713621633706285934057045369193958244500", - "8037395052364110730298837004334506829870972346962140206007064471173334027475" + "11934129596455521040620786944827826205713621633706285934057045369193958244500", + "8037395052364110730298837004334506829870972346962140206007064471173334027475" ] - ] - ], - "IC": [ - [ + ] + ], + "IC": [ + [ "10217961970561191542644673983819768829937049061556810432559046731768416748444", "6614275190456400384394041626145087414551326824635999101683327156828330915037", "1" - ], - [ + ], + [ "11971344866240172007938968889867162918709454623842568616296127157079254314975", "10060981430167258432297298832690153434217272087448231305232740724870906593798", "1" - ] ] - } \ No newline at end of file + ] +} diff --git a/integrationTests/package.json b/integrationTests/package.json index 9b6f144d03..d4a1239e47 100644 --- a/integrationTests/package.json +++ b/integrationTests/package.json @@ -7,9 +7,7 @@ "watch": "tsc --watch", "build": "tsc", "test": "ts-mocha --exit ./ts/__tests__/**.test.ts", - "test:genMaciKeypair": "ts-mocha --exit ./ts/__tests__/cli-genMaciKeypair.test.ts", - "test:genMaciPubkey": "ts-mocha --exit ./ts/__tests__/cli-genMaciPubkey.test.ts", - "test:integration": "NODE_OPTIONS=--max-old-space-size=4096 ts-mocha --exit ./ts/__tests__/integration.test.ts", + "test:suites": "NODE_OPTIONS=--max-old-space-size=4096 ts-mocha --exit ./ts/__tests__/suites.test.ts", "test:maciKeys": "ts-mocha --exit ./ts/__tests__/maci-keys.test.ts", "download-zkeys": "./scripts/download_zkeys.sh" }, From 5b6aa9255907cd0e02f692ad7d8487f9bd9a70f3 Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Mon, 8 Jan 2024 14:30:57 +0000 Subject: [PATCH 33/37] test(integration): ensure integration tests are using the correct user keys --- .../ts/__tests__/integration.test.ts | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/integrationTests/ts/__tests__/integration.test.ts b/integrationTests/ts/__tests__/integration.test.ts index a9ce3ac91f..ee857bb4ca 100644 --- a/integrationTests/ts/__tests__/integration.test.ts +++ b/integrationTests/ts/__tests__/integration.test.ts @@ -167,18 +167,22 @@ describe("integration tests", function test() { // loop through all users and generate keypair + signup for (let i = 0; i < users.length; i += 1) { - // generate a keypair - const keypair = new Keypair(); + const user = users[i]; const timestamp = Date.now(); // signup - const stateIndex = await signup(keypair.pubKey.serialize(), contracts.maciAddress, SG_DATA, ivcpData, true); + const stateIndex = await signup( + user.keypair.pubKey.serialize(), + contracts.maciAddress, + SG_DATA, + ivcpData, + true, + ); // signup on local maci state - maciState.signUp(keypair.pubKey, BigInt(initialVoiceCredits), BigInt(timestamp)); + maciState.signUp(user.keypair.pubKey, BigInt(initialVoiceCredits), BigInt(timestamp)); // publish messages - for (let j = 0; j < users[i].votes.length; j += 1) { - const user = users[i]; + for (let j = 0; j < user.votes.length; j += 1) { const isKeyChange = testCase.changeUsersKeys && j in testCase.changeUsersKeys[i]; const voteOptionIndex = isKeyChange ? testCase.changeUsersKeys?.[i][j].voteOptionIndex @@ -186,12 +190,17 @@ describe("integration tests", function test() { const newVoteWeight = isKeyChange ? testCase.changeUsersKeys?.[i][j].voteWeight : user.votes[j].voteWeight; const { nonce } = user.votes[j]; const salt = `0x${genRandomSalt().toString(16)}`; - const userPrivKey = isKeyChange ? user.changeKeypair() : keypair.privKey; + + // store the previous keypair + const oldKeypair = user.keypair; + // change + if (isKeyChange) { + user.changeKeypair(); + } // actually publish it - // @todo if key change we also need a new pub key const encryptionKey = await publish( - keypair.pubKey.serialize(), + user.keypair.pubKey.serialize(), Number(stateIndex), voteOptionIndex!, nonce, @@ -199,7 +208,8 @@ describe("integration tests", function test() { newVoteWeight!, contracts.maciAddress, salt, - userPrivKey.serialize(), + // if it's a key change command, then we pass the old private key otherwise just pass the current + isKeyChange ? oldKeypair.privKey.serialize() : user.keypair.privKey.serialize(), true, ); @@ -209,14 +219,14 @@ describe("integration tests", function test() { // create the command to add to the local state const command = new PCommand( BigInt(stateIndex), - keypair.pubKey, + user.keypair.pubKey, BigInt(voteOptionIndex!), BigInt(newVoteWeight!), BigInt(nonce), BigInt(pollId), BigInt(salt), ); - const signature = command.sign(keypair.privKey); + const signature = command.sign(isKeyChange ? oldKeypair.privKey : user.keypair.privKey); const message = command.encrypt(signature, Keypair.genEcdhSharedKey(encPrivKey, coordinatorKeypair.pubKey)); maciState.polls[pollId].publishMessage(message, encPubKey); } From 61a8bcd915fd3e4b4da3c00d40704d892c02f51b Mon Sep 17 00:00:00 2001 From: 0xmad <0xmad@users.noreply.github.com> Date: Mon, 8 Jan 2024 10:32:21 -0600 Subject: [PATCH 34/37] chore: linter unification - [x] Use extended config versions of eslint and tsconfig --- .eslintrc.js | 115 ++++++++++++++++++++++++++++----- circuits/.eslintrc.js | 89 +------------------------ circuits/tsconfig.json | 28 +------- cli/.eslintrc.js | 89 +------------------------ cli/tsconfig.json | 28 +------- contracts/.eslintrc.js | 89 +------------------------ contracts/tsconfig.json | 28 +------- core/.eslintrc.js | 89 +------------------------ core/tsconfig.json | 31 +-------- crypto/.eslintrc.js | 89 +------------------------ crypto/tsconfig.json | 28 +------- domainobjs/.eslintrc.js | 89 +------------------------ domainobjs/tsconfig.json | 28 +------- integrationTests/.eslintrc.js | 89 +------------------------ integrationTests/tsconfig.json | 28 +------- tsconfig.json | 33 ++++++---- 16 files changed, 135 insertions(+), 835 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 5fc28a1ec3..1a6eeeb2c5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,24 +1,107 @@ +const fs = require("fs"); +const path = require("path"); + +const prettierConfig = fs.readFileSync(path.resolve(__dirname, "./.prettierrc"), "utf8"); +const prettierOptions = JSON.parse(prettierConfig); +const isProduction = process.env.NODE_ENV === "production"; + module.exports = { - parser: "@typescript-eslint/parser", - plugins: ["@typescript-eslint"], + root: true, extends: [ - "eslint:recommended", + "airbnb", + "prettier", + "plugin:import/recommended", "plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended", - "prettier", + "plugin:@typescript-eslint/recommended-type-checked", + "plugin:@typescript-eslint/strict", + "plugin:@typescript-eslint/strict-type-checked", + "plugin:@typescript-eslint/stylistic", + "plugin:@typescript-eslint/stylistic-type-checked", + "plugin:import/typescript", ], + plugins: ["json", "prettier", "unused-imports", "import", "@typescript-eslint"], + parser: "@typescript-eslint/parser", + env: { + node: true, + mocha: true, + es2022: true, + }, + settings: { + react: { + version: "999.999.999", + }, + "import/resolver": { + typescript: {}, + node: { + extensions: [".ts", ".js"], + moduleDirectory: ["node_modules", "ts", "src"], + }, + }, + }, + parserOptions: { + project: path.resolve(__dirname, "./tsconfig.json"), + sourceType: "module", + typescript: true, + ecmaVersion: 2022, + experimentalDecorators: true, + requireConfigFile: false, + ecmaFeatures: { + classes: true, + impliedStrict: true, + }, + warnOnUnsupportedTypeScriptVersion: true, + }, + reportUnusedDisableDirectives: isProduction, rules: { - "no-console": "off", - "no-debugger": "off", - "no-prototype-builtins": "off", - "no-constant-condition": ["error", { checkLoops: false }], - "no-empty": ["error", { allowEmptyCatch: true }], - "@typescript-eslint/no-var-requires": "off", - "@typescript-eslint/interface-name-prefix": "off", - "@typescript-eslint/ban-ts-ignore": "off", - "@typescript-eslint/no-use-before-define": "off", - "@typescript-eslint/camelcase": "off", - "@typescript-eslint/explicit-function-return-type": "off", - "@typescript-eslint/no-explicit-any": "off", + "import/no-cycle": ["error"], + "unused-imports/no-unused-imports": "error", + "import/no-extraneous-dependencies": [ + "error", + { + devDependencies: ["**/*.test.ts"], + }, + ], + "no-debugger": isProduction ? "error" : "off", + "no-console": "error", + "no-underscore-dangle": "error", + "no-redeclare": ["error", { builtinGlobals: true }], + "import/order": [ + "error", + { + groups: ["external", "builtin", "internal", "type", "parent", "sibling", "index", "object"], + alphabetize: { + order: "asc", + caseInsensitive: true, + }, + warnOnUnassignedImports: true, + "newlines-between": "always", + }, + ], + "prettier/prettier": ["error", prettierOptions], + "import/prefer-default-export": "off", + "import/extensions": ["error", { json: "always" }], + "class-methods-use-this": "off", + "prefer-promise-reject-errors": "off", + "max-classes-per-file": "off", + "no-use-before-define": ["off"], + "no-shadow": "off", + curly: ["error", "all"], + + "@typescript-eslint/explicit-member-accessibility": ["error", { accessibility: "no-public" }], + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/prefer-nullish-coalescing": "off", + "@typescript-eslint/no-floating-promises": "off", + "@typescript-eslint/no-explicit-any": "error", + "@typescript-eslint/explicit-module-boundary-types": "error", + "@typescript-eslint/no-use-before-define": ["error", { functions: false, classes: false }], + "@typescript-eslint/no-misused-promises": ["error", { checksVoidReturn: false }], + "@typescript-eslint/no-shadow": [ + "error", + { + builtinGlobals: true, + allow: ["location", "event", "history", "name", "status", "Option", "test", "expect"], + }, + ], }, }; diff --git a/circuits/.eslintrc.js b/circuits/.eslintrc.js index a22d4fb52c..7d3f9cdc56 100644 --- a/circuits/.eslintrc.js +++ b/circuits/.eslintrc.js @@ -1,44 +1,9 @@ -const fs = require("fs"); const path = require("path"); -const prettierConfig = fs.readFileSync(path.resolve(__dirname, "../.prettierrc"), "utf8"); -const prettierOptions = JSON.parse(prettierConfig); -const isProduction = process.env.NODE_ENV === "production"; - module.exports = { root: true, - extends: [ - "airbnb", - "prettier", - "plugin:import/recommended", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-type-checked", - "plugin:@typescript-eslint/strict", - "plugin:@typescript-eslint/strict-type-checked", - "plugin:@typescript-eslint/stylistic", - "plugin:@typescript-eslint/stylistic-type-checked", - "plugin:import/typescript", - ], - plugins: ["json", "prettier", "unused-imports", "import", "@typescript-eslint"], + extends: ["../.eslintrc.js"], parser: "@typescript-eslint/parser", - env: { - node: true, - mocha: true, - es2022: true, - }, - settings: { - react: { - version: "999.999.999", - }, - "import/resolver": { - typescript: {}, - node: { - extensions: [".ts", ".js"], - moduleDirectory: ["node_modules", "ts", "src"], - }, - }, - }, parserOptions: { project: path.resolve(__dirname, "./tsconfig.json"), sourceType: "module", @@ -52,56 +17,4 @@ module.exports = { }, warnOnUnsupportedTypeScriptVersion: true, }, - reportUnusedDisableDirectives: isProduction, - rules: { - "import/no-cycle": ["error"], - "unused-imports/no-unused-imports": "error", - "import/no-extraneous-dependencies": [ - "error", - { - devDependencies: ["**/*.test.ts"], - }, - ], - "no-debugger": isProduction ? "error" : "off", - "no-console": "error", - "no-underscore-dangle": "error", - "no-redeclare": ["error", { builtinGlobals: true }], - "import/order": [ - "error", - { - groups: ["external", "builtin", "internal", "type", "parent", "sibling", "index", "object"], - alphabetize: { - order: "asc", - caseInsensitive: true, - }, - warnOnUnassignedImports: true, - "newlines-between": "always", - }, - ], - "prettier/prettier": ["error", prettierOptions], - "import/prefer-default-export": "off", - "import/extensions": ["error", { json: "always" }], - "class-methods-use-this": "off", - "prefer-promise-reject-errors": "off", - "max-classes-per-file": "off", - "no-use-before-define": ["off"], - "no-shadow": "off", - curly: ["error", "all"], - - "@typescript-eslint/explicit-member-accessibility": ["error", { accessibility: "no-public" }], - "@typescript-eslint/no-non-null-assertion": "off", - "@typescript-eslint/prefer-nullish-coalescing": "off", - "@typescript-eslint/no-floating-promises": "off", - "@typescript-eslint/no-explicit-any": "error", - "@typescript-eslint/explicit-module-boundary-types": "error", - "@typescript-eslint/no-use-before-define": ["error", { functions: false, classes: false }], - "@typescript-eslint/no-misused-promises": ["error", { checksVoidReturn: false }], - "@typescript-eslint/no-shadow": [ - "error", - { - builtinGlobals: true, - allow: ["location", "event", "history", "name", "status", "Option", "test", "expect"], - }, - ], - }, }; diff --git a/circuits/tsconfig.json b/circuits/tsconfig.json index cba918a45a..1243fccb26 100644 --- a/circuits/tsconfig.json +++ b/circuits/tsconfig.json @@ -1,33 +1,7 @@ { "extends": "../tsconfig.json", "compilerOptions": { - "outDir": "./build", - "declaration": true, - "allowJs": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "target": "ES2020", - "lib": ["es2020"], - "experimentalDecorators": true, - "strict": true, - "noFallthroughCasesInSwitch": true, - "noImplicitAny": true, - "strictPropertyInitialization": true, - "strictNullChecks": true, - "module": "commonjs", - "moduleResolution": "node", - "resolveJsonModule": true, - "skipLibCheck": true, - "esModuleInterop": true, - "isolatedModules": true, - "forceConsistentCasingInFileNames": true, - "allowSyntheticDefaultImports": true, - "composite": true, - "incremental": true, - "declarationMap": true, - "sourceMap": true, - "stripInternal": true + "outDir": "./build" }, "include": ["./ts"] } diff --git a/cli/.eslintrc.js b/cli/.eslintrc.js index a22d4fb52c..7d3f9cdc56 100644 --- a/cli/.eslintrc.js +++ b/cli/.eslintrc.js @@ -1,44 +1,9 @@ -const fs = require("fs"); const path = require("path"); -const prettierConfig = fs.readFileSync(path.resolve(__dirname, "../.prettierrc"), "utf8"); -const prettierOptions = JSON.parse(prettierConfig); -const isProduction = process.env.NODE_ENV === "production"; - module.exports = { root: true, - extends: [ - "airbnb", - "prettier", - "plugin:import/recommended", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-type-checked", - "plugin:@typescript-eslint/strict", - "plugin:@typescript-eslint/strict-type-checked", - "plugin:@typescript-eslint/stylistic", - "plugin:@typescript-eslint/stylistic-type-checked", - "plugin:import/typescript", - ], - plugins: ["json", "prettier", "unused-imports", "import", "@typescript-eslint"], + extends: ["../.eslintrc.js"], parser: "@typescript-eslint/parser", - env: { - node: true, - mocha: true, - es2022: true, - }, - settings: { - react: { - version: "999.999.999", - }, - "import/resolver": { - typescript: {}, - node: { - extensions: [".ts", ".js"], - moduleDirectory: ["node_modules", "ts", "src"], - }, - }, - }, parserOptions: { project: path.resolve(__dirname, "./tsconfig.json"), sourceType: "module", @@ -52,56 +17,4 @@ module.exports = { }, warnOnUnsupportedTypeScriptVersion: true, }, - reportUnusedDisableDirectives: isProduction, - rules: { - "import/no-cycle": ["error"], - "unused-imports/no-unused-imports": "error", - "import/no-extraneous-dependencies": [ - "error", - { - devDependencies: ["**/*.test.ts"], - }, - ], - "no-debugger": isProduction ? "error" : "off", - "no-console": "error", - "no-underscore-dangle": "error", - "no-redeclare": ["error", { builtinGlobals: true }], - "import/order": [ - "error", - { - groups: ["external", "builtin", "internal", "type", "parent", "sibling", "index", "object"], - alphabetize: { - order: "asc", - caseInsensitive: true, - }, - warnOnUnassignedImports: true, - "newlines-between": "always", - }, - ], - "prettier/prettier": ["error", prettierOptions], - "import/prefer-default-export": "off", - "import/extensions": ["error", { json: "always" }], - "class-methods-use-this": "off", - "prefer-promise-reject-errors": "off", - "max-classes-per-file": "off", - "no-use-before-define": ["off"], - "no-shadow": "off", - curly: ["error", "all"], - - "@typescript-eslint/explicit-member-accessibility": ["error", { accessibility: "no-public" }], - "@typescript-eslint/no-non-null-assertion": "off", - "@typescript-eslint/prefer-nullish-coalescing": "off", - "@typescript-eslint/no-floating-promises": "off", - "@typescript-eslint/no-explicit-any": "error", - "@typescript-eslint/explicit-module-boundary-types": "error", - "@typescript-eslint/no-use-before-define": ["error", { functions: false, classes: false }], - "@typescript-eslint/no-misused-promises": ["error", { checksVoidReturn: false }], - "@typescript-eslint/no-shadow": [ - "error", - { - builtinGlobals: true, - allow: ["location", "event", "history", "name", "status", "Option", "test", "expect"], - }, - ], - }, }; diff --git a/cli/tsconfig.json b/cli/tsconfig.json index 74aed8a08f..263bcbc977 100644 --- a/cli/tsconfig.json +++ b/cli/tsconfig.json @@ -1,33 +1,7 @@ { "extends": "../tsconfig.json", "compilerOptions": { - "outDir": "./build", - "declaration": true, - "allowJs": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "target": "ES2020", - "lib": ["es2020"], - "experimentalDecorators": true, - "strict": true, - "noFallthroughCasesInSwitch": true, - "noImplicitAny": true, - "strictPropertyInitialization": true, - "strictNullChecks": true, - "module": "commonjs", - "moduleResolution": "node", - "resolveJsonModule": true, - "skipLibCheck": true, - "esModuleInterop": true, - "isolatedModules": true, - "forceConsistentCasingInFileNames": true, - "allowSyntheticDefaultImports": true, - "composite": true, - "incremental": true, - "declarationMap": true, - "sourceMap": true, - "stripInternal": true + "outDir": "./build" }, "include": ["./ts", "./tests"], "files": ["./hardhat.config.ts"] diff --git a/contracts/.eslintrc.js b/contracts/.eslintrc.js index a22d4fb52c..7d3f9cdc56 100644 --- a/contracts/.eslintrc.js +++ b/contracts/.eslintrc.js @@ -1,44 +1,9 @@ -const fs = require("fs"); const path = require("path"); -const prettierConfig = fs.readFileSync(path.resolve(__dirname, "../.prettierrc"), "utf8"); -const prettierOptions = JSON.parse(prettierConfig); -const isProduction = process.env.NODE_ENV === "production"; - module.exports = { root: true, - extends: [ - "airbnb", - "prettier", - "plugin:import/recommended", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-type-checked", - "plugin:@typescript-eslint/strict", - "plugin:@typescript-eslint/strict-type-checked", - "plugin:@typescript-eslint/stylistic", - "plugin:@typescript-eslint/stylistic-type-checked", - "plugin:import/typescript", - ], - plugins: ["json", "prettier", "unused-imports", "import", "@typescript-eslint"], + extends: ["../.eslintrc.js"], parser: "@typescript-eslint/parser", - env: { - node: true, - mocha: true, - es2022: true, - }, - settings: { - react: { - version: "999.999.999", - }, - "import/resolver": { - typescript: {}, - node: { - extensions: [".ts", ".js"], - moduleDirectory: ["node_modules", "ts", "src"], - }, - }, - }, parserOptions: { project: path.resolve(__dirname, "./tsconfig.json"), sourceType: "module", @@ -52,56 +17,4 @@ module.exports = { }, warnOnUnsupportedTypeScriptVersion: true, }, - reportUnusedDisableDirectives: isProduction, - rules: { - "import/no-cycle": ["error"], - "unused-imports/no-unused-imports": "error", - "import/no-extraneous-dependencies": [ - "error", - { - devDependencies: ["**/*.test.ts"], - }, - ], - "no-debugger": isProduction ? "error" : "off", - "no-console": "error", - "no-underscore-dangle": "error", - "no-redeclare": ["error", { builtinGlobals: true }], - "import/order": [ - "error", - { - groups: ["external", "builtin", "internal", "type", "parent", "sibling", "index", "object"], - alphabetize: { - order: "asc", - caseInsensitive: true, - }, - warnOnUnassignedImports: true, - "newlines-between": "always", - }, - ], - "prettier/prettier": ["error", prettierOptions], - "import/prefer-default-export": "off", - "import/extensions": ["error", { json: "always" }], - "class-methods-use-this": "off", - "prefer-promise-reject-errors": "off", - "max-classes-per-file": "off", - "no-use-before-define": ["off"], - "no-shadow": "off", - curly: ["error", "all"], - - "@typescript-eslint/explicit-member-accessibility": ["error", { accessibility: "no-public" }], - "@typescript-eslint/no-non-null-assertion": "off", - "@typescript-eslint/prefer-nullish-coalescing": "off", - "@typescript-eslint/no-floating-promises": "off", - "@typescript-eslint/no-explicit-any": "error", - "@typescript-eslint/explicit-module-boundary-types": "error", - "@typescript-eslint/no-use-before-define": ["error", { functions: false, classes: false }], - "@typescript-eslint/no-misused-promises": ["error", { checksVoidReturn: false }], - "@typescript-eslint/no-shadow": [ - "error", - { - builtinGlobals: true, - allow: ["location", "event", "history", "name", "status", "Option", "test", "expect"], - }, - ], - }, }; diff --git a/contracts/tsconfig.json b/contracts/tsconfig.json index 4f60d5a87a..cfe9cef4f0 100644 --- a/contracts/tsconfig.json +++ b/contracts/tsconfig.json @@ -1,33 +1,7 @@ { "extends": "../tsconfig.json", "compilerOptions": { - "outDir": "./build", - "declaration": true, - "allowJs": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "target": "ES2020", - "lib": ["es2020"], - "experimentalDecorators": true, - "strict": true, - "noFallthroughCasesInSwitch": true, - "noImplicitAny": true, - "strictPropertyInitialization": true, - "strictNullChecks": true, - "module": "commonjs", - "moduleResolution": "node", - "resolveJsonModule": true, - "skipLibCheck": true, - "esModuleInterop": true, - "isolatedModules": true, - "forceConsistentCasingInFileNames": true, - "allowSyntheticDefaultImports": true, - "composite": true, - "incremental": true, - "declarationMap": true, - "sourceMap": true, - "stripInternal": true + "outDir": "./build" }, "include": ["./ts", "./tests", "./typechain-types"], "files": ["./hardhat.config.ts"] diff --git a/core/.eslintrc.js b/core/.eslintrc.js index a22d4fb52c..7d3f9cdc56 100644 --- a/core/.eslintrc.js +++ b/core/.eslintrc.js @@ -1,44 +1,9 @@ -const fs = require("fs"); const path = require("path"); -const prettierConfig = fs.readFileSync(path.resolve(__dirname, "../.prettierrc"), "utf8"); -const prettierOptions = JSON.parse(prettierConfig); -const isProduction = process.env.NODE_ENV === "production"; - module.exports = { root: true, - extends: [ - "airbnb", - "prettier", - "plugin:import/recommended", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-type-checked", - "plugin:@typescript-eslint/strict", - "plugin:@typescript-eslint/strict-type-checked", - "plugin:@typescript-eslint/stylistic", - "plugin:@typescript-eslint/stylistic-type-checked", - "plugin:import/typescript", - ], - plugins: ["json", "prettier", "unused-imports", "import", "@typescript-eslint"], + extends: ["../.eslintrc.js"], parser: "@typescript-eslint/parser", - env: { - node: true, - mocha: true, - es2022: true, - }, - settings: { - react: { - version: "999.999.999", - }, - "import/resolver": { - typescript: {}, - node: { - extensions: [".ts", ".js"], - moduleDirectory: ["node_modules", "ts", "src"], - }, - }, - }, parserOptions: { project: path.resolve(__dirname, "./tsconfig.json"), sourceType: "module", @@ -52,56 +17,4 @@ module.exports = { }, warnOnUnsupportedTypeScriptVersion: true, }, - reportUnusedDisableDirectives: isProduction, - rules: { - "import/no-cycle": ["error"], - "unused-imports/no-unused-imports": "error", - "import/no-extraneous-dependencies": [ - "error", - { - devDependencies: ["**/*.test.ts"], - }, - ], - "no-debugger": isProduction ? "error" : "off", - "no-console": "error", - "no-underscore-dangle": "error", - "no-redeclare": ["error", { builtinGlobals: true }], - "import/order": [ - "error", - { - groups: ["external", "builtin", "internal", "type", "parent", "sibling", "index", "object"], - alphabetize: { - order: "asc", - caseInsensitive: true, - }, - warnOnUnassignedImports: true, - "newlines-between": "always", - }, - ], - "prettier/prettier": ["error", prettierOptions], - "import/prefer-default-export": "off", - "import/extensions": ["error", { json: "always" }], - "class-methods-use-this": "off", - "prefer-promise-reject-errors": "off", - "max-classes-per-file": "off", - "no-use-before-define": ["off"], - "no-shadow": "off", - curly: ["error", "all"], - - "@typescript-eslint/explicit-member-accessibility": ["error", { accessibility: "no-public" }], - "@typescript-eslint/no-non-null-assertion": "off", - "@typescript-eslint/prefer-nullish-coalescing": "off", - "@typescript-eslint/no-floating-promises": "off", - "@typescript-eslint/no-explicit-any": "error", - "@typescript-eslint/explicit-module-boundary-types": "error", - "@typescript-eslint/no-use-before-define": ["error", { functions: false, classes: false }], - "@typescript-eslint/no-misused-promises": ["error", { checksVoidReturn: false }], - "@typescript-eslint/no-shadow": [ - "error", - { - builtinGlobals: true, - allow: ["location", "event", "history", "name", "status", "Option", "test", "expect"], - }, - ], - }, }; diff --git a/core/tsconfig.json b/core/tsconfig.json index 3e1726e913..1243fccb26 100644 --- a/core/tsconfig.json +++ b/core/tsconfig.json @@ -1,34 +1,7 @@ { "extends": "../tsconfig.json", "compilerOptions": { - "outDir": "./build", - "declaration": true, - "allowJs": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "target": "ES2020", - "lib": ["es2020"], - "experimentalDecorators": true, - "strict": true, - "noFallthroughCasesInSwitch": true, - "noImplicitAny": true, - "strictPropertyInitialization": true, - "strictNullChecks": true, - "module": "commonjs", - "moduleResolution": "node", - "resolveJsonModule": true, - "skipLibCheck": true, - "esModuleInterop": true, - "isolatedModules": true, - "forceConsistentCasingInFileNames": true, - "allowSyntheticDefaultImports": true, - "composite": true, - "incremental": true, - "declarationMap": true, - "sourceMap": true, - "stripInternal": true + "outDir": "./build" }, - "include": ["./ts"], - "exclude": ["./ts/__tests__.old"] + "include": ["./ts"] } diff --git a/crypto/.eslintrc.js b/crypto/.eslintrc.js index a22d4fb52c..7d3f9cdc56 100644 --- a/crypto/.eslintrc.js +++ b/crypto/.eslintrc.js @@ -1,44 +1,9 @@ -const fs = require("fs"); const path = require("path"); -const prettierConfig = fs.readFileSync(path.resolve(__dirname, "../.prettierrc"), "utf8"); -const prettierOptions = JSON.parse(prettierConfig); -const isProduction = process.env.NODE_ENV === "production"; - module.exports = { root: true, - extends: [ - "airbnb", - "prettier", - "plugin:import/recommended", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-type-checked", - "plugin:@typescript-eslint/strict", - "plugin:@typescript-eslint/strict-type-checked", - "plugin:@typescript-eslint/stylistic", - "plugin:@typescript-eslint/stylistic-type-checked", - "plugin:import/typescript", - ], - plugins: ["json", "prettier", "unused-imports", "import", "@typescript-eslint"], + extends: ["../.eslintrc.js"], parser: "@typescript-eslint/parser", - env: { - node: true, - mocha: true, - es2022: true, - }, - settings: { - react: { - version: "999.999.999", - }, - "import/resolver": { - typescript: {}, - node: { - extensions: [".ts", ".js"], - moduleDirectory: ["node_modules", "ts", "src"], - }, - }, - }, parserOptions: { project: path.resolve(__dirname, "./tsconfig.json"), sourceType: "module", @@ -52,56 +17,4 @@ module.exports = { }, warnOnUnsupportedTypeScriptVersion: true, }, - reportUnusedDisableDirectives: isProduction, - rules: { - "import/no-cycle": ["error"], - "unused-imports/no-unused-imports": "error", - "import/no-extraneous-dependencies": [ - "error", - { - devDependencies: ["**/*.test.ts"], - }, - ], - "no-debugger": isProduction ? "error" : "off", - "no-console": "error", - "no-underscore-dangle": "error", - "no-redeclare": ["error", { builtinGlobals: true }], - "import/order": [ - "error", - { - groups: ["external", "builtin", "internal", "type", "parent", "sibling", "index", "object"], - alphabetize: { - order: "asc", - caseInsensitive: true, - }, - warnOnUnassignedImports: true, - "newlines-between": "always", - }, - ], - "prettier/prettier": ["error", prettierOptions], - "import/prefer-default-export": "off", - "import/extensions": ["error", { json: "always" }], - "class-methods-use-this": "off", - "prefer-promise-reject-errors": "off", - "max-classes-per-file": "off", - "no-use-before-define": ["off"], - "no-shadow": "off", - curly: ["error", "all"], - - "@typescript-eslint/explicit-member-accessibility": ["error", { accessibility: "no-public" }], - "@typescript-eslint/no-non-null-assertion": "off", - "@typescript-eslint/prefer-nullish-coalescing": "off", - "@typescript-eslint/no-floating-promises": "off", - "@typescript-eslint/no-explicit-any": "error", - "@typescript-eslint/explicit-module-boundary-types": "error", - "@typescript-eslint/no-use-before-define": ["error", { functions: false, classes: false }], - "@typescript-eslint/no-misused-promises": ["error", { checksVoidReturn: false }], - "@typescript-eslint/no-shadow": [ - "error", - { - builtinGlobals: true, - allow: ["location", "event", "history", "name", "status", "Option", "test", "expect"], - }, - ], - }, }; diff --git a/crypto/tsconfig.json b/crypto/tsconfig.json index cba918a45a..1243fccb26 100644 --- a/crypto/tsconfig.json +++ b/crypto/tsconfig.json @@ -1,33 +1,7 @@ { "extends": "../tsconfig.json", "compilerOptions": { - "outDir": "./build", - "declaration": true, - "allowJs": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "target": "ES2020", - "lib": ["es2020"], - "experimentalDecorators": true, - "strict": true, - "noFallthroughCasesInSwitch": true, - "noImplicitAny": true, - "strictPropertyInitialization": true, - "strictNullChecks": true, - "module": "commonjs", - "moduleResolution": "node", - "resolveJsonModule": true, - "skipLibCheck": true, - "esModuleInterop": true, - "isolatedModules": true, - "forceConsistentCasingInFileNames": true, - "allowSyntheticDefaultImports": true, - "composite": true, - "incremental": true, - "declarationMap": true, - "sourceMap": true, - "stripInternal": true + "outDir": "./build" }, "include": ["./ts"] } diff --git a/domainobjs/.eslintrc.js b/domainobjs/.eslintrc.js index a22d4fb52c..7d3f9cdc56 100644 --- a/domainobjs/.eslintrc.js +++ b/domainobjs/.eslintrc.js @@ -1,44 +1,9 @@ -const fs = require("fs"); const path = require("path"); -const prettierConfig = fs.readFileSync(path.resolve(__dirname, "../.prettierrc"), "utf8"); -const prettierOptions = JSON.parse(prettierConfig); -const isProduction = process.env.NODE_ENV === "production"; - module.exports = { root: true, - extends: [ - "airbnb", - "prettier", - "plugin:import/recommended", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-type-checked", - "plugin:@typescript-eslint/strict", - "plugin:@typescript-eslint/strict-type-checked", - "plugin:@typescript-eslint/stylistic", - "plugin:@typescript-eslint/stylistic-type-checked", - "plugin:import/typescript", - ], - plugins: ["json", "prettier", "unused-imports", "import", "@typescript-eslint"], + extends: ["../.eslintrc.js"], parser: "@typescript-eslint/parser", - env: { - node: true, - mocha: true, - es2022: true, - }, - settings: { - react: { - version: "999.999.999", - }, - "import/resolver": { - typescript: {}, - node: { - extensions: [".ts", ".js"], - moduleDirectory: ["node_modules", "ts", "src"], - }, - }, - }, parserOptions: { project: path.resolve(__dirname, "./tsconfig.json"), sourceType: "module", @@ -52,56 +17,4 @@ module.exports = { }, warnOnUnsupportedTypeScriptVersion: true, }, - reportUnusedDisableDirectives: isProduction, - rules: { - "import/no-cycle": ["error"], - "unused-imports/no-unused-imports": "error", - "import/no-extraneous-dependencies": [ - "error", - { - devDependencies: ["**/*.test.ts"], - }, - ], - "no-debugger": isProduction ? "error" : "off", - "no-console": "error", - "no-underscore-dangle": "error", - "no-redeclare": ["error", { builtinGlobals: true }], - "import/order": [ - "error", - { - groups: ["external", "builtin", "internal", "type", "parent", "sibling", "index", "object"], - alphabetize: { - order: "asc", - caseInsensitive: true, - }, - warnOnUnassignedImports: true, - "newlines-between": "always", - }, - ], - "prettier/prettier": ["error", prettierOptions], - "import/prefer-default-export": "off", - "import/extensions": ["error", { json: "always" }], - "class-methods-use-this": "off", - "prefer-promise-reject-errors": "off", - "max-classes-per-file": "off", - "no-use-before-define": ["off"], - "no-shadow": "off", - curly: ["error", "all"], - - "@typescript-eslint/explicit-member-accessibility": ["error", { accessibility: "no-public" }], - "@typescript-eslint/no-non-null-assertion": "off", - "@typescript-eslint/prefer-nullish-coalescing": "off", - "@typescript-eslint/no-floating-promises": "off", - "@typescript-eslint/no-explicit-any": "error", - "@typescript-eslint/explicit-module-boundary-types": "error", - "@typescript-eslint/no-use-before-define": ["error", { functions: false, classes: false }], - "@typescript-eslint/no-misused-promises": ["error", { checksVoidReturn: false }], - "@typescript-eslint/no-shadow": [ - "error", - { - builtinGlobals: true, - allow: ["location", "event", "history", "name", "status", "Option", "test", "expect"], - }, - ], - }, }; diff --git a/domainobjs/tsconfig.json b/domainobjs/tsconfig.json index cba918a45a..1243fccb26 100644 --- a/domainobjs/tsconfig.json +++ b/domainobjs/tsconfig.json @@ -1,33 +1,7 @@ { "extends": "../tsconfig.json", "compilerOptions": { - "outDir": "./build", - "declaration": true, - "allowJs": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "target": "ES2020", - "lib": ["es2020"], - "experimentalDecorators": true, - "strict": true, - "noFallthroughCasesInSwitch": true, - "noImplicitAny": true, - "strictPropertyInitialization": true, - "strictNullChecks": true, - "module": "commonjs", - "moduleResolution": "node", - "resolveJsonModule": true, - "skipLibCheck": true, - "esModuleInterop": true, - "isolatedModules": true, - "forceConsistentCasingInFileNames": true, - "allowSyntheticDefaultImports": true, - "composite": true, - "incremental": true, - "declarationMap": true, - "sourceMap": true, - "stripInternal": true + "outDir": "./build" }, "include": ["./ts"] } diff --git a/integrationTests/.eslintrc.js b/integrationTests/.eslintrc.js index a22d4fb52c..7d3f9cdc56 100644 --- a/integrationTests/.eslintrc.js +++ b/integrationTests/.eslintrc.js @@ -1,44 +1,9 @@ -const fs = require("fs"); const path = require("path"); -const prettierConfig = fs.readFileSync(path.resolve(__dirname, "../.prettierrc"), "utf8"); -const prettierOptions = JSON.parse(prettierConfig); -const isProduction = process.env.NODE_ENV === "production"; - module.exports = { root: true, - extends: [ - "airbnb", - "prettier", - "plugin:import/recommended", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-type-checked", - "plugin:@typescript-eslint/strict", - "plugin:@typescript-eslint/strict-type-checked", - "plugin:@typescript-eslint/stylistic", - "plugin:@typescript-eslint/stylistic-type-checked", - "plugin:import/typescript", - ], - plugins: ["json", "prettier", "unused-imports", "import", "@typescript-eslint"], + extends: ["../.eslintrc.js"], parser: "@typescript-eslint/parser", - env: { - node: true, - mocha: true, - es2022: true, - }, - settings: { - react: { - version: "999.999.999", - }, - "import/resolver": { - typescript: {}, - node: { - extensions: [".ts", ".js"], - moduleDirectory: ["node_modules", "ts", "src"], - }, - }, - }, parserOptions: { project: path.resolve(__dirname, "./tsconfig.json"), sourceType: "module", @@ -52,56 +17,4 @@ module.exports = { }, warnOnUnsupportedTypeScriptVersion: true, }, - reportUnusedDisableDirectives: isProduction, - rules: { - "import/no-cycle": ["error"], - "unused-imports/no-unused-imports": "error", - "import/no-extraneous-dependencies": [ - "error", - { - devDependencies: ["**/*.test.ts"], - }, - ], - "no-debugger": isProduction ? "error" : "off", - "no-console": "error", - "no-underscore-dangle": "error", - "no-redeclare": ["error", { builtinGlobals: true }], - "import/order": [ - "error", - { - groups: ["external", "builtin", "internal", "type", "parent", "sibling", "index", "object"], - alphabetize: { - order: "asc", - caseInsensitive: true, - }, - warnOnUnassignedImports: true, - "newlines-between": "always", - }, - ], - "prettier/prettier": ["error", prettierOptions], - "import/prefer-default-export": "off", - "import/extensions": ["error", { json: "always" }], - "class-methods-use-this": "off", - "prefer-promise-reject-errors": "off", - "max-classes-per-file": "off", - "no-use-before-define": ["off"], - "no-shadow": "off", - curly: ["error", "all"], - - "@typescript-eslint/explicit-member-accessibility": ["error", { accessibility: "no-public" }], - "@typescript-eslint/no-non-null-assertion": "off", - "@typescript-eslint/prefer-nullish-coalescing": "off", - "@typescript-eslint/no-floating-promises": "off", - "@typescript-eslint/no-explicit-any": "error", - "@typescript-eslint/explicit-module-boundary-types": "error", - "@typescript-eslint/no-use-before-define": ["error", { functions: false, classes: false }], - "@typescript-eslint/no-misused-promises": ["error", { checksVoidReturn: false }], - "@typescript-eslint/no-shadow": [ - "error", - { - builtinGlobals: true, - allow: ["location", "event", "history", "name", "status", "Option", "test", "expect"], - }, - ], - }, }; diff --git a/integrationTests/tsconfig.json b/integrationTests/tsconfig.json index 26c748e754..f2423b9a54 100644 --- a/integrationTests/tsconfig.json +++ b/integrationTests/tsconfig.json @@ -1,33 +1,7 @@ { "extends": "../tsconfig.json", "compilerOptions": { - "outDir": "./build", - "declaration": true, - "allowJs": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "target": "ES2020", - "lib": ["es2020"], - "experimentalDecorators": true, - "strict": true, - "noFallthroughCasesInSwitch": true, - "noImplicitAny": true, - "strictPropertyInitialization": true, - "strictNullChecks": true, - "module": "commonjs", - "moduleResolution": "node", - "resolveJsonModule": true, - "skipLibCheck": true, - "esModuleInterop": true, - "isolatedModules": true, - "forceConsistentCasingInFileNames": true, - "allowSyntheticDefaultImports": true, - "composite": true, - "incremental": true, - "declarationMap": true, - "sourceMap": true, - "stripInternal": true + "outDir": "./build" }, "include": ["./ts"], "files": ["./hardhat.config.ts"] diff --git a/tsconfig.json b/tsconfig.json index 256167057e..475b5385ac 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,25 +1,34 @@ { "compilerOptions": { - "target": "ES2020", - "lib": ["es2020"], "module": "commonjs", "moduleResolution": "node", - "experimentalDecorators": true, "alwaysStrict": false, - "allowJs": true, - "noImplicitAny": false, "forceConsistentCasingInFileNames": true, - "noUnusedLocals": false, - "noUnusedParameters": false, - "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "sourceMap": true, - "strict": false, + "outDir": "./build", + "declaration": true, + "allowJs": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "target": "ES2020", + "lib": ["es2020"], + "experimentalDecorators": true, + "strict": true, + "noImplicitAny": true, + "strictPropertyInitialization": true, + "strictNullChecks": true, + "resolveJsonModule": true, "skipLibCheck": true, "esModuleInterop": true, - "outDir": "./build", - "declaration": true + "isolatedModules": true, + "allowSyntheticDefaultImports": true, + "composite": true, + "incremental": true, + "declarationMap": true, + "stripInternal": true }, "exclude": ["node_modules"], - "include": ["./**/ts"] + "include": ["./**/ts", "./**/typechain-types"] } From 69f038f55e6c740d43b8b5376db999bcf92de845 Mon Sep 17 00:00:00 2001 From: 0xmad <0xmad@users.noreply.github.com> Date: Mon, 8 Jan 2024 12:49:05 -0600 Subject: [PATCH 35/37] chore: add types check - [x] Add ci job step - [x] Add precommit-hook step - [x] Add scripts for packages --- .github/workflows/checks.yml | 2 +- .husky/pre-commit | 2 +- circuits/package.json | 1 + cli/package.json | 1 + contracts/package.json | 1 + core/package.json | 1 + crypto/package.json | 1 + domainobjs/package.json | 1 + integrationTests/package.json | 1 + package.json | 1 + website/package-lock.json | 215 +++++++++++++++++++--------------- website/package.json | 3 +- 12 files changed, 135 insertions(+), 95 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 73256f7c98..5c05f8f6e8 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -14,7 +14,7 @@ jobs: strategy: fail-fast: false matrix: - command: ["prettier", "lint:ts", "lint:sol"] + command: ["prettier", "types", "lint:ts", "lint:sol"] runs-on: ubuntu-22.04 diff --git a/.husky/pre-commit b/.husky/pre-commit index d24fdfc601..6026936097 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" -npx lint-staged +npx lint-staged && npm run types diff --git a/circuits/package.json b/circuits/package.json index 8afc86fddf..9f6f765c4a 100644 --- a/circuits/package.json +++ b/circuits/package.json @@ -8,6 +8,7 @@ "build-test-circuits-wasm": "bash ./scripts/build_arm.sh", "watch": "tsc --watch", "build": "tsc", + "types": "tsc -p tsconfig.json --noEmit", "test": "ts-mocha --exit ts/__tests__/*.test.ts", "test:hasher": "ts-mocha --exit ts/__tests__/Hasher.test.ts", "test:unpackElement": "ts-mocha --exit ts/__tests__/UnpackElement.test.ts", diff --git a/cli/package.json b/cli/package.json index 193caffe99..c3fa684447 100644 --- a/cli/package.json +++ b/cli/package.json @@ -14,6 +14,7 @@ "watch": "tsc --watch", "build": "tsc", "postbuild": "cp package.json ./build", + "types": "tsc -p tsconfig.json --noEmit", "test": "nyc ts-mocha --exit tests/**/*.test.ts", "test:e2e": "ts-mocha --exit tests/e2e.test.ts", "test:e2e-subsidy": "ts-mocha --exit tests/e2e.subsidy.test.ts", diff --git a/contracts/package.json b/contracts/package.json index 2d74b71459..6b790c1df6 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -11,6 +11,7 @@ "prebuild": "npm run compileSol", "build": "tsc", "postbuild": "cp -r ./artifacts ./build", + "types": "tsc -p tsconfig.json --noEmit", "docs": "hardhat docgen", "test": "hardhat test", "test:maci": "hardhat test ./tests/MACI.test.ts", diff --git a/core/package.json b/core/package.json index 3201ce0397..f42d749951 100644 --- a/core/package.json +++ b/core/package.json @@ -7,6 +7,7 @@ "scripts": { "watch": "tsc --watch", "build": "tsc", + "types": "tsc -p tsconfig.json --noEmit", "test:processMessage": "ts-mocha --exit ts/__tests__/ProcessMessage.test.ts", "test:maciState": "ts-mocha --exit ts/__tests__/MaciState.test.ts", "test:e2e": "ts-mocha --exit ts/__tests__/e2e.test.ts", diff --git a/crypto/package.json b/crypto/package.json index 36d8bb1a46..faec98f022 100644 --- a/crypto/package.json +++ b/crypto/package.json @@ -6,6 +6,7 @@ "scripts": { "watch": "tsc --watch", "build": "tsc", + "types": "tsc -p tsconfig.json --noEmit", "test": "nyc ts-mocha --exit ts/__tests__/*.test.ts", "test:crypto": "ts-mocha --exit ts/__tests__/Crypto.test.ts", "test:accQueue": "ts-mocha --exit ts/__tests__/AccQueue.test.ts", diff --git a/domainobjs/package.json b/domainobjs/package.json index 9085697b2e..2f6e7b3c13 100644 --- a/domainobjs/package.json +++ b/domainobjs/package.json @@ -6,6 +6,7 @@ "scripts": { "watch": "tsc --watch", "build": "tsc", + "types": "tsc -p tsconfig.json --noEmit", "test": "nyc ts-mocha --exit ts/__tests__/**.test.ts" }, "devDependencies": { diff --git a/integrationTests/package.json b/integrationTests/package.json index d4a1239e47..d409061398 100644 --- a/integrationTests/package.json +++ b/integrationTests/package.json @@ -6,6 +6,7 @@ "scripts": { "watch": "tsc --watch", "build": "tsc", + "types": "tsc -p tsconfig.json --noEmit", "test": "ts-mocha --exit ./ts/__tests__/**.test.ts", "test:suites": "NODE_OPTIONS=--max-old-space-size=4096 ts-mocha --exit ./ts/__tests__/suites.test.ts", "test:maciKeys": "ts-mocha --exit ./ts/__tests__/maci-keys.test.ts", diff --git a/package.json b/package.json index d08f740a7d..31655db509 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "test:cli": "lerna run test --scope \"maci-cli\"", "test:integration": "lerna run test --scope \"maci-integrationtests\"", "test": "lerna run test --ignore maci-integrationtests --ignore maci-cli", + "types": "lerna run types", "typedoc": "typedoc --plugin typedoc-plugin-markdown --options typedoc.json", "prepare": "is-ci || husky install" }, diff --git a/website/package-lock.json b/website/package-lock.json index a7bc4364dd..e7c79bd333 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@docusaurus/core": "3.0.0", "@docusaurus/preset-classic": "3.0.0", + "@docusaurus/theme-classic": "3.0.0", "@easyops-cn/docusaurus-search-local": "^0.37.4", "@mdx-js/react": "^3.0.0", "clsx": "^1.2.1", @@ -2568,7 +2569,48 @@ "react-dom": "^18.0.0" } }, - "node_modules/@docusaurus/preset-classic/node_modules/@docusaurus/theme-classic": { + "node_modules/@docusaurus/preset-classic/node_modules/@docusaurus/theme-common": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.0.0.tgz", + "integrity": "sha512-PahRpCLRK5owCMEqcNtUeTMOkTUCzrJlKA+HLu7f+8osYOni617YurXvHASCsSTxurjXaLz/RqZMnASnqATxIA==", + "dependencies": { + "@docusaurus/mdx-loader": "3.0.0", + "@docusaurus/module-type-aliases": "3.0.0", + "@docusaurus/plugin-content-blog": "3.0.0", + "@docusaurus/plugin-content-docs": "3.0.0", + "@docusaurus/plugin-content-pages": "3.0.0", + "@docusaurus/utils": "3.0.0", + "@docusaurus/utils-common": "3.0.0", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "clsx": "^1.2.1", + "parse-numeric-range": "^1.3.0", + "prism-react-renderer": "^2.1.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/react-loadable": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz", + "integrity": "sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ==", + "dependencies": { + "@types/react": "*", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": "*" + } + }, + "node_modules/@docusaurus/theme-classic": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.0.0.tgz", "integrity": "sha512-wWOHSrKMn7L4jTtXBsb5iEJ3xvTddBye5PjYBnWiCkTAlhle2yMdc4/qRXW35Ot+OV/VXu6YFG8XVUJEl99z0A==", @@ -2607,7 +2649,7 @@ "react-dom": "^18.0.0" } }, - "node_modules/@docusaurus/preset-classic/node_modules/@docusaurus/theme-common": { + "node_modules/@docusaurus/theme-classic/node_modules/@docusaurus/theme-common": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.0.0.tgz", "integrity": "sha512-PahRpCLRK5owCMEqcNtUeTMOkTUCzrJlKA+HLu7f+8osYOni617YurXvHASCsSTxurjXaLz/RqZMnASnqATxIA==", @@ -2636,31 +2678,19 @@ "react-dom": "^18.0.0" } }, - "node_modules/@docusaurus/react-loadable": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz", - "integrity": "sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ==", - "dependencies": { - "@types/react": "*", - "prop-types": "^15.6.2" - }, - "peerDependencies": { - "react": "*" - } - }, "node_modules/@docusaurus/theme-common": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.0.1.tgz", - "integrity": "sha512-cr9TOWXuIOL0PUfuXv6L5lPlTgaphKP+22NdVBOYah5jSq5XAAulJTjfe+IfLsEG4L7lJttLbhW7LXDFSAI7Ag==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.1.0.tgz", + "integrity": "sha512-YGwEFALLIbF5ocW/Fy6Ae7tFWUOugEN3iwxTx8UkLAcLqYUboDSadesYtVBmRCEB4FVA2qoP7YaW3lu3apUPPw==", "peer": true, "dependencies": { - "@docusaurus/mdx-loader": "3.0.1", - "@docusaurus/module-type-aliases": "3.0.1", - "@docusaurus/plugin-content-blog": "3.0.1", - "@docusaurus/plugin-content-docs": "3.0.1", - "@docusaurus/plugin-content-pages": "3.0.1", - "@docusaurus/utils": "3.0.1", - "@docusaurus/utils-common": "3.0.1", + "@docusaurus/mdx-loader": "3.1.0", + "@docusaurus/module-type-aliases": "3.1.0", + "@docusaurus/plugin-content-blog": "3.1.0", + "@docusaurus/plugin-content-docs": "3.1.0", + "@docusaurus/plugin-content-pages": "3.1.0", + "@docusaurus/utils": "3.1.0", + "@docusaurus/utils-common": "3.1.0", "@types/history": "^4.7.11", "@types/react": "*", "@types/react-router-config": "*", @@ -2679,9 +2709,9 @@ } }, "node_modules/@docusaurus/theme-common/node_modules/@docusaurus/core": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.0.1.tgz", - "integrity": "sha512-CXrLpOnW+dJdSv8M5FAJ3JBwXtL6mhUWxFA8aS0ozK6jBG/wgxERk5uvH28fCeFxOGbAT9v1e9dOMo1X2IEVhQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.1.0.tgz", + "integrity": "sha512-GWudMGYA9v26ssbAWJNfgeDZk+lrudUTclLPRsmxiknEBk7UMp7Rglonhqbsf3IKHOyHkMU4Fr5jFyg5SBx9jQ==", "peer": true, "dependencies": { "@babel/core": "^7.23.3", @@ -2694,13 +2724,13 @@ "@babel/runtime": "^7.22.6", "@babel/runtime-corejs3": "^7.22.6", "@babel/traverse": "^7.22.8", - "@docusaurus/cssnano-preset": "3.0.1", - "@docusaurus/logger": "3.0.1", - "@docusaurus/mdx-loader": "3.0.1", + "@docusaurus/cssnano-preset": "3.1.0", + "@docusaurus/logger": "3.1.0", + "@docusaurus/mdx-loader": "3.1.0", "@docusaurus/react-loadable": "5.5.2", - "@docusaurus/utils": "3.0.1", - "@docusaurus/utils-common": "3.0.1", - "@docusaurus/utils-validation": "3.0.1", + "@docusaurus/utils": "3.1.0", + "@docusaurus/utils-common": "3.1.0", + "@docusaurus/utils-validation": "3.1.0", "@slorber/static-site-generator-webpack-plugin": "^4.0.7", "@svgr/webpack": "^6.5.1", "autoprefixer": "^10.4.14", @@ -2766,9 +2796,9 @@ } }, "node_modules/@docusaurus/theme-common/node_modules/@docusaurus/cssnano-preset": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.0.1.tgz", - "integrity": "sha512-wjuXzkHMW+ig4BD6Ya1Yevx9UJadO4smNZCEljqBoQfIQrQskTswBs7lZ8InHP7mCt273a/y/rm36EZhqJhknQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.1.0.tgz", + "integrity": "sha512-ned7qsgCqSv/e7KyugFNroAfiszuxLwnvMW7gmT2Ywxb/Nyt61yIw7KHyAZCMKglOalrqnYA4gMhLUCK/mVePA==", "peer": true, "dependencies": { "cssnano-preset-advanced": "^5.3.10", @@ -2781,9 +2811,9 @@ } }, "node_modules/@docusaurus/theme-common/node_modules/@docusaurus/logger": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.0.1.tgz", - "integrity": "sha512-I5L6Nk8OJzkVA91O2uftmo71LBSxe1vmOn9AMR6JRCzYeEBrqneWMH02AqMvjJ2NpMiviO+t0CyPjyYV7nxCWQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.1.0.tgz", + "integrity": "sha512-p740M+HCst1VnKKzL60Hru9xfG4EUYJDarjlEC4hHeBy9+afPmY3BNPoSHx9/8zxuYfUlv/psf7I9NvRVdmdvg==", "peer": true, "dependencies": { "chalk": "^4.1.2", @@ -2794,16 +2824,16 @@ } }, "node_modules/@docusaurus/theme-common/node_modules/@docusaurus/mdx-loader": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.0.1.tgz", - "integrity": "sha512-ldnTmvnvlrONUq45oKESrpy+lXtbnTcTsFkOTIDswe5xx5iWJjt6eSa0f99ZaWlnm24mlojcIGoUWNCS53qVlQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.1.0.tgz", + "integrity": "sha512-D7onDz/3mgBonexWoQXPw3V2E5Bc4+jYRf9gGUUK+KoQwU8xMDaDkUUfsr7t6UBa/xox9p5+/3zwLuXOYMzGSg==", "peer": true, "dependencies": { "@babel/parser": "^7.22.7", "@babel/traverse": "^7.22.8", - "@docusaurus/logger": "3.0.1", - "@docusaurus/utils": "3.0.1", - "@docusaurus/utils-validation": "3.0.1", + "@docusaurus/logger": "3.1.0", + "@docusaurus/utils": "3.1.0", + "@docusaurus/utils-validation": "3.1.0", "@mdx-js/mdx": "^3.0.0", "@slorber/remark-comment": "^1.0.0", "escape-html": "^1.0.3", @@ -2835,13 +2865,13 @@ } }, "node_modules/@docusaurus/theme-common/node_modules/@docusaurus/module-type-aliases": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.0.1.tgz", - "integrity": "sha512-DEHpeqUDsLynl3AhQQiO7AbC7/z/lBra34jTcdYuvp9eGm01pfH1wTVq8YqWZq6Jyx0BgcVl/VJqtE9StRd9Ag==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.1.0.tgz", + "integrity": "sha512-XUl7Z4PWlKg4l6KF05JQ3iDHQxnPxbQUqTNKvviHyuHdlalOFv6qeDAm7IbzyQPJD5VA6y4dpRbTWSqP9ClwPg==", "peer": true, "dependencies": { "@docusaurus/react-loadable": "5.5.2", - "@docusaurus/types": "3.0.1", + "@docusaurus/types": "3.1.0", "@types/history": "^4.7.11", "@types/react": "*", "@types/react-router-config": "*", @@ -2855,18 +2885,18 @@ } }, "node_modules/@docusaurus/theme-common/node_modules/@docusaurus/plugin-content-blog": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.0.1.tgz", - "integrity": "sha512-cLOvtvAyaMQFLI8vm4j26svg3ktxMPSXpuUJ7EERKoGbfpJSsgtowNHcRsaBVmfuCsRSk1HZ/yHBsUkTmHFEsg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.1.0.tgz", + "integrity": "sha512-iMa6WBaaEdYuxckvJtLcq/HQdlA4oEbCXf/OFfsYJCCULcDX7GDZpKxLF3X1fLsax3sSm5bmsU+CA0WD+R1g3A==", "peer": true, "dependencies": { - "@docusaurus/core": "3.0.1", - "@docusaurus/logger": "3.0.1", - "@docusaurus/mdx-loader": "3.0.1", - "@docusaurus/types": "3.0.1", - "@docusaurus/utils": "3.0.1", - "@docusaurus/utils-common": "3.0.1", - "@docusaurus/utils-validation": "3.0.1", + "@docusaurus/core": "3.1.0", + "@docusaurus/logger": "3.1.0", + "@docusaurus/mdx-loader": "3.1.0", + "@docusaurus/types": "3.1.0", + "@docusaurus/utils": "3.1.0", + "@docusaurus/utils-common": "3.1.0", + "@docusaurus/utils-validation": "3.1.0", "cheerio": "^1.0.0-rc.12", "feed": "^4.2.2", "fs-extra": "^11.1.1", @@ -2887,18 +2917,18 @@ } }, "node_modules/@docusaurus/theme-common/node_modules/@docusaurus/plugin-content-docs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.0.1.tgz", - "integrity": "sha512-dRfAOA5Ivo+sdzzJGXEu33yAtvGg8dlZkvt/NEJ7nwi1F2j4LEdsxtfX2GKeETB2fP6XoGNSQnFXqa2NYGrHFg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.1.0.tgz", + "integrity": "sha512-el5GxhT8BLrsWD0qGa8Rq+Ttb/Ni6V3DGT2oAPio0qcs/mUAxeyXEAmihkvmLCnAgp6xD27Ce7dISZ5c6BXeqA==", "peer": true, "dependencies": { - "@docusaurus/core": "3.0.1", - "@docusaurus/logger": "3.0.1", - "@docusaurus/mdx-loader": "3.0.1", - "@docusaurus/module-type-aliases": "3.0.1", - "@docusaurus/types": "3.0.1", - "@docusaurus/utils": "3.0.1", - "@docusaurus/utils-validation": "3.0.1", + "@docusaurus/core": "3.1.0", + "@docusaurus/logger": "3.1.0", + "@docusaurus/mdx-loader": "3.1.0", + "@docusaurus/module-type-aliases": "3.1.0", + "@docusaurus/types": "3.1.0", + "@docusaurus/utils": "3.1.0", + "@docusaurus/utils-validation": "3.1.0", "@types/react-router-config": "^5.0.7", "combine-promises": "^1.1.0", "fs-extra": "^11.1.1", @@ -2917,16 +2947,16 @@ } }, "node_modules/@docusaurus/theme-common/node_modules/@docusaurus/plugin-content-pages": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.0.1.tgz", - "integrity": "sha512-oP7PoYizKAXyEttcvVzfX3OoBIXEmXTMzCdfmC4oSwjG4SPcJsRge3mmI6O8jcZBgUPjIzXD21bVGWEE1iu8gg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.1.0.tgz", + "integrity": "sha512-9gntYQFpk+93+Xl7gYczJu8I9uWoyRLnRwS0+NUFcs9iZtHKsdqKWPRrONC9elfN3wJ9ORwTbcVzsTiB8jvYlg==", "peer": true, "dependencies": { - "@docusaurus/core": "3.0.1", - "@docusaurus/mdx-loader": "3.0.1", - "@docusaurus/types": "3.0.1", - "@docusaurus/utils": "3.0.1", - "@docusaurus/utils-validation": "3.0.1", + "@docusaurus/core": "3.1.0", + "@docusaurus/mdx-loader": "3.1.0", + "@docusaurus/types": "3.1.0", + "@docusaurus/utils": "3.1.0", + "@docusaurus/utils-validation": "3.1.0", "fs-extra": "^11.1.1", "tslib": "^2.6.0", "webpack": "^5.88.1" @@ -2940,11 +2970,12 @@ } }, "node_modules/@docusaurus/theme-common/node_modules/@docusaurus/types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.0.1.tgz", - "integrity": "sha512-plyX2iU1tcUsF46uQ01pAd4JhexR7n0iiQ5MSnBFX6M6NSJgDYdru/i1/YNPKOnQHBoXGLHv0dNT6OAlDWNjrg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.1.0.tgz", + "integrity": "sha512-VaczOZf7+re8aFBIWnex1XENomwHdsSTkrdX43zyor7G/FY4OIsP6X28Xc3o0jiY0YdNuvIDyA5TNwOtpgkCVw==", "peer": true, "dependencies": { + "@mdx-js/mdx": "^3.0.0", "@types/history": "^4.7.11", "@types/react": "*", "commander": "^5.1.0", @@ -2960,12 +2991,12 @@ } }, "node_modules/@docusaurus/theme-common/node_modules/@docusaurus/utils": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.0.1.tgz", - "integrity": "sha512-TwZ33Am0q4IIbvjhUOs+zpjtD/mXNmLmEgeTGuRq01QzulLHuPhaBTTAC/DHu6kFx3wDgmgpAlaRuCHfTcXv8g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.1.0.tgz", + "integrity": "sha512-LgZfp0D+UBqAh7PZ//MUNSFBMavmAPku6Si9x8x3V+S318IGCNJ6hUr2O29UO0oLybEWUjD5Jnj9IUN6XyZeeg==", "peer": true, "dependencies": { - "@docusaurus/logger": "3.0.1", + "@docusaurus/logger": "3.1.0", "@svgr/webpack": "^6.5.1", "escape-string-regexp": "^4.0.0", "file-loader": "^6.2.0", @@ -2996,9 +3027,9 @@ } }, "node_modules/@docusaurus/theme-common/node_modules/@docusaurus/utils-common": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.0.1.tgz", - "integrity": "sha512-W0AxD6w6T8g6bNro8nBRWf7PeZ/nn7geEWM335qHU2DDDjHuV4UZjgUGP1AQsdcSikPrlIqTJJbKzer1lRSlIg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.1.0.tgz", + "integrity": "sha512-SfvnRLHoZ9bwTw67knkSs7IcUR0GY2SaGkpdB/J9pChrDiGhwzKNUhcieoPyPYrOWGRPk3rVNYtoy+Bc7psPAw==", "peer": true, "dependencies": { "tslib": "^2.6.0" @@ -3016,13 +3047,13 @@ } }, "node_modules/@docusaurus/theme-common/node_modules/@docusaurus/utils-validation": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.0.1.tgz", - "integrity": "sha512-ujTnqSfyGQ7/4iZdB4RRuHKY/Nwm58IIb+41s5tCXOv/MBU2wGAjOHq3U+AEyJ8aKQcHbxvTKJaRchNHYUVUQg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.1.0.tgz", + "integrity": "sha512-dFxhs1NLxPOSzmcTk/eeKxLY5R+U4cua22g9MsAMiRWcwFKStZ2W3/GDY0GmnJGqNS8QAQepJrxQoyxXkJNDeg==", "peer": true, "dependencies": { - "@docusaurus/logger": "3.0.1", - "@docusaurus/utils": "3.0.1", + "@docusaurus/logger": "3.1.0", + "@docusaurus/utils": "3.1.0", "joi": "^17.9.2", "js-yaml": "^4.1.0", "tslib": "^2.6.0" diff --git a/website/package.json b/website/package.json index 46fef52d1b..cb33e99a31 100644 --- a/website/package.json +++ b/website/package.json @@ -15,11 +15,12 @@ "serve": "docusaurus serve", "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids", - "typecheck": "tsc" + "types": "tsc -p tsconfig.json --noEmit" }, "dependencies": { "@docusaurus/core": "3.0.0", "@docusaurus/preset-classic": "3.0.0", + "@docusaurus/theme-classic": "3.0.0", "@easyops-cn/docusaurus-search-local": "^0.37.4", "@mdx-js/react": "^3.0.0", "clsx": "^1.2.1", From 183c1d8361bdf3a192a212ef610ae7855c96c587 Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Mon, 8 Jan 2024 16:25:23 +0000 Subject: [PATCH 36/37] docs(testing): revisit testing docs and add more in detail info --- .../ts/__tests__/data/suites.json | 41 ++++ .../ts/__tests__/utils/interfaces.ts | 1 - integrationTests/ts/__tests__/utils/utils.ts | 7 +- website/versioned_docs/version-v1.x/audit.md | 2 +- .../version-v1.x/ci-pipeline.md | 2 +- .../version-v1.x/coordinator-processing.md | 2 +- .../version-v1.x/integrating.md | 2 +- .../versioned_docs/version-v1.x/key-change.md | 2 +- website/versioned_docs/version-v1.x/spec.md | 2 +- .../version-v1.x/testing-in-details.md | 209 ++++++++++++++++++ .../versioned_docs/version-v1.x/testing.md | 87 ++++---- .../version-v1.x/troubleshooting.md | 2 +- .../versioned_docs/version-v1.x/versioning.md | 2 +- 13 files changed, 310 insertions(+), 51 deletions(-) create mode 100644 website/versioned_docs/version-v1.x/testing-in-details.md diff --git a/integrationTests/ts/__tests__/data/suites.json b/integrationTests/ts/__tests__/data/suites.json index 9315e6fb98..a8d161db97 100644 --- a/integrationTests/ts/__tests__/data/suites.json +++ b/integrationTests/ts/__tests__/data/suites.json @@ -27,6 +27,47 @@ "expectedSpentVoiceCredits": [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "expectedTotalSpentVoiceCredits": 4 }, + { + "name": "10 Users test", + "description": "Should signup 10 users, submit 10 votes and tally the results", + "numUsers": 10, + "numVotesPerUser": 1, + "votes": { + "0": { + "0": { "voteOptionIndex": 0, "voteWeight": 5 } + }, + "1": { + "0": { "voteOptionIndex": 0, "voteWeight": 9 } + }, + "2": { + "0": { "voteOptionIndex": 5, "voteWeight": 3 } + }, + "3": { + "0": { "voteOptionIndex": 3, "voteWeight": 2 } + }, + "4": { + "0": { "voteOptionIndex": 0, "voteWeight": 1 } + }, + "5": { + "0": { "voteOptionIndex": 9, "voteWeight": 1 } + }, + "6": { + "0": { "voteOptionIndex": 4, "voteWeight": 7 } + }, + "7": { + "0": { "voteOptionIndex": 7, "voteWeight": 5 } + }, + "8": { + "0": { "voteOptionIndex": 3, "voteWeight": 10 } + }, + "9": { + "0": { "voteOptionIndex": 8, "voteWeight": 2 } + } + }, + "expectedTally": [15, 0, 0, 12, 7, 3, 0, 5, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0], + "expectedSpentVoiceCredits": [107, 0, 0, 104, 49, 9, 0, 25, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "expectedTotalSpentVoiceCredits": 299 + }, { "name": "Reverse processing", "description": "2 batches, 1 briber", diff --git a/integrationTests/ts/__tests__/utils/interfaces.ts b/integrationTests/ts/__tests__/utils/interfaces.ts index 4394d7b8d2..b1d2285c38 100644 --- a/integrationTests/ts/__tests__/utils/interfaces.ts +++ b/integrationTests/ts/__tests__/utils/interfaces.ts @@ -5,7 +5,6 @@ export interface IVote { voteOptionIndex: number; voteWeight: number; nonce: number; - valid: boolean; } /** diff --git a/integrationTests/ts/__tests__/utils/utils.ts b/integrationTests/ts/__tests__/utils/utils.ts index e2365c5123..9d90e46b82 100644 --- a/integrationTests/ts/__tests__/utils/utils.ts +++ b/integrationTests/ts/__tests__/utils/utils.ts @@ -40,7 +40,6 @@ const getTestVoteValues = ( const useVotes = votes && userIndex in votes; let { voteOptionIndex } = defaultVote; let { voteWeight } = defaultVote; - let valid = true; // if we have bribers if (bribers && userIndex in bribers) { @@ -63,10 +62,9 @@ const getTestVoteValues = ( if (useVotes) { voteWeight = votes[userIndex][voteIndex].voteWeight; - valid = votes[userIndex][voteIndex].valid; } - return { voteOptionIndex, voteWeight, valid }; + return { voteOptionIndex, voteWeight }; }; /** @@ -89,12 +87,11 @@ export const genTestUserCommands = ( const votes: IVote[] = []; for (let j = 0; j < numVotesPerUser; j += 1) { - const { voteOptionIndex, voteWeight, valid } = getTestVoteValues(i, j, numVotesPerUser, presetVotes, bribers); + const { voteOptionIndex, voteWeight } = getTestVoteValues(i, j, numVotesPerUser, presetVotes, bribers); const vote = { voteOptionIndex, voteWeight, nonce: j + 1, - valid, }; votes.push(vote); diff --git a/website/versioned_docs/version-v1.x/audit.md b/website/versioned_docs/version-v1.x/audit.md index dd1c9677b3..0051fc9688 100644 --- a/website/versioned_docs/version-v1.x/audit.md +++ b/website/versioned_docs/version-v1.x/audit.md @@ -2,7 +2,7 @@ title: MACI Security Audits description: In the summer of 2022, MACI v1 was audited by HashCloak. The audit covered both the zk-SNARK circuits and the Solidity smart contracts. sidebar_label: Security Assessments -sidebar_position: 11 +sidebar_position: 12 --- # Security Audits diff --git a/website/versioned_docs/version-v1.x/ci-pipeline.md b/website/versioned_docs/version-v1.x/ci-pipeline.md index e328c3e950..27e3e6d5d9 100644 --- a/website/versioned_docs/version-v1.x/ci-pipeline.md +++ b/website/versioned_docs/version-v1.x/ci-pipeline.md @@ -2,7 +2,7 @@ title: CI Pipeline description: Introduction to how MACI's CI works sidebar_label: CI -sidebar_position: 12 +sidebar_position: 13 --- # Continuous Integration (CI) Pipeline diff --git a/website/versioned_docs/version-v1.x/coordinator-processing.md b/website/versioned_docs/version-v1.x/coordinator-processing.md index a26df3b258..9c17725830 100644 --- a/website/versioned_docs/version-v1.x/coordinator-processing.md +++ b/website/versioned_docs/version-v1.x/coordinator-processing.md @@ -2,7 +2,7 @@ title: Coordinator local processing description: How does the coordinator process and tallies messages locally sidebar_label: Coordinator local processing -sidebar_position: 13 +sidebar_position: 14 --- # Coordinator local processing diff --git a/website/versioned_docs/version-v1.x/integrating.md b/website/versioned_docs/version-v1.x/integrating.md index 83c8c362b5..eb67fbe989 100644 --- a/website/versioned_docs/version-v1.x/integrating.md +++ b/website/versioned_docs/version-v1.x/integrating.md @@ -2,7 +2,7 @@ title: Integrating MACI description: How to integrate MACI into your application sidebar_label: Integrating -sidebar_position: 10 +sidebar_position: 11 --- # Integrating MACI diff --git a/website/versioned_docs/version-v1.x/key-change.md b/website/versioned_docs/version-v1.x/key-change.md index fde3570164..4583baf98c 100644 --- a/website/versioned_docs/version-v1.x/key-change.md +++ b/website/versioned_docs/version-v1.x/key-change.md @@ -2,7 +2,7 @@ title: MACI key change description: How key change messages work sidebar_label: Key change -sidebar_position: 15 +sidebar_position: 16 --- # MACI Key Change diff --git a/website/versioned_docs/version-v1.x/spec.md b/website/versioned_docs/version-v1.x/spec.md index 4fb4f828b7..d2b77a327e 100644 --- a/website/versioned_docs/version-v1.x/spec.md +++ b/website/versioned_docs/version-v1.x/spec.md @@ -2,7 +2,7 @@ title: MACI v1.0 Specification description: A detailed specification meant to assist auditors in reviewing MACI version 1.0 sidebar_label: Specification -sidebar_position: 14 +sidebar_position: 15 --- # MACI v1.0 Specification diff --git a/website/versioned_docs/version-v1.x/testing-in-details.md b/website/versioned_docs/version-v1.x/testing-in-details.md new file mode 100644 index 0000000000..3bad51a409 --- /dev/null +++ b/website/versioned_docs/version-v1.x/testing-in-details.md @@ -0,0 +1,209 @@ +--- +title: MACI Testing in Details +description: How MACI tests work in details +sidebar_label: How Our Test Suites Work +sidebar_position: 10 +--- + +# Testing + +This doc extends on the [Testing](https://maci.pse.dev/docs/testing.md) doc and explains how MACI tests work in details. This information should be used by MACI's maintainers as well as contributors. + +## Automated Tests + +### CLI Tests + +MACI's CLI provides a series of commands that can be used by both the coordinator and voters, to interact with MACI, from deploying smart contracts to submitting a vote. + +Currently, there are a number of test cases that are available inside the cli tests folder. The tests are split into two categories: + +- e2e tests that include the entire MACI stack, from deploying the contracts to submitting a vote and tallying all results. +- e2e tests as above, but with the subsidy feature enabled. + +The goal of these tests is to ensure that the MACI stack works as expected, and that the coordinator and voters can interact with the system as expected. They currently do not attempt to verify whether the tally results are expected, or that all votes were accounted for. On the other hand, they test different scenarios, mixing different numbers of voters and messages. + +### Integration Tests + +Integration tests follow a similar fashion of the CLI tests, though they also ensure that the tally results are as expected. + +Currently, tests are defined using a JSON file, here is one example: + +```json +{ + "name": "Happy path", + "description": "Full tree, 4 batches, no bribers", + "numVotesPerUser": 1, + "numUsers": 15, + "expectedTally": [15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "expectedSpentVoiceCredits": [15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "expectedTotalSpentVoiceCredits": 15 +} +``` + +This test will generate 15 signups (as expressed in `numUsers`), and submit one vote (`numVotesPerUser`) for each of the users. As we did not provide any vote detail, it will use the default: `weight = 1`, `option = 0` for all voters. This will result of course in a tally result of 15 for option 0, and 0 for all other options. + +Finally, the whole process of merging the state and message trees is performed, proofs are generated and the tally result is verified against the expected result. + +#### How to implement a new test case + +To add a new test cases, it is quite simple. You can amend the `integrationTests/ts/__tests__/data/suites.json` file and add your test declaration in there. + +```json +{ + "name": "Subsidy test", + "description": "has subsidy result", + "numUsers": 4, + "numVotesPerUser": 1, + "votes": { + "0": { + "0": { "voteOptionIndex": 0, "voteWeight": 1, "valid": true } + }, + "1": { + "0": { "voteOptionIndex": 0, "voteWeight": 1, "valid": true } + }, + "2": { + "0": { "voteOptionIndex": 0, "voteWeight": 1, "valid": true } + }, + "3": { + "0": { "voteOptionIndex": 0, "voteWeight": 1, "valid": true } + } + }, + "expectedTally": [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "expectedSpentVoiceCredits": [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "expectedTotalSpentVoiceCredits": 4, + "subsidy": { + "enabled": true, + "expectedSubsidy": [117636, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + } +} +``` + +Let's look at the fields in detail: + +- `name`: the name of the test case +- `description`: a description of the test case +- `numUsers`: the number of users to generate +- `numVotesPerUser`: the number of votes to generate for each user +- `votes`: the votes to generate. This is an object where the key is the user index, and the value is another object where the key is the message index, and the value is the vote details. If you do not provide any vote details, the default will be used: `weight = 1`, `option = 0` for all voters. +- `expectedTally`: the expected tally result for each vote option (in order) +- `expectedSpentVoiceCredits`: the expected spent voice credits for each vote option (in order) +- `expectedTotalSpentVoiceCredits`: the expected total spent voice credits +- `subsidy`: an object that contains the subsidy details. If you do not provide any subsidy details, the default will be used: `enabled = false`, `expectedSubsidy = []`. If you do provide subsidy details, you must provide both fields. + +As an example, let's try to implement a test given the following criterias: + +1. We want 10 users to signup +2. We want each user to publish a different vote +3. We want to verify that the tally result is as expected +4. We will not use the subsidy feature + +```json +{ + "name": "10 Users test", + "description": "Should signup 10 users, submit 10 votes and tally the results", + "numUsers": 10, + "numVotesPerUser": 1, + "votes": { + "0": { + "0": { "voteOptionIndex": 0, "voteWeight": 5 } + }, + "1": { + "0": { "voteOptionIndex": 0, "voteWeight": 9 } + }, + "2": { + "0": { "voteOptionIndex": 5, "voteWeight": 3 } + }, + "3": { + "0": { "voteOptionIndex": 3, "voteWeight": 2 } + }, + "4": { + "0": { "voteOptionIndex": 0, "voteWeight": 1 } + }, + "5": { + "0": { "voteOptionIndex": 9, "voteWeight": 1 } + }, + "6": { + "0": { "voteOptionIndex": 4, "voteWeight": 7 } + }, + "7": { + "0": { "voteOptionIndex": 7, "voteWeight": 5 } + }, + "8": { + "0": { "voteOptionIndex": 3, "voteWeight": 10 } + }, + "9": { + "0": { "voteOptionIndex": 8, "voteWeight": 2 } + } + }, + "expectedTally": [15, 0, 0, 12, 7, 3, 0, 5, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0], + "expectedSpentVoiceCredits": [107, 0, 0, 104, 49, 9, 0, 25, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "expectedTotalSpentVoiceCredits": 299 +} +``` + +**Why expectedTally as above** + +[(5 + 9 + 1), 0, 0, (2 + 10), 7, 3, 0, 5, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0] -> [15, 0, 0, 12, 7, 3, 0, 5, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0] + +**Why 299 voice credits spent** + +- 5 ** 2 + 9 ** 2 + 3 ** 2 + 2 ** 2 + 1 ** 2 + 1 ** 1 + 7 ** 2 + 5 ** 2 + 10 ** 2 + 2 ** 2 = 25 + 81 + 9 + 4 + 1 + 1 + 49 + 25 + 100 + 4 = 299 + +**Why expectedSpentVoiceCredits as above** + +[(25 + 81 + 1), 0, 0, (4 + 100), 49, 0, 25, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0] -> [107, 0, 0, 104, 49, 0, 25, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + +#### MACI keys integration tests + +Another test file which is found inside the integration tests folder is the `maciKeys.test.ts` file. This file contains a number of tests that are used to verify that the MACI keys work as expected. These tests are written in TypeScript and use the `mocha` and `chai` frameworks. + +They are testing that between the `contracts`, `domainobjs` and `crypto` packages, the MACI keys are working correctly, and are serialized/deserialized as expected. This is particularly important to test due to different data formats for keys, especially when parsed from the smart contract events. + +### Contract tests + +Within the contracts folder, there are a number of tests that are used to verify that the contracts work as expected. These tests are written in TypeScript and use the `hardhat` framework. + +These tests interact with all other packages, such as crypto, domainobjs and core, where mock data comes from. Their main goal is to ensure that the smart contracts have the correct parameters when deployed, privileged functions cannot be called by non-privileged users, and that the contract state is as expected after a series of operations. + +### Circuits tests + +Within the circuits folder, there are a number of tests that are used to verify that the circuits work as expected. These tests are written in TypeScript and use the `circom_tester` (which runs on top of `mocha` and `chai`). + +These tests often use mock data from the `core` package. For instance, when testing the `processMessages` circuit, we are required to generate the parameters from the `core` packing, using the `Poll:processMessages` function. The same applies to vote tallying, where we need the `Poll:tally` function to be run first with mock users and vote messages. + +All of the tests run using test parameters, usually `10, 2, 1, 2`, aside from the tests inside: [`ceremonyParam`](https://github.com/privacy-scaling-explorations/maci/blob/dev/circuits/ts/__tests__/CeremonyParams.test.ts) which use the parameters of the latest MACI ceremony. More details on the trusted setup can be found [here](https://maci.pse.dev/docs/trusted-setup). + +### Core + +The core package contains a number of tests that are used to verify that the core functions work as expected. These tests are written in TypeScript and use the `mocha` and `chai` frameworks. + +These tests interact with the crypto and dombinobjs packages, where mock data comes from. Their main goal is to ensure that the core functions work as expected, and that the state is as expected after a series of operations. + +Currently, there is a blend of e2e and unit tests, where e2e tests are used to verify that the entire MACI local processing works as expcted (users signup, publish votes, messages are processed and finally these votes are tallied). Unit tests on the other hand are used to verify that the core functions work as expected, such as `processMessage` and `tallyVotes`. You will find them in separate files, with e2e being [here](https://github.com/privacy-scaling-explorations/maci/blob/dev/core/ts/__tests__/e2e.test.ts) and unit tests in the other files. + +### Domainobjs/Crypto tests + +These tests are used to verify that MACI's primitives such as private keys work as expected. They are written in TypeScript and use the `mocha` and `chai` frameworks. + +## "Manual" Testing + +To ensure that the MACI stack works as expected, without having to run the entire test suite (or even just the e2e tests), there is a [bash script](https://github.com/privacy-scaling-explorations/maci/blob/dev/cli/testScript.sh) inside the cli folder which can be used. + +This script contains a number of actions which touch all of the parts of MACI, and resemble exactly what other e2e tests do. + +Looking at this in more details we do the following: + +1. Deploy a `VkRegistry` contract +2. Set the verification keys on this smart contract +3. Deploy a `MACI` contract (and associated utility contracts) +4. Deploy a Poll from the MACI contract. +5. Signup 1 user +6. Publish 2 messages +7. Travel in time (local blockchain node) to arrive at the end of the poll +8. Merge the signups tree +9. Merge the messages tree +10. Generate proofs for the message processing and vote tallying +11. Update the on chain state +12. Verify that proofs and tally are correct + +The above is the minimum required to ensure that the stack works as expected, as it encompasses actions from both voters and the coordinator. diff --git a/website/versioned_docs/version-v1.x/testing.md b/website/versioned_docs/version-v1.x/testing.md index 985b201ad6..05a614f779 100644 --- a/website/versioned_docs/version-v1.x/testing.md +++ b/website/versioned_docs/version-v1.x/testing.md @@ -7,7 +7,7 @@ sidebar_position: 9 # Testing -### Unit tests +## Unit tests Unit tests within the project are built using [Mocha](https://mochajs.org/) and [Chai](https://www.chaijs.com/). Mocha is a test framework that provides the environment to write and run JavaScript tests, while Chai is an assertion library that allows us to write assertions in a more expressive and readable way. @@ -31,12 +31,12 @@ You can also run individual tests within submodules, for example: ```bash cd contracts -npm run test-accQueue +npm run test:accQueue ``` This test command will run `AccQueue.test.ts` -## Contracts +### Contracts First, compile the contracts. @@ -53,7 +53,7 @@ To run Contracts only tests, run: npm run test ``` -## Circuits +### Circuits To test the circuits, from the main `maci/` directory, run: @@ -67,11 +67,13 @@ Tests are run using [Mocha](https://mochajs.org/) and [`circom_tester`](https:// ## CLI You can test the CLI locally. First, you need to either generate `.zkey` files, -or download them. Do not use these testing `.zkey` files in production. +or download them. Please remember to not use these testing `.zkey` files in production. ### Download `.zkey` files or the witness generation binaries -MACI has three zk-SNARK circuits. Each circuit is parameterised. There should one +MACI has two main zk-SNARK circuits, `processMessages` and `tallyVotes` (`subsidyPerBatch` is optional). + +Each circuit is parameterised and there should be one `.zkey` file for each circuit and set of parameters. Unless you wish to generate a fresh set of `.zkey` files, you should obtain @@ -81,9 +83,10 @@ circuits. Note the locations of the `.zkey` files as the CLI requires them as command-line flags. -You cand download a `.zkey` files and associated `.r1cs` file with witness generation binaries from [here](https://github.com/privacy-scaling-explorations/maci/wiki/Download-Precompiled-Circuit-and-Zkeys). +For testing purposes you can download the required artifacts using the [`download_zkeys``](https://github.com/privacy-scaling-explorations/maci/blob/dev/integrationTests/scripts/download_zkeys.sh) script inside the `integrationTests/scripts` folder. The script will place all required artifacts inside the `cli/zkeys` folder. +You can run the script directly with bash or use npm: `npm run download-zkeys`. -### Compile the witness generation binaries +### Compile the witness generation binaries (if generating from scratch) From the main `maci/cli` directory, run: @@ -122,11 +125,23 @@ TallyVotes_10-1-2_test_js Next, ensure that the `prover` binary of `rapidsnark` is in `~/rapidsnark/build/prover`. +:::info +This step is only required if you wish to use rapidsnark, for faster proof generation. You can also use the WASM witnesses provided in the `cli/zkeys` folder. +::: + ### Run CLI tests You can find the tests in `maci/cli/tests`. -To run all tests: +To run the tests first start a hardhat node in the background: + +```bash +cd contracts +npm run hardhat & +cd ../cli +``` + +Then run the tests (this will run all tests): ```bash npm run test @@ -144,8 +159,6 @@ To run e2e with subsidy: npm run test:e2e-subsidy ``` -> Please note that these require a hardhat node running in the background for local testing. You can start one with `npm run hardhat` within the **contracts** folder. - ### Run integration tests You can find the tests in `maci/integrationTests/`. @@ -170,7 +183,7 @@ The followingcompiled circuits and zkeys are available to download: - glibc 2.11 (Default of Ubuntu 20.04 LTS) -## Prod Size +#### Prod Size - [zkeys-7-9-3-4.tar.gz](https://maci-develop-fra.s3.eu-central-1.amazonaws.com/v1.1.1-aa4ba27/7-9-3-4/zkeys_7-9-3-4_glibc-211.tar.gz) (2.8 GB) - [ProcessMessages_7-9-3-4_test.0.zkey](https://maci-develop-fra.s3.eu-central-1.amazonaws.com/v1.1.1-aa4ba27/7-9-3-4/ProcessMessages_7-9-3-4_test.0.zkey) (3.8 GB) @@ -178,7 +191,7 @@ The followingcompiled circuits and zkeys are available to download: - [TallyVotes_7-3-4_test.0.zkey](https://maci-develop-fra.s3.eu-central-1.amazonaws.com/v1.1.1-aa4ba27/7-9-3-4/TallyVotes_7-3-4_test.0.zkey) (8.5 GB) - generated using `powersOfTau28_hez_final_23.ptau` -### Message processing +##### Message processing | Parameter | Value | Description | | ------------------------ | ----- | ---------------------------------------------- | @@ -187,7 +200,7 @@ The followingcompiled circuits and zkeys are available to download: | Message batch tree depth | 3 | Allows 125 messages to be processed per batch. | | Vote option tree depth | 4 | Allows 625 vote options. | -### Vote tallying +##### Vote tallying | Parameter | Value | Description | | ------------------------ | ----- | -------------------------------------------------- | @@ -195,7 +208,7 @@ The followingcompiled circuits and zkeys are available to download: | State leaf batch depth | 3 | Allows 125 user's votes to be processed per batch. | | Message batch tree depth | 4 | Allows 625 messages to be processed per batch. | -## Micro size +#### Micro size - [zkeys_10-2-1-2_glibc-211.tar.gz](https://maci-develop-fra.s3.eu-central-1.amazonaws.com/v1.1.1-aa4ba27/10-2-1-2/zkeys_10-2-1-2_glibc-211.tar.gz) (403 MB) - [ProcessMessages_10-2-1-2_test.0.zkey](https://maci-develop-fra.s3.eu-central-1.amazonaws.com/v1.1.1-aa4ba27/10-2-1-2/ProcessMessages_10-2-1-2_test.0.zkey) (190 MB) @@ -204,7 +217,7 @@ The followingcompiled circuits and zkeys are available to download: `*.zkey` files are generated using `powersOfTau28_hez_final_20.ptau` -### Message processing +##### Message processing | Parameter | Value | Description | | ------------------------ | ----- | -------------------------------------------- | @@ -213,7 +226,7 @@ The followingcompiled circuits and zkeys are available to download: | Message batch tree depth | 1 | Allows 5 messages to be processed per batch. | | Vote option tree depth | 2 | Allows 25 vote options. | -### Vote tallying +##### Vote tallying | Parameter | Value | Description | | ------------------------ | ----- | ------------------------------------------------ | @@ -221,7 +234,7 @@ The followingcompiled circuits and zkeys are available to download: | State leaf batch depth | 1 | Allows 5 user's votes to be processed per batch. | | Message batch tree depth | 2 | Allows 25 messages to be processed per batch. | -## Small size +#### Small size - [zkeys_4-6-3-4_glibc-211.tar.gz](https://maci-develop-fra.s3.eu-central-1.amazonaws.com/v1.1.1-aa4ba27/4-6-3-4/zkeys_4-6-3-4_glibc-211.tar.gz) (2.6 GB) - [ProcessMessages_4-6-3-4_test.0.zkey](https://maci-develop-fra.s3.eu-central-1.amazonaws.com/v1.1.1-aa4ba27/4-6-3-4/ProcessMessages_4-6-3-4_test.0.zkey) (2.9 GB) @@ -229,7 +242,7 @@ The followingcompiled circuits and zkeys are available to download: - [TallyVotes_4-3-4_test.0.zkey](https://maci-develop-fra.s3.eu-central-1.amazonaws.com/v1.1.1-aa4ba27/4-6-3-4/TallyVotes_4-3-4_test.0.zkey) (8.5 GB) - generated using `powersOfTau28_hez_final_23.ptau` -### Message processing +##### Message processing | Parameter | Value | Description | | ------------------------ | ----- | ---------------------------------------------- | @@ -238,7 +251,7 @@ The followingcompiled circuits and zkeys are available to download: | Message batch tree depth | 3 | Allows 125 messages to be processed per batch. | | Vote option tree depth | 4 | Allows 625 vote options. | -### Vote tallying +##### Vote tallying | Parameter | Value | Description | | ------------------------ | ----- | -------------------------------------------------- | @@ -246,7 +259,7 @@ The followingcompiled circuits and zkeys are available to download: | State leaf batch depth | 3 | Allows 125 user's votes to be processed per batch. | | Message batch tree depth | 4 | Allows 625 messages to be processed per batch. | -## Medium size +#### Medium size - [zkeys_7-7-3-3_glibc-211.tar.gz](https://maci-develop-fra.s3.eu-central-1.amazonaws.com/v1.1.1-aa4ba27/7-7-3-3/zkeys_7-7-3-3_glibc-211.tar.gz) (4.9 GB) - [ProcessMessages_7-7-3-3_test.0.zkey](https://maci-develop-fra.s3.eu-central-1.amazonaws.com/v1.1.1-aa4ba27/7-7-3-3/ProcessMessages_7-7-3-3_test.0.zkey) (2.2 GB) @@ -254,7 +267,7 @@ The followingcompiled circuits and zkeys are available to download: - [TallyVotes_7-3-3_test.0.zkey](https://maci-develop-fra.s3.eu-central-1.amazonaws.com/v1.1.1-aa4ba27/7-7-3-3/TallyVotes_7-3-3_test.0.zkey) (884 MB) - generated using `powersOfTau28_hez_final_22.ptau` -### Message processing +##### Message processing | Parameter | Value | Description | | ------------------------ | ----- | ---------------------------------------------- | @@ -263,7 +276,7 @@ The followingcompiled circuits and zkeys are available to download: | Message batch tree depth | 3 | Allows 125 messages to be processed per batch. | | Vote option tree depth | 3 | Allows 125 vote options. | -### Vote tallying +##### Vote tallying | Parameter | Value | Description | | ------------------------ | ----- | -------------------------------------------------- | @@ -271,7 +284,7 @@ The followingcompiled circuits and zkeys are available to download: | State leaf batch depth | 3 | Allows 125 user's votes to be processed per batch. | | Message batch tree depth | 3 | Allows 125 messages to be processed per batch. | -## 6-8-3-3 +#### 6-8-3-3 - [zkeys_6-8-3-3_glibc-211.tar.gz](https://maci-develop-fra.s3.eu-central-1.amazonaws.com/v1.1.1-aa4ba27/6-8-3-3/zkeys_6-8-3-3_glibc-211.tar.gz) (1.1 GB) - [ProcessMessages_6-8-3-3_test.0.zkey](https://maci-develop-fra.s3.eu-central-1.amazonaws.com/v1.1.1-aa4ba27/6-8-3-3/ProcessMessages_6-8-3-3_test.0.zkey) (3.4 GB) @@ -279,7 +292,7 @@ The followingcompiled circuits and zkeys are available to download: - [TallyVotes_6-3-3_test.0.zkey](https://maci-develop-fra.s3.eu-central-1.amazonaws.com/v1.1.1-aa4ba27/6-8-3-3/TallyVotes_6-3-3_test.0.zkey) (1.8 MB) - generated using `powersOfTau28_hez_final_22.ptau` -### Message processing +#### Message processing | Parameter | Value | Description | | ------------------------ | ----- | ---------------------------------------------- | @@ -288,7 +301,7 @@ The followingcompiled circuits and zkeys are available to download: | Message batch tree depth | 3 | Allows 125 messages to be processed per batch. | | Vote option tree depth | 3 | Allows 125 vote options. | -### Vote tallying +#### Vote tallying | Parameter | Value | Description | | ------------------------ | ----- | -------------------------------------------------- | @@ -296,7 +309,7 @@ The followingcompiled circuits and zkeys are available to download: | State leaf batch depth | 3 | Allows 125 user's votes to be processed per batch. | | Message batch tree depth | 3 | Allows 125 messages to be processed per batch. | -## contents of `*.tar.gz` +#### contents of `*.tar.gz` It contains compiled result of the circuit: @@ -356,7 +369,7 @@ zkeys/TallyVotes_7-3-4_test --- -## Contribution Hash +##### Contribution Hash - [ProcessMessages_4-6-3-4_test.0.zkey](#ProcessMessages_4-6-3-4_test0zkey) - [TallyVotes_4-3-4_test.0.zkey](#TallyVotes_4-3-4_test0zkey) @@ -368,7 +381,7 @@ zkeys/TallyVotes_7-3-4_test - [ProcessMessages_7-7-3-3_test.0.zkey](#ProcessMessages_7-7-3-3_test0zkey) - [TallyVotes_7-3-3_test.0.zkey](#TallyVotes_7-3-3_test0zkey) -### ProcessMessages_4-6-3-4_test.0.zkey +###### ProcessMessages_4-6-3-4_test.0.zkey ``` 2d29ddba 11e5292e b20f681d 3ade88cd @@ -377,7 +390,7 @@ zkeys/TallyVotes_7-3-4_test 325cfc06 cb1ac909 38b2e5ff 22b34333 ``` -### TallyVotes_4-3-4_test.0.zkey +##### TallyVotes_4-3-4_test.0.zkey ``` d2d88532 c2e1e7bd 3c7be3fb f85da2e2 @@ -386,7 +399,7 @@ d2d88532 c2e1e7bd 3c7be3fb f85da2e2 f3a8a155 cd338e2c 5f364836 bfd7913d ``` -### ProcessMessages_7-9-3-4_test.0.zkey +##### ProcessMessages_7-9-3-4_test.0.zkey ``` 75256709 6e8a034e a067ea67 16192fb2 @@ -395,7 +408,7 @@ f3a8a155 cd338e2c 5f364836 bfd7913d b1094e74 b8aaa9a3 9af75b22 0d9229e6 ``` -### TallyVotes_7-3-4_test.0.zkey +##### TallyVotes_7-3-4_test.0.zkey ``` f44cf32e 1709e2c4 c8dbe8dc 5b6de4be @@ -404,7 +417,7 @@ f44cf32e 1709e2c4 c8dbe8dc 5b6de4be 9b6ced66 c970a87d 745d35e4 5f47d7f9 ``` -### ProcessMessages_10-2-1-2_test.0.zkey +##### ProcessMessages_10-2-1-2_test.0.zkey ``` 23eb4980 d584c7ef 647478b9 dea49a6d @@ -413,7 +426,7 @@ f44cf32e 1709e2c4 c8dbe8dc 5b6de4be 1c2c2662 20e0df3d 12a057f3 2a071937 ``` -### TallyVotes_10-1-2_test.0.zkey +##### TallyVotes_10-1-2_test.0.zkey ``` ae12edd2 6f7f1d25 530177ab 27483fe0 @@ -422,7 +435,7 @@ ce9a8c26 9f015c49 203376da 911e295c 61be4031 56220ca7 06ed3b9f e8504f11 ``` -### SubsidyPerBatch_10-1-2_test.0.zkey +##### SubsidyPerBatch_10-1-2_test.0.zkey ``` 16dfc388 eda0bfd7 ff529e42 505ed6b7 @@ -431,7 +444,7 @@ cbffbb79 9218b09b cfa2fe29 0806097a c84bb980 a1346082 fb00a947 3c97d99e ``` -### ProcessMessages_7-7-3-3_test.0.zkey +##### ProcessMessages_7-7-3-3_test.0.zkey ``` e688264b e1326553 b58492d4 7c2028bc @@ -440,7 +453,7 @@ cda175f9 b786c4eb 44453080 369ab861 a0f752f8 413a81ba f481d335 187e0091 ``` -### TallyVotes_7-3-3_test.0.zkey +##### TallyVotes_7-3-3_test.0.zkey ``` 6869646d 1faf2aec d8c70c85 0021858f diff --git a/website/versioned_docs/version-v1.x/troubleshooting.md b/website/versioned_docs/version-v1.x/troubleshooting.md index 81dd1bc0fd..f6c0f0d7e8 100644 --- a/website/versioned_docs/version-v1.x/troubleshooting.md +++ b/website/versioned_docs/version-v1.x/troubleshooting.md @@ -2,7 +2,7 @@ title: Troubleshooting description: How to troubleshoot MACI's failures sidebar_label: Troubleshooting -sidebar_position: 16 +sidebar_position: 17 --- # Troubleshooting diff --git a/website/versioned_docs/version-v1.x/versioning.md b/website/versioned_docs/version-v1.x/versioning.md index 9edd8047b2..13063ec114 100644 --- a/website/versioned_docs/version-v1.x/versioning.md +++ b/website/versioned_docs/version-v1.x/versioning.md @@ -2,7 +2,7 @@ title: MACI versioning and release process description: How MACI's versioning and release process works sidebar_label: MACI versioning -sidebar_position: 13 +sidebar_position: 18 --- # MACI versioning and release process From 0460554261c9e76973aa0dc0f56ca4ad6fd2f50a Mon Sep 17 00:00:00 2001 From: Sam Richards Date: Wed, 27 Dec 2023 12:40:12 -0500 Subject: [PATCH 37/37] feat: add new post on roadmap updates --- website/blog/2024-01-10-roadmap.md | 102 +++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 website/blog/2024-01-10-roadmap.md diff --git a/website/blog/2024-01-10-roadmap.md b/website/blog/2024-01-10-roadmap.md new file mode 100644 index 0000000000..85043cfb36 --- /dev/null +++ b/website/blog/2024-01-10-roadmap.md @@ -0,0 +1,102 @@ +--- +slug: 2024-team-roadmap +title: New year, new MACI +authors: + name: Sam Richards + title: MACI team + url: https://x.com/samonchain + image_url: https://avatars.githubusercontent.com/u/8097623?v=4 +tags: [maci, roadmap] +--- + +Greetings anons, + +Happy 2024 and welcome to the new MACI documentation website and blog! Moving forward, we’ll post here with our latest project news and development updates. + +We have a few exciting announcements to share, but first a quick review: + +## MACI Overview + +### WTF is MACI? + +**Minimal Anti-Collusion Infrastructure (MACI) is an on-chain voting platform which protects privacy and minimizes the risk of collusion and bribery.** + +MACI is a set of smart contracts and zero-knowledge circuits upon which which developers can build applications, such as voting systems or quadratic funding platforms. It was originally [proposed by Vitalik Buterin](https://ethresear.ch/t/minimal-anti-collusion-infrastructure/5413) in 2019, then implemented and maintained by community members with support from the [Ethereum Foundation](https://ethereum.foundation/). It's now actively maintained within [Privacy & Scaling Explorations (PSE)](https://pse.dev/). + +For a general overview, brief history, and context on the importance of MACI, see the [Release Announcement: MACI 1.0](/blog/maci-1-0-release) by Wei Jie, one of the creators. He also created a helpful [overview of MACI video](https://www.youtube.com/watch?v=sKuNj_IQVYI). Kyle Charbonnet wrote a great [Technical Introduction to MACI 1.0](/blog/maci-1-0-technical-introduction) that provides a walkthrough on how MACI operates. I also recently presented an [introduction to MACI](https://app.streameth.org/zuzalu/zuconnect_hackathon/session/maci_workshop) at Devconnect. + +### MACI Vision + +MACI is a public good that is quickly becoming a core piece of infrastructure for Ethereum-based applications to support on-chain voting while protecting user privacy. Using MACI, no voter can prove how they voted yet voting results are published publicly and verified with cryptographic proofs to prevent censorship, bribery, collusion, and other nefarious acts common in public polling processes. + +**Our MACI team’s vision is to build the most secure e-voting solution in the world.** + +Let's hop into our updates to see how we plan to execute on this bold vision. + +## Project updates + +New year, new team, new roadmap! + +### 1) New team + +Over the past few months we've undergone lot of change within the MACI core team. I'd like to take this chance to introduce and welcome our new core members! + +MACI is now maintained and will be continuously improved by our core team: + +- [ctrlc03](https://github.com/ctrlc03) +- [Sam Richards](https://x.com/samonchain) +- [0xmad](https://github.com/0xmad) +- [kittybest](https://github.com/kittybest) +- [crisgarner](https://github.com/crisgarner) +- [aguzmant103](https://github.com/aguzmant103) +- Vee + +Great time to mention that **we stand on the shoulders of giants**. Many gigabrains have made heroic advancements in this project. Major thanks to all those who have contributed to date! Too many people to list here, but calling out a few notable players: + +- Vitalik, Barry, Wei Jei for the original idea, architecture, initial implementation, and ongoing guidance +- Folks from our most recent team that launched our [v1.1.1 release](/blog/maci-v1-1-1-release) and have since moved on: Q, Jei, Chao, and Daehyun + +We're excited to carry the baton forward to bring the MACI vision into reality! + +### 2) New roadmap + +As a new team working in open source, we're taking a concerted effort to make our work more accessible and to foster more collaboration from our open source community. As part of this work, we're making our team roadmap public and will continue to do so. + +[Read our full roadmap here](/roadmap). + +The TL;DR is that we'll be focusing most of our time on: + +1. **Developer experience** (documentation, tooling) so that MACI is easier for projects to integrate +2. **Community engagement** (integration support, hackathon bounties, conference presentations) to more quickly iterate and improve based off feedback +3. [**Quadratic Funding Experiments**](https://qf.pse.dev/) to support real-world adoption of this technology + +### 3) New documentation + +MACI now has a fresh new website, with [revamped documentation](/docs/introduction)! + +Our team quickly saw the need for improved educational content about MACI. It's a complex project with several core components (ZK circuits, Ethereum smart contracts, TypeScript libraries). Whether you're a developer looking to integrate MACI into your application or an open-source developer interested in contributing, we want to improve your onboarding experience. + +[Please take a look and let us know what you think](/docs/introduction). + +### 4) New community access + +Wether you're interested in contributing to MACI or merely want to follow along with developments, we're making that much easier. Here's some ways you can keep in touch: + +- [GitHub](https://github.com/privacy-scaling-explorations/maci): open an issue or PR or [join our active discussions](https://github.com/privacy-scaling-explorations/maci/discussions) +- [Discord](https://discord.com/invite/sF5CT5rzrR): join the [PSE server](https://discord.com/invite/sF5CT5rzrR) and hop into the `#🗳️-maci` channel to chat with our core team +- [Twitter/X](https://twitter.com/zkmaci): follow our new handle [@zkMACI](https://twitter.com/zkmaci) for updates and hit us up with feedback +- This website: we'll continue to post updates here (at least 1 blog post every quarter)! + +Expect to see announcements around new MACI releases, integrations, relevant events (quadratic funding rounds, conferences, hackathons), and grant RFPs. + +We look forward to working more closely with our open source community! + +## How’s that sound? + +Questions? Concerns? Ideas? We’d love to hear from you! + +If there's a feature you think we should work on or an initiative you'd like to collaborate with us on, please let us know! We welcome input from anyone in the community. + +Feel free to [hit us up on X](https://twitter.com/zkmaci) or reach out to our team in the [PSE Discord](https://discord.com/invite/sF5CT5rzrR) (`#🗳️-maci` channel). + +Onward and upward.