mirror of
https://github.com/d0zingcat/solana-agent-kit.git
synced 2026-05-16 23:26:45 +00:00
Merge branch 'main' into getTokenDataByAddress
This commit is contained in:
@@ -2,7 +2,6 @@ import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { BN } from "@coral-xyz/anchor";
|
||||
import { Decimal } from "decimal.js";
|
||||
import { orcaCreateSingleSidedLiquidityPool } from "../tools";
|
||||
|
||||
@@ -87,7 +86,7 @@ const createOrcaSingleSidedWhirlpoolAction: Action = {
|
||||
const otherTokenMint = new PublicKey(input.otherTokenMint);
|
||||
const initialPrice = new Decimal(input.initialPrice);
|
||||
const maxPrice = new Decimal(input.maxPrice);
|
||||
const feeTier = input.feeTier
|
||||
const feeTier = input.feeTier;
|
||||
|
||||
// Create the whirlpool
|
||||
const signature = await orcaCreateSingleSidedLiquidityPool(
|
||||
|
||||
29
src/actions/getWalletAddress.ts
Normal file
29
src/actions/getWalletAddress.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { z } from "zod";
|
||||
import { SolanaAgentKit } from "..";
|
||||
import { get_wallet_address } from "../tools";
|
||||
import { Action } from "../types/action";
|
||||
|
||||
const getWalletAddressAction: Action = {
|
||||
name: "GET_WALLET_ADDRESS",
|
||||
similes: ["wallet address", "address", "wallet"],
|
||||
description: "Get wallet address of the agent",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {},
|
||||
output: {
|
||||
status: "success",
|
||||
address: "0x1234567890abcdef",
|
||||
},
|
||||
explanation: "The agent's wallet address is 0x1234567890abcdef",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({}),
|
||||
handler: async (agent: SolanaAgentKit) => ({
|
||||
status: "success",
|
||||
address: get_wallet_address(agent),
|
||||
}),
|
||||
};
|
||||
|
||||
export default getWalletAddressAction;
|
||||
@@ -10,6 +10,7 @@ import getTokenDataAction from "./getTokenData";
|
||||
import getTPSAction from "./getTPS";
|
||||
import fetchPriceAction from "./fetchPrice";
|
||||
import stakeWithJupAction from "./stakeWithJup";
|
||||
import stakeWithSolayerAction from "./stakeWithSolayer";
|
||||
import registerDomainAction from "./registerDomain";
|
||||
import lendAssetAction from "./lendAsset";
|
||||
import createGibworkTaskAction from "./createGibworkTask";
|
||||
@@ -26,36 +27,40 @@ import raydiumCreateCpmmAction from "./raydiumCreateCpmm";
|
||||
import raydiumCreateAmmV4Action from "./raydiumCreateAmmV4";
|
||||
import createOrcaSingleSidedWhirlpoolAction from "./createOrcaSingleSidedWhirlpool";
|
||||
import launchPumpfunTokenAction from "./launchPumpfunToken";
|
||||
import getWalletAddressAction from "./getWalletAddress";
|
||||
|
||||
export const ACTIONS = {
|
||||
"DEPLOY_TOKEN_ACTION" : deployTokenAction,
|
||||
"BALANCE_ACTION" : balanceAction,
|
||||
"TRANSFER_ACTION" : transferAction,
|
||||
"DEPLOY_COLLECTION_ACTION" : deployCollectionAction,
|
||||
"MINT_NFT_ACTION" : mintNFTAction,
|
||||
"TRADE_ACTION" : tradeAction,
|
||||
"REQUEST_FUNDS_ACTION" : requestFundsAction,
|
||||
"RESOLVE_DOMAIN_ACTION" : resolveDomainAction,
|
||||
"GET_TOKEN_DATA_ACTION" : getTokenDataAction,
|
||||
"GET_TPS_ACTION" : getTPSAction,
|
||||
"FETCH_PRICE_ACTION" : fetchPriceAction,
|
||||
"STAKE_WITH_JUP_ACTION" : stakeWithJupAction,
|
||||
"REGISTER_DOMAIN_ACTION" : registerDomainAction,
|
||||
"LEND_ASSET_ACTION" : lendAssetAction,
|
||||
"CREATE_GIBWORK_TASK_ACTION" : createGibworkTaskAction,
|
||||
"RESOLVE_SOL_DOMAIN_ACTION" : resolveSolDomainAction,
|
||||
"PYTH_FETCH_PRICE_ACTION" : pythFetchPriceAction,
|
||||
"GET_OWNED_DOMAINS_FOR_TLD_ACTION" : getOwnedDomainsForTLDAction,
|
||||
"GET_PRIMARY_DOMAIN_ACTION" : getPrimaryDomainAction,
|
||||
"GET_ALL_DOMAINS_TLDS_ACTION" : getAllDomainsTLDsAction,
|
||||
"GET_OWNED_ALL_DOMAINS_ACTION" : getOwnedAllDomainsAction,
|
||||
"CREATE_IMAGE_ACTION" : createImageAction,
|
||||
"GET_MAIN_ALL_DOMAINS_DOMAIN_ACTION" : getMainAllDomainsDomainAction,
|
||||
"GET_ALL_REGISTERED_ALL_DOMAINS_ACTION" : getAllRegisteredAllDomainsAction,
|
||||
"RAYDIUM_CREATE_CPMM_ACTION" : raydiumCreateCpmmAction,
|
||||
"RAYDIUM_CREATE_AMM_V4_ACTION" : raydiumCreateAmmV4Action,
|
||||
"CREATE_ORCA_SINGLE_SIDED_WHIRLPOOL_ACTION" : createOrcaSingleSidedWhirlpoolAction,
|
||||
"LAUNCH_PUMPFUN_TOKEN_ACTION" : launchPumpfunTokenAction,
|
||||
WALLET_ADDRESS_ACTION: getWalletAddressAction,
|
||||
DEPLOY_TOKEN_ACTION: deployTokenAction,
|
||||
BALANCE_ACTION: balanceAction,
|
||||
TRANSFER_ACTION: transferAction,
|
||||
DEPLOY_COLLECTION_ACTION: deployCollectionAction,
|
||||
MINT_NFT_ACTION: mintNFTAction,
|
||||
TRADE_ACTION: tradeAction,
|
||||
REQUEST_FUNDS_ACTION: requestFundsAction,
|
||||
RESOLVE_DOMAIN_ACTION: resolveDomainAction,
|
||||
GET_TOKEN_DATA_ACTION: getTokenDataAction,
|
||||
GET_TPS_ACTION: getTPSAction,
|
||||
FETCH_PRICE_ACTION: fetchPriceAction,
|
||||
STAKE_WITH_JUP_ACTION: stakeWithJupAction,
|
||||
STAKE_WITH_SOLAYER_ACTION : stakeWithSolayerAction,
|
||||
REGISTER_DOMAIN_ACTION: registerDomainAction,
|
||||
LEND_ASSET_ACTION: lendAssetAction,
|
||||
CREATE_GIBWORK_TASK_ACTION: createGibworkTaskAction,
|
||||
RESOLVE_SOL_DOMAIN_ACTION: resolveSolDomainAction,
|
||||
PYTH_FETCH_PRICE_ACTION: pythFetchPriceAction,
|
||||
GET_OWNED_DOMAINS_FOR_TLD_ACTION: getOwnedDomainsForTLDAction,
|
||||
GET_PRIMARY_DOMAIN_ACTION: getPrimaryDomainAction,
|
||||
GET_ALL_DOMAINS_TLDS_ACTION: getAllDomainsTLDsAction,
|
||||
GET_OWNED_ALL_DOMAINS_ACTION: getOwnedAllDomainsAction,
|
||||
CREATE_IMAGE_ACTION: createImageAction,
|
||||
GET_MAIN_ALL_DOMAINS_DOMAIN_ACTION: getMainAllDomainsDomainAction,
|
||||
GET_ALL_REGISTERED_ALL_DOMAINS_ACTION: getAllRegisteredAllDomainsAction,
|
||||
RAYDIUM_CREATE_CPMM_ACTION: raydiumCreateCpmmAction,
|
||||
RAYDIUM_CREATE_AMM_V4_ACTION: raydiumCreateAmmV4Action,
|
||||
CREATE_ORCA_SINGLE_SIDED_WHIRLPOOL_ACTION:
|
||||
createOrcaSingleSidedWhirlpoolAction,
|
||||
LAUNCH_PUMPFUN_TOKEN_ACTION: launchPumpfunTokenAction,
|
||||
};
|
||||
|
||||
export type { Action, ActionExample, Handler } from "../types/action";
|
||||
|
||||
60
src/actions/stakeWithSolayer.ts
Normal file
60
src/actions/stakeWithSolayer.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { stakeWithSolayer } from "../tools";
|
||||
|
||||
const stakeWithSolayerAction: Action = {
|
||||
name: "STAKE_WITH_SOLAYER",
|
||||
similes: [
|
||||
"stake sol",
|
||||
"solayer sol",
|
||||
"ssol",
|
||||
"stake with solayer",
|
||||
"solayer restaking",
|
||||
"solayer staking",
|
||||
"stake with sol",
|
||||
"liquid staking solayer",
|
||||
"get solayer sol",
|
||||
"solayer sol restaking",
|
||||
"solayer sol staking",
|
||||
],
|
||||
description:
|
||||
"Stake native SOL with Solayer's restaking protocol to receive Solayer SOL (sSOL)",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
amount: 1.0,
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
signature: "3FgHn9...",
|
||||
message: "Successfully staked 1.0 SOL for Solayer SOL (sSOL)",
|
||||
},
|
||||
explanation: "Stake 1.0 SOL to receive Solayer SOL (sSOL)",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
amount: z.number().positive().describe("Amount of SOL to stake"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const amount = input.amount as number;
|
||||
|
||||
const res = await stakeWithSolayer(agent, amount);
|
||||
return {
|
||||
status: "success",
|
||||
res,
|
||||
message: `Successfully staked ${amount} SOL for Solayer SOL (sSOL)`,
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Solayer staking failed: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default stakeWithSolayerAction;
|
||||
@@ -2,7 +2,7 @@ import { Connection, Keypair, PublicKey } from "@solana/web3.js";
|
||||
import bs58 from "bs58";
|
||||
import Decimal from "decimal.js";
|
||||
import { DEFAULT_OPTIONS } from "../constants";
|
||||
import { Config } from "../types";
|
||||
import { Config, TokenCheck } from "../types";
|
||||
import {
|
||||
deploy_collection,
|
||||
deploy_token,
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
getTokenDataByAddress,
|
||||
getTokenDataByTicker,
|
||||
stakeWithJup,
|
||||
stakeWithSolayer,
|
||||
sendCompressedAirdrop,
|
||||
orcaCreateSingleSidedLiquidityPool,
|
||||
orcaCreateCLMM,
|
||||
@@ -51,6 +52,8 @@ import {
|
||||
create_TipLink,
|
||||
listNFTForSale,
|
||||
cancelListing,
|
||||
fetchTokenReportSummary,
|
||||
fetchTokenDetailedReport,
|
||||
OrderParams,
|
||||
} from "../tools";
|
||||
|
||||
@@ -85,24 +88,30 @@ export class SolanaAgentKit {
|
||||
* @deprecated Using openai_api_key directly in constructor is deprecated.
|
||||
* Please use the new constructor with Config object instead:
|
||||
* @example
|
||||
* const agent = new SolanaAgentKit(privateKey, rpcUrl, {
|
||||
* const agent = new SolanaAgentKit(privateKey, rpcUrl, {
|
||||
* OPENAI_API_KEY: 'your-key'
|
||||
* });
|
||||
*/
|
||||
constructor(private_key: string, rpc_url: string, openai_api_key: string | null);
|
||||
constructor(
|
||||
private_key: string,
|
||||
rpc_url: string,
|
||||
openai_api_key: string | null,
|
||||
);
|
||||
constructor(private_key: string, rpc_url: string, config: Config);
|
||||
constructor(
|
||||
private_key: string,
|
||||
rpc_url: string,
|
||||
configOrKey: Config | string | null,
|
||||
) {
|
||||
this.connection = new Connection(rpc_url || "https://api.mainnet-beta.solana.com");
|
||||
this.connection = new Connection(
|
||||
rpc_url || "https://api.mainnet-beta.solana.com",
|
||||
);
|
||||
this.wallet = Keypair.fromSecretKey(bs58.decode(private_key));
|
||||
this.wallet_address = this.wallet.publicKey;
|
||||
|
||||
// Handle both old and new patterns
|
||||
if (typeof configOrKey === 'string' || configOrKey === null) {
|
||||
this.config = { OPENAI_API_KEY: configOrKey || '' };
|
||||
if (typeof configOrKey === "string" || configOrKey === null) {
|
||||
this.config = { OPENAI_API_KEY: configOrKey || "" };
|
||||
} else {
|
||||
this.config = configOrKey;
|
||||
}
|
||||
@@ -246,6 +255,10 @@ export class SolanaAgentKit {
|
||||
return stakeWithJup(this, amount);
|
||||
}
|
||||
|
||||
async restake(amount: number): Promise<string> {
|
||||
return stakeWithSolayer(this, amount);
|
||||
}
|
||||
|
||||
async sendCompressedAirdrop(
|
||||
mintAddress: string,
|
||||
amount: number,
|
||||
@@ -476,4 +489,12 @@ export class SolanaAgentKit {
|
||||
async tensorCancelListing(nftMint: PublicKey): Promise<string> {
|
||||
return cancelListing(this, nftMint);
|
||||
}
|
||||
|
||||
async fetchTokenReportSummary(mint: string): Promise<TokenCheck> {
|
||||
return fetchTokenReportSummary(mint);
|
||||
}
|
||||
|
||||
async fetchTokenDetailedReport(mint: string): Promise<TokenCheck> {
|
||||
return fetchTokenDetailedReport(mint);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { SolanaAgentKit } from "./agent";
|
||||
import { createSolanaTools } from "./langchain";
|
||||
import { createSolanaTools as createVercelAITools } from "./vercel-ai";
|
||||
|
||||
export { SolanaAgentKit, createSolanaTools };
|
||||
export { SolanaAgentKit, createSolanaTools, createVercelAITools };
|
||||
|
||||
// Optional: Export types that users might need
|
||||
export * from "./types";
|
||||
|
||||
@@ -862,6 +862,39 @@ export class SolanaStakeTool extends Tool {
|
||||
}
|
||||
}
|
||||
|
||||
export class SolanaRestakeTool extends Tool {
|
||||
name = "solana_restake";
|
||||
description = `This tool can be used to restake your SOL on Solayer to receive Solayer SOL (sSOL) as a Liquid Staking Token (LST).
|
||||
|
||||
Inputs:
|
||||
amount: number, eg 1 or 0.01 (required)`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected async _call(input: string): Promise<string> {
|
||||
try {
|
||||
const parsedInput = JSON.parse(input) || Number(input);
|
||||
|
||||
const tx = await this.solanaKit.restake(parsedInput.amount);
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "Staked successfully",
|
||||
transaction: tx,
|
||||
amount: parsedInput.amount,
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tool to fetch the price of a token in USDC
|
||||
*/
|
||||
@@ -1002,7 +1035,7 @@ export class SolanaClosePosition extends Tool {
|
||||
name = "orca_close_position";
|
||||
description = `Closes an existing liquidity position in an Orca Whirlpool. This function fetches the position
|
||||
details using the provided mint address and closes the position with a 1% slippage.
|
||||
|
||||
|
||||
Inputs (JSON string):
|
||||
- positionMintAddress: string, the address of the position mint that represents the liquidity position.`;
|
||||
|
||||
@@ -1089,9 +1122,9 @@ export class SolanaOrcaCreateCLMM extends Tool {
|
||||
|
||||
export class SolanaOrcaCreateSingleSideLiquidityPool extends Tool {
|
||||
name = "orca_create_single_sided_liquidity_pool";
|
||||
description = `Create a single-sided liquidity pool on Orca, the most efficient and capital-optimized CLMM platform on Solana.
|
||||
description = `Create a single-sided liquidity pool on Orca, the most efficient and capital-optimized CLMM platform on Solana.
|
||||
|
||||
This function initializes a single-sided liquidity pool, ideal for community driven project, fair launches, and fundraising. Minimize price impact by setting a narrow price range.
|
||||
This function initializes a single-sided liquidity pool, ideal for community driven project, fair launches, and fundraising. Minimize price impact by setting a narrow price range.
|
||||
|
||||
Inputs (JSON string):
|
||||
- depositTokenAmount: number, in units of the deposit token including decimals, e.g., 1000000000 (required).
|
||||
@@ -1919,6 +1952,67 @@ export class SolanaCancelNFTListingTool extends Tool {
|
||||
}
|
||||
}
|
||||
|
||||
export class SolanaFetchTokenReportSummaryTool extends Tool {
|
||||
name = "solana_fetch_token_report_summary";
|
||||
description = `Fetches a summary report for a specific token from RugCheck.
|
||||
Inputs:
|
||||
- mint: string, the mint address of the token, e.g., "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN" (required).`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected async _call(input: string): Promise<string> {
|
||||
try {
|
||||
const mint = input.trim();
|
||||
const report = await this.solanaKit.fetchTokenReportSummary(mint);
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "Token report summary fetched successfully",
|
||||
report,
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "FETCH_TOKEN_REPORT_SUMMARY_ERROR",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class SolanaFetchTokenDetailedReportTool extends Tool {
|
||||
name = "solana_fetch_token_detailed_report";
|
||||
description = `Fetches a detailed report for a specific token from RugCheck.
|
||||
Inputs:
|
||||
- mint: string, the mint address of the token, e.g., "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN" (required).`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected async _call(input: string): Promise<string> {
|
||||
try {
|
||||
const mint = input.trim();
|
||||
const detailedReport =
|
||||
await this.solanaKit.fetchTokenDetailedReport(mint);
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "Detailed token report fetched successfully",
|
||||
report: detailedReport,
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "FETCH_TOKEN_DETAILED_REPORT_ERROR",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function createSolanaTools(solanaKit: SolanaAgentKit) {
|
||||
return [
|
||||
new SolanaBalanceTool(solanaKit),
|
||||
@@ -1936,6 +2030,7 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) {
|
||||
new SolanaLendAssetTool(solanaKit),
|
||||
new SolanaTPSCalculatorTool(solanaKit),
|
||||
new SolanaStakeTool(solanaKit),
|
||||
new SolanaRestakeTool(solanaKit),
|
||||
new SolanaFetchPriceTool(solanaKit),
|
||||
new SolanaGetDomainTool(solanaKit),
|
||||
new SolanaTokenDataTool(solanaKit),
|
||||
@@ -1968,5 +2063,7 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) {
|
||||
new SolanaTipLinkTool(solanaKit),
|
||||
new SolanaListNFTForSaleTool(solanaKit),
|
||||
new SolanaCancelNFTListingTool(solanaKit),
|
||||
new SolanaFetchTokenReportSummaryTool(solanaKit),
|
||||
new SolanaFetchTokenDetailedReportTool(solanaKit),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ export async function getMainAllDomainsDomain(
|
||||
mainDomain = await _getFavoriteDomain(agent.connection, owner);
|
||||
return mainDomain.stale ? null : mainDomain.reverse;
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ export async function getPrimaryDomain(
|
||||
);
|
||||
}
|
||||
return reverse;
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
throw new Error(
|
||||
`Failed to get primary domain for account: ${account.toBase58()}`,
|
||||
);
|
||||
|
||||
10
src/tools/get_wallet_address.ts
Normal file
10
src/tools/get_wallet_address.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { SolanaAgentKit } from "..";
|
||||
|
||||
/**
|
||||
* Get the agents wallet address
|
||||
* @param agent - SolanaAgentKit instance
|
||||
* @returns string
|
||||
*/
|
||||
export function get_wallet_address(agent: SolanaAgentKit) {
|
||||
return agent.wallet_address.toBase58();
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
export * from "./get_wallet_address";
|
||||
export * from "./request_faucet_funds";
|
||||
export * from "./get_wallet_address";
|
||||
export * from "./request_faucet_funds";
|
||||
export * from "./deploy_token";
|
||||
export * from "./deploy_collection";
|
||||
@@ -18,6 +21,7 @@ export * from "./lend";
|
||||
export * from "./get_tps";
|
||||
export * from "./get_token_data";
|
||||
export * from "./stake_with_jup";
|
||||
export * from "./stake_with_solayer";
|
||||
export * from "./fetch_price";
|
||||
export * from "./send_compressed_airdrop";
|
||||
export * from "./orca_close_position";
|
||||
@@ -53,3 +57,4 @@ export * from "./rock_paper_scissor";
|
||||
export * from "./create_tiplinks";
|
||||
|
||||
export * from "./tensor_trade";
|
||||
export * from "./rugcheck";
|
||||
|
||||
@@ -24,7 +24,8 @@ export async function resolveSolDomain(
|
||||
|
||||
try {
|
||||
return await resolve(agent.connection, domain);
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
throw new Error(`Failed to resolve domain: ${domain}`);
|
||||
}
|
||||
}
|
||||
|
||||
53
src/tools/rugcheck.ts
Normal file
53
src/tools/rugcheck.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { TokenCheck } from "../types";
|
||||
|
||||
const BASE_URL = "https://api.rugcheck.xyz/v1";
|
||||
|
||||
/**
|
||||
* Fetches a summary report for a specific token.
|
||||
* @async
|
||||
* @param {string} mint - The mint address of the token.
|
||||
* @returns {Promise<TokenCheck>} The token summary report.
|
||||
* @throws {Error} If the API call fails.
|
||||
*/
|
||||
export async function fetchTokenReportSummary(
|
||||
mint: string,
|
||||
): Promise<TokenCheck> {
|
||||
try {
|
||||
const response = await fetch(`${BASE_URL}/tokens/${mint}/report/summary`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
return await response.json();
|
||||
} catch (error: any) {
|
||||
console.error(
|
||||
`Error fetching report summary for token ${mint}:`,
|
||||
error.message,
|
||||
);
|
||||
throw new Error(`Failed to fetch report summary for token ${mint}.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a detailed report for a specific token.
|
||||
* @async
|
||||
* @param {string} mint - The mint address of the token.
|
||||
* @returns {Promise<TokenCheck>} The detailed token report.
|
||||
* @throws {Error} If the API call fails.
|
||||
*/
|
||||
export async function fetchTokenDetailedReport(
|
||||
mint: string,
|
||||
): Promise<TokenCheck> {
|
||||
try {
|
||||
const response = await fetch(`${BASE_URL}/tokens/${mint}/report`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
return await response.json();
|
||||
} catch (error: any) {
|
||||
console.error(
|
||||
`Error fetching detailed report for token ${mint}:`,
|
||||
error.message,
|
||||
);
|
||||
throw new Error(`Failed to fetch detailed report for token ${mint}.`);
|
||||
}
|
||||
}
|
||||
@@ -88,6 +88,7 @@ export async function sendCompressedAirdrop(
|
||||
agent.wallet.publicKey,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
throw new Error(
|
||||
"Source token account not found and failed to create it. Please add funds to your wallet and try again.",
|
||||
);
|
||||
|
||||
64
src/tools/stake_with_solayer.ts
Normal file
64
src/tools/stake_with_solayer.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { VersionedTransaction } from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../index";
|
||||
|
||||
/**
|
||||
* Stake SOL with Solayer
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param amount Amount of SOL to stake
|
||||
* @returns Transaction signature
|
||||
*/
|
||||
export async function stakeWithSolayer(
|
||||
agent: SolanaAgentKit,
|
||||
amount: number,
|
||||
): Promise<string> {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`https://app.solayer.org/api/action/restake/ssol?amount=${amount}`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
account: agent.wallet.publicKey.toBase58(),
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
throw new Error(errorData.message || 'Staking request failed');
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
// Deserialize and prepare transaction
|
||||
const txn = VersionedTransaction.deserialize(
|
||||
Buffer.from(data.transaction, "base64"),
|
||||
);
|
||||
|
||||
// Update blockhash
|
||||
const { blockhash } = await agent.connection.getLatestBlockhash();
|
||||
txn.message.recentBlockhash = blockhash;
|
||||
|
||||
// Sign and send transaction
|
||||
txn.sign([agent.wallet]);
|
||||
const signature = await agent.connection.sendTransaction(txn, {
|
||||
preflightCommitment: "confirmed",
|
||||
maxRetries: 3,
|
||||
});
|
||||
|
||||
// Wait for confirmation
|
||||
const latestBlockhash = await agent.connection.getLatestBlockhash();
|
||||
await agent.connection.confirmTransaction({
|
||||
signature,
|
||||
blockhash: latestBlockhash.blockhash,
|
||||
lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
|
||||
});
|
||||
|
||||
return signature;
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
throw new Error(`Solayer sSOL staking failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ export async function listNFTForSale(
|
||||
throw new Error(`You don't own this NFT (${nftMint.toString()})`);
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
throw new Error(
|
||||
`No token account found for mint ${nftMint.toString()}. Make sure you own this NFT.`,
|
||||
);
|
||||
|
||||
@@ -153,3 +153,15 @@ export interface Action {
|
||||
*/
|
||||
handler: Handler;
|
||||
}
|
||||
|
||||
export interface TokenCheck {
|
||||
tokenProgram: string;
|
||||
tokenType: string;
|
||||
risks: Array<{
|
||||
name: string;
|
||||
level: string;
|
||||
description: string;
|
||||
score: number;
|
||||
}>;
|
||||
score: number;
|
||||
}
|
||||
|
||||
25
src/vercel-ai/index.ts
Normal file
25
src/vercel-ai/index.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { tool, type CoreTool } from "ai";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { executeAction } from "../utils/actionExecutor";
|
||||
import { ACTIONS } from "../actions";
|
||||
|
||||
export function createSolanaTools(
|
||||
solanaAgentKit: SolanaAgentKit,
|
||||
): Record<string, CoreTool> {
|
||||
const tools: Record<string, CoreTool> = {};
|
||||
const actionKeys = Object.keys(ACTIONS);
|
||||
|
||||
for (const key of actionKeys) {
|
||||
const action = ACTIONS[key as keyof typeof ACTIONS];
|
||||
tools[key] = tool({
|
||||
// @ts-expect-error Value matches type however TS still shows error
|
||||
id: action.name,
|
||||
description: action.description,
|
||||
parameters: action.schema,
|
||||
execute: async (params) =>
|
||||
await executeAction(action, solanaAgentKit, params),
|
||||
});
|
||||
}
|
||||
|
||||
return tools;
|
||||
}
|
||||
Reference in New Issue
Block a user