diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5c6ef4e..ffcf302 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -26,6 +26,11 @@ jobs: uses: actions/setup-node@v2 with: node-version: 20.x + + - name: Set up Git + run: | + git config --global user.email "nova.web3.collective@gmail.com" + git config --global user.name "nova collective" - name: Install dependencies run: node ci --function installDeps diff --git a/README.md b/README.md index 7718eee..ab9d7a3 100644 --- a/README.md +++ b/README.md @@ -89,29 +89,48 @@ For the local network the parameter to pass is `localhost`, there is no need to ### Prerequisites -* edit the scripts mocks file: `election-scripts/__mocks__.ts`; +* Edit the scripts mocks file: `election-scripts/__mocks__.ts`; * edit the municipality election contract data, in particular registrationStart and registrationEnd are timestamps in seconds; * edit the data of the parties and candidates as you prefer; + * edit the data of the Voter as you prefer; +* Compile the smart contracts in order to produce the artifacts: `npm run compile`; +* Creates the `typechain-types` folder with the command: `npx hardhat typechain`; +* start the local network (unless you want to run the scripts on Sepolia): `npm run node:start`; ### 1. The Public Authority / Admin creates the DECs Registry -For the creation of the registry we deploy the DECs Registry smart contract using ignition: +For the creation of the registry we deploy the DECs Registry smart contract: -`npm run deploy-contract Registry localhost`; +`npx hardhat run election-scripts/create-decs-registry.ts --network localhost`; + +Take note of the contract address returned by the script; ### 2. The Public Authority / Admin creates the EOA for the Voter +If you are using the local network, you can skip this step and just take note of one EOA returned by the start of the local network. + Execute the `create-voter` scripts and take note of the resulting `address` and `privateKey`: `npx hardhat run election-scripts/create-voter-eoa.ts` ### 3. The Public Authority / Admin creates the DEC for the Voter and register the DEC into the DECs Registry -[TO DO] +in the `election-scripts/create-dec.ts` file, insert the Voter's private key and save the file. +Then, deploy the contract encrypting the Voter's data with the command: + +`npx hardhat run election-scripts/create-dec.ts --network localhost` + +Take note of the DEC contract address returned by the script; + +### 4. The Public Authority / Admin registers the Voters DECs on the DECs Registry +Write in the `__mock__.ts` file the data required in the `DECsRegistryData`. The data are retrieved by the previous scripts. +Then run the script in order to register the Voter DEC into the DECsRegistry: + +`npx hardhat run election-scripts/register-dec.ts --network localhost` -### 4. The Public Authority / Admin creates a Municipality Election +### 5. The Public Authority / Admin creates a Municipality Election At this point we have the EOA credentials and the DEC for our voters, and the DECs are registered on the DECs Registry. It's time to create an election: as an example we implemented a smart contract for a municipality election, that elects the major and the council. Now it's time to deploy the smart contract election and register parties, councilor and major candidates, parties coalitions in the municipality election contract, run the command: -`npx hardhat run election-scripts/create-election.ts` +`npx hardhat run election-scripts/create-election.ts --network localhost` Please note that to make the registration of parties and coalition working, the functions must be called in the registration period set before. diff --git a/contracts/DEC.sol b/contracts/DEC.sol index 84141ac..e0a5719 100644 --- a/contracts/DEC.sol +++ b/contracts/DEC.sol @@ -6,16 +6,23 @@ pragma solidity ^0.8.24; /// @custom:experimental This is an experimental contract. contract DEC { address public owner; - bytes taxCode; - bytes municipality; - bytes region; - bytes country; + Encrypted taxCode; + Encrypted municipality; + Encrypted region; + Encrypted country; + + struct Encrypted { + string iv; + string ephemPublicKey; + string ciphertext; + string mac; + } constructor( - bytes memory _taxCode, - bytes memory _municipality, - bytes memory _region, - bytes memory _country + Encrypted memory _taxCode, + Encrypted memory _municipality, + Encrypted memory _region, + Encrypted memory _country ) { /// @dev only the owner of the contract has write permissions owner = msg.sender; @@ -30,35 +37,35 @@ contract DEC { _; } - function setTaxCode(bytes memory _taxCode) external onlyOwner { + function setTaxCode(Encrypted memory _taxCode) external onlyOwner { taxCode = _taxCode; } - function getTaxCode() external view returns (bytes memory) { + function getTaxCode() external view returns (Encrypted memory) { return taxCode; } - function setMunicipality(bytes memory _municipality) external onlyOwner { + function setMunicipality(Encrypted memory _municipality) external onlyOwner { municipality = _municipality; } - function getMunicipality() external view returns (bytes memory) { + function getMunicipality() external view returns (Encrypted memory) { return municipality; } - function setRegion(bytes memory _region) external onlyOwner { + function setRegion(Encrypted memory _region) external onlyOwner { region = _region; } - function getRegion() external view returns (bytes memory) { + function getRegion() external view returns (Encrypted memory) { return region; } - function setCountry(bytes memory _country) external onlyOwner { + function setCountry(Encrypted memory _country) external onlyOwner { country = _country; } - function getCountry() external view returns (bytes memory) { + function getCountry() external view returns (Encrypted memory) { return country; } diff --git a/docs/assets/architecture.png b/docs/assets/architecture.png index 64370ea..8ef2364 100644 Binary files a/docs/assets/architecture.png and b/docs/assets/architecture.png differ diff --git a/docs/diagrams/Agora-high-level.drawio b/docs/diagrams/Agora-high-level.drawio index 5228cfc..df0cd6f 100644 --- a/docs/diagrams/Agora-high-level.drawio +++ b/docs/diagrams/Agora-high-level.drawio @@ -1,33 +1,33 @@ - + - + - - + + - - + + - - + + - - + + - + @@ -35,29 +35,29 @@ - + - - + + - + - - + + - + @@ -65,53 +65,30 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - + - + @@ -119,12 +96,12 @@ - + - + @@ -133,34 +110,34 @@ - - + + - + - + - + - + - + @@ -169,7 +146,7 @@ - + @@ -180,7 +157,7 @@ - + @@ -191,7 +168,7 @@ - + @@ -199,7 +176,7 @@ - + @@ -209,42 +186,88 @@ - - - - - - + - - + + - - + + - + - + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/election-scripts/__mocks__.ts b/election-scripts/__mocks__.ts index 5654604..cd9a0d5 100644 --- a/election-scripts/__mocks__.ts +++ b/election-scripts/__mocks__.ts @@ -1,5 +1,24 @@ import { Party } from "./types"; +export const DECsRegistryData = { + name: "Italy DECs Registry", + address: "0x5fbdb2315678afecb367f032d93f642f64180aa3", + DECAddress: "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", +}; + +export const VoterEOA = { + address: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + privateKey: + "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", +}; + +export const DECMock = { + taxCode: "RSSMRA85C27H501W", + municipality: "Ardea", + region: "Lazio", + country: "Italy", +}; + export const MUNICIPALITY_ELECTION_DATA = { name: "Election of major of Braccagni city", municipality: "Braccagni", diff --git a/election-scripts/create-dec.test.ts b/election-scripts/create-dec.test.ts new file mode 100644 index 0000000..53cba63 --- /dev/null +++ b/election-scripts/create-dec.test.ts @@ -0,0 +1,22 @@ +import { assert } from "chai"; +import { main } from "./create-dec"; +import { Response, result, CreateDECResponse } from "../election-scripts/types"; +import { DECMock, VoterEOA } from "./__mocks__"; + +describe("Create DEC Script", () => { + it("Should run without errors", async () => { + const response: Response = await main( + DECMock, + VoterEOA.privateKey, + ); + assert.equal(response.result, result.OK); + }); + + it("Should encrypt and deploy DEC correctly", async () => { + const response: Response = await main( + DECMock, + VoterEOA.privateKey, + ); + assert.equal(response.result, result.OK); + }); +}); diff --git a/election-scripts/create-dec.ts b/election-scripts/create-dec.ts new file mode 100644 index 0000000..1c06107 --- /dev/null +++ b/election-scripts/create-dec.ts @@ -0,0 +1,69 @@ +/** + * In order to run this script in hardhat, run the command: npx hardhat run election-scripts/create-dec.ts + * to run the script over a network configured in the hardhat.config.ts run: + * npx hardhat run election-scripts/create-dec.ts --network , example: + * npx hardhat run election-scripts/create-dec.ts --network sepolia + * + * This is the third step of the voting process: a public authority creates an EOA for the Voter. + * The EOA has a public address and a private key. + * This script deploys the DEC for the Voter by encrypting the data using the Voter's EOA private key. + */ + +import { ethers } from "hardhat"; +import { DEC, Response, result, CreateDECResponse } from "./types"; +import { DECMock, VoterEOA } from "./__mocks__"; +import { encryptString } from "../lib"; +import { Encrypted } from "eth-crypto"; + +/** + * This function encrypt the Voter's DECs data and deploys the smart contract instance. + * + * @param {DEC} decsData - the list of DECs to deploy + * @returns {Promise>} - the api response containing the output of the operation + */ +export async function main( + decsData?: DEC, + privateKey?: string, +): Promise> { + const response: Response = { + result: result.OK, + }; + + try { + const ContractFactory = await ethers.getContractFactory("DEC"); + + const dec = decsData || DECMock; + const key = privateKey || VoterEOA.privateKey; + + const eTaxCode: Encrypted = await encryptString(dec.taxCode, key); + const eMunicipality: Encrypted = await encryptString(dec.municipality, key); + const eRegion: Encrypted = await encryptString(dec.region, key); + const eCountry: Encrypted = await encryptString(dec.country, key); + + const contract = await ContractFactory.deploy( + eTaxCode, + eMunicipality, + eRegion, + eCountry, + ); + + response.data = { + DECAddress: await contract.getAddress(), + }; + + return response; + } catch (e: any) { + response.result = result.ERROR; + response.errorMessage = e.message || "unknown error"; + return response; + } +} + +main() + .then((response) => { + console.log(JSON.stringify(response)); + return response; + }) + .catch((error) => { + console.error(error); + }); diff --git a/election-scripts/create-decs-registry.test.ts b/election-scripts/create-decs-registry.test.ts new file mode 100644 index 0000000..08a6af4 --- /dev/null +++ b/election-scripts/create-decs-registry.test.ts @@ -0,0 +1,10 @@ +import { assert } from "chai"; +import { main } from "./create-decs-registry"; +import { RegistryResponse, Response, result } from "../election-scripts/types"; + +describe("Create DECs Registry Script", () => { + it("Should run without errors", async () => { + const response: Response = await main(); + assert.equal(response.result, result.OK); + }); +}); diff --git a/election-scripts/create-decs-registry.ts b/election-scripts/create-decs-registry.ts new file mode 100644 index 0000000..49f81cc --- /dev/null +++ b/election-scripts/create-decs-registry.ts @@ -0,0 +1,66 @@ +/** + * In order to run this script in hardhat, run the command: npx hardhat run election-scripts/create-decs-registry.ts + * to run the script over a network configured in the hardhat.config.ts run: + * npx hardhat run election-scripts/create-decs-registry.ts --network , example: + * npx hardhat run election-scripts/create-decs-registry.ts --network sepolia + * + * This is the first step of the voting process: a public authority creates the public registry of the DECs + * where all the DECs are registered. In a next step, after the DEC creation, the Voter DEC is registered on the Registry. + * This register is created once for all the future elections. + */ +import { ethers } from "hardhat"; +import { Response, result, RegistryResponse } from "./types"; +import { DECsRegistryData } from "./__mocks__"; +import { DECsRegistry } from "../typechain-types"; +import { Signer } from "ethers"; + +let owner: Signer; + +/** + * This function deploy an instance of the DECs Registry. The registry is unique and needs to be + * deployed only once. + * + * @returns {Promise>} - the api response containing the output of the operation + */ +export async function main(): Promise> { + const response: Response = { + result: result.OK, + }; + + try { + const ContractFactory = await ethers.getContractFactory("DECsRegistry"); + const contract: DECsRegistry = await ContractFactory.deploy( + DECsRegistryData.name, + ); + + const contractName = await contract.getName(); + + console.log( + `The contract "${contractName}" has been successfully deployed`, + ); + + const address = await contract.getAddress(); + [owner] = await ethers.getSigners(); + + const registryResponse: RegistryResponse = { + address, + owner, + }; + response.data = registryResponse; + + return response; + } catch (e: any) { + response.result = result.ERROR; + response.errorMessage = e.message || "unknown error"; + return response; + } +} + +main() + .then((response) => { + console.log(JSON.stringify(response)); + return response; + }) + .catch((error) => { + console.error(error); + }); diff --git a/election-scripts/create-election.ts b/election-scripts/create-election.ts index b3130f0..9348a09 100644 --- a/election-scripts/create-election.ts +++ b/election-scripts/create-election.ts @@ -1,10 +1,10 @@ /** - * In order to run this script in hardhat, run the command: npx hardhat run script/create-election.ts + * In order to run this script in hardhat, run the command: npx hardhat run election-scripts/create-election.ts * to run the script over a network configured in the hardhat.config.ts run: - * npx hardhat run script/create-voter-eoa.ts --network , example: - * npx hardhat run script/create-voter-eoa.ts --network sepolia + * npx hardhat run election-scripts/create-voter-eoa.ts --network , example: + * npx hardhat run election-scripts/create-voter-eoa.ts --network sepolia * - * This is the third step of the voting process: a public authority creates an election by + * This is the fifth step of the voting process: a public authority creates an election by * deploying the election smart contract passing the required data in the constructor. * Then, the script registers the parties and the names of the councilior and major candidates. */ @@ -46,105 +46,112 @@ export async function main( result: result.OK, }; - const ContractFactory = await ethers.getContractFactory( - "MunicipalityElection", - ); - - [owner] = await ethers.getSigners(); - - const contract: MunicipalityElection = await ContractFactory.deploy( - electionData?.name || MUNICIPALITY_ELECTION_DATA.name, - electionData?.municipality || MUNICIPALITY_ELECTION_DATA.municipality, - electionData?.region || MUNICIPALITY_ELECTION_DATA.region, - electionData?.country || MUNICIPALITY_ELECTION_DATA.country, - electionData?.registrationStart || - MUNICIPALITY_ELECTION_DATA.registrationStart, - electionData?.registrationEnd || MUNICIPALITY_ELECTION_DATA.registrationEnd, - electionData?.votingPoints || MUNICIPALITY_ELECTION_DATA.votingPoints, - ); - - const address = await contract.getAddress(); - const parties: Party[] = []; - const coalitions: Coalition[] = []; - - for (const party of PARTIES) { - await contract - .connect(owner) - .registerParty(party.name, party.councilorCandidates); - const candidatesRegistered = await contract.getCandidatesByParty( - party.name, + try { + const ContractFactory = await ethers.getContractFactory( + "MunicipalityElection", ); - parties.push(party); - console.log( - `registered party ${party.name} with candidates: ${JSON.stringify(candidatesRegistered)}`, + [owner] = await ethers.getSigners(); + + const contract: MunicipalityElection = await ContractFactory.deploy( + electionData?.name || MUNICIPALITY_ELECTION_DATA.name, + electionData?.municipality || MUNICIPALITY_ELECTION_DATA.municipality, + electionData?.region || MUNICIPALITY_ELECTION_DATA.region, + electionData?.country || MUNICIPALITY_ELECTION_DATA.country, + electionData?.registrationStart || + MUNICIPALITY_ELECTION_DATA.registrationStart, + electionData?.registrationEnd || + MUNICIPALITY_ELECTION_DATA.registrationEnd, + electionData?.votingPoints || MUNICIPALITY_ELECTION_DATA.votingPoints, ); - } - await contract - .connect(owner) - .registerCoalition(MAJOR_CANDIDATE_1, [PARTY_NAME_A, PARTY_NAME_B]); - const coalition1Raw = await contract.getCoalition(0); - - const coalition1: Coalition = { - majorCandidate: { - name: coalition1Raw[0][0], - candidatesFor: coalition1Raw[0][1] as Candidature, - points: Number(coalition1Raw[0][2]), - }, - parties: [], - }; + const address = await contract.getAddress(); + const parties: Party[] = []; + const coalitions: Coalition[] = []; + + for (const party of PARTIES) { + await contract + .connect(owner) + .registerParty(party.name, party.councilorCandidates); + const candidatesRegistered = await contract.getCandidatesByParty( + party.name, + ); + parties.push(party); + + console.log( + `registered party ${party.name} with candidates: ${JSON.stringify(candidatesRegistered)}`, + ); + } - for (const p of parties) { - for (const k of coalition1Raw[1]) { - if (k === p.name) { - coalition1.parties.push(p); + await contract + .connect(owner) + .registerCoalition(MAJOR_CANDIDATE_1, [PARTY_NAME_A, PARTY_NAME_B]); + const coalition1Raw = await contract.getCoalition(0); + + const coalition1: Coalition = { + majorCandidate: { + name: coalition1Raw[0][0], + candidatesFor: coalition1Raw[0][1] as Candidature, + points: Number(coalition1Raw[0][2]), + }, + parties: [], + }; + + for (const p of parties) { + for (const k of coalition1Raw[1]) { + if (k === p.name) { + coalition1.parties.push(p); + } } } - } - - coalitions.push(coalition1); - console.log( - `registered coalition for major candidate: ${coalition1Raw[0]} and parties ${coalition1Raw[1]}`, - ); + coalitions.push(coalition1); - await contract - .connect(owner) - .registerCoalition(MAJOR_CANDIDATE_2, [PARTY_NAME_C, PARTY_NAME_D]); - const coalition2Raw = await contract.getCoalition(1); - - const coalition2: Coalition = { - majorCandidate: { - name: coalition2Raw[0][0], - candidatesFor: coalition2Raw[0][1] as Candidature, - points: Number(coalition2Raw[0][2]), - }, - parties: [], - }; + console.log( + `registered coalition for major candidate: ${coalition1Raw[0]} and parties ${coalition1Raw[1]}`, + ); - for (const p of parties) { - for (const k of coalition2Raw[1]) { - if (k === p.name) { - coalition2.parties.push(p); + await contract + .connect(owner) + .registerCoalition(MAJOR_CANDIDATE_2, [PARTY_NAME_C, PARTY_NAME_D]); + const coalition2Raw = await contract.getCoalition(1); + + const coalition2: Coalition = { + majorCandidate: { + name: coalition2Raw[0][0], + candidatesFor: coalition2Raw[0][1] as Candidature, + points: Number(coalition2Raw[0][2]), + }, + parties: [], + }; + + for (const p of parties) { + for (const k of coalition2Raw[1]) { + if (k === p.name) { + coalition2.parties.push(p); + } } } - } - coalitions.push(coalition2); + coalitions.push(coalition2); - console.log( - `registered coalition for major candidate: ${coalition2Raw[0]} and parties ${coalition2Raw[1]}`, - ); + console.log( + `registered coalition for major candidate: ${coalition2Raw[0]} and parties ${coalition2Raw[1]}`, + ); - const ballot: Ballot = { - contractAddress: address, - coalitions, - }; + const ballot: Ballot = { + contractAddress: address, + coalitions, + }; - response.data = ballot; + response.data = ballot; - return response; + return response; + } catch (e: any) { + response.result = result.ERROR; + response.errorMessage = e.message || "unknown error"; + return response; + } } main() diff --git a/election-scripts/create-voter-eoa.ts b/election-scripts/create-voter-eoa.ts index c179fed..2ce6b2b 100644 --- a/election-scripts/create-voter-eoa.ts +++ b/election-scripts/create-voter-eoa.ts @@ -1,10 +1,10 @@ /** - * In order to run this script in hardhat, run the command: npx hardhat run script/create-voter-eoa.ts + * In order to run this script in hardhat, run the command: npx hardhat run election-scripts/create-voter-eoa.ts * to run the script over a network configured in the hardhat.config.ts run: - * npx hardhat run script/create-voter-eoa.ts --network , example: - * npx hardhat run script/create-voter-eoa.ts --network sepolia + * npx hardhat run election-scripts/create-voter-eoa.ts --network , example: + * npx hardhat run election-scripts/create-voter-eoa.ts --network sepolia * - * This is the first step of the voting process: a public authority creates an EOA for the Voter, the + * This is the second step of the voting process: a public authority creates an EOA for the Voter, the * script returns the public address and the private key that are communicated to the Voter. */ import { ethers } from "hardhat"; diff --git a/election-scripts/register-dec.ts b/election-scripts/register-dec.ts new file mode 100644 index 0000000..09021f4 --- /dev/null +++ b/election-scripts/register-dec.ts @@ -0,0 +1,60 @@ +/** + * In order to run this script in hardhat, run the command: npx hardhat run election-scripts/register-dec.ts + * to run the script over a network configured in the hardhat.config.ts run: + * npx hardhat run election-scripts/register-dec.ts --network , example: + * npx hardhat run election-scripts/register-dec.ts --network sepolia + * + * This is the fourth step of the voting process: a public authority register the Voter's DEC on the registry. + */ +import { ethers } from "hardhat"; +import { Response, result } from "./types"; +import { DECsRegistryData, VoterEOA } from "./__mocks__"; +import { Signer } from "ethers"; + +let owner: Signer; + +/** + * This function registers a DEC in the DECs Registry + * + * @returns {Promise>} - the api response containing the output of the operation + */ +export async function main(): Promise> { + const response: Response = { + result: result.OK, + }; + + const contract = await ethers.getContractAt( + "DECsRegistry", + DECsRegistryData.address, + ); + + [owner] = await ethers.getSigners(); + + await contract + .connect(owner) + .registerDEC(DECsRegistryData.DECAddress, VoterEOA.address); + + const registryName = await contract.getName(); + const dec = await contract.getDEC(VoterEOA.address); + + console.log( + `The DEC ${dec} was successfully registered for voter ${VoterEOA.address} in the registry ${registryName}`, + ); + + try { + return response; + } catch (e: any) { + response.result = result.ERROR; + response.errorMessage = e.message || "unknown error"; + return response; + } +} + +main() + .then((response) => { + console.log(JSON.stringify(response)); + return response; + }) + .catch((error) => { + console.error(error); + }); diff --git a/election-scripts/types.ts b/election-scripts/types.ts index 4c7757b..40730a9 100644 --- a/election-scripts/types.ts +++ b/election-scripts/types.ts @@ -1,3 +1,5 @@ +import { Signer } from "ethers"; + export enum result { OK = "ok", ERROR = "error", @@ -14,6 +16,10 @@ export type EOAResponse = { privateKey: string; }; +export type CreateDECResponse = { + DECAddress: string; +}; + export enum Candidature { MAJOR = "major", COUNCILOR = "councilor", @@ -62,3 +68,15 @@ export type ElectionData = { registrationEnd: number; votingPoints: number; }; + +export type DEC = { + taxCode: string; + municipality: string; + region: string; + country: string; +}; + +export type RegistryResponse = { + address: string; + owner: Signer; +}; diff --git a/ignition/modules/DECs.ts b/ignition/modules/DECs.ts index 431ce4a..731a190 100644 --- a/ignition/modules/DECs.ts +++ b/ignition/modules/DECs.ts @@ -2,10 +2,10 @@ import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; export default buildModule("DEC", (m) => { const DEC1 = m.contract("TomsDEC", [ - "RSSMRA85C27H501W", - "Ardea", - "Lazio", - "Italy", + m.getParameter("taxCode"), + m.getParameter("municipality"), + m.getParameter("region"), + m.getParameter("country"), ]); m.call(DEC1, "getName", []); diff --git a/ignition/modules/README.md b/ignition/modules/README.md new file mode 100644 index 0000000..b63a487 --- /dev/null +++ b/ignition/modules/README.md @@ -0,0 +1,4 @@ +# Contracts Ignition modules + +The ignition modules contained in this folder deploy the smart contracts on a local network. +These modules are used for testing purposes only \ No newline at end of file diff --git a/ignition/parameters.json b/ignition/parameters.json index 33459ba..c262460 100644 --- a/ignition/parameters.json +++ b/ignition/parameters.json @@ -1,4 +1,11 @@ { + + "DEC": { + "taxCode": "RSSMRA85C27H501W", + "municipality": "Ardea", + "region": "Lazio", + "country": "Italy" + }, "CountryElection": { "registrationStart": 1714578352000, "registrationEnd": 1717256752000 diff --git a/lib/__mocks__.ts b/lib/__mocks__.ts new file mode 100644 index 0000000..3ac57de --- /dev/null +++ b/lib/__mocks__.ts @@ -0,0 +1,8 @@ +export const mockEOAs = [ + { + address: + "b71c24d551889a96d104514bc8766c4e9d5e8ae10df152d1a717052cf73e3ef6ecdcb170df95340942154d5cffc7b5db5d0225097bb530cbe50d844677cdf886", + privateKey: + "0x70866392fdfd32ba237e801266da6fa25410215440dd74f576de15c9ca3814f9", + }, +]; diff --git a/lib/crypto-utils.test.ts b/lib/crypto-utils.test.ts new file mode 100644 index 0000000..bbb2d7c --- /dev/null +++ b/lib/crypto-utils.test.ts @@ -0,0 +1,24 @@ +import { encryptString, decryptString } from "./crypto-utils"; +import { mockEOAs } from "./__mocks__"; + +describe("Crypto Utils", () => { + const privateKey = mockEOAs[0].privateKey; + + it("should encrypt and decrypt a string", async () => { + const originalString = "Hello, world!"; + const encryptedString = await encryptString(originalString, privateKey); + + const decryptedString = await decryptString(encryptedString, privateKey); + expect(decryptedString).toEqual(originalString); + }); + + it("should handle decryption with incorrect private key", async () => { + const originalString = "Hello, world!"; + const encryptedString = await encryptString(originalString, privateKey); + const incorrectPrivateKey = "incorrectPrivateKey"; + + await expect( + decryptString(encryptedString, incorrectPrivateKey), + ).rejects.toThrow("Error decrypting string"); + }); +}); diff --git a/lib/crypto-utils.ts b/lib/crypto-utils.ts new file mode 100644 index 0000000..fbfced0 --- /dev/null +++ b/lib/crypto-utils.ts @@ -0,0 +1,60 @@ +/** + * This library expose a set of utilities that help with cryptographic tasks. + * Some data in the smart contracts needs to be sent encrypted (e.g. DEC) because contains personal sensitive information. + * + * The reason why the encryption is done before to send the data to the smart contract (and not in the smart contract itself) + * is because If we send the data and then encrypt it in solidity, the data will be visible in the transaction that + * in the first place was used to send the data to the contract. Also, solidity doesn't have a function to encrypt. + */ +import * as EthCrypto from "eth-crypto"; +import { Encrypted } from "eth-crypto"; + +/** + * This function encrypt a string by using a private key possibly from an EOA (Voter's account). + * The function generates a public key from the private key given in input and then uses the public key + * to encrypt the string. + * + * @param {string} decryptedString - the string to be encrypted + * @param {string} privateKey - a private key, e.g. from the EOA + * @returns {Promise} - the encrypted output string + */ +export async function encryptString( + decryptedString: string, + privateKey: string, +): Promise { + try { + const publicKey = await EthCrypto.publicKeyByPrivateKey(privateKey); + + const encrypted = await EthCrypto.encryptWithPublicKey( + publicKey, + decryptedString, + ); + return encrypted; + } catch (e) { + console.error(e); + throw new Error("Error encrypting string"); + } +} + +/** + * This function decrypt a string using the private key possibly from an EOA. + * + * @param {Encrypted} encryptedString - the secret to decrypt + * @param {string} privateKey - A private key possibly from an EOA + * @returns {Promise} - the string decrypted + */ +export async function decryptString( + encryptedString: Encrypted, + privateKey: string, +): Promise { + try { + const decrypted = await EthCrypto.decryptWithPrivateKey( + privateKey, + encryptedString, + ); + return decrypted; + } catch (e) { + console.error(e); + throw new Error("Error decrypting string"); + } +} diff --git a/lib/index.ts b/lib/index.ts new file mode 100644 index 0000000..7cc1db4 --- /dev/null +++ b/lib/index.ts @@ -0,0 +1 @@ +export { encryptString, decryptString } from "./crypto-utils"; diff --git a/package-lock.json b/package-lock.json index a0f9cf6..aaebcb0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,16 @@ { "name": "agora", - "version": "0.3.0", + "version": "0.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "agora", - "version": "0.3.0", + "version": "0.4.0", "license": "GPL-3.0", "dependencies": { - "dotenv": "^16.4.5" + "dotenv": "^16.4.5", + "eth-crypto": "^2.6.0" }, "devDependencies": { "@commitlint/cli": "^19.2.1", @@ -554,6 +555,17 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz", + "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==", + "dependencies": { + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.24.0", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", @@ -1460,6 +1472,52 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@ethereumjs/common": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.5.tgz", + "integrity": "sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==", + "dependencies": { + "crc-32": "^1.2.0", + "ethereumjs-util": "^7.1.5" + } + }, + "node_modules/@ethereumjs/common/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/@ethereumjs/common/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/rlp": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", @@ -1472,6 +1530,52 @@ "node": ">=14" } }, + "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": { + "@ethereumjs/common": "^2.6.4", + "ethereumjs-util": "^7.1.5" + } + }, + "node_modules/@ethereumjs/tx/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/@ethereumjs/tx/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": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", @@ -1553,7 +1657,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "dev": true, "funding": [ { "type": "individual", @@ -1580,7 +1683,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "dev": true, "funding": [ { "type": "individual", @@ -1605,7 +1707,6 @@ "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==", - "dev": true, "funding": [ { "type": "individual", @@ -1628,7 +1729,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "dev": true, "funding": [ { "type": "individual", @@ -1651,7 +1751,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "dev": true, "funding": [ { "type": "individual", @@ -1670,7 +1769,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "dev": true, "funding": [ { "type": "individual", @@ -1690,7 +1788,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "dev": true, "funding": [ { "type": "individual", @@ -1711,7 +1808,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "dev": true, "funding": [ { "type": "individual", @@ -1730,7 +1826,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "dev": true, "funding": [ { "type": "individual", @@ -1749,7 +1844,6 @@ "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==", - "dev": true, "funding": [ { "type": "individual", @@ -1777,7 +1871,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "dev": true, "funding": [ { "type": "individual", @@ -1804,7 +1897,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "dev": true, "funding": [ { "type": "individual", @@ -1834,7 +1926,6 @@ "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==", - "dev": true, "funding": [ { "type": "individual", @@ -1864,14 +1955,12 @@ "node_modules/@ethersproject/json-wallets/node_modules/aes-js": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "dev": true + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" }, "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==", - "dev": true, "funding": [ { "type": "individual", @@ -1891,7 +1980,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "dev": true, "funding": [ { "type": "individual", @@ -1907,7 +1995,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", - "dev": true, "funding": [ { "type": "individual", @@ -1926,7 +2013,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "dev": true, "funding": [ { "type": "individual", @@ -1946,7 +2032,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "dev": true, "funding": [ { "type": "individual", @@ -1965,7 +2050,6 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", - "dev": true, "funding": [ { "type": "individual", @@ -2003,7 +2087,6 @@ "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "dev": true, "engines": { "node": ">=8.3.0" }, @@ -2024,7 +2107,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", - "dev": true, "funding": [ { "type": "individual", @@ -2044,7 +2126,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "dev": true, "funding": [ { "type": "individual", @@ -2064,7 +2145,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "dev": true, "funding": [ { "type": "individual", @@ -2085,7 +2165,6 @@ "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==", - "dev": true, "funding": [ { "type": "individual", @@ -2109,7 +2188,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "dev": true, "funding": [ { "type": "individual", @@ -2133,7 +2211,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "dev": true, "funding": [ { "type": "individual", @@ -2154,7 +2231,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", - "dev": true, "funding": [ { "type": "individual", @@ -2181,7 +2257,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "dev": true, "funding": [ { "type": "individual", @@ -2202,7 +2277,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "dev": true, "funding": [ { "type": "individual", @@ -2235,7 +2309,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", - "dev": true, "funding": [ { "type": "individual", @@ -2258,7 +2331,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "dev": true, "funding": [ { "type": "individual", @@ -4506,7 +4578,6 @@ "version": "5.1.5", "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -4637,7 +4708,6 @@ "version": "20.11.30", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", - "dev": true, "dependencies": { "undici-types": "~5.26.4" } @@ -4652,7 +4722,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -4674,7 +4743,6 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -5428,7 +5496,6 @@ "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==", - "dev": true, "dependencies": { "safe-buffer": "^5.0.1" } @@ -5456,8 +5523,7 @@ "node_modules/bech32": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", - "dev": true + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" }, "node_modules/binary-extensions": { "version": "2.3.0", @@ -5471,6 +5537,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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==", + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bip66": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", + "integrity": "sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw==", + "optional": true, + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -5485,8 +5569,7 @@ "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==", - "dev": true + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" }, "node_modules/blamer": { "version": "1.0.6", @@ -5599,8 +5682,7 @@ "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==", - "dev": true + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" }, "node_modules/boxen": { "version": "5.1.2", @@ -5731,8 +5813,7 @@ "node_modules/brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" }, "node_modules/browser-stdout": { "version": "1.3.1", @@ -5744,7 +5825,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, "dependencies": { "buffer-xor": "^1.0.3", "cipher-base": "^1.0.0", @@ -5802,7 +5882,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", - "dev": true, "dependencies": { "base-x": "^3.0.2" } @@ -5811,7 +5890,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "dev": true, "dependencies": { "bs58": "^4.0.0", "create-hash": "^1.1.0", @@ -5860,8 +5938,21 @@ "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==", - "dev": true + "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", @@ -6098,7 +6189,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -6771,11 +6861,21 @@ "typescript": ">=4" } }, + "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==", - "dev": true, "dependencies": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", @@ -6788,7 +6888,6 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, "dependencies": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", @@ -7213,6 +7312,72 @@ "url": "https://dotenvx.com" } }, + "node_modules/drbg.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", + "integrity": "sha512-F4wZ06PvqxYLFEZKkFxTDcns9oFNk34hvmJSEwdzsxVQ8YI5YaxtACgQatkYgv2VI2CFkUd2Y+xosPQnHv809g==", + "optional": true, + "dependencies": { + "browserify-aes": "^1.0.6", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/eccrypto": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/eccrypto/-/eccrypto-1.1.6.tgz", + "integrity": "sha512-d78ivVEzu7Tn0ZphUUaL43+jVPKTMPFGtmgtz1D0LrFn7cY3K8CdrvibuLz2AAkHBLKZtR8DMbB2ukRYFk987A==", + "hasInstallScript": true, + "dependencies": { + "acorn": "7.1.1", + "elliptic": "6.5.4", + "es6-promise": "4.2.8", + "nan": "2.14.0" + }, + "optionalDependencies": { + "secp256k1": "3.7.1" + } + }, + "node_modules/eccrypto/node_modules/acorn": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/eccrypto/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==", + "optional": true + }, + "node_modules/eccrypto/node_modules/secp256k1": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz", + "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "bindings": "^1.5.0", + "bip66": "^1.1.5", + "bn.js": "^4.11.8", + "create-hash": "^1.2.0", + "drbg.js": "^1.0.1", + "elliptic": "^6.4.1", + "nan": "^2.14.0", + "safe-buffer": "^5.1.2" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/electron-to-chromium": { "version": "1.4.719", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.719.tgz", @@ -7223,7 +7388,6 @@ "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", @@ -7237,8 +7401,7 @@ "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==", - "dev": true + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, "node_modules/emittery": { "version": "0.13.1", @@ -7325,6 +7488,11 @@ "node": ">= 0.4" } }, + "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/escalade": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", @@ -7739,6 +7907,148 @@ "node": ">=0.10.0" } }, + "node_modules/eth-crypto": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/eth-crypto/-/eth-crypto-2.6.0.tgz", + "integrity": "sha512-GCX4ffFYRUGgnuWR5qxcZIRQJ1KEqPFiyXU9yVy7s6dtXIMlUXZQ2h+5ID6rFaOHWbpJbjfkC6YdhwtwRYCnug==", + "dependencies": { + "@babel/runtime": "7.20.13", + "@ethereumjs/tx": "3.5.2", + "@types/bn.js": "5.1.1", + "eccrypto": "1.1.6", + "ethereumjs-util": "7.1.5", + "ethers": "5.7.2", + "secp256k1": "5.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/pubkey" + } + }, + "node_modules/eth-crypto/node_modules/@types/bn.js": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", + "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/eth-crypto/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/eth-crypto/node_modules/ethereum-cryptography/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": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/eth-crypto/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/eth-crypto/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/eth-crypto/node_modules/secp256k1": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-5.0.0.tgz", + "integrity": "sha512-TKWX8xvoGHrxVdqbYeZM9w+izTF4b9z3NhSaDkdn81btvuh+ivbIMGT/zQvDtTFWhRlThpoz6LEYTr7n8A5GcA==", + "hasInstallScript": true, + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/eth-crypto/node_modules/secp256k1/node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" + }, "node_modules/eth-gas-reporter": { "version": "0.2.27", "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.27.tgz", @@ -8037,7 +8347,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, "dependencies": { "md5.js": "^1.3.4", "safe-buffer": "^5.1.1" @@ -8257,6 +8566,12 @@ "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==", + "optional": true + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -9193,7 +9508,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, "dependencies": { "inherits": "^2.0.4", "readable-stream": "^3.6.0", @@ -9207,7 +9521,6 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, "dependencies": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.1" @@ -9244,7 +9557,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, "dependencies": { "hash.js": "^1.0.3", "minimalistic-assert": "^1.0.0", @@ -9504,8 +9816,7 @@ "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 + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { "version": "4.1.1", @@ -11642,8 +11953,7 @@ "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==", - "dev": true + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" }, "node_modules/js-stringify": { "version": "1.0.2", @@ -11821,7 +12131,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", - "dev": true, "hasInstallScript": true, "dependencies": { "node-addon-api": "^2.0.0", @@ -12635,7 +12944,6 @@ "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1", @@ -12736,14 +13044,12 @@ "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==", - "dev": true + "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==", - "dev": true + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" }, "node_modules/minimatch": { "version": "3.1.2", @@ -13017,6 +13323,11 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -13062,8 +13373,7 @@ "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==", - "dev": true + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" }, "node_modules/node-emoji": { "version": "1.11.0", @@ -13078,7 +13388,6 @@ "version": "4.8.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==", - "dev": true, "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -13507,7 +13816,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, "dependencies": { "create-hash": "^1.1.2", "create-hmac": "^1.1.4", @@ -13940,7 +14248,6 @@ "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" } @@ -13970,7 +14277,6 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -14026,6 +14332,11 @@ "node": ">=6" } }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, "node_modules/repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", @@ -14195,7 +14506,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1" @@ -14205,7 +14515,6 @@ "version": "2.2.7", "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "dev": true, "dependencies": { "bn.js": "^5.2.0" }, @@ -14259,7 +14568,6 @@ "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", @@ -14387,14 +14695,12 @@ "node_modules/scrypt-js": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", - "dev": true + "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==", - "dev": true, "hasInstallScript": true, "dependencies": { "elliptic": "^6.5.4", @@ -14449,8 +14755,7 @@ "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==", - "dev": true + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" }, "node_modules/setprototypeof": { "version": "1.2.0", @@ -14462,7 +14767,6 @@ "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -14884,7 +15188,6 @@ "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==", - "dev": true, "dependencies": { "safe-buffer": "~5.2.0" } @@ -15748,8 +16051,7 @@ "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 + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, "node_modules/unicorn-magic": { "version": "0.1.0", @@ -15820,6 +16122,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", @@ -15829,8 +16145,7 @@ "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==", - "dev": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/uuid": { "version": "8.3.2", diff --git a/package.json b/package.json index 2b8cb2f..466ff0d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "agora", - "version": "0.4.0", + "version": "0.5.0", "description": "A confidentiality-first electronic voting system", "author": { "name": "nova collective", @@ -27,7 +27,7 @@ "prepare-commit": "git-cz", "node:start": "npx hardhat node", "test-contracts": "npx hardhat test", - "test-scripts": " jest --coverage --bail" + "test-scripts": " jest --coverage --bail --forceExit" }, "repository": { "type": "git", @@ -53,7 +53,8 @@ "npm": "~10.2.4" }, "dependencies": { - "dotenv": "^16.4.5" + "dotenv": "^16.4.5", + "eth-crypto": "^2.6.0" }, "devDependencies": { "@commitlint/cli": "^19.2.1", diff --git a/script/create-voter-eoa.test.ts b/script/create-voter-eoa.test.ts deleted file mode 100644 index aa69390..0000000 --- a/script/create-voter-eoa.test.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { expect } from "chai"; -import { ethers } from "hardhat"; -import { main } from "./create-voter-eoa"; - -describe("Main function", () => { - afterEach(() => { - jest.clearAllMocks(); - }); - - it("should return a valid response with address and private key", async () => { - ethers.Wallet.createRandom = jest.fn().mockReturnValue({ - address: "mockedAddress", - privateKey: "mockedPrivateKey", - }); - const response = await main(); - - expect(response.result).to.equal("ok"); - expect(response.data).to.deep.equal({ - address: "mockedAddress", - privateKey: "mockedPrivateKey", - }); - }); - - it("should return an error if ethers.Wallet does not return the data", async () => { - ethers.Wallet.createRandom = jest.fn().mockImplementation(() => { - throw new Error("mock error"); - }); - const response = await main(); - - expect(response.result).to.equal("error"); - expect(response.errorMessage).to.equal("mock error"); - }); -}); diff --git a/script/create-voter-eoa.ts b/script/create-voter-eoa.ts deleted file mode 100644 index 16ca946..0000000 --- a/script/create-voter-eoa.ts +++ /dev/null @@ -1,41 +0,0 @@ -/** - * In order to run this script in hardhat, run the command: npx hardhat run script/create-voter-eoa.ts - * to run the script over a network configured in the hardhat.config.ts run: - * npx hardhat run script/create-voter-eoa.ts --network , example: - * npx hardhat run script/create-voter-eoa.ts --network goerli - * - * This is the first step of the voting process: a public authority creates an EOA for the Voter, the - * script returns the public address and the private key that are communicated to the Voter. - */ -import { ethers } from "hardhat"; -import { Response, EOAResponse, result } from "./types"; - -export async function main(): Promise> { - const response: Response = { - result: result.OK, - }; - try { - const wallet = ethers.Wallet.createRandom(); - - const EOAResponse: EOAResponse = { - address: wallet.address, - privateKey: wallet.privateKey, - }; - - response.data = EOAResponse; - - return response; - } catch (e: any) { - response.result = result.ERROR; - response.errorMessage = e.message || "unknown error"; - return response; - } -} - -main() - .then((response) => { - console.log(response); - }) - .catch((error) => { - console.error(error); - }); diff --git a/script/types.ts b/script/types.ts deleted file mode 100644 index d99a19d..0000000 --- a/script/types.ts +++ /dev/null @@ -1,15 +0,0 @@ -export enum result { - OK = "ok", - ERROR = "error", -} - -export interface Response { - result: result; - errorMessage?: string; - data?: T; -} - -export type EOAResponse = { - address: string; - privateKey: string; -}; diff --git a/test/DEC.ts b/test/DEC.ts index 7aa4aac..52d7f64 100644 --- a/test/DEC.ts +++ b/test/DEC.ts @@ -1,18 +1,45 @@ import { assert } from "chai"; import { ethers } from "hardhat"; import { DEC } from "../typechain-types/DEC"; +import { encryptString, decryptString } from "../lib"; +import { Encrypted } from "eth-crypto"; describe("DEC Contract", () => { let dec: DEC; + const encryptedDataFactory = function ( + iv: string, + ephemPublicKey: string, + ciphertext: string, + mac: string, + ): Encrypted { + return { + iv, + ephemPublicKey, + ciphertext, + mac, + }; + }; + + const taxCode = "12345678901"; + const municipality = "Roma"; + const region = "Lazio"; + const country = "Italia"; + const PRIVATE_KEY = + "0x70866392fdfd32ba237e801266da6fa25410215440dd74f576de15c9ca3814f9"; + + let eTaxCode: Encrypted; + let eMunicipality: Encrypted; + let eRegion: Encrypted; + let eCountry: Encrypted; + beforeEach(async () => { + eTaxCode = await encryptString(taxCode, PRIVATE_KEY); + eMunicipality = await encryptString(municipality, PRIVATE_KEY); + eRegion = await encryptString(region, PRIVATE_KEY); + eCountry = await encryptString(country, PRIVATE_KEY); const DECFactory = await ethers.getContractFactory("DEC"); - dec = await DECFactory.deploy( - ethers.encodeBytes32String("12345678901"), - ethers.encodeBytes32String("Roma"), - ethers.encodeBytes32String("Lazio"), - ethers.encodeBytes32String("Italia"), - ); + dec = await DECFactory.deploy(eTaxCode, eMunicipality, eRegion, eCountry); }); it("Should set initial data correctly", async () => { @@ -20,44 +47,111 @@ describe("DEC Contract", () => { await dec.owner(), await (await ethers.provider.getSigner(0)).getAddress(), ); - assert.equal( - ethers.decodeBytes32String(await dec.getTaxCode()), - "12345678901", + + const registeredTaxCode = await dec.getTaxCode(); + const registeredMunicipality = await dec.getMunicipality(); + const registeredRegion = await dec.getRegion(); + const registeredCountry = await dec.getCountry(); + + const enTaxCode = encryptedDataFactory( + registeredTaxCode[0], + registeredTaxCode[1], + registeredTaxCode[2], + registeredTaxCode[3], ); - assert.equal( - ethers.decodeBytes32String(await dec.getMunicipality()), - "Roma", + + const enMunicipality = encryptedDataFactory( + registeredMunicipality[0], + registeredMunicipality[1], + registeredMunicipality[2], + registeredMunicipality[3], + ); + + const enRegion = encryptedDataFactory( + registeredRegion[0], + registeredRegion[1], + registeredRegion[2], + registeredRegion[3], + ); + + const enCountry = encryptedDataFactory( + registeredCountry[0], + registeredCountry[1], + registeredCountry[2], + registeredCountry[3], + ); + + const decodedTaxCode = await decryptString(enTaxCode, PRIVATE_KEY); + const decodedMunicipality = await decryptString( + enMunicipality, + PRIVATE_KEY, ); - assert.equal(ethers.decodeBytes32String(await dec.getRegion()), "Lazio"); - assert.equal(ethers.decodeBytes32String(await dec.getCountry()), "Italia"); + const decodedRegion = await decryptString(enRegion, PRIVATE_KEY); + const decodedCountry = await decryptString(enCountry, PRIVATE_KEY); + + assert.equal(decodedTaxCode, taxCode); + assert.equal(decodedMunicipality, municipality); + assert.equal(decodedRegion, region); + assert.equal(decodedCountry, country); }); it("Should set and get tax code correctly", async () => { - await dec.setTaxCode(ethers.encodeBytes32String("98765432109")); - assert.equal( - ethers.decodeBytes32String(await dec.getTaxCode()), - "98765432109", + await dec.setTaxCode(eTaxCode); + + const getTaxCode = await dec.getTaxCode(); + + const gTaxCode = encryptedDataFactory( + getTaxCode[0], + getTaxCode[1], + getTaxCode[2], + getTaxCode[3], ); + + assert.equal(JSON.stringify(eTaxCode), JSON.stringify(gTaxCode)); }); it("Should set and get municipality correctly", async () => { - await dec.setMunicipality(ethers.encodeBytes32String("Milano")); - assert.equal( - ethers.decodeBytes32String(await dec.getMunicipality()), - "Milano", + await dec.setMunicipality(eMunicipality); + + const getMunicipality = await dec.getMunicipality(); + + const gMunicipality = encryptedDataFactory( + getMunicipality[0], + getMunicipality[1], + getMunicipality[2], + getMunicipality[3], ); + + assert.equal(JSON.stringify(eMunicipality), JSON.stringify(gMunicipality)); }); it("Should set and get region correctly", async () => { - await dec.setRegion(ethers.encodeBytes32String("Lombardia")); - assert.equal( - ethers.decodeBytes32String(await dec.getRegion()), - "Lombardia", + await dec.setRegion(eRegion); + + const getRegion = await dec.getRegion(); + + const gRegion = encryptedDataFactory( + getRegion[0], + getRegion[1], + getRegion[2], + getRegion[3], ); + + assert.equal(JSON.stringify(eRegion), JSON.stringify(gRegion)); }); it("Should set and get country correctly", async () => { - await dec.setCountry(ethers.encodeBytes32String("Francia")); - assert.equal(ethers.decodeBytes32String(await dec.getCountry()), "Francia"); + await dec.setCountry(eCountry); + + const getCountry = await dec.getCountry(); + + const gCountry = encryptedDataFactory( + getCountry[0], + getCountry[1], + getCountry[2], + getCountry[3], + ); + + assert.equal(JSON.stringify(eCountry), JSON.stringify(gCountry)); }); });