From f1acd36e171d493ac9077d71c07a5cf18e27a0ce Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 11 Sep 2024 12:18:23 +0800 Subject: [PATCH 01/20] feat: task to stop localnet --- hardhat.config.ts | 1 + packages/tasks/src/index.ts | 1 + packages/tasks/src/localnet.ts | 33 +++++++++++++++++++++++++++++++-- packages/tasks/src/stop.ts | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 packages/tasks/src/stop.ts diff --git a/hardhat.config.ts b/hardhat.config.ts index 6bce46f..e2c90f2 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,4 +1,5 @@ import "./packages/tasks/src/localnet"; +import "./packages/tasks/src/stop"; import { HardhatUserConfig } from "hardhat/config"; diff --git a/packages/tasks/src/index.ts b/packages/tasks/src/index.ts index bf4bb0d..34737e4 100644 --- a/packages/tasks/src/index.ts +++ b/packages/tasks/src/index.ts @@ -1 +1,2 @@ export { localnetTask } from "./localnet"; +export { localnetStopTask } from "./stop"; diff --git a/packages/tasks/src/localnet.ts b/packages/tasks/src/localnet.ts index a58366b..531814b 100644 --- a/packages/tasks/src/localnet.ts +++ b/packages/tasks/src/localnet.ts @@ -3,6 +3,9 @@ import { initLocalnet } from "../../localnet/src"; import { exec } from "child_process"; import waitOn from "wait-on"; import ansis from "ansis"; +import fs from "fs"; + +const LOCALNET_PID_FILE = "./localnet.pid"; const main = async (args: any) => { const port = args.port || 8545; @@ -53,15 +56,41 @@ System contract: ${addr.sytemContractZetaChain}`); ); }); + // Save the localnet script's process ID (PID) + fs.writeFileSync(LOCALNET_PID_FILE, process.pid.toString(), "utf-8"); + + const cleanup = () => { + console.log("\nShutting down anvil and cleaning up..."); + if (anvilProcess) { + anvilProcess.kill(); // Kill the Anvil process + } + if (fs.existsSync(LOCALNET_PID_FILE)) { + fs.unlinkSync(LOCALNET_PID_FILE); // Clean up the PID file + } + }; + + // Handle various termination signals process.on("SIGINT", () => { - console.log("\nReceived Ctrl-C, shutting down anvil..."); - anvilProcess.kill(); + console.log("\nReceived SIGINT (Ctrl-C), shutting down..."); + cleanup(); + process.exit(); + }); + + process.on("SIGTERM", () => { + console.log("\nReceived SIGTERM, shutting down..."); + cleanup(); process.exit(); }); + process.on("exit", () => { + console.log("\nProcess exiting, cleaning up..."); + cleanup(); + }); + await new Promise(() => {}); }; +// Task to start localnet and store PID export const localnetTask = task("localnet", "Start localnet", main) .addOptionalParam("port", "Port to run anvil on", 8545, types.int) .addOptionalParam( diff --git a/packages/tasks/src/stop.ts b/packages/tasks/src/stop.ts new file mode 100644 index 0000000..21124ce --- /dev/null +++ b/packages/tasks/src/stop.ts @@ -0,0 +1,32 @@ +import { task } from "hardhat/config"; +import fs from "fs"; +import ansis from "ansis"; + +const LOCALNET_PID_FILE = "./localnet.pid"; + +const localnetStop = async (args: any) => { + if (!fs.existsSync(LOCALNET_PID_FILE)) { + console.log(ansis.red("Localnet is not running or PID file is missing.")); + return; + } + + const pid = fs.readFileSync(LOCALNET_PID_FILE, "utf-8").trim(); + try { + process.kill(Number(pid)); + console.log(ansis.green(`Successfully stopped localnet (PID: ${pid})`)); + + // Unlink PID file only if it exists + if (fs.existsSync(LOCALNET_PID_FILE)) { + fs.unlinkSync(LOCALNET_PID_FILE); + console.log(ansis.green(`PID file ${LOCALNET_PID_FILE} removed.`)); + } + } catch (err) { + console.error(ansis.red(`Failed to stop localnet: ${err}`)); + } +}; + +export const localnetStopTask = task( + "localnet-stop", + "Stop localnet", + localnetStop +); From edf92df5213a9741b162ed3a69bed7cea535e663 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 11 Sep 2024 12:20:03 +0800 Subject: [PATCH 02/20] fix double cleanup --- packages/tasks/src/localnet.ts | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/packages/tasks/src/localnet.ts b/packages/tasks/src/localnet.ts index 531814b..f64992c 100644 --- a/packages/tasks/src/localnet.ts +++ b/packages/tasks/src/localnet.ts @@ -56,41 +56,34 @@ System contract: ${addr.sytemContractZetaChain}`); ); }); - // Save the localnet script's process ID (PID) fs.writeFileSync(LOCALNET_PID_FILE, process.pid.toString(), "utf-8"); const cleanup = () => { console.log("\nShutting down anvil and cleaning up..."); if (anvilProcess) { - anvilProcess.kill(); // Kill the Anvil process + anvilProcess.kill(); } if (fs.existsSync(LOCALNET_PID_FILE)) { - fs.unlinkSync(LOCALNET_PID_FILE); // Clean up the PID file + fs.unlinkSync(LOCALNET_PID_FILE); } }; - // Handle various termination signals - process.on("SIGINT", () => { - console.log("\nReceived SIGINT (Ctrl-C), shutting down..."); + const handleExit = (signal: string) => { + console.log(`\nReceived ${signal}, shutting down...`); cleanup(); process.exit(); - }); + }; - process.on("SIGTERM", () => { - console.log("\nReceived SIGTERM, shutting down..."); - cleanup(); - process.exit(); - }); + process.on("SIGINT", () => handleExit("SIGINT")); + process.on("SIGTERM", () => handleExit("SIGTERM")); process.on("exit", () => { - console.log("\nProcess exiting, cleaning up..."); - cleanup(); + console.log("Process exiting..."); }); await new Promise(() => {}); }; -// Task to start localnet and store PID export const localnetTask = task("localnet", "Start localnet", main) .addOptionalParam("port", "Port to run anvil on", 8545, types.int) .addOptionalParam( From 8d12a5485389f566ab11478818c4d98e63e03b8d Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 11 Sep 2024 12:22:16 +0800 Subject: [PATCH 03/20] rename main to localnet --- packages/tasks/src/localnet.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/tasks/src/localnet.ts b/packages/tasks/src/localnet.ts index f64992c..d587224 100644 --- a/packages/tasks/src/localnet.ts +++ b/packages/tasks/src/localnet.ts @@ -7,7 +7,7 @@ import fs from "fs"; const LOCALNET_PID_FILE = "./localnet.pid"; -const main = async (args: any) => { +const localnet = async (args: any) => { const port = args.port || 8545; const anvilArgs = args.anvil ? `${args.anvil}` : ""; @@ -84,7 +84,7 @@ System contract: ${addr.sytemContractZetaChain}`); await new Promise(() => {}); }; -export const localnetTask = task("localnet", "Start localnet", main) +export const localnetTask = task("localnet", "Start localnet", localnet) .addOptionalParam("port", "Port to run anvil on", 8545, types.int) .addOptionalParam( "anvil", From 4ffa884e57fb6962a6575d57190683dc971f6909 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 11 Sep 2024 12:29:42 +0800 Subject: [PATCH 04/20] console log anvil args only when not empty --- packages/tasks/src/localnet.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/tasks/src/localnet.ts b/packages/tasks/src/localnet.ts index d587224..4c2effa 100644 --- a/packages/tasks/src/localnet.ts +++ b/packages/tasks/src/localnet.ts @@ -9,12 +9,12 @@ const LOCALNET_PID_FILE = "./localnet.pid"; const localnet = async (args: any) => { const port = args.port || 8545; - const anvilArgs = args.anvil ? `${args.anvil}` : ""; - console.log(`Starting anvil on port ${port} with args: ${anvilArgs}`); + if (args.anvil !== "") + console.log(`Starting anvil on port ${port} with args: ${args.anvil}`); const anvilProcess = exec( - `anvil --auto-impersonate --port ${port} ${anvilArgs}` + `anvil --auto-impersonate --port ${port} ${args.anvil}` ); if (anvilProcess.stdout && anvilProcess.stderr) { From 88b77c100bd03c74abfef4cf60074bbe72dcb16d Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 11 Sep 2024 12:48:56 +0800 Subject: [PATCH 05/20] prompt user to kill anvil --- package.json | 1 + packages/tasks/src/localnet.ts | 33 ++++- yarn.lock | 217 ++++++++++++++++++++++++++++++++- 3 files changed, 247 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index b0e48d3..3021a74 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "typescript": "^5.5.4" }, "dependencies": { + "@inquirer/prompts": "^5.5.0", "@uniswap/v2-core": "^1.0.1", "@uniswap/v2-periphery": "^1.1.0-beta.0", "@zetachain/protocol-contracts": "10.0.0-rc10", diff --git a/packages/tasks/src/localnet.ts b/packages/tasks/src/localnet.ts index 4c2effa..35a1532 100644 --- a/packages/tasks/src/localnet.ts +++ b/packages/tasks/src/localnet.ts @@ -1,15 +1,46 @@ import { task, types } from "hardhat/config"; import { initLocalnet } from "../../localnet/src"; -import { exec } from "child_process"; +import { exec, execSync } from "child_process"; import waitOn from "wait-on"; import ansis from "ansis"; import fs from "fs"; +import { confirm } from "@inquirer/prompts"; const LOCALNET_PID_FILE = "./localnet.pid"; +const killProcessOnPort = async (port: number) => { + try { + const output = execSync(`lsof -ti tcp:${port}`).toString().trim(); + if (output) { + console.log( + ansis.yellow(`Port ${port} is already in use by process ${output}.`) + ); + + const answer = await confirm({ + message: `Do you want to kill the process running on port ${port}?`, + default: true, + }); + + if (answer) { + execSync(`kill -9 ${output}`); + console.log( + ansis.green(`Successfully killed process ${output} on port ${port}.`) + ); + } else { + console.log(ansis.red("Process not killed. Exiting...")); + process.exit(1); + } + } + } catch (error) { + // Silently continue if no process is found or killing fails + } +}; + const localnet = async (args: any) => { const port = args.port || 8545; + await killProcessOnPort(port); + if (args.anvil !== "") console.log(`Starting anvil on port ${port} with args: ${args.anvil}`); diff --git a/yarn.lock b/yarn.lock index 5f61390..c202ed0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -294,6 +294,145 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.0.tgz#6d86b8cb322660f03d3f0aa94b99bdd8e172d570" integrity sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew== +"@inquirer/checkbox@^2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@inquirer/checkbox/-/checkbox-2.5.0.tgz#41c5c9dd332c0a8fa159be23982ce080d0b199d4" + integrity sha512-sMgdETOfi2dUHT8r7TT1BTKOwNvdDGFDXYWtQ2J69SvlYNntk9I/gJe7r5yvMwwsuKnYbuRs3pNhx4tgNck5aA== + dependencies: + "@inquirer/core" "^9.1.0" + "@inquirer/figures" "^1.0.5" + "@inquirer/type" "^1.5.3" + ansi-escapes "^4.3.2" + yoctocolors-cjs "^2.1.2" + +"@inquirer/confirm@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-3.2.0.tgz#6af1284670ea7c7d95e3f1253684cfbd7228ad6a" + integrity sha512-oOIwPs0Dvq5220Z8lGL/6LHRTEr9TgLHmiI99Rj1PJ1p1czTys+olrgBqZk4E2qC0YTzeHprxSQmoHioVdJ7Lw== + dependencies: + "@inquirer/core" "^9.1.0" + "@inquirer/type" "^1.5.3" + +"@inquirer/core@^9.1.0": + version "9.1.0" + resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-9.1.0.tgz#158b82dc44564a1abd0ce14723d50c3efa0634a2" + integrity sha512-RZVfH//2ytTjmaBIzeKT1zefcQZzuruwkpTwwbe/i2jTl4o9M+iML5ChULzz6iw1Ok8iUBBsRCjY2IEbD8Ft4w== + dependencies: + "@inquirer/figures" "^1.0.5" + "@inquirer/type" "^1.5.3" + "@types/mute-stream" "^0.0.4" + "@types/node" "^22.5.2" + "@types/wrap-ansi" "^3.0.0" + ansi-escapes "^4.3.2" + cli-spinners "^2.9.2" + cli-width "^4.1.0" + mute-stream "^1.0.0" + signal-exit "^4.1.0" + strip-ansi "^6.0.1" + wrap-ansi "^6.2.0" + yoctocolors-cjs "^2.1.2" + +"@inquirer/editor@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@inquirer/editor/-/editor-2.2.0.tgz#a41eb7b151bd9a6bc3c0b69219d02d82547bc387" + integrity sha512-9KHOpJ+dIL5SZli8lJ6xdaYLPPzB8xB9GZItg39MBybzhxA16vxmszmQFrRwbOA918WA2rvu8xhDEg/p6LXKbw== + dependencies: + "@inquirer/core" "^9.1.0" + "@inquirer/type" "^1.5.3" + external-editor "^3.1.0" + +"@inquirer/expand@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@inquirer/expand/-/expand-2.3.0.tgz#afc44aee303315a85563e9d0275e658f0ee0e701" + integrity sha512-qnJsUcOGCSG1e5DTOErmv2BPQqrtT6uzqn1vI/aYGiPKq+FgslGZmtdnXbhuI7IlT7OByDoEEqdnhUnVR2hhLw== + dependencies: + "@inquirer/core" "^9.1.0" + "@inquirer/type" "^1.5.3" + yoctocolors-cjs "^2.1.2" + +"@inquirer/figures@^1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-1.0.5.tgz#57f9a996d64d3e3345d2a3ca04d36912e94f8790" + integrity sha512-79hP/VWdZ2UVc9bFGJnoQ/lQMpL74mGgzSYX1xUqCVk7/v73vJCMw1VuyWN1jGkZ9B3z7THAbySqGbCNefcjfA== + +"@inquirer/input@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@inquirer/input/-/input-2.3.0.tgz#9b99022f53780fecc842908f3f319b52a5a16865" + integrity sha512-XfnpCStx2xgh1LIRqPXrTNEEByqQWoxsWYzNRSEUxJ5c6EQlhMogJ3vHKu8aXuTacebtaZzMAHwEL0kAflKOBw== + dependencies: + "@inquirer/core" "^9.1.0" + "@inquirer/type" "^1.5.3" + +"@inquirer/number@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@inquirer/number/-/number-1.1.0.tgz#4dac004021ea67c89552a261564f103a494cac96" + integrity sha512-ilUnia/GZUtfSZy3YEErXLJ2Sljo/mf9fiKc08n18DdwdmDbOzRcTv65H1jjDvlsAuvdFXf4Sa/aL7iw/NanVA== + dependencies: + "@inquirer/core" "^9.1.0" + "@inquirer/type" "^1.5.3" + +"@inquirer/password@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@inquirer/password/-/password-2.2.0.tgz#0b6f26336c259c8a9e5f5a3f2e1a761564f764ba" + integrity sha512-5otqIpgsPYIshqhgtEwSspBQE40etouR8VIxzpJkv9i0dVHIpyhiivbkH9/dGiMLdyamT54YRdGJLfl8TFnLHg== + dependencies: + "@inquirer/core" "^9.1.0" + "@inquirer/type" "^1.5.3" + ansi-escapes "^4.3.2" + +"@inquirer/prompts@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@inquirer/prompts/-/prompts-5.5.0.tgz#5805aa15a13180017829aa31d071fd37a43b735d" + integrity sha512-BHDeL0catgHdcHbSFFUddNzvx/imzJMft+tWDPwTm3hfu8/tApk1HrooNngB2Mb4qY+KaRWF+iZqoVUPeslEog== + dependencies: + "@inquirer/checkbox" "^2.5.0" + "@inquirer/confirm" "^3.2.0" + "@inquirer/editor" "^2.2.0" + "@inquirer/expand" "^2.3.0" + "@inquirer/input" "^2.3.0" + "@inquirer/number" "^1.1.0" + "@inquirer/password" "^2.2.0" + "@inquirer/rawlist" "^2.3.0" + "@inquirer/search" "^1.1.0" + "@inquirer/select" "^2.5.0" + +"@inquirer/rawlist@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@inquirer/rawlist/-/rawlist-2.3.0.tgz#6b2c0da39c1cd855af5608b2d627681cdac7277d" + integrity sha512-zzfNuINhFF7OLAtGHfhwOW2TlYJyli7lOUoJUXw/uyklcwalV6WRXBXtFIicN8rTRK1XTiPWB4UY+YuW8dsnLQ== + dependencies: + "@inquirer/core" "^9.1.0" + "@inquirer/type" "^1.5.3" + yoctocolors-cjs "^2.1.2" + +"@inquirer/search@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@inquirer/search/-/search-1.1.0.tgz#665928cac2326b9501ddafbb8606ce4823b3106b" + integrity sha512-h+/5LSj51dx7hp5xOn4QFnUaKeARwUCLs6mIhtkJ0JYPBLmEYjdHSYh7I6GrLg9LwpJ3xeX0FZgAG1q0QdCpVQ== + dependencies: + "@inquirer/core" "^9.1.0" + "@inquirer/figures" "^1.0.5" + "@inquirer/type" "^1.5.3" + yoctocolors-cjs "^2.1.2" + +"@inquirer/select@^2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@inquirer/select/-/select-2.5.0.tgz#345c6908ecfaeef3d84ddd2f9feb2f487c558efb" + integrity sha512-YmDobTItPP3WcEI86GvPo+T2sRHkxxOq/kXmsBjHS5BVXUgvgZ5AfJjkvQvZr03T81NnI3KrrRuMzeuYUQRFOA== + dependencies: + "@inquirer/core" "^9.1.0" + "@inquirer/figures" "^1.0.5" + "@inquirer/type" "^1.5.3" + ansi-escapes "^4.3.2" + yoctocolors-cjs "^2.1.2" + +"@inquirer/type@^1.5.3": + version "1.5.3" + resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-1.5.3.tgz#220ae9f3d5ae17dd3b2ce5ffd6b48c4a30c73181" + integrity sha512-xUQ14WQGR/HK5ei+2CvgcwoH9fQ4PgPGmVFSN0pc1+fVyDL3MREhyAY7nxEErSu6CkllBM3D7e3e+kOvtu+eIg== + dependencies: + mute-stream "^1.0.0" + "@jridgewell/resolve-uri@^3.0.3": version "3.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" @@ -653,6 +792,13 @@ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.5.tgz#ec10755e871497bcd83efe927e43ec46e8c0747e" integrity sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag== +"@types/mute-stream@^0.0.4": + version "0.0.4" + resolved "https://registry.yarnpkg.com/@types/mute-stream/-/mute-stream-0.0.4.tgz#77208e56a08767af6c5e1237be8888e2f255c478" + integrity sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow== + dependencies: + "@types/node" "*" + "@types/node@*": version "22.2.0" resolved "https://registry.yarnpkg.com/@types/node/-/node-22.2.0.tgz#7cf046a99f0ba4d628ad3088cb21f790df9b0c5b" @@ -665,6 +811,13 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== +"@types/node@^22.5.2": + version "22.5.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.4.tgz#83f7d1f65bc2ed223bdbf57c7884f1d5a4fa84e8" + integrity sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg== + dependencies: + undici-types "~6.19.2" + "@types/normalize-package-data@^2.4.0": version "2.4.4" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" @@ -691,6 +844,11 @@ dependencies: "@types/node" "*" +"@types/wrap-ansi@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz#18b97a972f94f60a679fd5c796d96421b9abb9fd" + integrity sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g== + "@typescript-eslint/eslint-plugin@^8.0.1": version "8.0.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.0.1.tgz#5dbd1b498fdea83a16d292322d27d293ce156f94" @@ -876,7 +1034,7 @@ ansi-colors@^4.1.1, ansi-colors@^4.1.3: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== -ansi-escapes@^4.3.0: +ansi-escapes@^4.3.0, ansi-escapes@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== @@ -1107,6 +1265,11 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + chokidar@^3.4.0, chokidar@^3.5.3: version "3.6.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" @@ -1152,6 +1315,16 @@ cli-boxes@^2.2.1: resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== +cli-spinners@^2.9.2: + version "2.9.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" + integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== + +cli-width@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5" + integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ== + cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -1607,6 +1780,15 @@ evp_bytestokey@^1.0.3: md5.js "^1.3.4" safe-buffer "^5.1.1" +external-editor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -1955,7 +2137,7 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" -iconv-lite@0.4.24: +iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -2395,6 +2577,11 @@ ms@^2.1.3: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +mute-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" + integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -2798,6 +2985,11 @@ shell-quote@^1.8.1: resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== +signal-exit@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -2945,7 +3137,7 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== -tmp@0.0.33: +tmp@0.0.33, tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== @@ -3065,6 +3257,11 @@ undici-types@~6.13.0: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.13.0.tgz#e3e79220ab8c81ed1496b5812471afd7cf075ea5" integrity sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg== +undici-types@~6.19.2: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== + undici@^5.14.0: version "5.28.4" resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.4.tgz#6b280408edb6a1a604a9b20340f45b422e373068" @@ -3147,6 +3344,15 @@ workerpool@^6.5.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544" integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA== +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -3236,3 +3442,8 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +yoctocolors-cjs@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz#f4b905a840a37506813a7acaa28febe97767a242" + integrity sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA== From 16022d4d89cf801c47c0ea334215c27a75ce65d1 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 11 Sep 2024 12:51:15 +0800 Subject: [PATCH 06/20] force kill flag --- packages/tasks/src/localnet.ts | 36 +++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/packages/tasks/src/localnet.ts b/packages/tasks/src/localnet.ts index 35a1532..ed5b944 100644 --- a/packages/tasks/src/localnet.ts +++ b/packages/tasks/src/localnet.ts @@ -8,7 +8,7 @@ import { confirm } from "@inquirer/prompts"; const LOCALNET_PID_FILE = "./localnet.pid"; -const killProcessOnPort = async (port: number) => { +const killProcessOnPort = async (port: number, forceKill: boolean) => { try { const output = execSync(`lsof -ti tcp:${port}`).toString().trim(); if (output) { @@ -16,19 +16,30 @@ const killProcessOnPort = async (port: number) => { ansis.yellow(`Port ${port} is already in use by process ${output}.`) ); - const answer = await confirm({ - message: `Do you want to kill the process running on port ${port}?`, - default: true, - }); - - if (answer) { + if (forceKill) { + // In CI or automated environments, force kill without prompting execSync(`kill -9 ${output}`); console.log( ansis.green(`Successfully killed process ${output} on port ${port}.`) ); } else { - console.log(ansis.red("Process not killed. Exiting...")); - process.exit(1); + // Prompt the user for confirmation if not using forceKill + const answer = await confirm({ + message: `Do you want to kill the process running on port ${port}?`, + default: true, + }); + + if (answer) { + execSync(`kill -9 ${output}`); + console.log( + ansis.green( + `Successfully killed process ${output} on port ${port}.` + ) + ); + } else { + console.log(ansis.red("Process not killed. Exiting...")); + process.exit(1); + } } } } catch (error) { @@ -38,8 +49,10 @@ const killProcessOnPort = async (port: number) => { const localnet = async (args: any) => { const port = args.port || 8545; + const forceKill = args.forceKill || false; - await killProcessOnPort(port); + // Kill any process using the port, either with or without prompting + await killProcessOnPort(port, forceKill); if (args.anvil !== "") console.log(`Starting anvil on port ${port} with args: ${args.anvil}`); @@ -122,4 +135,5 @@ export const localnetTask = task("localnet", "Start localnet", localnet) "Additional arguments to pass to anvil", "", types.string - ); + ) + .addFlag("forceKill", "Force kill any process on the port without prompting"); // Added forceKill flag From 1c33bc39795dff0a13aac587038a5dd3bab16082 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 11 Sep 2024 12:55:16 +0800 Subject: [PATCH 07/20] if localnet fails, clean up --- packages/tasks/src/localnet.ts | 60 +++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/packages/tasks/src/localnet.ts b/packages/tasks/src/localnet.ts index ed5b944..53cfd80 100644 --- a/packages/tasks/src/localnet.ts +++ b/packages/tasks/src/localnet.ts @@ -17,13 +17,11 @@ const killProcessOnPort = async (port: number, forceKill: boolean) => { ); if (forceKill) { - // In CI or automated environments, force kill without prompting execSync(`kill -9 ${output}`); console.log( ansis.green(`Successfully killed process ${output} on port ${port}.`) ); } else { - // Prompt the user for confirmation if not using forceKill const answer = await confirm({ message: `Do you want to kill the process running on port ${port}?`, default: true, @@ -68,9 +66,20 @@ const localnet = async (args: any) => { await waitOn({ resources: [`tcp:127.0.0.1:${port}`] }); - const addr = await initLocalnet(port); + const cleanup = () => { + console.log("\nShutting down anvil and cleaning up..."); + if (anvilProcess) { + anvilProcess.kill(); + } + if (fs.existsSync(LOCALNET_PID_FILE)) { + fs.unlinkSync(LOCALNET_PID_FILE); + } + }; + + try { + const addr = await initLocalnet(port); - console.log(ansis.cyan` + console.log(ansis.cyan` EVM Contract Addresses ====================== @@ -79,13 +88,13 @@ ERC-20 custody: ${addr.custodyEVM} TSS: ${addr.tssEVM} ZETA: ${addr.zetaEVM}`); - addr.foreignCoins - .filter((coin: any) => coin.asset !== "") - .forEach((coin: any) => { - console.log(ansis.cyan`ERC-20 ${coin.symbol}: ${coin.asset}`); - }); + addr.foreignCoins + .filter((coin: any) => coin.asset !== "") + .forEach((coin: any) => { + console.log(ansis.cyan`ERC-20 ${coin.symbol}: ${coin.asset}`); + }); - console.log(ansis.green` + console.log(ansis.green` ZetaChain Contract Addresses ============================ @@ -94,24 +103,21 @@ ZETA: ${addr.zetaZetaChain} Fungible module: ${addr.fungibleModuleZetaChain} System contract: ${addr.sytemContractZetaChain}`); - addr.foreignCoins.forEach((coin: any) => { - console.log( - ansis.green`ZRC-20 ${coin.symbol}: ${coin.zrc20_contract_address}` - ); - }); - - fs.writeFileSync(LOCALNET_PID_FILE, process.pid.toString(), "utf-8"); + addr.foreignCoins.forEach((coin: any) => { + console.log( + ansis.green`ZRC-20 ${coin.symbol}: ${coin.zrc20_contract_address}` + ); + }); - const cleanup = () => { - console.log("\nShutting down anvil and cleaning up..."); - if (anvilProcess) { - anvilProcess.kill(); - } - if (fs.existsSync(LOCALNET_PID_FILE)) { - fs.unlinkSync(LOCALNET_PID_FILE); - } - }; + fs.writeFileSync(LOCALNET_PID_FILE, process.pid.toString(), "utf-8"); + } catch (error: any) { + // If initLocalnet fails, cleanup and exit + console.error(ansis.red`Error initializing localnet: ${error}`); + cleanup(); + process.exit(1); + } + // Set up cleanup on exit or signals const handleExit = (signal: string) => { console.log(`\nReceived ${signal}, shutting down...`); cleanup(); @@ -136,4 +142,4 @@ export const localnetTask = task("localnet", "Start localnet", localnet) "", types.string ) - .addFlag("forceKill", "Force kill any process on the port without prompting"); // Added forceKill flag + .addFlag("forceKill", "Force kill any process on the port without prompting"); From 7262ed4f6ae1f6d98959f8bca9e77f7615b85b48 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 11 Sep 2024 12:56:15 +0800 Subject: [PATCH 08/20] wip --- packages/tasks/src/localnet.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/tasks/src/localnet.ts b/packages/tasks/src/localnet.ts index 53cfd80..ed60f0b 100644 --- a/packages/tasks/src/localnet.ts +++ b/packages/tasks/src/localnet.ts @@ -49,7 +49,6 @@ const localnet = async (args: any) => { const port = args.port || 8545; const forceKill = args.forceKill || false; - // Kill any process using the port, either with or without prompting await killProcessOnPort(port, forceKill); if (args.anvil !== "") @@ -111,13 +110,11 @@ System contract: ${addr.sytemContractZetaChain}`); fs.writeFileSync(LOCALNET_PID_FILE, process.pid.toString(), "utf-8"); } catch (error: any) { - // If initLocalnet fails, cleanup and exit console.error(ansis.red`Error initializing localnet: ${error}`); cleanup(); process.exit(1); } - // Set up cleanup on exit or signals const handleExit = (signal: string) => { console.log(`\nReceived ${signal}, shutting down...`); cleanup(); From f620bf74b073a7b3b120010a51947acca8a9a132 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 11 Sep 2024 13:11:03 +0800 Subject: [PATCH 09/20] format table --- packages/tasks/src/localnet.ts | 58 +++++++++++++++++----------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/packages/tasks/src/localnet.ts b/packages/tasks/src/localnet.ts index ed60f0b..f2f79e3 100644 --- a/packages/tasks/src/localnet.ts +++ b/packages/tasks/src/localnet.ts @@ -78,35 +78,35 @@ const localnet = async (args: any) => { try { const addr = await initLocalnet(port); - console.log(ansis.cyan` -EVM Contract Addresses -====================== - -Gateway EVM: ${addr.gatewayEVM} -ERC-20 custody: ${addr.custodyEVM} -TSS: ${addr.tssEVM} -ZETA: ${addr.zetaEVM}`); - - addr.foreignCoins - .filter((coin: any) => coin.asset !== "") - .forEach((coin: any) => { - console.log(ansis.cyan`ERC-20 ${coin.symbol}: ${coin.asset}`); - }); - - console.log(ansis.green` -ZetaChain Contract Addresses -============================ - -Gateway ZetaChain: ${addr.gatewayZetaChain} -ZETA: ${addr.zetaZetaChain} -Fungible module: ${addr.fungibleModuleZetaChain} -System contract: ${addr.sytemContractZetaChain}`); - - addr.foreignCoins.forEach((coin: any) => { - console.log( - ansis.green`ZRC-20 ${coin.symbol}: ${coin.zrc20_contract_address}` - ); - }); + const evmAddresses = { + "Gateway EVM": addr.gatewayEVM, + "ERC-20 Custody": addr.custodyEVM, + TSS: addr.tssEVM, + ZETA: addr.zetaEVM, + ...addr.foreignCoins + .filter((coin: any) => coin.asset !== "") + .reduce((acc: any, coin: any) => { + acc[`ERC-20 ${coin.symbol}`] = coin.asset; + return acc; + }, {}), + }; + + console.log(ansis.cyan("EVM Contract Addresses and Foreign ERC-20 Tokens")); + console.table(evmAddresses); + + const zetaAddresses = { + "Gateway ZetaChain": addr.gatewayZetaChain, + ZETA: addr.zetaZetaChain, + "Fungible Module": addr.fungibleModuleZetaChain, + "System Contract": addr.sytemContractZetaChain, + ...addr.foreignCoins.reduce((acc: any, coin: any) => { + acc[`ZRC-20 ${coin.symbol}`] = coin.zrc20_contract_address; + return acc; + }, {}), + }; + + console.log(ansis.green("ZetaChain Contract Addresses and ZRC-20 Tokens")); + console.table(zetaAddresses); fs.writeFileSync(LOCALNET_PID_FILE, process.pid.toString(), "utf-8"); } catch (error: any) { From ccc5e77be6834fb43b6a753df3f2fac89161baad Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 11 Sep 2024 13:13:25 +0800 Subject: [PATCH 10/20] formatting --- packages/tasks/src/localnet.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/tasks/src/localnet.ts b/packages/tasks/src/localnet.ts index f2f79e3..c8f1625 100644 --- a/packages/tasks/src/localnet.ts +++ b/packages/tasks/src/localnet.ts @@ -78,6 +78,10 @@ const localnet = async (args: any) => { try { const addr = await initLocalnet(port); + // EVM Contract Addresses + const evmHeader = "\nEVM Contract Addresses"; + console.log(ansis.cyan(`${evmHeader}\n${"=".repeat(evmHeader.length)}`)); + const evmAddresses = { "Gateway EVM": addr.gatewayEVM, "ERC-20 Custody": addr.custodyEVM, @@ -91,9 +95,12 @@ const localnet = async (args: any) => { }, {}), }; - console.log(ansis.cyan("EVM Contract Addresses and Foreign ERC-20 Tokens")); console.table(evmAddresses); + // ZetaChain Contract Addresses + const zetaHeader = "\nZetaChain Contract Addresses"; + console.log(ansis.green(`${zetaHeader}\n${"=".repeat(zetaHeader.length)}`)); + const zetaAddresses = { "Gateway ZetaChain": addr.gatewayZetaChain, ZETA: addr.zetaZetaChain, @@ -105,7 +112,6 @@ const localnet = async (args: any) => { }, {}), }; - console.log(ansis.green("ZetaChain Contract Addresses and ZRC-20 Tokens")); console.table(zetaAddresses); fs.writeFileSync(LOCALNET_PID_FILE, process.pid.toString(), "utf-8"); From 2253d2bcf5f866e0149a96de4d64bdd0bed5258b Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 11 Sep 2024 14:13:48 +0800 Subject: [PATCH 11/20] fix: when using custom block time --- packages/localnet/src/createToken.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/localnet/src/createToken.ts b/packages/localnet/src/createToken.ts index b79f7a6..e7bfb7d 100644 --- a/packages/localnet/src/createToken.ts +++ b/packages/localnet/src/createToken.ts @@ -51,6 +51,8 @@ export const createToken = async ({ deployOpts ); + await zrc20.waitForDeployment(); + if (!isGasToken) { const erc20Factory = new ethers.ContractFactory( TestERC20.abi, @@ -58,6 +60,7 @@ export const createToken = async ({ deployer ); erc20 = await erc20Factory.deploy(symbol, symbol, deployOpts); + await erc20.waitForDeployment(); const erc20Decimals = await (erc20 as any).connect(deployer).decimals(); await (erc20 as any) From c7ec285c1d6cb85d5c519104e13c784fd7954d78 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 11 Sep 2024 14:20:52 +0800 Subject: [PATCH 12/20] stop after init --- packages/tasks/src/localnet.ts | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/packages/tasks/src/localnet.ts b/packages/tasks/src/localnet.ts index c8f1625..366c6fc 100644 --- a/packages/tasks/src/localnet.ts +++ b/packages/tasks/src/localnet.ts @@ -46,16 +46,13 @@ const killProcessOnPort = async (port: number, forceKill: boolean) => { }; const localnet = async (args: any) => { - const port = args.port || 8545; - const forceKill = args.forceKill || false; - - await killProcessOnPort(port, forceKill); + await killProcessOnPort(args.port, args.forceKill); if (args.anvil !== "") - console.log(`Starting anvil on port ${port} with args: ${args.anvil}`); + console.log(`Starting anvil on port ${args.port} with args: ${args.anvil}`); const anvilProcess = exec( - `anvil --auto-impersonate --port ${port} ${args.anvil}` + `anvil --auto-impersonate --port ${args.port} ${args.anvil}` ); if (anvilProcess.stdout && anvilProcess.stderr) { @@ -63,7 +60,7 @@ const localnet = async (args: any) => { anvilProcess.stderr.pipe(process.stderr); } - await waitOn({ resources: [`tcp:127.0.0.1:${port}`] }); + await waitOn({ resources: [`tcp:127.0.0.1:${args.port}`] }); const cleanup = () => { console.log("\nShutting down anvil and cleaning up..."); @@ -76,7 +73,7 @@ const localnet = async (args: any) => { }; try { - const addr = await initLocalnet(port); + const addr = await initLocalnet(args.port); // EVM Contract Addresses const evmHeader = "\nEVM Contract Addresses"; @@ -97,7 +94,6 @@ const localnet = async (args: any) => { console.table(evmAddresses); - // ZetaChain Contract Addresses const zetaHeader = "\nZetaChain Contract Addresses"; console.log(ansis.green(`${zetaHeader}\n${"=".repeat(zetaHeader.length)}`)); @@ -115,6 +111,14 @@ const localnet = async (args: any) => { console.table(zetaAddresses); fs.writeFileSync(LOCALNET_PID_FILE, process.pid.toString(), "utf-8"); + + if (args.stopAfterInit) { + console.log( + ansis.green("Localnet successfully initialized. Stopping...") + ); + cleanup(); + process.exit(0); + } } catch (error: any) { console.error(ansis.red`Error initializing localnet: ${error}`); cleanup(); @@ -145,4 +149,8 @@ export const localnetTask = task("localnet", "Start localnet", localnet) "", types.string ) - .addFlag("forceKill", "Force kill any process on the port without prompting"); + .addFlag("forceKill", "Force kill any process on the port without prompting") + .addFlag( + "stopAfterInit", + "Stop the localnet after successful initialization" + ); From 5d5f470cd45e1b78ad79d7cf176a0ed3503fb45e Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 11 Sep 2024 14:23:05 +0800 Subject: [PATCH 13/20] ci: run localnet workflow --- .github/workflows/run.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/run.yml diff --git a/.github/workflows/run.yml b/.github/workflows/run.yml new file mode 100644 index 0000000..d90d09e --- /dev/null +++ b/.github/workflows/run.yml @@ -0,0 +1,30 @@ +name: Run Localnet + +on: + pull_request: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + start-localnet: + runs-on: ubuntu-latest + needs: build + + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "21" + registry-url: "https://registry.npmjs.org" + + - name: Install Dependencies + run: yarn + + - name: Start Localnet + run: yarn hardhat localnet --stop-after-init From 1524d74c1788d81ea96192bbf60561b764f2e593 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 11 Sep 2024 14:24:23 +0800 Subject: [PATCH 14/20] ci: fix --- .github/workflows/run.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run.yml b/.github/workflows/run.yml index d90d09e..06e863d 100644 --- a/.github/workflows/run.yml +++ b/.github/workflows/run.yml @@ -9,7 +9,7 @@ concurrency: cancel-in-progress: true jobs: - start-localnet: + start: runs-on: ubuntu-latest needs: build From 63791f9ae803227a505f91ff446c17359fc34be4 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 11 Sep 2024 14:24:44 +0800 Subject: [PATCH 15/20] ci: fix --- .github/workflows/run.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/run.yml b/.github/workflows/run.yml index 06e863d..62be063 100644 --- a/.github/workflows/run.yml +++ b/.github/workflows/run.yml @@ -11,7 +11,6 @@ concurrency: jobs: start: runs-on: ubuntu-latest - needs: build steps: - name: Checkout Repository From e79ca20d4db82dd79282cae48fef1bf7061f0115 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 11 Sep 2024 14:29:32 +0800 Subject: [PATCH 16/20] ci: fix --- packages/tasks/src/localnet.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/tasks/src/localnet.ts b/packages/tasks/src/localnet.ts index 366c6fc..7059d04 100644 --- a/packages/tasks/src/localnet.ts +++ b/packages/tasks/src/localnet.ts @@ -111,14 +111,6 @@ const localnet = async (args: any) => { console.table(zetaAddresses); fs.writeFileSync(LOCALNET_PID_FILE, process.pid.toString(), "utf-8"); - - if (args.stopAfterInit) { - console.log( - ansis.green("Localnet successfully initialized. Stopping...") - ); - cleanup(); - process.exit(0); - } } catch (error: any) { console.error(ansis.red`Error initializing localnet: ${error}`); cleanup(); @@ -138,6 +130,12 @@ const localnet = async (args: any) => { console.log("Process exiting..."); }); + if (args.stopAfterInit) { + console.log(ansis.green("Localnet successfully initialized. Stopping...")); + cleanup(); + process.exit(0); + } + await new Promise(() => {}); }; From 209ed0b7446a08c8873aca0d31246ef33535e29b Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 11 Sep 2024 14:32:30 +0800 Subject: [PATCH 17/20] ci: install foundry --- .github/workflows/run.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/run.yml b/.github/workflows/run.yml index 62be063..89e76fe 100644 --- a/.github/workflows/run.yml +++ b/.github/workflows/run.yml @@ -22,6 +22,9 @@ jobs: node-version: "21" registry-url: "https://registry.npmjs.org" + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + - name: Install Dependencies run: yarn From 1eea8b4f96e5a3c696a0a8974ea016af7632cbd0 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 11 Sep 2024 14:36:28 +0800 Subject: [PATCH 18/20] throw error if anvil not found --- .github/workflows/run.yml | 4 ++-- packages/tasks/src/localnet.ts | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run.yml b/.github/workflows/run.yml index 89e76fe..d2899d6 100644 --- a/.github/workflows/run.yml +++ b/.github/workflows/run.yml @@ -22,8 +22,8 @@ jobs: node-version: "21" registry-url: "https://registry.npmjs.org" - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 + # - name: Install Foundry + # uses: foundry-rs/foundry-toolchain@v1 - name: Install Dependencies run: yarn diff --git a/packages/tasks/src/localnet.ts b/packages/tasks/src/localnet.ts index 7059d04..281932e 100644 --- a/packages/tasks/src/localnet.ts +++ b/packages/tasks/src/localnet.ts @@ -46,6 +46,17 @@ const killProcessOnPort = async (port: number, forceKill: boolean) => { }; const localnet = async (args: any) => { + try { + execSync("which anvil"); + } catch (error) { + console.error( + ansis.red( + "Error: 'anvil' not found. Please install Foundry: https://getfoundry.sh" + ) + ); + process.exit(1); + } + await killProcessOnPort(args.port, args.forceKill); if (args.anvil !== "") From 34a822aec49811b47c211f20932c6bd083b7ba69 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 11 Sep 2024 14:38:12 +0800 Subject: [PATCH 19/20] add install foundry back, now check should pass --- .github/workflows/run.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run.yml b/.github/workflows/run.yml index d2899d6..89e76fe 100644 --- a/.github/workflows/run.yml +++ b/.github/workflows/run.yml @@ -22,8 +22,8 @@ jobs: node-version: "21" registry-url: "https://registry.npmjs.org" - # - name: Install Foundry - # uses: foundry-rs/foundry-toolchain@v1 + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 - name: Install Dependencies run: yarn From 136f37392046215c5527cb48d792928165f57c72 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 11 Sep 2024 21:59:29 +0800 Subject: [PATCH 20/20] remove file check --- packages/tasks/src/stop.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/tasks/src/stop.ts b/packages/tasks/src/stop.ts index 21124ce..9fb1a1f 100644 --- a/packages/tasks/src/stop.ts +++ b/packages/tasks/src/stop.ts @@ -14,12 +14,8 @@ const localnetStop = async (args: any) => { try { process.kill(Number(pid)); console.log(ansis.green(`Successfully stopped localnet (PID: ${pid})`)); - - // Unlink PID file only if it exists - if (fs.existsSync(LOCALNET_PID_FILE)) { - fs.unlinkSync(LOCALNET_PID_FILE); - console.log(ansis.green(`PID file ${LOCALNET_PID_FILE} removed.`)); - } + fs.unlinkSync(LOCALNET_PID_FILE); + console.log(ansis.green(`PID file ${LOCALNET_PID_FILE} removed.`)); } catch (err) { console.error(ansis.red(`Failed to stop localnet: ${err}`)); }