Repository: BuidlGuidl/ctf.buidlguidl.com
Pull request #21: extension tweaks
Author: login: technophile-04
Created: 2025-05-21T12:43:00Z | Merged: 2025-05-23T12:36:07Z

### Description: 

TODO: 

- [X] Tweak stuff in extension to be inlined with latest SE-2 changes 
- [x] Scripts dir
   - [x]  make the scripts dir work with encrypted PKs for hardhat and foundry


Diff:
diff --git a/README.md b/README.md
index b71bd63..55327a8 100644
--- a/README.md
+++ b/README.md
@@ -191,12 +191,18 @@ which helps you interface with the Blockchain using Typescript scripts.
   - `example.ts`: A basic example script demonstrating how to interact with contracts.
 - `contracts/`: Contains deployed contracts ABIs and addresses. (generated by `yarn deploy`)
 
-To run scripts, navigate to the scripts package and run the script using `yarn tsx`:
+To run the script in the local chain (test account PK with loaded funds):
 
 ```shell
 cd packages/scripts
 yarn tsx src/example.ts
 ```
 
-- You can generate a PK for the deployer account with `yarn generate` or fill the `.env` file with your own PK to run the transactions.
+To run the script with your own PK (generated via `yarn generate` or `yarn account:import`):
+
+```shell
+cd packages/scripts
+yarn tsx-with-pk src/example.ts
+```
+
 - Check the `TARGET_CHAIN` variable in the example script to see how to deploy to the live network. (default is localhost)
diff --git a/extension/README.md.args.mjs b/extension/README.md.args.mjs
index 6fd9ae8..c863987 100644
--- a/extension/README.md.args.mjs
+++ b/extension/README.md.args.mjs
@@ -193,12 +193,18 @@ which helps you interface with the Blockchain using Typescript scripts.
   - \`example.ts\`: A basic example script demonstrating how to interact with contracts.
 - \`contracts/\`: Contains deployed contracts ABIs and addresses. (generated by \`yarn deploy\`)
 
-To run scripts, navigate to the scripts package and run the script using \`yarn tsx\`:
+To run the script in the local chain (test account PK with loaded funds): 
 
 \`\`\`shell
 cd packages/scripts
 yarn tsx src/example.ts
 \`\`\`
 
-- You can generate a PK for the deployer account with \`yarn generate\` or fill the \`.env\` file with your own PK to run the transactions.
+To run the script with your own PK (generated via \`yarn generate\` or \`yarn account:import\`):
+
+\`\`\`shell
+cd packages/scripts
+yarn tsx-with-pk src/example.ts
+\`\`\`
+
 - Check the \`TARGET_CHAIN\` variable in the example script to see how to deploy to the live network. (default is localhost)`;
diff --git a/extension/packages/hardhat/deploy/02_deploy_challenge_2_solution.ts b/extension/packages/hardhat/deploy/02_deploy_challenge_2_solution.ts
index 73ae8db..2b8b580 100644
--- a/extension/packages/hardhat/deploy/02_deploy_challenge_2_solution.ts
+++ b/extension/packages/hardhat/deploy/02_deploy_challenge_2_solution.ts
@@ -9,7 +9,7 @@ import { DeployFunction } from "hardhat-deploy/types";
 const deployChallengeSolution: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
   // This is the deployer account:
   // - localhost: hardhat account 0
-  // - live network: PK in .env file (use `yarn generate` to generate one or fill the .env file with your own PK)
+  // - live network: encrypted PK in .env file (use `yarn generate` to generate one or `yarn account:import` to import your own PK)
   //
   //   const { deployer } = await hre.getNamedAccounts();
   //   const { deploy } = hre.deployments;
diff --git a/extension/packages/nextjs/app/page.tsx.args.mjs b/extension/packages/nextjs/app/page.tsx.args.mjs
index 5a45a8a..4defbff 100644
--- a/extension/packages/nextjs/app/page.tsx.args.mjs
+++ b/extension/packages/nextjs/app/page.tsx.args.mjs
@@ -1,14 +1,14 @@
 export const imports = `import { FlagTracker } from "~~/components/FlagTracker";`;
 
 export const description = `
-  <div className="mt-8 max-w-2xl mx-auto">
+          <div className="mt-8 max-w-2xl mx-auto">
             <p className="text-base-content mb-4">
               This stack contains all the tools you need to play the CTF locally, from contract debugging to scripting
               and transaction tracking.
             </p>
             <p className="text-base-content">
-              Once you're ready to capture real flags, you'll need to deploy your solutions to Optimism and track your
-              progress at{" "}
+              Once you&apos;re ready to capture real flags, you&apos;ll need to deploy your solutions to Optimism and
+              track your progress at{" "}
               <a href="https://ctf.buidlguidl.com" target="_blank" rel="noopener noreferrer" className="link">
                 ctf.buidlguidl.com
               </a>
diff --git a/extension/packages/nextjs/components/FlagTracker.tsx b/extension/packages/nextjs/components/FlagTracker.tsx
index c45cf15..cd880ee 100644
--- a/extension/packages/nextjs/components/FlagTracker.tsx
+++ b/extension/packages/nextjs/components/FlagTracker.tsx
@@ -16,14 +16,21 @@ export const FlagTracker = () => {
     filters: {
       minter: connectedAddress,
     },
+    enabled: !!connectedAddress,
   });
 
-  const userMintedChallengeIds = new Set(userFlags?.map(event => event.args.challengeId?.toString()) || []);
+  const userMintedChallengeIds = new Set(userFlags?.map(event => event?.args?.challengeId?.toString()) || []);
 
   const allChallengeIds = Array.from({ length: 12 }, (_, i) => (i + 1).toString());
 
   const remainingFlags = allChallengeIds.filter(id => !userMintedChallengeIds.has(id));
 
+  if (!connectedAddress) {
+    return (
+      <div className="bg-base-100 p-6 rounded-lg shadow-md">Connect your wallet to view your collected flags.</div>
+    );
+  }
+
   return (
     <div className="bg-base-100 p-6 rounded-lg shadow-md">
       <h2 className="text-2xl font-bold mb-4">Flag Tracker 🚩</h2>
@@ -36,12 +43,12 @@ export const FlagTracker = () => {
             {userFlags && userFlags.length > 0 ? (
               userFlags.map(event => (
                 <div
-                  key={event.args.tokenId?.toString()}
+                  key={event?.args?.tokenId?.toString()}
                   className="flex items-center space-x-2 bg-success/20 p-2 rounded"
                 >
                   <span className="text-success">✓</span>
                   <span>
-                    Flag #{event.args.challengeId?.toString()} (Token ID: {event.args.tokenId?.toString()})
+                    Flag #{event?.args?.challengeId?.toString()} (Token ID: {event?.args?.tokenId?.toString()})
                   </span>
                 </div>
               ))
@@ -62,7 +69,7 @@ export const FlagTracker = () => {
                 </div>
               ))
             ) : (
-              <p className="text-sm text-base-content/70">Congratulations! You've captured all flags! 🎉</p>
+              <p className="text-sm text-base-content/70">Congratulations! You&apos;ve captured all flags! 🎉</p>
             )}
           </div>
         </div>
diff --git a/extension/packages/scripts/package.json b/extension/packages/scripts/package.json
index 818e786..21762d3 100644
--- a/extension/packages/scripts/package.json
+++ b/extension/packages/scripts/package.json
@@ -6,10 +6,13 @@
   "scripts": {
     "build": "tsc",
     "start": "node dist/index.js",
-    "type-check": "tsc --noEmit"
+    "type-check": "tsc --noEmit",
+    "tsx-with-pk": "tsx proxy/index.ts"
   },
   "dependencies": {
+    "@inquirer/password": "^4.0.13",
     "dotenv": "^16.4.5",
+    "ethers": "^6.13.2",
     "viem": "^2.21.5"
   },
   "devDependencies": {
diff --git a/extension/packages/scripts/proxy/foundry.ts b/extension/packages/scripts/proxy/foundry.ts
new file mode 100644
index 0000000..d12ac6c
--- /dev/null
+++ b/extension/packages/scripts/proxy/foundry.ts
@@ -0,0 +1,55 @@
+import { listKeystores } from "./listKeystores.js";
+import { execSync, spawn } from "child_process";
+import { fileURLToPath } from "url";
+import { dirname } from "path";
+
+if (!process.argv[2]) {
+  console.error("Usage: yarn tsx-with-pk src/yourScript.ts");
+  process.exit(1);
+}
+
+const targetScript = process.argv[2];
+const extraArgs = process.argv.slice(3);
+
+async function main() {
+  // 1. Select keystore
+  const selectedKeystore = await listKeystores(
+    "Select a keystore to use for deployment (enter the number, e.g., 1): "
+  );
+  if (!selectedKeystore) {
+    console.error("❌ No keystore selected");
+    process.exit(1);
+  }
+
+  // 2. Decrypt keystore
+  let revealPKResult: string;
+  try {
+    const keystorePath = `${process.env.HOME}/.foundry/keystores/${selectedKeystore}`;
+    const revealPKCommand = `cast wallet decrypt-keystore ${keystorePath}`;
+    revealPKResult = execSync(revealPKCommand, { stdio: [0, "pipe", "pipe"] })
+      .toString()
+      .trim();
+  } catch (error) {
+    console.error("\n❌ Failed to decrypt keystore. Wrong password?");
+    process.exit(1);
+  }
+
+  // 3. Extract private key
+  const match = revealPKResult.match(/private key is:\s*(0x[a-fA-F0-9]{64})/);
+  if (!match) {
+    console.error("❌ Could not extract private key from output");
+    process.exit(1);
+  }
+  const privateKey = match[1];
+
+  // 4. Set env var and spawn child process
+  process.env.__RUNTIME_DEPLOYER_PRIVATE_KEY = privateKey;
+  const child = spawn("tsx", [targetScript, ...extraArgs], {
+    stdio: "inherit",
+    env: process.env,
+    shell: process.platform === "win32",
+  });
+  child.on("exit", (code) => process.exit(code || 0));
+}
+
+main().catch(console.error);
diff --git a/extension/packages/scripts/proxy/hardhat.ts b/extension/packages/scripts/proxy/hardhat.ts
new file mode 100644
index 0000000..0dd062b
--- /dev/null
+++ b/extension/packages/scripts/proxy/hardhat.ts
@@ -0,0 +1,46 @@
+import * as dotenv from "dotenv";
+import { dirname, resolve } from "path";
+import { fileURLToPath } from "url";
+import { Wallet } from "ethers";
+import password from "@inquirer/password";
+import { spawn } from "child_process";
+
+const __dirname = dirname(fileURLToPath(import.meta.url));
+dotenv.config({ path: resolve(__dirname, "../../hardhat/.env") });
+
+if (!process.argv[2]) {
+  console.error("Usage: yarn tsx-with-pk src/yourScript.ts");
+  process.exit(1);
+}
+
+const targetScript = process.argv[2];
+const extraArgs = process.argv.slice(3);
+
+async function main() {
+  const encryptedKey = process.env.DEPLOYER_PRIVATE_KEY_ENCRYPTED;
+  if (!encryptedKey) {
+    console.log(
+      "\nNo encrypted key found, make sure to generate (`yarn generate`) or import account (`yarn account:import`) first by going to root directory and running this commands\n",
+    );
+    return;
+  }
+
+  // Prompt for password and decrypt
+  const pass = await password({
+    message: "Enter password to decrypt private key:",
+  });
+  try {
+    const wallet = await Wallet.fromEncryptedJson(encryptedKey, pass);
+    process.env.__RUNTIME_DEPLOYER_PRIVATE_KEY = wallet.privateKey;
+    const child = spawn("tsx", [targetScript, ...extraArgs], {
+      stdio: "inherit",
+      env: process.env,
+      shell: process.platform === "win32",
+    });
+    child.on("exit", (code) => process.exit(code || 0));
+  } catch (e) {
+    console.error("Failed to decrypt private key. Wrong password?");
+    process.exit(1);
+  }
+}
+main().catch(console.error);
diff --git a/extension/packages/scripts/proxy/index.ts b/extension/packages/scripts/proxy/index.ts
new file mode 100644
index 0000000..51b5711
--- /dev/null
+++ b/extension/packages/scripts/proxy/index.ts
@@ -0,0 +1,29 @@
+import { existsSync } from "fs";
+import { spawn } from "child_process";
+import { join, dirname } from "path";
+import { fileURLToPath } from "url";
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = dirname(__filename);
+
+if (!process.argv[2]) {
+  console.error("Usage: yarn tsx-with-pk src/yourScript.ts");
+  process.exit(1);
+}
+
+const targetScript = process.argv[2];
+const extraArgs = process.argv.slice(3);
+
+// Check for hardhat.ts, otherwise use foundry.ts
+const hardhatPath = join(__dirname, "hardhat.ts");
+const foundryPath = join(__dirname, "foundry.ts");
+
+const scriptToRun = existsSync(hardhatPath) ? hardhatPath : foundryPath;
+
+const child = spawn("tsx", [scriptToRun, targetScript, ...extraArgs], {
+  stdio: "inherit",
+  env: process.env,
+  shell: process.platform === "win32",
+});
+
+child.on("exit", (code) => process.exit(code || 0));
diff --git a/extension/packages/scripts/proxy/listKeystores.ts b/extension/packages/scripts/proxy/listKeystores.ts
new file mode 100644
index 0000000..ab8b6c8
--- /dev/null
+++ b/extension/packages/scripts/proxy/listKeystores.ts
@@ -0,0 +1,67 @@
+import { readdirSync } from "fs";
+import { join } from "path";
+import readline from "readline";
+import { fileURLToPath } from "url";
+
+export async function listKeystores(
+  selectMessage = "Select a keystore (enter the number, e.g., 1):"
+): Promise<string | undefined> {
+  const rl = readline.createInterface({
+    input: process.stdin,
+    output: process.stdout,
+  });
+
+  const keystorePath = join(process.env.HOME || "", ".foundry", "keystores");
+
+  try {
+    const keystores = readdirSync(keystorePath).filter(
+      (keystore) => keystore !== "scaffold-eth-default"
+    );
+
+    if (keystores.length === 0) {
+      console.error(
+        "\n❌ No keystores found in ~/.foundry/keystores, please create a new keystore by running:"
+      );
+      console.log("\n\tyarn account:generate\n");
+      process.exit(1);
+    }
+
+    console.log("\n💼 Available keystores:");
+
+    keystores.forEach((keystore, index) => {
+      console.log(`${index + 1}. ${keystore}`);
+    });
+
+    const answer = await new Promise<string>((resolve) => {
+      rl.question(`\n${selectMessage}`, resolve);
+    });
+
+    const selection = parseInt(answer);
+
+    if (isNaN(selection) || selection < 1 || selection > keystores.length) {
+      console.error("\n❌ Invalid selection");
+      process.exit(1);
+    }
+
+    const selectedKeystore = keystores[selection - 1];
+
+    return selectedKeystore;
+  } catch (error: any) {
+    console.error("\n❌ Error reading keystores:", error);
+    process.exit(1);
+  } finally {
+    rl.close();
+  }
+}
+
+// Run the selection if this script is called directly
+if (process.argv[1] === fileURLToPath(import.meta.url)) {
+  listKeystores()
+    .then((keystore) => {
+      console.log("\n🔑 Selected keystore:", keystore);
+    })
+    .catch((error) => {
+      console.error(error);
+      process.exit(1);
+    });
+}
diff --git a/extension/packages/scripts/src/example.ts b/extension/packages/scripts/src/example.ts
index 54451ed..536d986 100644
--- a/extension/packages/scripts/src/example.ts
+++ b/extension/packages/scripts/src/example.ts
@@ -5,20 +5,24 @@ import {
   http,
 } from "viem";
 import { privateKeyToAccount } from "viem/accounts";
-import { hardhat } from "viem/chains";
+import * as chains from "viem/chains";
 import * as dotenv from "dotenv";
 import { contractsData } from "../contracts/types";
 
 dotenv.config();
 
 // If you want to deploy to optimism:
-// 1. import { optimism } from "viem/chains";
-// 2. set TARGET_CHAIN = optimism;
-const TARGET_CHAIN = hardhat;
+// set TARGET_CHAIN = chains.optimism;
+const TARGET_CHAIN = chains.hardhat;
 
-// We use the private key of account generated via `yarn generate`, if not present we use default hardhat/foundry 5th account
-const MY_WALLET_PK = (process.env.DEPLOYER_PRIVATE_KEY ??
-  "0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba") as `0x${string}`;
+const LOCAL_CHAIN_5TH_ACCOUNT_PK =
+  "0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba" as const;
+
+// Run this script directly `yarn tsx src/example.ts` in local chain (uses test account PK with loaded funds).
+// Run this script via `yarn tsx-with-pk --file src/example.ts` to use your own PK (generated via `yarn generate` or `yarn account:import`)
+const MY_WALLET_PK =
+  (process.env.__RUNTIME_DEPLOYER_PRIVATE_KEY as `0x${string}`) ||
+  LOCAL_CHAIN_5TH_ACCOUNT_PK;
 const myWalletAccount = privateKeyToAccount(MY_WALLET_PK);
 
 // We need wallet client to do write operations/send transactions
@@ -48,7 +52,7 @@ async function main() {
   // Writing to a contract
   const txHash = await challenge1Contract.write.registerMe(["Bob"]);
   console.log(
-    `📝 Called 'registerMe' function with address ${myWalletAccount.address} and name 'Bob', txHash: ${txHash}`,
+    `📝 Called 'registerMe' function with address ${myWalletAccount.address} and name 'Bob', txHash: ${txHash}`
   );
 
   // Waits for the Transaction to be included on a Block (one confirmation)


Reviews:
user: login: carletex
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-22T14:50:20Z
user: login: carletex
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-22T14:52:08Z
user: login: carletex
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-22T15:24:24Z
user: login: carletex
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-22T15:33:26Z
user: login: technophile-04
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-22T16:58:48Z
user: login: technophile-04
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-22T16:59:23Z
user: login: technophile-04
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-22T17:02:04Z
user: login: carletex
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-23T12:35:54Z

Review comments:
path: extension/packages/nextjs/components/FlagTracker.tsx
user: login: carletex
body: I think we need to add 

```
enabled: !!connectedAddress,
```

to the `useScaffoldEventHistory` hook params. If not, I'm getting ALL the flags when I'm on optimism and no wallet connected. (I guess minter = null means all the minter addresses :D)

![image](https://github.com/user-attachments/assets/495c292b-2d2b-4694-8bf3-e4cd868fe2b6)



created_at: 2025-05-22T14:50:20Z
author_association: MEMBER
path: extension/packages/nextjs/components/FlagTracker.tsx
user: login: carletex
body: We could also return early with something like:

```tsx
  if (!connectedAddress) {
    return (
      <div className="bg-base-100 p-6 rounded-lg shadow-md">Connect your wallet to view your collected flags.</div>
    );
  }
```
created_at: 2025-05-22T14:52:08Z
author_association: MEMBER
path: extension/packages/scripts/src/example.ts
user: login: carletex
body: For the target chain...Instead of:

```ts
// If you want to deploy to optimism:
// 1. import { optimism } from "viem/chains";
// 2. set TARGET_CHAIN = optimism;
```

Could we just import `import * as chains from "viem/chains";` as in scaffold.config?

So we can do

```ts
const TARGET_CHAIN = chains.optimism;
```
created_at: 2025-05-22T15:24:24Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,46 @@
+import * as dotenv from "dotenv";
+import { dirname, resolve } from "path";
+import { fileURLToPath } from "url";
+import { Wallet } from "ethers";
+import password from "@inquirer/password";
+import { spawn } from "child_process";
+
+const __dirname = dirname(fileURLToPath(import.meta.url));
+dotenv.config({ path: resolve(__dirname, "../hardhat/.env") });
path: extension/packages/scripts/proxy/hardhat.ts
user: login: carletex
body: ```
No encrypted key found, make sure to generate (`yarn generate`) or import account (`yarn account:import`) first b
y going to root directory and running this commands
```

Are missing an extra `../`? I think we need to go 2 levels up: proxy & scripts
created_at: 2025-05-22T15:33:26Z
author_association: MEMBER
path: extension/packages/nextjs/components/FlagTracker.tsx
user: login: technophile-04
body: Ohh yes tysm! Fixed it at https://github.com/BuidlGuidl/ctf.buidlguidl.com/pull/21/commits/b6cab51d64591a12e9a3d729207a4381780ef31c

![image](https://github.com/user-attachments/assets/52bd4d95-a0a9-4f97-9861-702ca2913dcc)

![image](https://github.com/user-attachments/assets/d705583f-82c7-489e-88f6-f460b76b336c)

created_at: 2025-05-22T16:58:48Z
author_association: MEMBER
path: extension/packages/scripts/src/example.ts
user: login: technophile-04
body: Ohhh actually! thanks! Updated it at https://github.com/BuidlGuidl/ctf.buidlguidl.com/pull/21/commits/124af70d132de52849c22d1791ba9338b90f5d04
created_at: 2025-05-22T16:59:23Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,46 @@
+import * as dotenv from "dotenv";
+import { dirname, resolve } from "path";
+import { fileURLToPath } from "url";
+import { Wallet } from "ethers";
+import password from "@inquirer/password";
+import { spawn } from "child_process";
+
+const __dirname = dirname(fileURLToPath(import.meta.url));
+dotenv.config({ path: resolve(__dirname, "../hardhat/.env") });
path: extension/packages/scripts/proxy/hardhat.ts
user: login: technophile-04
body: Ohhh yes yes :( not sure when I changed(probably cursort tab) but it would should work now 🙌 

![image](https://github.com/user-attachments/assets/24c46008-a900-4ec7-866c-fba957a71197)

created_at: 2025-05-22T17:02:04Z
author_association: MEMBER

PR comments:
user: login: vercel[bot]
created_at: 2025-05-21T12:43:04Z
body: [vc]: #Oz1GkPWhAAS4pHAGScv2d+trHho7jBsfxQZO51DmGmw=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJjdGYtZGV2Y29uIiwicm9vdERpcmVjdG9yeSI6InBhY2thZ2VzL25leHRqcyIsImxpdmVGZWVkYmFjayI6eyJyZXNvbHZlZCI6MCwidW5yZXNvbHZlZCI6MCwidG90YWwiOjAsImxpbmsiOiIifSwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL2J1aWRsZ3VpZGxkYW8vY3RmLWRldmNvbi9HQ3BoRXFVaWRzekJDY2IzQ1RTSERXekVmVjlLIiwibmV4dENvbW1pdFN0YXR1cyI6IklHTk9SRUQifSx7Im5hbWUiOiJjdGYuYnVpZGxndWlkbC5jb20iLCJyb290RGlyZWN0b3J5IjoicGFja2FnZXMvbmV4dGpzIiwibGl2ZUZlZWRiYWNrIjp7InJlc29sdmVkIjowLCJ1bnJlc29sdmVkIjowLCJ0b3RhbCI6MCwibGluayI6IiJ9LCJpbnNwZWN0b3JVcmwiOiJodHRwczovL3ZlcmNlbC5jb20vYnVpZGxndWlkbGRhby9jdGYuYnVpZGxndWlkbC5jb20vQWF2d3NBa3Z2TlVDRW5EVEQ5b0NZRWpMUk5meiIsInByZXZpZXdVcmwiOiIiLCJuZXh0Q29tbWl0U3RhdHVzIjoiRkFJTEVEIn1dfQ==
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Comments | Updated (UTC) |
| :--- | :----- | :------ | :------- | :------ |
| **ctf.buidlguidl.com** | ❌ Failed ([Inspect](https://vercel.com/buidlguidldao/ctf.buidlguidl.com/AavwsAkvvNUCEnDTD9oCYEjLRNfz)) |  |  | May 22, 2025 4:53pm |

<details><summary>1 Skipped Deployment</summary>

| Name | Status | Preview | Comments | Updated (UTC) |
| :--- | :----- | :------ | :------- | :------ |
| **ctf-devcon** | ⬜️ Ignored ([Inspect](https://vercel.com/buidlguidldao/ctf-devcon/GCphEqUidszBCcb3CTSHDWzEfV9K)) |  |  | May 22, 2025 4:53pm |
</details>



author_association: NONE
user: login: technophile-04
created_at: 2025-05-22T12:50:54Z
body: Just the tweaks which we discussed over the call 🙌 

- Removing `--file` arg. 
- Aborting if encrypted key is not present (in hardhat) 
- tweaking the `tsx-with-pk` command
author_association: MEMBER