datahaven/test/scripts/deploy-contracts.ts
Facundo Farall e161accac2
fix: 🧑‍💻 Fix and improve bun cli logging and functionalities (#60)
This PR:
1. Generally improves the logging of the testing CLI, making the logs
more concise and easier to follow, with clearer sections and
separations.
2. Launches DataHaven solochain nodes at the beginning not the end.
3. Prompts the user if they want to launch DataHaven nodes and
Snowbridge Relayers.

---------

Co-authored-by: Tim B <79199034+timbrinded@users.noreply.github.com>
2025-05-08 09:42:45 -03:00

142 lines
4.4 KiB
TypeScript

import { $ } from "bun";
import invariant from "tiny-invariant";
import {
confirmWithTimeout,
logger,
printDivider,
printHeader,
runShellCommandWithLogger
} from "utils";
interface DeployContractsOptions {
rpcUrl: string;
verified?: boolean;
blockscoutBackendUrl?: string;
deployContracts?: boolean;
}
/**
* Deploys smart contracts to the specified RPC URL
*
* @param options - Configuration options for deployment
* @param options.rpcUrl - The RPC URL to deploy to
* @param options.verified - Whether to verify contracts (requires blockscoutBackendUrl)
* @param options.blockscoutBackendUrl - URL for the Blockscout API (required if verified is true)
* @param options.deployContracts - Flag to control deployment (if undefined, will prompt)
* @returns Promise resolving to true if contracts were deployed successfully, false if skipped
*/
export const deployContracts = async (options: DeployContractsOptions): Promise<boolean> => {
const { rpcUrl, verified = false, blockscoutBackendUrl, deployContracts } = options;
// Check if deployContracts option was set via flags, or prompt if not
let shouldDeployContracts = deployContracts;
if (shouldDeployContracts === undefined) {
shouldDeployContracts = await confirmWithTimeout(
"Do you want to deploy the smart contracts?",
true,
10
);
} else {
logger.info(
`Using flag option: ${shouldDeployContracts ? "will deploy" : "will not deploy"} smart contracts`
);
}
if (!shouldDeployContracts) {
logger.info("Skipping contract deployment. Done!");
printDivider();
return false;
}
// Check if required parameters are provided
invariant(rpcUrl, "❌ RPC URL is required");
if (verified) {
invariant(blockscoutBackendUrl, "❌ Blockscout backend URL is required for verification");
}
printHeader("Deploying Smart Contracts");
// Build contracts
logger.info("🛳️ Building contracts...");
const {
exitCode: buildExitCode,
stderr: buildStderr,
stdout: buildStdout
} = await $`forge build`.cwd("../contracts").nothrow().quiet();
if (buildExitCode !== 0) {
logger.error(buildStderr.toString());
throw Error("❌ Contracts have failed to build properly.");
}
logger.debug(buildStdout.toString());
let deployCommand = `forge script script/deploy/DeployLocal.s.sol --rpc-url ${rpcUrl} --color never -vv --no-rpc-rate-limit --non-interactive --broadcast`;
if (verified && blockscoutBackendUrl) {
deployCommand += ` --verify --verifier blockscout --verifier-url ${blockscoutBackendUrl}/api/ --delay 0`;
logger.info("🔍 Contract verification enabled");
}
logger.info("⏳ Deploying contracts (this might take a few minutes)...");
// Using custom shell command to improve logging with forge's stdoutput
await runShellCommandWithLogger(deployCommand, { cwd: "../contracts" });
logger.success("Contracts deployed successfully");
printDivider();
return true;
};
// Allow script to be run directly with CLI arguments
if (import.meta.main) {
const args = process.argv.slice(2);
const options: {
rpcUrl?: string;
verified: boolean;
blockscoutBackendUrl?: string;
deployContracts?: boolean;
} = {
verified: args.includes("--verified"),
deployContracts: args.includes("--deploy-contracts")
? true
: args.includes("--no-deploy-contracts")
? false
: undefined
};
// Extract RPC URL
const rpcUrlIndex = args.indexOf("--rpc-url");
if (rpcUrlIndex !== -1 && rpcUrlIndex + 1 < args.length) {
options.rpcUrl = args[rpcUrlIndex + 1];
}
// Extract Blockscout URL if verification is enabled
if (options.verified) {
const blockscoutUrlIndex = args.indexOf("--blockscout-url");
if (blockscoutUrlIndex !== -1 && blockscoutUrlIndex + 1 < args.length) {
options.blockscoutBackendUrl = args[blockscoutUrlIndex + 1];
}
}
if (!options.rpcUrl) {
console.error("Error: --rpc-url parameter is required");
process.exit(1);
}
if (options.verified && !options.blockscoutBackendUrl) {
console.error("Error: --blockscout-url parameter is required when using --verified");
process.exit(1);
}
deployContracts({
rpcUrl: options.rpcUrl,
verified: options.verified,
blockscoutBackendUrl: options.blockscoutBackendUrl,
deployContracts: options.deployContracts
}).catch((error) => {
console.error("Deployment failed:", error);
process.exit(1);
});
}