Harden membership deploy script with env validation and output metadata
This commit is contained in:
parent
8e6c1ceace
commit
d91b9927f8
@ -8,3 +8,5 @@ TREASURY_WALLET=0x0000000000000000000000000000000000000000
|
|||||||
MINT_CURRENCY_ADDRESS=0x0000000000000000000000000000000000000000
|
MINT_CURRENCY_ADDRESS=0x0000000000000000000000000000000000000000
|
||||||
MINT_AMOUNT_ATOMIC=5000000000000000
|
MINT_AMOUNT_ATOMIC=5000000000000000
|
||||||
|
|
||||||
|
# Optional: write deployment metadata JSON (address, tx hash, params).
|
||||||
|
# DEPLOY_OUTPUT_PATH=./deploy/membership-deploy.sepolia.json
|
||||||
|
|||||||
@ -23,6 +23,8 @@ Features:
|
|||||||
|
|
||||||
## Local Commands
|
## Local Commands
|
||||||
|
|
||||||
|
Use a Hardhat-supported Node runtime (`20.x` recommended).
|
||||||
|
|
||||||
1. `npm install`
|
1. `npm install`
|
||||||
2. `npm run build`
|
2. `npm run build`
|
||||||
3. `npm run test`
|
3. `npm run test`
|
||||||
@ -40,6 +42,7 @@ Copy `.env.example` values into your shell/session before deploy:
|
|||||||
3. `TREASURY_WALLET`
|
3. `TREASURY_WALLET`
|
||||||
4. `MINT_CURRENCY_ADDRESS` (`0x000...000` for ETH)
|
4. `MINT_CURRENCY_ADDRESS` (`0x000...000` for ETH)
|
||||||
5. `MINT_AMOUNT_ATOMIC`
|
5. `MINT_AMOUNT_ATOMIC`
|
||||||
|
6. `DEPLOY_OUTPUT_PATH` (optional)
|
||||||
|
|
||||||
Example (Sepolia):
|
Example (Sepolia):
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
const hre = require("hardhat");
|
const hre = require("hardhat");
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
function requiredEnv(name) {
|
function requiredEnv(name) {
|
||||||
const value = process.env[name];
|
const value = process.env[name];
|
||||||
@ -8,10 +10,36 @@ function requiredEnv(name) {
|
|||||||
return value.trim();
|
return value.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function requireAddress(name, value, { allowZero = false } = {}) {
|
||||||
|
if (!hre.ethers.utils.isAddress(value)) {
|
||||||
|
throw new Error(`Invalid address for ${name}: ${value}`);
|
||||||
|
}
|
||||||
|
if (!allowZero && value === hre.ethers.constants.AddressZero) {
|
||||||
|
throw new Error(`${name} cannot be zero address`);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseUint(name, value) {
|
||||||
|
try {
|
||||||
|
const parsed = hre.ethers.BigNumber.from(value);
|
||||||
|
if (parsed.lt(0)) {
|
||||||
|
throw new Error("must be >= 0");
|
||||||
|
}
|
||||||
|
return parsed;
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(`Invalid uint for ${name}: ${value} (${err.message})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const treasury = requiredEnv("TREASURY_WALLET");
|
const treasury = requireAddress("TREASURY_WALLET", requiredEnv("TREASURY_WALLET"));
|
||||||
const mintCurrency = (process.env.MINT_CURRENCY_ADDRESS || hre.ethers.constants.AddressZero).trim();
|
const mintCurrency = requireAddress(
|
||||||
const mintAmountAtomic = requiredEnv("MINT_AMOUNT_ATOMIC");
|
"MINT_CURRENCY_ADDRESS",
|
||||||
|
(process.env.MINT_CURRENCY_ADDRESS || hre.ethers.constants.AddressZero).trim(),
|
||||||
|
{ allowZero: true },
|
||||||
|
);
|
||||||
|
const mintAmountAtomic = parseUint("MINT_AMOUNT_ATOMIC", requiredEnv("MINT_AMOUNT_ATOMIC"));
|
||||||
|
|
||||||
const [deployer] = await hre.ethers.getSigners();
|
const [deployer] = await hre.ethers.getSigners();
|
||||||
console.log("deployer:", deployer.address);
|
console.log("deployer:", deployer.address);
|
||||||
@ -25,10 +53,27 @@ async function main() {
|
|||||||
await contract.deployed();
|
await contract.deployed();
|
||||||
|
|
||||||
console.log("membership_contract:", contract.address);
|
console.log("membership_contract:", contract.address);
|
||||||
|
|
||||||
|
const output = {
|
||||||
|
network: hre.network.name,
|
||||||
|
chainId: hre.network.config.chainId || null,
|
||||||
|
deployer: deployer.address,
|
||||||
|
treasury,
|
||||||
|
mintCurrency,
|
||||||
|
mintAmountAtomic: mintAmountAtomic.toString(),
|
||||||
|
membershipContract: contract.address,
|
||||||
|
txHash: contract.deployTransaction.hash,
|
||||||
|
};
|
||||||
|
const outputPath = (process.env.DEPLOY_OUTPUT_PATH || "").trim();
|
||||||
|
if (outputPath) {
|
||||||
|
const absolute = path.resolve(outputPath);
|
||||||
|
fs.mkdirSync(path.dirname(absolute), { recursive: true });
|
||||||
|
fs.writeFileSync(absolute, JSON.stringify(output, null, 2));
|
||||||
|
console.log("deployment_output:", absolute);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
main().catch((err) => {
|
main().catch((err) => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
process.exitCode = 1;
|
process.exitCode = 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user