Skip to content

Commit

Permalink
Rugcheck API Integrated [Latest] (#109)
Browse files Browse the repository at this point in the history
# Pull Request Description
Provides a streamlined integration with the RugCheck API for Solana
tokens, allowing developers to access and interact with key features
like token reports, statistics, and voting functionality.
## Related Issue
Fixes # (issue number)
#17 
and it's a followm up and latest pull for this PR #90 

## Changes Made
This PR adds the following changes:
<!-- List the key changes made in this PR -->
Integrated Endpoints and Methods : 
**GET** `/tokens/{mint}/report/summary`: Generate a summary report for a
specific token.
**GET** `/tokens/{mint}/report`: Fetch a detailed report for a specific
token.

## Implementation Details
<!-- Provide technical details about the implementation -->

This integration enables efficient access to RugCheck's token data and
analytics, making it a valuable tool for developers.

**Features** : 
- Generate a summary report for a specific token.
- Retrieve a detailed report for a specific token.

## Transaction executed by agent 
<!-- If applicable, provide example usage, transactions, or screenshots
-->
Example transaction: 

## Prompt Used
<!-- If relevant, include the prompt or configuration used -->
```
```

## Additional Notes
<!-- Any additional information that reviewers should know -->

## Checklist
- [x] I have tested these changes locally
- [ ] I have updated the documentation
- [ ] I have added a transaction link
- [ ] I have added the prompt used to test it
  • Loading branch information
thearyanag authored Jan 3, 2025
2 parents bfa7872 + b3a02fe commit cb0e3a6
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 36 deletions.
2 changes: 1 addition & 1 deletion src/actions/createOrcaSingleSidedWhirlpool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
57 changes: 29 additions & 28 deletions src/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
28 changes: 22 additions & 6 deletions src/agent/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -51,6 +51,8 @@ import {
create_TipLink,
listNFTForSale,
cancelListing,
fetchTokenReportSummary,
fetchTokenDetailedReport,
OrderParams,
} from "../tools";

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -476,4 +484,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);
}
}
63 changes: 63 additions & 0 deletions src/langchain/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<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),
Expand Down Expand Up @@ -1968,5 +2029,7 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) {
new SolanaTipLinkTool(solanaKit),
new SolanaListNFTForSaleTool(solanaKit),
new SolanaCancelNFTListingTool(solanaKit),
new SolanaFetchTokenReportSummaryTool(solanaKit),
new SolanaFetchTokenDetailedReportTool(solanaKit),
];
}
3 changes: 3 additions & 0 deletions src/tools/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import exp from "constants";

export * from "./request_faucet_funds";
export * from "./deploy_token";
export * from "./deploy_collection";
Expand Down Expand Up @@ -53,3 +55,4 @@ export * from "./rock_paper_scissor";
export * from "./create_tiplinks";

export * from "./tensor_trade";
export * from "./rugcheck";
53 changes: 53 additions & 0 deletions src/tools/rugcheck.ts
Original file line number Diff line number Diff line change
@@ -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}.`);
}
}
12 changes: 12 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
2 changes: 1 addition & 1 deletion test/index.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand Down

0 comments on commit cb0e3a6

Please sign in to comment.