diff --git a/packages/plugin-misc/src/index.ts b/packages/plugin-misc/src/index.ts index e09fb333b..d8e9b167b 100644 --- a/packages/plugin-misc/src/index.ts +++ b/packages/plugin-misc/src/index.ts @@ -168,6 +168,7 @@ import { get_verification_job_status, get_verified_programs, verify_program, + automated_verify_program, } from "./ottersec/tools"; import createVerificationPdaAction from "./ottersec/actions/createVerificationPda"; @@ -177,6 +178,7 @@ import getProgramVerificationStatusAction from "./ottersec/actions/getProgramVer import getVerificationJobStatusAction from "./ottersec/actions/getVerificationJobStatus"; import getVerifiedProgramsAction from "./ottersec/actions/getVerifiedPrograms"; import verifyProgramAction from "./ottersec/actions/verifyProgram"; +import automatedVerifyProgramAction from "./ottersec/actions/automatedVerifyProgram"; // Define and export the plugin const MiscPlugin = { @@ -248,6 +250,7 @@ const MiscPlugin = { get_verification_job_status, get_verified_programs, verify_program, + automated_verify_program, }, // Combine all actions @@ -315,6 +318,7 @@ const MiscPlugin = { getVerificationJobStatusAction, getVerifiedProgramsAction, verifyProgramAction, + automatedVerifyProgramAction, ], // Initialize function diff --git a/packages/plugin-misc/src/ottersec/actions/automatedVerifyProgram.ts b/packages/plugin-misc/src/ottersec/actions/automatedVerifyProgram.ts new file mode 100644 index 000000000..610a28033 --- /dev/null +++ b/packages/plugin-misc/src/ottersec/actions/automatedVerifyProgram.ts @@ -0,0 +1,58 @@ +import { Action, SolanaAgentKit } from "solana-agent-kit"; +import { z } from "zod"; +import { automated_verify_program } from "../tools/automated_verify_program"; + +const automatedVerifyProgramAction: Action = { + name: "AUTOMATED_VERIFY_PROGRAM_ACTION", + description: + "Automatically verify a Solana program using its GitHub repository and program ID. This tool fetches the latest commit hash and deployment slot automatically.", + similes: [ + "verify program from repo", + "automatic solana program verification", + "sign verification pda for repo", + ], + examples: [ + [ + { + input: { + programId: "PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY", + repoUrl: "https://github.com/Ellipsis-Labs/phoenix-v1", + }, + output: { + status: "success", + data: { + signature: "5Kj...", + pda: "2CN...", + }, + message: "Solana program verification PDA is successfully generated", + }, + explanation: "The agent automatically fetched the commit hash and deployment slot to sign the verification PDA.", + }, + ], + ], + schema: z.object({ + programId: z.string(), + repoUrl: z.string().url(), + }), + handler: async (agent: SolanaAgentKit, input: Record) => { + try { + const { programId, repoUrl } = input; + + const result = await automated_verify_program(agent, programId, repoUrl); + + return { + status: "success", + data: result, + message: "Solana program verification PDA is successfully generated", + }; + } catch (error: any) { + return { + status: "error", + message: `Failed to automate program verification: ${error.message}`, + code: "AUTOMATED_VERIFY_PROGRAM_FAILED", + }; + } + }, +}; + +export default automatedVerifyProgramAction; diff --git a/packages/plugin-misc/src/ottersec/tools/automated_verify_program.ts b/packages/plugin-misc/src/ottersec/tools/automated_verify_program.ts new file mode 100644 index 000000000..89b6565d8 --- /dev/null +++ b/packages/plugin-misc/src/ottersec/tools/automated_verify_program.ts @@ -0,0 +1,50 @@ +import { SolanaAgentKit } from "solana-agent-kit"; +import { PublicKey } from "@solana/web3.js"; +import { create_verification_pda } from "./create_verification_pda"; + +/** + * @name automated_verify_program + * @description Automatically verify a Solana program by fetching metadata from GitHub and Solana + * @param agent + * @param programId + * @param repoUrl + */ +export async function automated_verify_program( + agent: SolanaAgentKit, + programId: string, + repoUrl: string +) { + try { + // 1. Fetch latest commit hash from GitHub + // Example: https://github.com/owner/repo -> api.github.com/repos/owner/repo/commits + const repoPath = repoUrl.replace("https://github.com/", ""); + const githubResponse = await fetch(`https://api.github.com/repos/${repoPath}/commits/main`); + const githubData = await githubResponse.json(); + const commitHash = githubData.sha; + + // 2. Fetch deployment slot from Solana + const programPubkey = new PublicKey(programId); + const accountInfo = await agent.connection.getParsedAccountInfo(programPubkey); + if (!accountInfo.value) throw new Error("Program not found"); + + // @ts-ignore + const programDataAddress = accountInfo.value.data.parsed.info.programData; + const programDataInfo = await agent.connection.getParsedAccountInfo(new PublicKey(programDataAddress)); + // @ts-ignore + const deploySlot = programDataInfo.value.data.parsed.info.slot; + + // 3. Call the existing PDA creation tool + // We'll use some sensible defaults for version and args + const result = await create_verification_pda(agent, programId, { + version: "0.1.0", // Default or could be fetched from Cargo.toml + gitUrl: repoUrl, + commit: commitHash, + args: [], // Default empty args + deploySlot: Number(deploySlot), + }); + + return result; + } catch (error: any) { + throw new Error(`Automated verification failed: ${error.message}`); + } +} diff --git a/packages/plugin-misc/src/ottersec/tools/index.ts b/packages/plugin-misc/src/ottersec/tools/index.ts index b1f69b68e..60d0c4ddc 100644 --- a/packages/plugin-misc/src/ottersec/tools/index.ts +++ b/packages/plugin-misc/src/ottersec/tools/index.ts @@ -5,3 +5,4 @@ export * from "./get_program_verification_status"; export * from "./get_verification_job_status"; export * from "./get_verified_programs"; export * from "./verify_program"; +export * from "./automated_verify_program";