diff --git a/src/actions/createOrcaSingleSidedWhirlpool.ts b/src/actions/createOrcaSingleSidedWhirlpool.ts index affc445b..3a1fb526 100644 --- a/src/actions/createOrcaSingleSidedWhirlpool.ts +++ b/src/actions/createOrcaSingleSidedWhirlpool.ts @@ -87,7 +87,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( diff --git a/src/actions/index.ts b/src/actions/index.ts index b66c89e2..1ccdb640 100644 --- a/src/actions/index.ts +++ b/src/actions/index.ts @@ -28,34 +28,35 @@ import createOrcaSingleSidedWhirlpoolAction from "./createOrcaSingleSidedWhirlpo import launchPumpfunTokenAction from "./launchPumpfunToken"; 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, + 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, }; export type { Action, ActionExample, Handler } from "../types/action"; diff --git a/src/agent/index.ts b/src/agent/index.ts index d0b017ac..94f94d4b 100644 --- a/src/agent/index.ts +++ b/src/agent/index.ts @@ -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, @@ -51,6 +51,8 @@ import { create_TipLink, listNFTForSale, cancelListing, + fetchTokenReportSummary, + fetchTokenDetailedReport, OrderParams, } from "../tools"; @@ -85,24 +87,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; } @@ -476,4 +484,12 @@ export class SolanaAgentKit { async tensorCancelListing(nftMint: PublicKey): Promise { return cancelListing(this, nftMint); } + + async fetchTokenReportSummary(mint: string): Promise { + return fetchTokenReportSummary(mint); + } + + async fetchTokenDetailedReport(mint: string): Promise { + return fetchTokenDetailedReport(mint); + } } diff --git a/src/langchain/index.ts b/src/langchain/index.ts index 4c50cc75..38fd7eca 100644 --- a/src/langchain/index.ts +++ b/src/langchain/index.ts @@ -1919,6 +1919,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 { + 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 { + 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), @@ -1968,5 +2029,7 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) { new SolanaTipLinkTool(solanaKit), new SolanaListNFTForSaleTool(solanaKit), new SolanaCancelNFTListingTool(solanaKit), + new SolanaFetchTokenReportSummaryTool(solanaKit), + new SolanaFetchTokenDetailedReportTool(solanaKit), ]; } diff --git a/src/tools/index.ts b/src/tools/index.ts index 28554593..9e4a355d 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -1,3 +1,5 @@ +import exp from "constants"; + export * from "./request_faucet_funds"; export * from "./deploy_token"; export * from "./deploy_collection"; @@ -53,3 +55,4 @@ export * from "./rock_paper_scissor"; export * from "./create_tiplinks"; export * from "./tensor_trade"; +export * from "./rugcheck"; diff --git a/src/tools/rugcheck.ts b/src/tools/rugcheck.ts new file mode 100644 index 00000000..11d533de --- /dev/null +++ b/src/tools/rugcheck.ts @@ -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} The token summary report. + * @throws {Error} If the API call fails. + */ +export async function fetchTokenReportSummary( + mint: string, +): Promise { + 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} The detailed token report. + * @throws {Error} If the API call fails. + */ +export async function fetchTokenDetailedReport( + mint: string, +): Promise { + 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}.`); + } +} diff --git a/src/types/index.ts b/src/types/index.ts index 6d31949c..1dac764b 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -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; +} diff --git a/test/index.ts b/test/index.ts index 2a3312b7..00f9976f 100644 --- a/test/index.ts +++ b/test/index.ts @@ -1,4 +1,4 @@ -import { SolanaAgentKit , ACTIONS} from "../src"; +import { SolanaAgentKit, ACTIONS } from "../src"; import { createSolanaTools } from "../src/langchain"; import { HumanMessage } from "@langchain/core/messages"; import { MemorySaver } from "@langchain/langgraph";