Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/plugin-misc/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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 = {
Expand Down Expand Up @@ -248,6 +250,7 @@ const MiscPlugin = {
get_verification_job_status,
get_verified_programs,
verify_program,
automated_verify_program,
},

// Combine all actions
Expand Down Expand Up @@ -315,6 +318,7 @@ const MiscPlugin = {
getVerificationJobStatusAction,
getVerifiedProgramsAction,
verifyProgramAction,
automatedVerifyProgramAction,
],

// Initialize function
Expand Down
Original file line number Diff line number Diff line change
@@ -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<string, any>) => {
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;
Original file line number Diff line number Diff line change
@@ -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}`);
}
}
1 change: 1 addition & 0 deletions packages/plugin-misc/src/ottersec/tools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";