From 94daae6ad1fd6e9738214215a1092143663a40a5 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Fri, 1 Dec 2023 12:31:43 -0500 Subject: [PATCH] remove obsolete scripts --- contracts/scripts/deployBrightIdSponsor.ts | 30 -- contracts/scripts/deployTestRound.ts | 380 --------------------- contracts/scripts/generate-key.ts | 16 - contracts/scripts/get-bytecode.ts | 27 -- contracts/scripts/prepare-results.ts | 97 ------ contracts/scripts/verify.ts | 16 - 6 files changed, 566 deletions(-) delete mode 100644 contracts/scripts/deployBrightIdSponsor.ts delete mode 100644 contracts/scripts/deployTestRound.ts delete mode 100644 contracts/scripts/generate-key.ts delete mode 100644 contracts/scripts/get-bytecode.ts delete mode 100644 contracts/scripts/prepare-results.ts delete mode 100644 contracts/scripts/verify.ts diff --git a/contracts/scripts/deployBrightIdSponsor.ts b/contracts/scripts/deployBrightIdSponsor.ts deleted file mode 100644 index c2967cdd5..000000000 --- a/contracts/scripts/deployBrightIdSponsor.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { ethers } from 'hardhat' - -async function main() { - console.log('**************************************') - console.log('Deploying a BrightId sponsor contract!') - console.log('**************************************') - - const [deployer] = await ethers.getSigners() - console.log('Deployer address', deployer.address) - - const BrightIdSponsor = await ethers.getContractFactory( - 'BrightIdSponsor', - deployer - ) - const sponsor = await BrightIdSponsor.deploy() - console.log('Transaction hash', sponsor.deployTransaction.hash) - await sponsor.deployTransaction.wait() - console.log('Sponsor contract', sponsor.address) - - console.log('*******************') - console.log('Deploy complete!') - console.log('*******************') -} - -main() - .then(() => process.exit(0)) - .catch((error) => { - console.error(error) - process.exit(1) - }) diff --git a/contracts/scripts/deployTestRound.ts b/contracts/scripts/deployTestRound.ts deleted file mode 100644 index 97f7746cb..000000000 --- a/contracts/scripts/deployTestRound.ts +++ /dev/null @@ -1,380 +0,0 @@ -import fs from 'fs' -import { ethers } from 'hardhat' -import { Keypair } from '@clrfund/common' - -import { UNIT } from '../utils/constants' -import { getEventArg } from '../utils/contracts' -import { MaciParameters } from '../utils/maci' - -async function main() { - // We're hardcoding factory address due to a buidler limitation: - // https://github.com/nomiclabs/buidler/issues/651 - const factoryAddress = '0x5FC8d32690cc91D4c39d9d3abcBD16989F875707' - const [ - deployer, - , - poolContributor, - recipient1, - recipient2, - recipient3, - recipient4, - recipient5, - recipient6, - recipient7, - recipient8, - recipient9, - contributor1, - contributor2, - ] = await ethers.getSigners() - - // Deploy ERC20 token contract - const Token = await ethers.getContractFactory('AnyOldERC20Token', deployer) - const tokenInitialSupply = UNIT.mul(1000) - const token = await Token.deploy(tokenInitialSupply) - await token.deployTransaction.wait() - console.log(`Token deployed: ${token.address}`) - - const tokenReceivers = [poolContributor, contributor1, contributor2] - let transferTx - for (const account of tokenReceivers) { - transferTx = await token.transfer(account.getAddress(), UNIT.mul(100)) - transferTx.wait() - } - - // Configure factory - const factory = await ethers.getContractAt( - 'FundingRoundFactory', - factoryAddress - ) - const setTokenTx = await factory.setToken(token.address) - await setTokenTx.wait() - const coordinatorKeyPair = new Keypair() - const setCoordinatorTx = await factory.setCoordinator( - deployer.getAddress(), - coordinatorKeyPair.pubKey.asContractParam() - ) - await setCoordinatorTx.wait() - - // Configure MACI factory - const maciFactoryAddress = await factory.maciFactory() - const maciFactory = await ethers.getContractAt( - 'MACIFactory', - maciFactoryAddress - ) - const maciParameters = await MaciParameters.read(maciFactory) - maciParameters.update({ - signUpDuration: 60 * 5, // 5 minutes - votingDuration: 60 * 5, - }) - const setMaciParametersTx = await factory.setMaciParameters( - ...maciParameters.values() - ) - await setMaciParametersTx.wait() - - // Add to matching pool - const poolContributionAmount = UNIT.mul(10) - const poolContributorToken = token.connect(poolContributor) - const poolContributionTx = await poolContributorToken.transfer( - factory.address, - poolContributionAmount - ) - await poolContributionTx.wait() - - // Add contributors - const userRegistryType = process.env.USER_REGISTRY_TYPE || 'simple' - if (userRegistryType === 'simple') { - const userRegistryAddress = await factory.userRegistry() - const userRegistry = await ethers.getContractAt( - 'SimpleUserRegistry', - userRegistryAddress - ) - const users = [contributor1, contributor2] - let addUserTx - for (const account of users) { - addUserTx = await userRegistry.addUser(account.getAddress()) - addUserTx.wait() - } - } - - // Add dummy recipients - // TODO add better dummy data - const metadataRecipient1 = { - name: 'Commons Simulator', - description: - 'Funding open-source projects & other public goods is the killer app of blockchain tech. Giveth & BlockScience are joining forces to build the Commons Stack: a modular library of well engineered components that can be used to create economic models for projects that are creating value, yet have trouble finding sustainable business models.', - imageHash: 'QmbMP2fMiy6ek5uQZaxG3bzT9gSqMWxpdCUcQg1iSeEFMU', - tagline: 'Modeling Sustainable Funding for Public Good', - category: 'Data', - problemSpace: 'metadata.problemSpace', - plans: 'metadata.plans', - teamName: 'metadata.teamName', - teamDescription: 'metadata.teamDescription', - githubUrl: 'https://github.com/', - radicleUrl: 'https://radicle.xyz/', - websiteUrl: 'https://website.com/', - twitterUrl: 'https://twitter.com/', - discordUrl: 'https://discord.com/', - bannerImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - thumbnailImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - } - - const metadataRecipient2 = { - name: 'Synthereum', - description: - 'The aim of our synthetic assets is to help creating fiat-based wallet and applications on any local currencies, and help to create stock, commodities portfolio in order to bring more traditional users within the DeFi ecosystem.', - imageHash: 'QmbMP2fMiy6ek5uQZaxG3bzT9gSqMWxpdCUcQg1iSeEFMU', - tagline: - 'Synthetic assets with liquidity pools to bridge traditional and digital finance.', - category: 'Content', - problemSpace: 'metadata.problemSpace', - plans: 'metadata.plans', - teamName: 'metadata.teamName', - teamDescription: 'metadata.teamDescription', - githubUrl: 'https://github.com/', - radicleUrl: 'https://radicle.xyz/', - websiteUrl: 'https://website.com/', - twitterUrl: 'https://twitter.com/', - discordUrl: 'https://discord.com/', - bannerImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - thumbnailImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - } - - const metadataRecipient3 = { - name: 'Commons Simulator', - description: - 'Funding open-source projects & other public goods is the killer app of blockchain tech. Giveth & BlockScience are joining forces to build the Commons Stack: a modular library of well engineered components that can be used to create economic models for projects that are creating value, yet have trouble finding sustainable business models.', - imageHash: 'QmbMP2fMiy6ek5uQZaxG3bzT9gSqMWxpdCUcQg1iSeEFMU', - tagline: 'Modeling Sustainable Funding for Public Good', - category: 'Data', - problemSpace: 'metadata.problemSpace', - plans: 'metadata.plans', - teamName: 'metadata.teamName', - teamDescription: 'metadata.teamDescription', - githubUrl: 'https://github.com/', - radicleUrl: 'https://radicle.xyz/', - websiteUrl: 'https://website.com/', - twitterUrl: 'https://twitter.com/', - discordUrl: 'https://discord.com/', - bannerImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - thumbnailImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - } - const metadataRecipient4 = { - name: 'Synthereum', - description: - 'The aim of our synthetic assets is to help creating fiat-based wallet and applications on any local currencies, and help to create stock, commodities portfolio in order to bring more traditional users within the DeFi ecosystem.', - imageHash: 'QmbMP2fMiy6ek5uQZaxG3bzT9gSqMWxpdCUcQg1iSeEFMU', - tagline: - 'Synthetic assets with liquidity pools to bridge traditional and digital finance.', - category: 'Content', - problemSpace: 'metadata.problemSpace', - plans: 'metadata.plans', - teamName: 'metadata.teamName', - teamDescription: 'metadata.teamDescription', - githubUrl: 'https://github.com/', - radicleUrl: 'https://radicle.xyz/', - websiteUrl: 'https://website.com/', - twitterUrl: 'https://twitter.com/', - discordUrl: 'https://discord.com/', - bannerImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - thumbnailImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - } - const metadataRecipient5 = { - name: 'Commons Simulator', - description: - 'Funding open-source projects & other public goods is the killer app of blockchain tech. Giveth & BlockScience are joining forces to build the Commons Stack: a modular library of well engineered components that can be used to create economic models for projects that are creating value, yet have trouble finding sustainable business models.', - imageHash: 'QmbMP2fMiy6ek5uQZaxG3bzT9gSqMWxpdCUcQg1iSeEFMU', - tagline: 'Modeling Sustainable Funding for Public Good', - category: 'Data', - problemSpace: 'metadata.problemSpace', - plans: 'metadata.plans', - teamName: 'metadata.teamName', - teamDescription: 'metadata.teamDescription', - githubUrl: 'https://github.com/', - radicleUrl: 'https://radicle.xyz/', - websiteUrl: 'https://website.com/', - twitterUrl: 'https://twitter.com/', - discordUrl: 'https://discord.com/', - bannerImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - thumbnailImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - } - const metadataRecipient6 = { - name: 'Synthereum', - description: - 'The aim of our synthetic assets is to help creating fiat-based wallet and applications on any local currencies, and help to create stock, commodities portfolio in order to bring more traditional users within the DeFi ecosystem.', - imageHash: 'QmbMP2fMiy6ek5uQZaxG3bzT9gSqMWxpdCUcQg1iSeEFMU', - tagline: - 'Synthetic assets with liquidity pools to bridge traditional and digital finance.', - category: 'Content', - problemSpace: 'metadata.problemSpace', - plans: 'metadata.plans', - teamName: 'metadata.teamName', - teamDescription: 'metadata.teamDescription', - githubUrl: 'https://github.com/', - radicleUrl: 'https://radicle.xyz/', - websiteUrl: 'https://website.com/', - twitterUrl: 'https://twitter.com/', - discordUrl: 'https://discord.com/', - bannerImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - thumbnailImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - } - const metadataRecipient7 = { - name: 'Commons Simulator', - description: - 'Funding open-source projects & other public goods is the killer app of blockchain tech. Giveth & BlockScience are joining forces to build the Commons Stack: a modular library of well engineered components that can be used to create economic models for projects that are creating value, yet have trouble finding sustainable business models.', - imageHash: 'QmbMP2fMiy6ek5uQZaxG3bzT9gSqMWxpdCUcQg1iSeEFMU', - tagline: 'Modeling Sustainable Funding for Public Good', - category: 'Data', - problemSpace: 'metadata.problemSpace', - plans: 'metadata.plans', - teamName: 'metadata.teamName', - teamDescription: 'metadata.teamDescription', - githubUrl: 'https://github.com/', - radicleUrl: 'https://radicle.xyz/', - websiteUrl: 'https://website.com/', - twitterUrl: 'https://twitter.com/', - discordUrl: 'https://discord.com/', - bannerImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - thumbnailImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - } - const metadataRecipient8 = { - name: 'Synthereum', - description: - 'The aim of our synthetic assets is to help creating fiat-based wallet and applications on any local currencies, and help to create stock, commodities portfolio in order to bring more traditional users within the DeFi ecosystem.', - imageHash: 'QmbMP2fMiy6ek5uQZaxG3bzT9gSqMWxpdCUcQg1iSeEFMU', - tagline: - 'Synthetic assets with liquidity pools to bridge traditional and digital finance.', - category: 'Content', - problemSpace: 'metadata.problemSpace', - plans: 'metadata.plans', - teamName: 'metadata.teamName', - teamDescription: 'metadata.teamDescription', - githubUrl: 'https://github.com/', - radicleUrl: 'https://radicle.xyz/', - websiteUrl: 'https://website.com/', - twitterUrl: 'https://twitter.com/', - discordUrl: 'https://discord.com/', - bannerImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - thumbnailImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - } - const metadataRecipient9 = { - name: 'Commons Simulator', - description: - 'Funding open-source projects & other public goods is the killer app of blockchain tech. Giveth & BlockScience are joining forces to build the Commons Stack: a modular library of well engineered components that can be used to create economic models for projects that are creating value, yet have trouble finding sustainable business models.', - imageHash: 'QmbMP2fMiy6ek5uQZaxG3bzT9gSqMWxpdCUcQg1iSeEFMU', - tagline: 'Modeling Sustainable Funding for Public Good', - category: 'Data', - problemSpace: 'metadata.problemSpace', - plans: 'metadata.plans', - teamName: 'metadata.teamName', - teamDescription: 'metadata.teamDescription', - githubUrl: 'https://github.com/', - radicleUrl: 'https://radicle.xyz/', - websiteUrl: 'https://website.com/', - twitterUrl: 'https://twitter.com/', - discordUrl: 'https://discord.com/', - bannerImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - thumbnailImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - } - - // Deploy new funding round and MACI - const deployNewRoundTx = await factory.deployNewRound() - await deployNewRoundTx.wait() - const fundingRoundAddress = await factory.getCurrentRound() - console.log(`Funding round deployed: ${fundingRoundAddress}`) - const fundingRound = await ethers.getContractAt( - 'FundingRound', - fundingRoundAddress - ) - const maciAddress = await fundingRound.maci() - console.log(`MACI address: ${maciAddress}`) - - const recipientRegistryType = process.env.RECIPIENT_REGISTRY_TYPE || 'simple' - const recipientRegistryAddress = await factory.recipientRegistry() - if (recipientRegistryType === 'simple') { - const recipientRegistry = await ethers.getContractAt( - 'SimpleRecipientRegistry', - recipientRegistryAddress - ) - const recipients = [ - { account: recipient1, metadata: metadataRecipient1 }, - { account: recipient2, metadata: metadataRecipient2 }, - { account: recipient3, metadata: metadataRecipient3 }, - { account: recipient4, metadata: metadataRecipient4 }, - { account: recipient5, metadata: metadataRecipient5 }, - { account: recipient6, metadata: metadataRecipient6 }, - { account: recipient7, metadata: metadataRecipient7 }, - { account: recipient8, metadata: metadataRecipient8 }, - { account: recipient9, metadata: metadataRecipient9 }, - ] - let addRecipientTx - for (const recipient of recipients) { - addRecipientTx = await recipientRegistry.addRecipient( - recipient.account.getAddress(), - JSON.stringify(recipient.metadata) - ) - addRecipientTx.wait() - } - } else if (recipientRegistryType === 'optimistic') { - const recipientRegistry = await ethers.getContractAt( - 'OptimisticRecipientRegistry', - recipientRegistryAddress - ) - const deposit = await recipientRegistry.baseDeposit() - const recipient1Added = await recipientRegistry.addRecipient( - recipient1.getAddress(), - JSON.stringify(metadataRecipient1), - { value: deposit } - ) - await recipient1Added.wait() - - const recipient1Id = await getEventArg( - recipient1Added, - recipientRegistry, - 'RequestSubmitted', - '_recipientId' - ) - const executeRequest1 = await recipientRegistry.executeRequest(recipient1Id) - await executeRequest1.wait() - - const recipient2Added = await recipientRegistry.addRecipient( - recipient2.getAddress(), - JSON.stringify(metadataRecipient2), - { value: deposit } - ) - await recipient2Added.wait() - - const recipient2Id = await getEventArg( - recipient2Added, - recipientRegistry, - 'RequestSubmitted', - '_recipientId' - ) - const executeRequest2 = await recipientRegistry.executeRequest(recipient2Id) - await executeRequest2.wait() - - // Add recipient without executing - const recipient3Added = await recipientRegistry.addRecipient( - recipient3.getAddress(), - JSON.stringify(metadataRecipient3), - { value: deposit } - ) - recipient3Added.wait() - } - - // Save the current state of the round - fs.writeFileSync( - 'state.json', - JSON.stringify({ - factory: factory.address, - fundingRound: fundingRoundAddress, - coordinatorPrivKey: coordinatorKeyPair.privKey.serialize(), - }) - ) -} - -main() - .then(() => process.exit(0)) - .catch((error) => { - console.error(error) - process.exit(1) - }) diff --git a/contracts/scripts/generate-key.ts b/contracts/scripts/generate-key.ts deleted file mode 100644 index e7d527188..000000000 --- a/contracts/scripts/generate-key.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Keypair } from '@clrfund/common' - -async function main() { - const keypair = new Keypair() - const serializedPrivKey = keypair.privKey.serialize() - const serializedPubKey = keypair.pubKey.serialize() - console.log('Private key:', serializedPrivKey) - console.log('Public key: ', serializedPubKey) -} - -main() - .then(() => process.exit(0)) - .catch((error) => { - console.error(error) - process.exit(1) - }) diff --git a/contracts/scripts/get-bytecode.ts b/contracts/scripts/get-bytecode.ts deleted file mode 100644 index b800378a5..000000000 --- a/contracts/scripts/get-bytecode.ts +++ /dev/null @@ -1,27 +0,0 @@ -// Usage: yarn ts-node scripts/get-bytecode.ts MACI -import { artifacts } from 'hardhat' -import { linkBytecode } from '../utils/deployment' - -async function main() { - const contractName = process.argv[2] - const poseidonT3Address = process.argv[3] - const poseidonT6Address = process.argv[4] - const artifact = await artifacts.readArtifact(contractName) - let result: string - if (poseidonT3Address && poseidonT6Address) { - result = linkBytecode(artifact.deployedBytecode, { - '@clrfund/maci-contracts/sol/Poseidon.sol:PoseidonT3': poseidonT3Address, - '@clrfund/maci-contracts/sol/Poseidon.sol:PoseidonT6': poseidonT6Address, - }) - } else { - result = artifact.deployedBytecode - } - console.info(result) -} - -main() - .then(() => process.exit(0)) - .catch((error) => { - console.error(error) - process.exit(1) - }) diff --git a/contracts/scripts/prepare-results.ts b/contracts/scripts/prepare-results.ts deleted file mode 100644 index e979d2f27..000000000 --- a/contracts/scripts/prepare-results.ts +++ /dev/null @@ -1,97 +0,0 @@ -import fetch from 'node-fetch' -import { ethers } from 'hardhat' -import { Event } from 'ethers' -import { gtcrDecode } from '@kleros/gtcr-encoder' -import { DEFAULT_IPFS_GATEWAY } from '../utils/constants' - -const ipfsGatewayUrl = process.env.IPFS_GATEWAY_URL || DEFAULT_IPFS_GATEWAY - -interface Project { - id: string - name: string - index: number - result?: number - spent?: number -} - -interface TcrColumn { - label: string - type: string -} - -function decodeRecipientAdded(event: Event, columns: TcrColumn[]): Project { - const args = event.args as any - const consoleError = console.error - console.error = function () {} // eslint-disable-line @typescript-eslint/no-empty-function - const decodedMetadata = gtcrDecode({ columns, values: args._metadata }) - console.error = consoleError - /* eslint-enable no-console */ - return { - id: args._tcrItemId, - name: decodedMetadata[0] as string, - index: args._index.toNumber(), - } -} - -async function main() { - const fundingRound = await ethers.getContractAt( - 'FundingRound', - process.env.ROUND_ADDRESS as string - ) - const startBlock = await fundingRound.startBlock() - const maci = await ethers.getContractAt('MACI', await fundingRound.maci()) - const signUpDuration = await maci.signUpDurationSeconds() - const votingDuration = await maci.votingDurationSeconds() - const endBlock = startBlock.add(signUpDuration.add(votingDuration).div(15)) - const tallyHash = await fundingRound.tallyHash() - const tallyResponse = await fetch(`${ipfsGatewayUrl}/ipfs/${tallyHash}`) - const tally = await tallyResponse.json() - const registry = await ethers.getContractAt( - 'KlerosGTCRAdapter', - await fundingRound.recipientRegistry() - ) - const tcr = await ethers.getContractAt('KlerosGTCRMock', await registry.tcr()) - const metaEvidenceFilter = tcr.filters.MetaEvidence() - const metaEvidenceEvents = await tcr.queryFilter(metaEvidenceFilter, 0) - const regMetaEvidenceEvent = metaEvidenceEvents[metaEvidenceEvents.length - 2] - const tcrEvidenceIpfsPath = (regMetaEvidenceEvent.args as any)._evidence - const tcrDataResponse = await fetch(`${ipfsGatewayUrl}${tcrEvidenceIpfsPath}`) - const tcrData = await tcrDataResponse.json() - const tcrColumns = tcrData.metadata.columns - const recipientAddedFilter = registry.filters.RecipientAdded() - const recipientAddedEvents = await registry.queryFilter( - recipientAddedFilter, - 0 - ) - const recipientRemovedFilter = registry.filters.RecipientRemoved() - const recipientRemovedEvents = await registry.queryFilter( - recipientRemovedFilter, - 0 - ) - const projects: Project[] = [] - for (const event of recipientAddedEvents) { - const project = decodeRecipientAdded(event, tcrColumns) - if (event.blockNumber >= endBlock.toNumber()) { - continue - } - const removed = recipientRemovedEvents.find((event) => { - return (event.args as any)._tcrItemId === project.id - }) - if (removed) { - continue - } - project.result = parseInt(tally.results.tally[project.index]) - project.spent = parseInt( - tally.totalVoiceCreditsPerVoteOption.tally[project.index] - ) - projects.push(project) - } - console.log(JSON.stringify(projects)) -} - -main() - .then(() => process.exit(0)) - .catch((error) => { - console.error(error) - process.exit(1) - }) diff --git a/contracts/scripts/verify.ts b/contracts/scripts/verify.ts deleted file mode 100644 index 0cb07c074..000000000 --- a/contracts/scripts/verify.ts +++ /dev/null @@ -1,16 +0,0 @@ -// Usage: yarn ts-node scripts/verify.ts tally.json -import { verify } from 'maci-cli' - -async function main() { - const tallyFile = process.argv[2] - await verify({ - tally_file: tallyFile, // eslint-disable-line @typescript-eslint/camelcase - }) -} - -main() - .then(() => process.exit(0)) - .catch((error) => { - console.error(error) - process.exit(1) - })