diff --git a/packages/plugin-defi/src/blueprint/actions/blueprintCheckAccounts.ts b/packages/plugin-defi/src/blueprint/actions/blueprintCheckAccounts.ts new file mode 100644 index 000000000..5d39cf2fc --- /dev/null +++ b/packages/plugin-defi/src/blueprint/actions/blueprintCheckAccounts.ts @@ -0,0 +1,45 @@ +import type { Action, SolanaAgentKit } from "solana-agent-kit"; +import { z } from "zod"; +import { blueprintCheckAccounts } from "../tools"; + +export const blueprintCheckAccountsAction: Action = { + name: "CHECK_BLUEPRINT_STAKE_ACCOUNTS", + similes: [ + "check Blueprint stake accounts", + "list Blueprint stakes", + "get my Blueprint staking status", + ], + description: + "Check all stake accounts delegated to Blueprint validator for the agent's wallet. Returns account status, balance, and epoch timing for each stake account.", + examples: [ + [ + { + input: {}, + output: { + status: "success", + message: "Found 2 Blueprint stake accounts", + accounts: [], + }, + explanation: + "List all stake accounts for the agent's wallet that are delegated to Blueprint", + }, + ], + ], + schema: z.object({}), + handler: async (agent: SolanaAgentKit, _input: Record) => { + try { + const data = await blueprintCheckAccounts(agent); + + return { + status: "success", + message: `Found ${data.stakeAccounts?.length ?? 0} Blueprint stake accounts`, + ...data, + }; + } catch (error: any) { + return { + status: "error", + message: `Failed to check Blueprint stake accounts: ${error.message}`, + }; + } + }, +}; diff --git a/packages/plugin-defi/src/blueprint/actions/blueprintDonate.ts b/packages/plugin-defi/src/blueprint/actions/blueprintDonate.ts new file mode 100644 index 000000000..b975f4c10 --- /dev/null +++ b/packages/plugin-defi/src/blueprint/actions/blueprintDonate.ts @@ -0,0 +1,51 @@ +import type { Action, SolanaAgentKit } from "solana-agent-kit"; +import { z } from "zod"; +import { blueprintDonate } from "../tools"; + +export const blueprintDonateAction: Action = { + name: "DONATE_TO_BLUEPRINT", + similes: [ + "donate to Blueprint", + "support Blueprint staking", + "tip Blueprint validator", + ], + description: + "Donate SOL to Blueprint to support development of the agentic staking platform. Blueprint is free for all agents — donations help maintain the infrastructure.", + examples: [ + [ + { + input: { + amountSol: 0.1, + }, + output: { + status: "success", + message: "Successfully donated 0.1 SOL to Blueprint", + signature: "5abc...def", + }, + explanation: "Donate 0.1 SOL to support Blueprint development", + }, + ], + ], + schema: z.object({ + amountSol: z + .number() + .positive() + .describe("Amount of SOL to donate to Blueprint"), + }), + handler: async (agent: SolanaAgentKit, input: Record) => { + try { + const signature = await blueprintDonate(agent, input.amountSol); + + return { + status: "success", + message: `Successfully donated ${input.amountSol} SOL to Blueprint`, + signature, + }; + } catch (error: any) { + return { + status: "error", + message: `Blueprint donation failed: ${error.message}`, + }; + } + }, +}; diff --git a/packages/plugin-defi/src/blueprint/actions/blueprintGetValidator.ts b/packages/plugin-defi/src/blueprint/actions/blueprintGetValidator.ts new file mode 100644 index 000000000..8733bac0b --- /dev/null +++ b/packages/plugin-defi/src/blueprint/actions/blueprintGetValidator.ts @@ -0,0 +1,47 @@ +import type { Action, SolanaAgentKit } from "solana-agent-kit"; +import { z } from "zod"; +import { blueprintGetValidator } from "../tools"; + +export const blueprintGetValidatorAction: Action = { + name: "GET_BLUEPRINT_VALIDATOR_INFO", + similes: [ + "get Blueprint validator info", + "check Blueprint APY", + "Blueprint validator stats", + "Blueprint staking APY", + ], + description: + "Get Blueprint validator information including live APY (~6%), vote success rate, active stake, commission, and infrastructure details. Use this to evaluate the validator before staking.", + examples: [ + [ + { + input: {}, + output: { + status: "success", + message: "Blueprint validator info fetched", + name: "Blueprint", + totalApy: 6.1, + voteSuccess: 99.8, + }, + explanation: "Get live stats for Blueprint validator", + }, + ], + ], + schema: z.object({}), + handler: async (_agent: SolanaAgentKit, _input: Record) => { + try { + const data = await blueprintGetValidator(); + + return { + status: "success", + message: "Blueprint validator info fetched", + ...data, + }; + } catch (error: any) { + return { + status: "error", + message: `Failed to get Blueprint validator info: ${error.message}`, + }; + } + }, +}; diff --git a/packages/plugin-defi/src/blueprint/actions/blueprintStake.ts b/packages/plugin-defi/src/blueprint/actions/blueprintStake.ts new file mode 100644 index 000000000..765ab586d --- /dev/null +++ b/packages/plugin-defi/src/blueprint/actions/blueprintStake.ts @@ -0,0 +1,54 @@ +import type { Action, SolanaAgentKit } from "solana-agent-kit"; +import { z } from "zod"; +import { blueprintStake } from "../tools"; + +export const blueprintStakeAction: Action = { + name: "STAKE_SOL_WITH_BLUEPRINT", + similes: [ + "stake SOL with Blueprint", + "native stake SOL", + "delegate SOL to Blueprint validator", + "stake SOL natively", + "stake with Blueprint validator", + ], + description: + "Stake SOL natively with Blueprint validator (~6% APY). Zero custody — transaction is signed locally. This is native staking (not liquid staking), your wallet retains full authority over the stake account.", + examples: [ + [ + { + input: { + amountSol: 10, + }, + output: { + status: "success", + message: "Successfully staked 10 SOL with Blueprint validator", + signature: "5abc...def", + }, + explanation: + "Stake 10 SOL natively with Blueprint validator at ~6% APY", + }, + ], + ], + schema: z.object({ + amountSol: z + .number() + .positive() + .describe("Amount of SOL to stake with Blueprint validator"), + }), + handler: async (agent: SolanaAgentKit, input: Record) => { + try { + const signature = await blueprintStake(agent, input.amountSol); + + return { + status: "success", + message: `Successfully staked ${input.amountSol} SOL with Blueprint validator`, + signature, + }; + } catch (error: any) { + return { + status: "error", + message: `Blueprint staking failed: ${error.message}`, + }; + } + }, +}; diff --git a/packages/plugin-defi/src/blueprint/actions/blueprintUnstake.ts b/packages/plugin-defi/src/blueprint/actions/blueprintUnstake.ts new file mode 100644 index 000000000..1c774afc3 --- /dev/null +++ b/packages/plugin-defi/src/blueprint/actions/blueprintUnstake.ts @@ -0,0 +1,53 @@ +import type { Action, SolanaAgentKit } from "solana-agent-kit"; +import { z } from "zod"; +import { blueprintUnstake } from "../tools"; + +export const blueprintUnstakeAction: Action = { + name: "UNSTAKE_SOL_FROM_BLUEPRINT", + similes: [ + "unstake SOL from Blueprint", + "deactivate Blueprint stake", + "undelegate from Blueprint", + ], + description: + "Unstake (deactivate) SOL from Blueprint validator. After deactivation completes at the end of the current epoch, the SOL can be withdrawn.", + examples: [ + [ + { + input: { + stakeAccountAddress: "7xKX...", + }, + output: { + status: "success", + message: "Successfully deactivated stake account 7xKX...", + signature: "5abc...def", + }, + explanation: "Deactivate a stake account delegated to Blueprint", + }, + ], + ], + schema: z.object({ + stakeAccountAddress: z + .string() + .describe("The stake account address to deactivate"), + }), + handler: async (agent: SolanaAgentKit, input: Record) => { + try { + const signature = await blueprintUnstake( + agent, + input.stakeAccountAddress, + ); + + return { + status: "success", + message: `Successfully deactivated stake account ${input.stakeAccountAddress}`, + signature, + }; + } catch (error: any) { + return { + status: "error", + message: `Blueprint unstaking failed: ${error.message}`, + }; + } + }, +}; diff --git a/packages/plugin-defi/src/blueprint/actions/index.ts b/packages/plugin-defi/src/blueprint/actions/index.ts new file mode 100644 index 000000000..520e0eb36 --- /dev/null +++ b/packages/plugin-defi/src/blueprint/actions/index.ts @@ -0,0 +1,5 @@ +export * from "./blueprintStake"; +export * from "./blueprintUnstake"; +export * from "./blueprintCheckAccounts"; +export * from "./blueprintGetValidator"; +export * from "./blueprintDonate"; diff --git a/packages/plugin-defi/src/blueprint/constants/index.ts b/packages/plugin-defi/src/blueprint/constants/index.ts new file mode 100644 index 000000000..f817dad7c --- /dev/null +++ b/packages/plugin-defi/src/blueprint/constants/index.ts @@ -0,0 +1,3 @@ +export const BLUEPRINT_API_BASE = "https://solentic.theblueprint.xyz"; +export const BLUEPRINT_VOTE_ACCOUNT = + "528hi3StRe7uGjt99d35myh95JPc2MqBEHTPYcEhqMg5"; diff --git a/packages/plugin-defi/src/blueprint/tools/blueprint_check_accounts.ts b/packages/plugin-defi/src/blueprint/tools/blueprint_check_accounts.ts new file mode 100644 index 000000000..25d3f59bb --- /dev/null +++ b/packages/plugin-defi/src/blueprint/tools/blueprint_check_accounts.ts @@ -0,0 +1,22 @@ +import type { SolanaAgentKit } from "solana-agent-kit"; +import axios from "redaxios"; +import { BLUEPRINT_API_BASE } from "../constants"; + +/** + * Check all Blueprint stake accounts for a wallet. + * Returns stake accounts with status, balance, and epoch timing. + * + * @param agent - SolanaAgentKit instance + * @returns Stake accounts data from Blueprint API + */ +export async function blueprintCheckAccounts( + agent: SolanaAgentKit, +): Promise> { + const walletAddress = agent.wallet.publicKey.toBase58(); + + const response = await axios.get( + `${BLUEPRINT_API_BASE}/api/v1/stake/accounts/${walletAddress}`, + ); + + return response.data; +} diff --git a/packages/plugin-defi/src/blueprint/tools/blueprint_donate.ts b/packages/plugin-defi/src/blueprint/tools/blueprint_donate.ts new file mode 100644 index 000000000..8f44e8ac6 --- /dev/null +++ b/packages/plugin-defi/src/blueprint/tools/blueprint_donate.ts @@ -0,0 +1,37 @@ +import type { SolanaAgentKit } from "solana-agent-kit"; +import { Transaction } from "@solana/web3.js"; +import axios from "redaxios"; +import { BLUEPRINT_API_BASE } from "../constants"; + +/** + * Donate SOL to Blueprint to support development of the agentic staking platform. + * Zero custody — transaction is signed locally. + * + * @param agent - SolanaAgentKit instance + * @param amountSol - Amount of SOL to donate + * @returns Transaction signature after signing and submitting + */ +export async function blueprintDonate( + agent: SolanaAgentKit, + amountSol: number, +): Promise { + const walletAddress = agent.wallet.publicKey.toBase58(); + + const response = await axios.post( + `${BLUEPRINT_API_BASE}/api/v1/donate`, + { + walletAddress, + amountSol, + }, + ); + + const { transaction } = response.data; + const tx = Transaction.from(Buffer.from(transaction, "base64")); + tx.sign(agent.wallet); + + const signature = await agent.connection.sendRawTransaction( + tx.serialize(), + ); + + return signature; +} diff --git a/packages/plugin-defi/src/blueprint/tools/blueprint_get_validator.ts b/packages/plugin-defi/src/blueprint/tools/blueprint_get_validator.ts new file mode 100644 index 000000000..438a0ba0b --- /dev/null +++ b/packages/plugin-defi/src/blueprint/tools/blueprint_get_validator.ts @@ -0,0 +1,16 @@ +import axios from "redaxios"; +import { BLUEPRINT_API_BASE } from "../constants"; + +/** + * Get Blueprint validator information including APY, vote success, + * active stake, commission, and infrastructure details. + * + * @returns Validator profile data + */ +export async function blueprintGetValidator(): Promise> { + const response = await axios.get( + `${BLUEPRINT_API_BASE}/api/v1/validator`, + ); + + return response.data; +} diff --git a/packages/plugin-defi/src/blueprint/tools/blueprint_stake.ts b/packages/plugin-defi/src/blueprint/tools/blueprint_stake.ts new file mode 100644 index 000000000..2d7c8d5b7 --- /dev/null +++ b/packages/plugin-defi/src/blueprint/tools/blueprint_stake.ts @@ -0,0 +1,37 @@ +import type { SolanaAgentKit } from "solana-agent-kit"; +import { Transaction } from "@solana/web3.js"; +import axios from "redaxios"; +import { BLUEPRINT_API_BASE } from "../constants"; + +/** + * Stake SOL natively with Blueprint validator (~6% APY, zero custody). + * Returns the unsigned transaction base64 for the agent to sign and submit. + * + * @param agent - SolanaAgentKit instance + * @param amountSol - Amount of SOL to stake + * @returns Transaction signature after signing and submitting + */ +export async function blueprintStake( + agent: SolanaAgentKit, + amountSol: number, +): Promise { + const walletAddress = agent.wallet.publicKey.toBase58(); + + const response = await axios.post( + `${BLUEPRINT_API_BASE}/api/v1/stake/transaction`, + { + walletAddress, + amountSol, + }, + ); + + const { transaction } = response.data; + const tx = Transaction.from(Buffer.from(transaction, "base64")); + tx.sign(agent.wallet); + + const signature = await agent.connection.sendRawTransaction( + tx.serialize(), + ); + + return signature; +} diff --git a/packages/plugin-defi/src/blueprint/tools/blueprint_unstake.ts b/packages/plugin-defi/src/blueprint/tools/blueprint_unstake.ts new file mode 100644 index 000000000..f1bdff9c8 --- /dev/null +++ b/packages/plugin-defi/src/blueprint/tools/blueprint_unstake.ts @@ -0,0 +1,37 @@ +import type { SolanaAgentKit } from "solana-agent-kit"; +import { Transaction } from "@solana/web3.js"; +import axios from "redaxios"; +import { BLUEPRINT_API_BASE } from "../constants"; + +/** + * Unstake (deactivate) SOL from Blueprint validator. + * After deactivation, SOL can be withdrawn after the cooldown epoch. + * + * @param agent - SolanaAgentKit instance + * @param stakeAccountAddress - The stake account to deactivate + * @returns Transaction signature after signing and submitting + */ +export async function blueprintUnstake( + agent: SolanaAgentKit, + stakeAccountAddress: string, +): Promise { + const walletAddress = agent.wallet.publicKey.toBase58(); + + const response = await axios.post( + `${BLUEPRINT_API_BASE}/api/v1/unstake/transaction`, + { + walletAddress, + stakeAccountAddress, + }, + ); + + const { transaction } = response.data; + const tx = Transaction.from(Buffer.from(transaction, "base64")); + tx.sign(agent.wallet); + + const signature = await agent.connection.sendRawTransaction( + tx.serialize(), + ); + + return signature; +} diff --git a/packages/plugin-defi/src/blueprint/tools/index.ts b/packages/plugin-defi/src/blueprint/tools/index.ts new file mode 100644 index 000000000..488e4507d --- /dev/null +++ b/packages/plugin-defi/src/blueprint/tools/index.ts @@ -0,0 +1,5 @@ +export * from "./blueprint_stake"; +export * from "./blueprint_unstake"; +export * from "./blueprint_check_accounts"; +export * from "./blueprint_get_validator"; +export * from "./blueprint_donate"; diff --git a/packages/plugin-defi/src/index.ts b/packages/plugin-defi/src/index.ts index ef3b8ca53..3a576dad7 100644 --- a/packages/plugin-defi/src/index.ts +++ b/packages/plugin-defi/src/index.ts @@ -209,6 +209,22 @@ import { sanctumSwapLST, } from "./sanctum/tools"; +// Import Blueprint actions & tools +import { + blueprintStakeAction, + blueprintUnstakeAction, + blueprintCheckAccountsAction, + blueprintGetValidatorAction, + blueprintDonateAction, +} from "./blueprint/actions"; +import { + blueprintStake, + blueprintUnstake, + blueprintCheckAccounts, + blueprintGetValidator, + blueprintDonate, +} from "./blueprint/tools"; + // Import OKX tools import { getTokens, @@ -338,6 +354,13 @@ const DefiPlugin = { getLiquidity, getChainData, executeSwap, + + // Blueprint methods + blueprintStake, + blueprintUnstake, + blueprintCheckAccounts, + blueprintGetValidator, + blueprintDonate, }, // Combine all actions @@ -443,6 +466,13 @@ const DefiPlugin = { getLiquidityAction, getChainDataAction, executeSwapAction, + + // Blueprint actions + blueprintStakeAction, + blueprintUnstakeAction, + blueprintCheckAccountsAction, + blueprintGetValidatorAction, + blueprintDonateAction, ], // Initialize function