From 5d3080a252043e060bacfa1ccb8ae8f249e6c1df Mon Sep 17 00:00:00 2001 From: PragyaTripathi990 <16pragyatripathi@gmail.com> Date: Sun, 10 May 2026 17:23:10 +0530 Subject: [PATCH] fix: repair deploy script, per-network env vars, add .env.example deploy.js had PPTToken deployment commented out and hardcoded the MedInvoiceContract's token address. Restored both deployments in sequence so PPTToken is always deployed first and its address passed automatically. Added contract verification for non-local networks with error handling. hardhat.config.js used a single RPC_URL for all 6 networks, making it impossible to deploy to more than one without editing the file. Replaced with per-network env vars (CALIBNET_RPC_URL, OP_SEPOLIA_RPC_URL, etc.) and per-explorer API keys. Accounts and URLs default to empty string/array so hardhat doesn't throw on startup when variables are not set. Added .env.example documenting all required environment variables with links to where API keys can be obtained for each network. Closes #3 --- .env.example | 23 ++++++++++++++ hardhat.config.js | 47 ++++++++++++++-------------- scripts/deploy.js | 79 ++++++++++++++++++++++++++++------------------- 3 files changed, 94 insertions(+), 55 deletions(-) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..d4847bd --- /dev/null +++ b/.env.example @@ -0,0 +1,23 @@ +# Private key of the deployer wallet (no 0x prefix) +PRIVATE_KEY=your_private_key_here + +# RPC URLs — get these from Alchemy, Infura, Ankr, or the chain's public docs +CALIBNET_RPC_URL=https://api.calibration.node.glif.io/rpc/v1 +FILECOIN_RPC_URL=https://api.node.glif.io/rpc/v1 +OP_SEPOLIA_RPC_URL=https://sepolia.optimism.io +OP_MAINNET_RPC_URL=https://mainnet.optimism.io +ARBITRUM_SEPOLIA_RPC_URL=https://sepolia-rollup.arbitrum.io/rpc +CELO_ALFAJORES_RPC_URL=https://alfajores-forno.celo-testnet.org + +# Block explorer API keys for contract verification +# Filecoin Calibration: https://calibration.filscan.io +CALIBNET_VERIFY_KEY=your_filscan_api_key + +# Optimism (Etherscan): https://optimistic.etherscan.io/myapikey +OP_VERIFY_KEY=your_optimism_etherscan_api_key + +# Arbitrum (Arbiscan): https://arbiscan.io/myapikey +ARBITRUM_VERIFY_KEY=your_arbiscan_api_key + +# Celo (Celoscan): https://celoscan.io/myapikey +CELO_VERIFY_KEY=your_celoscan_api_key diff --git a/hardhat.config.js b/hardhat.config.js index 7b68e08..c0d5537 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -1,42 +1,43 @@ require("@nomicfoundation/hardhat-toolbox"); -require('dotenv').config() +require('dotenv').config(); + /** @type import('hardhat/config').HardhatUserConfig */ module.exports = { solidity: "0.8.20", networks: { "calibnet": { - url: process.env.RPC_URL, - accounts: [process.env.PRIVATE_KEY] + url: process.env.CALIBNET_RPC_URL || "", + accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [] }, "filecoin": { - url: process.env.RPC_URL, - accounts: [process.env.PRIVATE_KEY] + url: process.env.FILECOIN_RPC_URL || "", + accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [] }, "op-sepolia": { - url: process.env.RPC_URL, - accounts: [process.env.PRIVATE_KEY] + url: process.env.OP_SEPOLIA_RPC_URL || "", + accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [] }, "op-mainnet": { - url: process.env.RPC_URL, - accounts: [process.env.PRIVATE_KEY] + url: process.env.OP_MAINNET_RPC_URL || "", + accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [] }, "arbitrumSepolia": { - url: process.env.RPC_URL, - accounts: [process.env.PRIVATE_KEY] + url: process.env.ARBITRUM_SEPOLIA_RPC_URL || "", + accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [] }, "celo-alfajores": { - url: process.env.RPC_URL, - accounts: [process.env.PRIVATE_KEY] + url: process.env.CELO_ALFAJORES_RPC_URL || "", + accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [] } }, etherscan: { apiKey: { - "calibnet": process.env.VERIFY_KEY, - "op-sepolia": process.env.VERIFY_KEY, - "op-mainnet": process.env.VERIFY_KEY, - "optimism": process.env.VERIFY_KEY, - "arbitrumSepolia": process.env.VERIFY_KEY, - "celo-alfajores": process.env.VERIFY_KEY + "calibnet": process.env.CALIBNET_VERIFY_KEY || "", + "op-sepolia": process.env.OP_VERIFY_KEY || "", + "op-mainnet": process.env.OP_VERIFY_KEY || "", + "optimism": process.env.OP_VERIFY_KEY || "", + "arbitrumSepolia": process.env.ARBITRUM_VERIFY_KEY || "", + "celo-alfajores": process.env.CELO_VERIFY_KEY || "" }, customChains: [ { @@ -75,9 +76,9 @@ module.exports = { network: "celo-alfajores", chainId: 44787, urls: { - apiURL: "https://api-alfajores.celoscan.io/api", - browserURL: "https://alfajores.celoscan.io", - }, + apiURL: "https://api-alfajores.celoscan.io/api", + browserURL: "https://alfajores.celoscan.io" + } }, { network: "op-mainnet", @@ -89,4 +90,4 @@ module.exports = { } ] } -}; \ No newline at end of file +}; diff --git a/scripts/deploy.js b/scripts/deploy.js index feff66b..02dfd1c 100644 --- a/scripts/deploy.js +++ b/scripts/deploy.js @@ -1,39 +1,54 @@ -const hre = require('hardhat') +const hre = require('hardhat'); -async function main(){ +async function main() { + const network = hre.network.name; + console.log(`\nDeploying to network: ${network}`); - // const contract = await hre.ethers.deployContract("PPTToken",[200_000_000]) - // await contract.waitForDeployment(); + // Step 1: Deploy PPTToken + const initialSupply = 200_000_000; + const pptToken = await hre.ethers.deployContract("PPTToken", [initialSupply]); + await pptToken.waitForDeployment(); + console.log(`PPTToken deployed at: ${pptToken.target}`); - // console.log("Contract deployed at : ",contract.target); - - // console.log("Waiting 30 seconds before verification...") - // await new Promise(resolve => setTimeout(resolve, 30000)); - - // await hre.run("verify:verify",{ - // address : contract.target, - // constructorArguments : [200_000_000] - // }) - - const invoiceContract = await hre.ethers.deployContract("MedInvoiceContract",["0xC00BBC9A2C88712dC1e094866973F036373C7134"]) + // Step 2: Deploy MedInvoiceContract using PPTToken address + const invoiceContract = await hre.ethers.deployContract("MedInvoiceContract", [pptToken.target]); await invoiceContract.waitForDeployment(); - - console.log("Contract deployed at : ",invoiceContract.target); - - console.log("Waiting 30 seconds before verification...") - await new Promise(resolve => setTimeout(resolve, 30000)); - - // await hre.run("verify:verify",{ - // address : invoiceContract.target, - // constructorArguments : [contract.target] - // }) - + console.log(`MedInvoiceContract deployed at: ${invoiceContract.target}`); + + // Step 3: Verify contracts on block explorer (skip for local hardhat network) + if (network !== "hardhat" && network !== "localhost") { + console.log("\nWaiting 30 seconds before verification..."); + await new Promise(resolve => setTimeout(resolve, 30000)); + + try { + await hre.run("verify:verify", { + address: pptToken.target, + constructorArguments: [initialSupply] + }); + console.log("PPTToken verified."); + } catch (e) { + console.warn("PPTToken verification failed:", e.message); + } + + try { + await hre.run("verify:verify", { + address: invoiceContract.target, + constructorArguments: [pptToken.target] + }); + console.log("MedInvoiceContract verified."); + } catch (e) { + console.warn("MedInvoiceContract verification failed:", e.message); + } + } + + console.log("\nDeployment complete."); + console.log(` PPTToken: ${pptToken.target}`); + console.log(` MedInvoiceContract: ${invoiceContract.target}`); } - main() -.then(()=>{process.exit(0)}) -.catch((error)=>{ - console.log(error); - process.exit(1); -}) \ No newline at end of file + .then(() => { process.exit(0); }) + .catch((error) => { + console.error(error); + process.exit(1); + });